2011-11-18 10:28:17 -08:00
|
|
|
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
2012-05-21 04:12:37 -07:00
|
|
|
* 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/. */
|
2011-11-18 10:28:17 -08:00
|
|
|
|
|
|
|
package org.mozilla.gecko;
|
|
|
|
|
2012-07-27 17:53:54 -07:00
|
|
|
import org.mozilla.gecko.gfx.InputConnectionHandler;
|
|
|
|
|
2012-02-27 16:29:35 -08:00
|
|
|
import android.R;
|
2012-07-19 11:00:07 -07:00
|
|
|
import android.content.Context;
|
2012-06-08 10:57:16 -07:00
|
|
|
import android.os.Build;
|
2012-02-27 16:29:35 -08:00
|
|
|
import android.text.Editable;
|
|
|
|
import android.text.InputType;
|
|
|
|
import android.text.Selection;
|
|
|
|
import android.text.method.KeyListener;
|
|
|
|
import android.text.method.TextKeyListener;
|
2012-05-23 18:53:42 -07:00
|
|
|
import android.util.DisplayMetrics;
|
2012-02-27 16:29:35 -08:00
|
|
|
import android.util.Log;
|
|
|
|
import android.view.KeyEvent;
|
|
|
|
import android.view.View;
|
|
|
|
import android.view.inputmethod.BaseInputConnection;
|
|
|
|
import android.view.inputmethod.EditorInfo;
|
|
|
|
import android.view.inputmethod.ExtractedText;
|
|
|
|
import android.view.inputmethod.ExtractedTextRequest;
|
|
|
|
import android.view.inputmethod.InputConnection;
|
|
|
|
import android.view.inputmethod.InputMethodManager;
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2012-11-01 13:11:03 -07:00
|
|
|
import java.lang.reflect.InvocationHandler;
|
|
|
|
import java.lang.reflect.Method;
|
|
|
|
import java.lang.reflect.Proxy;
|
2012-02-27 16:29:35 -08:00
|
|
|
import java.util.Timer;
|
|
|
|
import java.util.TimerTask;
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2012-08-02 11:56:52 -07:00
|
|
|
class GeckoInputConnection
|
2011-11-18 10:28:17 -08:00
|
|
|
extends BaseInputConnection
|
2012-11-01 13:11:02 -07:00
|
|
|
implements InputConnectionHandler, GeckoEditableListener {
|
2012-02-27 16:29:22 -08:00
|
|
|
|
2011-12-15 13:35:45 -08:00
|
|
|
private static final boolean DEBUG = false;
|
|
|
|
protected static final String LOGTAG = "GeckoInputConnection";
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2012-02-27 16:29:44 -08:00
|
|
|
// IME stuff
|
|
|
|
public static final int IME_STATE_DISABLED = 0;
|
|
|
|
public static final int IME_STATE_ENABLED = 1;
|
|
|
|
public static final int IME_STATE_PASSWORD = 2;
|
|
|
|
public static final int IME_STATE_PLUGIN = 3;
|
|
|
|
|
|
|
|
private static final int NOTIFY_IME_RESETINPUTSTATE = 0;
|
|
|
|
private static final int NOTIFY_IME_CANCELCOMPOSITION = 2;
|
|
|
|
private static final int NOTIFY_IME_FOCUSCHANGE = 3;
|
|
|
|
|
2012-05-23 18:53:42 -07:00
|
|
|
private static final int INLINE_IME_MIN_DISPLAY_SIZE = 480;
|
|
|
|
|
Backout 533faa3c50ed, 718abc1bd4ad, af2d5272c06b, ad5554e1345d, c9ef1b41b829, d3a825311d11, 0a51bcb3eb9e, a01a327e8ec4, 973b0ed30b8b, 39851bbcfaa1 & a92d2d2a3b0e (bug 805162), d4884aab5ce6, 06fcbaf40cb4, daccc3fe7c70, 881eb2a2906e, 76232441ae06, 01ae34fa1b3f & 5f405fc4e323 (bug 783092), a03d8d4db1c2, 49beb3801192, 174634554a97, 0bd27e755a83, 19e8f151ca67, a6604e038bc0, ed3b8237e76e & 082cf8d72554 (bug 785945) for bustage or conflicting with backout of said bustage on a CLOSED TREE
2012-10-31 17:16:35 -07:00
|
|
|
private static final Timer mIMETimer = new Timer("GeckoInputConnection Timer");
|
2012-11-01 13:11:03 -07:00
|
|
|
|
2012-02-27 16:29:44 -08:00
|
|
|
private static int mIMEState;
|
2012-08-14 08:21:19 -07:00
|
|
|
private static String mIMETypeHint = "";
|
2012-08-26 19:16:22 -07:00
|
|
|
private static String mIMEModeHint = "";
|
2012-08-14 08:21:19 -07:00
|
|
|
private static String mIMEActionHint = "";
|
2012-02-27 16:29:44 -08:00
|
|
|
|
2012-07-19 11:00:07 -07:00
|
|
|
private String mCurrentInputMethod;
|
|
|
|
|
2012-11-01 13:11:02 -07:00
|
|
|
private final GeckoEditableClient mEditableClient;
|
2012-08-09 15:38:10 -07:00
|
|
|
protected int mBatchEditCount;
|
2012-02-27 16:29:44 -08:00
|
|
|
private ExtractedTextRequest mUpdateRequest;
|
|
|
|
private final ExtractedText mUpdateExtract = new ExtractedText();
|
|
|
|
|
2012-11-01 13:11:02 -07:00
|
|
|
public static InputConnectionHandler create(View targetView,
|
|
|
|
GeckoEditableClient editable) {
|
2011-12-15 13:35:45 -08:00
|
|
|
if (DEBUG)
|
2012-11-01 13:11:02 -07:00
|
|
|
return DebugGeckoInputConnection.create(targetView, editable);
|
2011-12-15 13:35:45 -08:00
|
|
|
else
|
2012-11-01 13:11:02 -07:00
|
|
|
return new GeckoInputConnection(targetView, editable);
|
2011-11-18 10:28:17 -08:00
|
|
|
}
|
|
|
|
|
2012-11-01 13:11:02 -07:00
|
|
|
protected GeckoInputConnection(View targetView,
|
|
|
|
GeckoEditableClient editable) {
|
2011-11-18 10:28:17 -08:00
|
|
|
super(targetView, true);
|
2012-11-01 13:11:02 -07:00
|
|
|
mEditableClient = editable;
|
|
|
|
// install the editable => input connection listener
|
|
|
|
editable.setListener(this);
|
2011-11-18 10:28:17 -08:00
|
|
|
mIMEState = IME_STATE_DISABLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2012-11-01 13:11:03 -07:00
|
|
|
public synchronized boolean beginBatchEdit() {
|
2012-08-09 15:38:10 -07:00
|
|
|
mBatchEditCount++;
|
2012-11-01 13:11:03 -07:00
|
|
|
mEditableClient.setUpdateGecko(false);
|
2011-11-18 10:28:17 -08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2012-11-01 13:11:03 -07:00
|
|
|
public synchronized boolean endBatchEdit() {
|
2012-08-09 15:38:10 -07:00
|
|
|
if (mBatchEditCount > 0) {
|
|
|
|
mBatchEditCount--;
|
2012-11-01 13:11:03 -07:00
|
|
|
if (mBatchEditCount == 0) {
|
|
|
|
mEditableClient.setUpdateGecko(true);
|
|
|
|
}
|
2012-08-09 15:38:10 -07:00
|
|
|
} else {
|
|
|
|
Log.w(LOGTAG, "endBatchEdit() called, but mBatchEditCount == 0?!");
|
|
|
|
}
|
2011-11-18 10:28:17 -08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Editable getEditable() {
|
2012-11-01 13:11:02 -07:00
|
|
|
return mEditableClient.getEditable();
|
2011-11-18 10:28:17 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean performContextMenuAction(int id) {
|
2012-11-01 13:11:03 -07:00
|
|
|
Editable editable = getEditable();
|
|
|
|
int selStart = Selection.getSelectionStart(editable);
|
|
|
|
int selEnd = Selection.getSelectionEnd(editable);
|
2011-11-18 10:28:17 -08:00
|
|
|
|
|
|
|
switch (id) {
|
|
|
|
case R.id.selectAll:
|
2012-11-01 13:11:03 -07:00
|
|
|
setSelection(0, editable.length());
|
2011-11-18 10:28:17 -08:00
|
|
|
break;
|
|
|
|
case R.id.cut:
|
2011-12-15 13:35:45 -08:00
|
|
|
// If selection is empty, we'll select everything
|
2012-11-01 13:11:03 -07:00
|
|
|
if (selStart == selEnd) {
|
|
|
|
// Fill the clipboard
|
|
|
|
GeckoAppShell.setClipboardText(editable.toString());
|
|
|
|
editable.clear();
|
|
|
|
} else {
|
|
|
|
GeckoAppShell.setClipboardText(
|
|
|
|
editable.toString().substring(
|
|
|
|
Math.min(selStart, selEnd),
|
|
|
|
Math.max(selStart, selEnd)));
|
|
|
|
editable.delete(selStart, selEnd);
|
|
|
|
}
|
2011-11-18 10:28:17 -08:00
|
|
|
break;
|
|
|
|
case R.id.paste:
|
|
|
|
commitText(GeckoAppShell.getClipboardText(), 1);
|
|
|
|
break;
|
|
|
|
case R.id.copy:
|
2012-06-19 12:13:41 -07:00
|
|
|
// Copy the current selection or the empty string if nothing is selected.
|
2012-11-01 13:11:03 -07:00
|
|
|
String copiedText = selStart == selEnd ? "" :
|
|
|
|
editable.toString().substring(
|
|
|
|
Math.min(selStart, selEnd),
|
|
|
|
Math.max(selStart, selEnd));
|
|
|
|
GeckoAppShell.setClipboardText(copiedText);
|
2011-11-18 10:28:17 -08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public ExtractedText getExtractedText(ExtractedTextRequest req, int flags) {
|
|
|
|
if (req == null)
|
|
|
|
return null;
|
|
|
|
|
2012-01-06 18:27:09 -08:00
|
|
|
if ((flags & GET_EXTRACTED_TEXT_MONITOR) != 0)
|
|
|
|
mUpdateRequest = req;
|
|
|
|
|
2012-11-01 13:11:03 -07:00
|
|
|
Editable editable = getEditable();
|
|
|
|
int selStart = Selection.getSelectionStart(editable);
|
|
|
|
int selEnd = Selection.getSelectionEnd(editable);
|
2012-06-19 12:13:41 -07:00
|
|
|
|
2011-11-18 10:28:17 -08:00
|
|
|
ExtractedText extract = new ExtractedText();
|
|
|
|
extract.flags = 0;
|
|
|
|
extract.partialStartOffset = -1;
|
|
|
|
extract.partialEndOffset = -1;
|
2012-11-01 13:11:03 -07:00
|
|
|
extract.selectionStart = selStart;
|
|
|
|
extract.selectionEnd = selEnd;
|
2011-12-15 13:35:45 -08:00
|
|
|
extract.startOffset = 0;
|
2012-11-01 13:11:03 -07:00
|
|
|
extract.text = editable;
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2011-12-15 13:35:45 -08:00
|
|
|
return extract;
|
2011-11-18 10:28:17 -08:00
|
|
|
}
|
|
|
|
|
2012-08-07 08:09:15 -07:00
|
|
|
private static void postToUiThread(Runnable runnable) {
|
|
|
|
// postToUiThread() is called by the Gecko and TimerTask threads.
|
|
|
|
// The UI thread does not need to post Runnables to itself.
|
|
|
|
GeckoApp.mAppContext.mMainHandler.post(runnable);
|
|
|
|
}
|
|
|
|
|
2012-07-23 11:52:55 -07:00
|
|
|
private static View getView() {
|
2012-08-20 12:43:53 -07:00
|
|
|
return GeckoApp.mAppContext.getLayerView();
|
2012-07-23 11:52:55 -07:00
|
|
|
}
|
|
|
|
|
2012-02-27 16:29:55 -08:00
|
|
|
private static InputMethodManager getInputMethodManager() {
|
2012-07-26 10:53:51 -07:00
|
|
|
View view = getView();
|
|
|
|
if (view == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
Context context = view.getContext();
|
2012-07-22 00:18:14 -07:00
|
|
|
return InputMethods.getInputMethodManager(context);
|
2012-02-27 16:29:55 -08:00
|
|
|
}
|
|
|
|
|
2012-11-01 13:11:02 -07:00
|
|
|
public void onTextChange(String text, int start, int oldEnd, int newEnd) {
|
2012-07-18 15:26:15 -07:00
|
|
|
|
2012-11-01 13:11:02 -07:00
|
|
|
if (mBatchEditCount > 0 || mUpdateRequest == null) {
|
Backout 533faa3c50ed, 718abc1bd4ad, af2d5272c06b, ad5554e1345d, c9ef1b41b829, d3a825311d11, 0a51bcb3eb9e, a01a327e8ec4, 973b0ed30b8b, 39851bbcfaa1 & a92d2d2a3b0e (bug 805162), d4884aab5ce6, 06fcbaf40cb4, daccc3fe7c70, 881eb2a2906e, 76232441ae06, 01ae34fa1b3f & 5f405fc4e323 (bug 783092), a03d8d4db1c2, 49beb3801192, 174634554a97, 0bd27e755a83, 19e8f151ca67, a6604e038bc0, ed3b8237e76e & 082cf8d72554 (bug 785945) for bustage or conflicting with backout of said bustage on a CLOSED TREE
2012-10-31 17:16:35 -07:00
|
|
|
return;
|
2012-11-01 13:11:02 -07:00
|
|
|
}
|
Backout 533faa3c50ed, 718abc1bd4ad, af2d5272c06b, ad5554e1345d, c9ef1b41b829, d3a825311d11, 0a51bcb3eb9e, a01a327e8ec4, 973b0ed30b8b, 39851bbcfaa1 & a92d2d2a3b0e (bug 805162), d4884aab5ce6, 06fcbaf40cb4, daccc3fe7c70, 881eb2a2906e, 76232441ae06, 01ae34fa1b3f & 5f405fc4e323 (bug 783092), a03d8d4db1c2, 49beb3801192, 174634554a97, 0bd27e755a83, 19e8f151ca67, a6604e038bc0, ed3b8237e76e & 082cf8d72554 (bug 785945) for bustage or conflicting with backout of said bustage on a CLOSED TREE
2012-10-31 17:16:35 -07:00
|
|
|
|
2012-11-01 13:11:02 -07:00
|
|
|
final InputMethodManager imm = getInputMethodManager();
|
|
|
|
if (imm == null) {
|
2012-09-19 17:47:39 -07:00
|
|
|
return;
|
2012-11-01 13:11:02 -07:00
|
|
|
}
|
|
|
|
final View v = getView();
|
|
|
|
final Editable editable = getEditable();
|
2012-01-06 18:27:09 -08:00
|
|
|
|
|
|
|
mUpdateExtract.flags = 0;
|
2012-11-01 13:11:02 -07:00
|
|
|
// Update from (0, oldEnd) to (0, newEnd) because some IMEs
|
2012-01-06 18:27:09 -08:00
|
|
|
// assume that updates start at zero, according to jchen.
|
|
|
|
mUpdateExtract.partialStartOffset = 0;
|
2012-11-01 13:11:02 -07:00
|
|
|
mUpdateExtract.partialEndOffset = editable.length();
|
|
|
|
mUpdateExtract.selectionStart =
|
|
|
|
Selection.getSelectionStart(editable);
|
|
|
|
mUpdateExtract.selectionEnd =
|
|
|
|
Selection.getSelectionEnd(editable);
|
2012-01-06 18:27:09 -08:00
|
|
|
mUpdateExtract.startOffset = 0;
|
2012-11-01 13:11:02 -07:00
|
|
|
mUpdateExtract.text = editable;
|
2012-01-06 18:27:09 -08:00
|
|
|
|
2012-11-01 13:11:02 -07:00
|
|
|
imm.updateExtractedText(v, mUpdateRequest.token,
|
|
|
|
mUpdateExtract);
|
2011-11-18 10:28:17 -08:00
|
|
|
}
|
|
|
|
|
2012-11-01 13:11:02 -07:00
|
|
|
public void onSelectionChange(int start, int end) {
|
Backout 533faa3c50ed, 718abc1bd4ad, af2d5272c06b, ad5554e1345d, c9ef1b41b829, d3a825311d11, 0a51bcb3eb9e, a01a327e8ec4, 973b0ed30b8b, 39851bbcfaa1 & a92d2d2a3b0e (bug 805162), d4884aab5ce6, 06fcbaf40cb4, daccc3fe7c70, 881eb2a2906e, 76232441ae06, 01ae34fa1b3f & 5f405fc4e323 (bug 783092), a03d8d4db1c2, 49beb3801192, 174634554a97, 0bd27e755a83, 19e8f151ca67, a6604e038bc0, ed3b8237e76e & 082cf8d72554 (bug 785945) for bustage or conflicting with backout of said bustage on a CLOSED TREE
2012-10-31 17:16:35 -07:00
|
|
|
|
2012-11-01 13:11:02 -07:00
|
|
|
if (mBatchEditCount > 0) {
|
|
|
|
return;
|
2012-10-31 14:35:31 -07:00
|
|
|
}
|
2012-11-01 13:11:02 -07:00
|
|
|
final InputMethodManager imm = getInputMethodManager();
|
|
|
|
if (imm == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
final View v = getView();
|
|
|
|
final Editable editable = getEditable();
|
|
|
|
imm.updateSelection(v, start, end, getComposingSpanStart(editable),
|
|
|
|
getComposingSpanEnd(editable));
|
2011-11-18 10:28:17 -08:00
|
|
|
}
|
|
|
|
|
2012-06-01 11:09:29 -07:00
|
|
|
protected void resetCompositionState() {
|
2012-08-09 15:38:10 -07:00
|
|
|
if (mBatchEditCount > 0) {
|
|
|
|
Log.d(LOGTAG, "resetCompositionState: resetting mBatchEditCount "
|
|
|
|
+ mBatchEditCount + " -> 0");
|
|
|
|
mBatchEditCount = 0;
|
|
|
|
}
|
|
|
|
|
2012-11-01 13:11:03 -07:00
|
|
|
removeComposingSpans(getEditable());
|
2012-01-06 18:27:09 -08:00
|
|
|
mUpdateRequest = null;
|
2011-11-18 10:28:17 -08:00
|
|
|
}
|
|
|
|
|
2012-02-27 16:29:22 -08:00
|
|
|
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
|
2011-11-18 10:28:17 -08:00
|
|
|
outAttrs.inputType = InputType.TYPE_CLASS_TEXT;
|
|
|
|
outAttrs.imeOptions = EditorInfo.IME_ACTION_NONE;
|
|
|
|
outAttrs.actionLabel = null;
|
|
|
|
|
|
|
|
if (mIMEState == IME_STATE_PASSWORD)
|
|
|
|
outAttrs.inputType |= InputType.TYPE_TEXT_VARIATION_PASSWORD;
|
|
|
|
else if (mIMETypeHint.equalsIgnoreCase("url"))
|
|
|
|
outAttrs.inputType |= InputType.TYPE_TEXT_VARIATION_URI;
|
|
|
|
else if (mIMETypeHint.equalsIgnoreCase("email"))
|
|
|
|
outAttrs.inputType |= InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
|
|
|
|
else if (mIMETypeHint.equalsIgnoreCase("search"))
|
|
|
|
outAttrs.imeOptions = EditorInfo.IME_ACTION_SEARCH;
|
|
|
|
else if (mIMETypeHint.equalsIgnoreCase("tel"))
|
|
|
|
outAttrs.inputType = InputType.TYPE_CLASS_PHONE;
|
|
|
|
else if (mIMETypeHint.equalsIgnoreCase("number") ||
|
|
|
|
mIMETypeHint.equalsIgnoreCase("range"))
|
2012-06-29 15:49:48 -07:00
|
|
|
outAttrs.inputType = InputType.TYPE_CLASS_NUMBER
|
|
|
|
| InputType.TYPE_NUMBER_FLAG_SIGNED
|
|
|
|
| InputType.TYPE_NUMBER_FLAG_DECIMAL;
|
2012-08-08 00:42:00 -07:00
|
|
|
else if (mIMETypeHint.equalsIgnoreCase("week") ||
|
|
|
|
mIMETypeHint.equalsIgnoreCase("month"))
|
|
|
|
outAttrs.inputType = InputType.TYPE_CLASS_DATETIME
|
|
|
|
| InputType.TYPE_DATETIME_VARIATION_DATE;
|
2012-08-26 19:16:22 -07:00
|
|
|
else if (mIMEModeHint.equalsIgnoreCase("numeric"))
|
|
|
|
outAttrs.inputType = InputType.TYPE_CLASS_NUMBER |
|
|
|
|
InputType.TYPE_NUMBER_FLAG_SIGNED |
|
|
|
|
InputType.TYPE_NUMBER_FLAG_DECIMAL;
|
|
|
|
else if (mIMEModeHint.equalsIgnoreCase("digit"))
|
|
|
|
outAttrs.inputType = InputType.TYPE_CLASS_NUMBER;
|
2012-10-26 18:24:42 -07:00
|
|
|
else {
|
|
|
|
outAttrs.inputType |= InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
|
|
|
|
if (mIMEModeHint.equalsIgnoreCase("uppercase"))
|
|
|
|
outAttrs.inputType |= InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS;
|
|
|
|
else if (mIMEModeHint.equalsIgnoreCase("titlecase"))
|
|
|
|
outAttrs.inputType |= InputType.TYPE_TEXT_FLAG_CAP_WORDS;
|
|
|
|
else if (mIMEModeHint.equalsIgnoreCase("autocapitalized"))
|
|
|
|
outAttrs.inputType |= InputType.TYPE_TEXT_FLAG_CAP_SENTENCES;
|
|
|
|
// lowercase mode is the default
|
|
|
|
}
|
2011-11-18 10:28:17 -08:00
|
|
|
|
|
|
|
if (mIMEActionHint.equalsIgnoreCase("go"))
|
|
|
|
outAttrs.imeOptions = EditorInfo.IME_ACTION_GO;
|
|
|
|
else if (mIMEActionHint.equalsIgnoreCase("done"))
|
|
|
|
outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE;
|
|
|
|
else if (mIMEActionHint.equalsIgnoreCase("next"))
|
|
|
|
outAttrs.imeOptions = EditorInfo.IME_ACTION_NEXT;
|
|
|
|
else if (mIMEActionHint.equalsIgnoreCase("search"))
|
|
|
|
outAttrs.imeOptions = EditorInfo.IME_ACTION_SEARCH;
|
|
|
|
else if (mIMEActionHint.equalsIgnoreCase("send"))
|
|
|
|
outAttrs.imeOptions = EditorInfo.IME_ACTION_SEND;
|
2012-08-14 08:21:19 -07:00
|
|
|
else if (mIMEActionHint.length() > 0) {
|
|
|
|
if (DEBUG)
|
|
|
|
Log.w(LOGTAG, "Unexpected mIMEActionHint=\"" + mIMEActionHint + "\"");
|
2011-11-18 10:28:17 -08:00
|
|
|
outAttrs.actionLabel = mIMEActionHint;
|
2012-08-14 08:21:19 -07:00
|
|
|
}
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2012-08-01 14:42:11 -07:00
|
|
|
GeckoApp app = GeckoApp.mAppContext;
|
2012-08-01 14:56:26 -07:00
|
|
|
DisplayMetrics metrics = app.getResources().getDisplayMetrics();
|
2012-05-23 18:53:42 -07:00
|
|
|
if (Math.min(metrics.widthPixels, metrics.heightPixels) > INLINE_IME_MIN_DISPLAY_SIZE) {
|
|
|
|
// prevent showing full-screen keyboard only when the screen is tall enough
|
|
|
|
// to show some reasonable amount of the page (see bug 752709)
|
|
|
|
outAttrs.imeOptions |= EditorInfo.IME_FLAG_NO_EXTRACT_UI
|
|
|
|
| EditorInfo.IME_FLAG_NO_FULLSCREEN;
|
|
|
|
}
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2012-07-19 11:00:07 -07:00
|
|
|
String prevInputMethod = mCurrentInputMethod;
|
2012-08-01 14:42:11 -07:00
|
|
|
mCurrentInputMethod = InputMethods.getCurrentInputMethod(app);
|
2012-10-25 23:49:08 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
Log.d(LOGTAG, "IME: CurrentInputMethod=" + mCurrentInputMethod);
|
|
|
|
}
|
2012-07-19 11:00:07 -07:00
|
|
|
|
2012-07-22 00:18:14 -07:00
|
|
|
// If the user has changed IMEs, then notify input method observers.
|
2012-07-19 11:00:07 -07:00
|
|
|
if (mCurrentInputMethod != prevInputMethod) {
|
2012-08-01 14:42:11 -07:00
|
|
|
FormAssistPopup popup = app.mFormAssistPopup;
|
2012-07-19 11:00:07 -07:00
|
|
|
if (popup != null) {
|
2012-07-22 00:18:14 -07:00
|
|
|
popup.onInputMethodChanged(mCurrentInputMethod);
|
2012-07-19 11:00:07 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-01 11:09:29 -07:00
|
|
|
resetCompositionState();
|
2011-11-18 10:28:17 -08:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
2012-08-16 12:12:05 -07:00
|
|
|
return processKeyDown(keyCode, event);
|
2011-11-18 10:28:17 -08:00
|
|
|
}
|
|
|
|
|
2012-08-16 12:12:05 -07:00
|
|
|
private boolean processKeyDown(int keyCode, KeyEvent event) {
|
2012-06-28 11:03:53 -07:00
|
|
|
if (keyCode > KeyEvent.getMaxKeyCode())
|
|
|
|
return false;
|
|
|
|
|
2011-11-18 10:28:17 -08:00
|
|
|
switch (keyCode) {
|
|
|
|
case KeyEvent.KEYCODE_MENU:
|
|
|
|
case KeyEvent.KEYCODE_BACK:
|
|
|
|
case KeyEvent.KEYCODE_VOLUME_UP:
|
|
|
|
case KeyEvent.KEYCODE_VOLUME_DOWN:
|
|
|
|
case KeyEvent.KEYCODE_SEARCH:
|
|
|
|
return false;
|
|
|
|
case KeyEvent.KEYCODE_ENTER:
|
|
|
|
if ((event.getFlags() & KeyEvent.FLAG_EDITOR_ACTION) != 0 &&
|
|
|
|
mIMEActionHint.equalsIgnoreCase("next"))
|
|
|
|
event = new KeyEvent(event.getAction(), KeyEvent.KEYCODE_TAB);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2012-07-23 11:52:55 -07:00
|
|
|
View view = getView();
|
2012-03-12 16:02:06 -07:00
|
|
|
KeyListener keyListener = TextKeyListener.getInstance();
|
2011-11-18 10:28:17 -08:00
|
|
|
|
|
|
|
// KeyListener returns true if it handled the event for us.
|
|
|
|
if (mIMEState == IME_STATE_DISABLED ||
|
2012-01-06 18:27:09 -08:00
|
|
|
keyCode == KeyEvent.KEYCODE_ENTER ||
|
|
|
|
keyCode == KeyEvent.KEYCODE_DEL ||
|
|
|
|
keyCode == KeyEvent.KEYCODE_TAB ||
|
|
|
|
(event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) != 0 ||
|
2012-11-01 13:11:03 -07:00
|
|
|
!keyListener.onKeyDown(view, getEditable(), keyCode, event)) {
|
|
|
|
mEditableClient.sendEvent(GeckoEvent.createKeyEvent(event));
|
2012-01-06 18:27:09 -08:00
|
|
|
}
|
2011-11-18 10:28:17 -08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
2012-08-16 12:12:05 -07:00
|
|
|
return processKeyUp(keyCode, event);
|
2011-11-18 10:28:17 -08:00
|
|
|
}
|
|
|
|
|
2012-08-16 12:12:05 -07:00
|
|
|
private boolean processKeyUp(int keyCode, KeyEvent event) {
|
2012-06-28 11:03:53 -07:00
|
|
|
if (keyCode > KeyEvent.getMaxKeyCode())
|
|
|
|
return false;
|
|
|
|
|
2011-11-18 10:28:17 -08:00
|
|
|
switch (keyCode) {
|
|
|
|
case KeyEvent.KEYCODE_BACK:
|
|
|
|
case KeyEvent.KEYCODE_SEARCH:
|
|
|
|
case KeyEvent.KEYCODE_MENU:
|
|
|
|
return false;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2012-07-23 11:52:55 -07:00
|
|
|
View view = getView();
|
2012-03-12 16:02:06 -07:00
|
|
|
KeyListener keyListener = TextKeyListener.getInstance();
|
2011-11-18 10:28:17 -08:00
|
|
|
|
|
|
|
if (mIMEState == IME_STATE_DISABLED ||
|
|
|
|
keyCode == KeyEvent.KEYCODE_ENTER ||
|
|
|
|
keyCode == KeyEvent.KEYCODE_DEL ||
|
|
|
|
(event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) != 0 ||
|
2012-11-01 13:11:03 -07:00
|
|
|
!keyListener.onKeyUp(view, getEditable(), keyCode, event)) {
|
|
|
|
mEditableClient.sendEvent(GeckoEvent.createKeyEvent(event));
|
2012-03-12 16:02:06 -07:00
|
|
|
}
|
|
|
|
|
2011-11-18 10:28:17 -08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
|
2012-11-01 13:11:03 -07:00
|
|
|
while ((repeatCount--) != 0) {
|
|
|
|
if (!processKeyDown(keyCode, event) ||
|
|
|
|
!processKeyUp(keyCode, event)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2011-11-18 10:28:17 -08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
|
2012-07-23 11:52:55 -07:00
|
|
|
View v = getView();
|
2011-11-18 10:28:17 -08:00
|
|
|
switch (keyCode) {
|
|
|
|
case KeyEvent.KEYCODE_MENU:
|
2012-02-27 16:29:55 -08:00
|
|
|
InputMethodManager imm = getInputMethodManager();
|
2011-11-18 10:28:17 -08:00
|
|
|
imm.toggleSoftInputFromWindow(v.getWindowToken(),
|
2012-02-14 12:28:27 -08:00
|
|
|
InputMethodManager.SHOW_FORCED, 0);
|
2011-11-18 10:28:17 -08:00
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-12-03 19:59:27 -08:00
|
|
|
public boolean isIMEEnabled() {
|
|
|
|
// make sure this picks up PASSWORD and PLUGIN states as well
|
|
|
|
return mIMEState != IME_STATE_DISABLED;
|
|
|
|
}
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2012-09-19 11:08:39 -07:00
|
|
|
public void notifyIME(final int type, final int state) {
|
2012-11-01 13:11:02 -07:00
|
|
|
|
|
|
|
final View v = getView();
|
|
|
|
if (v == null)
|
|
|
|
return;
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case NOTIFY_IME_RESETINPUTSTATE:
|
|
|
|
if (DEBUG) Log.d(LOGTAG, ". . . notifyIME: reset");
|
|
|
|
|
|
|
|
resetCompositionState();
|
|
|
|
|
|
|
|
// Don't use IMEStateUpdater for reset.
|
|
|
|
// Because IME may not work showSoftInput()
|
|
|
|
// after calling restartInput() immediately.
|
|
|
|
// So we have to call showSoftInput() delay.
|
|
|
|
InputMethodManager imm = getInputMethodManager();
|
|
|
|
if (imm == null) {
|
|
|
|
// no way to reset IME status directly
|
|
|
|
IMEStateUpdater.resetIME();
|
|
|
|
} else {
|
|
|
|
imm.restartInput(v);
|
2012-10-31 14:35:31 -07:00
|
|
|
}
|
2012-11-01 13:11:02 -07:00
|
|
|
|
|
|
|
// keep current enabled state
|
|
|
|
IMEStateUpdater.enableIME();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NOTIFY_IME_CANCELCOMPOSITION:
|
|
|
|
if (DEBUG) Log.d(LOGTAG, ". . . notifyIME: cancel");
|
|
|
|
removeComposingSpans(getEditable());
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NOTIFY_IME_FOCUSCHANGE:
|
|
|
|
if (DEBUG) Log.d(LOGTAG, ". . . notifyIME: focus");
|
|
|
|
IMEStateUpdater.resetIME();
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
if (DEBUG) {
|
|
|
|
throw new IllegalArgumentException("Unexpected NOTIFY_IME=" + type);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2012-07-09 11:00:09 -07:00
|
|
|
}
|
|
|
|
|
2012-11-01 13:11:02 -07:00
|
|
|
public void notifyIMEEnabled(final int state, final String typeHint,
|
|
|
|
final String modeHint, final String actionHint) {
|
2012-08-07 08:09:15 -07:00
|
|
|
// For some input type we will use a widget to display the ui, for those we must not
|
|
|
|
// display the ime. We can display a widget for date and time types and, if the sdk version
|
|
|
|
// is greater than 11, for datetime/month/week as well.
|
|
|
|
if (typeHint.equals("date") || typeHint.equals("time") ||
|
|
|
|
(Build.VERSION.SDK_INT > 10 &&
|
|
|
|
(typeHint.equals("datetime") || typeHint.equals("month") ||
|
|
|
|
typeHint.equals("week") || typeHint.equals("datetime-local")))) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-11-01 13:11:02 -07:00
|
|
|
final View v = getView();
|
|
|
|
if (v == null)
|
|
|
|
return;
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2012-11-01 13:11:02 -07:00
|
|
|
/* When IME is 'disabled', IME processing is disabled.
|
|
|
|
In addition, the IME UI is hidden */
|
|
|
|
mIMEState = state;
|
|
|
|
mIMETypeHint = (typeHint == null) ? "" : typeHint;
|
|
|
|
mIMEModeHint = (modeHint == null) ? "" : modeHint;
|
|
|
|
mIMEActionHint = (actionHint == null) ? "" : actionHint;
|
|
|
|
IMEStateUpdater.enableIME();
|
2011-11-18 10:28:17 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Delay updating IME states (see bug 573800) */
|
2012-02-27 16:29:22 -08:00
|
|
|
private static final class IMEStateUpdater extends TimerTask {
|
2012-02-27 16:29:44 -08:00
|
|
|
private static IMEStateUpdater instance;
|
|
|
|
private boolean mEnable;
|
|
|
|
private boolean mReset;
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2012-02-27 16:29:44 -08:00
|
|
|
private static IMEStateUpdater getInstance() {
|
2011-11-18 10:28:17 -08:00
|
|
|
if (instance == null) {
|
|
|
|
instance = new IMEStateUpdater();
|
|
|
|
mIMETimer.schedule(instance, 200);
|
|
|
|
}
|
|
|
|
return instance;
|
|
|
|
}
|
|
|
|
|
2012-02-27 16:29:44 -08:00
|
|
|
public static synchronized void enableIME() {
|
2011-11-18 10:28:17 -08:00
|
|
|
getInstance().mEnable = true;
|
|
|
|
}
|
|
|
|
|
2012-02-27 16:29:44 -08:00
|
|
|
public static synchronized void resetIME() {
|
2011-11-18 10:28:17 -08:00
|
|
|
getInstance().mReset = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void run() {
|
2012-11-01 13:11:03 -07:00
|
|
|
if (DEBUG) Log.d(LOGTAG, "IME: IMEStateUpdater.run()");
|
2012-02-27 16:29:22 -08:00
|
|
|
synchronized (IMEStateUpdater.class) {
|
2011-11-18 10:28:17 -08:00
|
|
|
instance = null;
|
|
|
|
}
|
|
|
|
|
2012-09-19 11:08:39 -07:00
|
|
|
// TimerTask.run() is running on a random background thread, so post to UI thread.
|
|
|
|
postToUiThread(new Runnable() {
|
|
|
|
public void run() {
|
|
|
|
final View v = getView();
|
|
|
|
if (v == null)
|
2012-07-23 11:52:55 -07:00
|
|
|
return;
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2012-09-19 11:08:39 -07:00
|
|
|
final InputMethodManager imm = getInputMethodManager();
|
|
|
|
if (imm == null)
|
|
|
|
return;
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2012-09-19 11:08:39 -07:00
|
|
|
if (mReset)
|
|
|
|
imm.restartInput(v);
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2012-09-19 11:08:39 -07:00
|
|
|
if (!mEnable)
|
|
|
|
return;
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2012-09-19 11:08:39 -07:00
|
|
|
if (mIMEState != IME_STATE_DISABLED) {
|
|
|
|
imm.showSoftInput(v, 0);
|
|
|
|
} else if (imm.isActive(v)) {
|
|
|
|
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2011-11-18 10:28:17 -08:00
|
|
|
}
|
|
|
|
}
|
2012-11-01 13:11:03 -07:00
|
|
|
}
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2012-11-01 13:11:03 -07:00
|
|
|
final class DebugGeckoInputConnection
|
|
|
|
extends GeckoInputConnection
|
|
|
|
implements InvocationHandler {
|
Backout 533faa3c50ed, 718abc1bd4ad, af2d5272c06b, ad5554e1345d, c9ef1b41b829, d3a825311d11, 0a51bcb3eb9e, a01a327e8ec4, 973b0ed30b8b, 39851bbcfaa1 & a92d2d2a3b0e (bug 805162), d4884aab5ce6, 06fcbaf40cb4, daccc3fe7c70, 881eb2a2906e, 76232441ae06, 01ae34fa1b3f & 5f405fc4e323 (bug 783092), a03d8d4db1c2, 49beb3801192, 174634554a97, 0bd27e755a83, 19e8f151ca67, a6604e038bc0, ed3b8237e76e & 082cf8d72554 (bug 785945) for bustage or conflicting with backout of said bustage on a CLOSED TREE
2012-10-31 17:16:35 -07:00
|
|
|
|
2012-11-01 13:11:03 -07:00
|
|
|
private InputConnection mProxy;
|
Backout 533faa3c50ed, 718abc1bd4ad, af2d5272c06b, ad5554e1345d, c9ef1b41b829, d3a825311d11, 0a51bcb3eb9e, a01a327e8ec4, 973b0ed30b8b, 39851bbcfaa1 & a92d2d2a3b0e (bug 805162), d4884aab5ce6, 06fcbaf40cb4, daccc3fe7c70, 881eb2a2906e, 76232441ae06, 01ae34fa1b3f & 5f405fc4e323 (bug 783092), a03d8d4db1c2, 49beb3801192, 174634554a97, 0bd27e755a83, 19e8f151ca67, a6604e038bc0, ed3b8237e76e & 082cf8d72554 (bug 785945) for bustage or conflicting with backout of said bustage on a CLOSED TREE
2012-10-31 17:16:35 -07:00
|
|
|
|
2012-11-01 13:11:03 -07:00
|
|
|
private DebugGeckoInputConnection(View targetView,
|
|
|
|
GeckoEditableClient editable) {
|
|
|
|
super(targetView, editable);
|
Backout 533faa3c50ed, 718abc1bd4ad, af2d5272c06b, ad5554e1345d, c9ef1b41b829, d3a825311d11, 0a51bcb3eb9e, a01a327e8ec4, 973b0ed30b8b, 39851bbcfaa1 & a92d2d2a3b0e (bug 805162), d4884aab5ce6, 06fcbaf40cb4, daccc3fe7c70, 881eb2a2906e, 76232441ae06, 01ae34fa1b3f & 5f405fc4e323 (bug 783092), a03d8d4db1c2, 49beb3801192, 174634554a97, 0bd27e755a83, 19e8f151ca67, a6604e038bc0, ed3b8237e76e & 082cf8d72554 (bug 785945) for bustage or conflicting with backout of said bustage on a CLOSED TREE
2012-10-31 17:16:35 -07:00
|
|
|
}
|
|
|
|
|
2012-11-01 13:11:03 -07:00
|
|
|
public static InputConnectionHandler create(View targetView,
|
|
|
|
GeckoEditableClient editable) {
|
|
|
|
final Class[] PROXY_INTERFACES = { InputConnection.class,
|
|
|
|
InputConnectionHandler.class,
|
|
|
|
GeckoEditableListener.class };
|
|
|
|
DebugGeckoInputConnection dgic =
|
|
|
|
new DebugGeckoInputConnection(targetView, editable);
|
|
|
|
dgic.mProxy = (InputConnection)Proxy.newProxyInstance(
|
|
|
|
GeckoInputConnection.class.getClassLoader(),
|
|
|
|
PROXY_INTERFACES, dgic);
|
|
|
|
editable.setListener((GeckoEditableListener)dgic.mProxy);
|
|
|
|
return (InputConnectionHandler)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()) {
|
2012-11-02 07:21:19 -07:00
|
|
|
sb.append(obj.getClass().getComponentType().getSimpleName()).append("[")
|
2012-11-01 13:11:03 -07:00
|
|
|
.append(java.lang.reflect.Array.getLength(obj)).append("]");
|
|
|
|
} else {
|
|
|
|
sb.append(obj.toString());
|
Backout 533faa3c50ed, 718abc1bd4ad, af2d5272c06b, ad5554e1345d, c9ef1b41b829, d3a825311d11, 0a51bcb3eb9e, a01a327e8ec4, 973b0ed30b8b, 39851bbcfaa1 & a92d2d2a3b0e (bug 805162), d4884aab5ce6, 06fcbaf40cb4, daccc3fe7c70, 881eb2a2906e, 76232441ae06, 01ae34fa1b3f & 5f405fc4e323 (bug 783092), a03d8d4db1c2, 49beb3801192, 174634554a97, 0bd27e755a83, 19e8f151ca67, a6604e038bc0, ed3b8237e76e & 082cf8d72554 (bug 785945) for bustage or conflicting with backout of said bustage on a CLOSED TREE
2012-10-31 17:16:35 -07:00
|
|
|
}
|
2012-11-01 13:11:03 -07:00
|
|
|
return sb;
|
Backout 533faa3c50ed, 718abc1bd4ad, af2d5272c06b, ad5554e1345d, c9ef1b41b829, d3a825311d11, 0a51bcb3eb9e, a01a327e8ec4, 973b0ed30b8b, 39851bbcfaa1 & a92d2d2a3b0e (bug 805162), d4884aab5ce6, 06fcbaf40cb4, daccc3fe7c70, 881eb2a2906e, 76232441ae06, 01ae34fa1b3f & 5f405fc4e323 (bug 783092), a03d8d4db1c2, 49beb3801192, 174634554a97, 0bd27e755a83, 19e8f151ca67, a6604e038bc0, ed3b8237e76e & 082cf8d72554 (bug 785945) for bustage or conflicting with backout of said bustage on a CLOSED TREE
2012-10-31 17:16:35 -07:00
|
|
|
}
|
|
|
|
|
2012-11-01 13:11:03 -07:00
|
|
|
public Object invoke(Object proxy, Method method, Object[] args)
|
|
|
|
throws Throwable {
|
Backout 533faa3c50ed, 718abc1bd4ad, af2d5272c06b, ad5554e1345d, c9ef1b41b829, d3a825311d11, 0a51bcb3eb9e, a01a327e8ec4, 973b0ed30b8b, 39851bbcfaa1 & a92d2d2a3b0e (bug 805162), d4884aab5ce6, 06fcbaf40cb4, daccc3fe7c70, 881eb2a2906e, 76232441ae06, 01ae34fa1b3f & 5f405fc4e323 (bug 783092), a03d8d4db1c2, 49beb3801192, 174634554a97, 0bd27e755a83, 19e8f151ca67, a6604e038bc0, ed3b8237e76e & 082cf8d72554 (bug 785945) for bustage or conflicting with backout of said bustage on a CLOSED TREE
2012-10-31 17:16:35 -07:00
|
|
|
|
|
|
|
GeckoApp.assertOnUiThread();
|
2012-11-01 13:11:03 -07:00
|
|
|
Object ret = method.invoke(this, args);
|
|
|
|
if (ret == this) {
|
|
|
|
ret = mProxy;
|
2012-10-31 14:35:32 -07:00
|
|
|
}
|
Backout 533faa3c50ed, 718abc1bd4ad, af2d5272c06b, ad5554e1345d, c9ef1b41b829, d3a825311d11, 0a51bcb3eb9e, a01a327e8ec4, 973b0ed30b8b, 39851bbcfaa1 & a92d2d2a3b0e (bug 805162), d4884aab5ce6, 06fcbaf40cb4, daccc3fe7c70, 881eb2a2906e, 76232441ae06, 01ae34fa1b3f & 5f405fc4e323 (bug 783092), a03d8d4db1c2, 49beb3801192, 174634554a97, 0bd27e755a83, 19e8f151ca67, a6604e038bc0, ed3b8237e76e & 082cf8d72554 (bug 785945) for bustage or conflicting with backout of said bustage on a CLOSED TREE
2012-10-31 17:16:35 -07:00
|
|
|
|
2012-11-01 13:11:03 -07:00
|
|
|
StringBuilder log = new StringBuilder(method.getName());
|
|
|
|
log.append("(");
|
|
|
|
for (Object arg : args) {
|
|
|
|
debugAppend(log, arg).append(", ");
|
|
|
|
}
|
|
|
|
if (args.length > 0) {
|
|
|
|
log.setLength(log.length() - 2);
|
|
|
|
}
|
|
|
|
if (method.getReturnType().equals(Void.TYPE)) {
|
|
|
|
log.append(")");
|
|
|
|
} else {
|
|
|
|
debugAppend(log.append(") = "), ret);
|
|
|
|
}
|
|
|
|
Log.d(LOGTAG, log.toString());
|
2012-08-10 21:12:28 -07:00
|
|
|
|
2012-11-01 13:11:03 -07:00
|
|
|
return ret;
|
2012-08-10 21:12:28 -07:00
|
|
|
}
|
2012-06-01 11:09:29 -07:00
|
|
|
}
|
2011-12-15 13:35:45 -08:00
|
|
|
|