summaryrefslogtreecommitdiff
path: root/core/java/android/inputmethodservice/InputMethodService.java
diff options
context:
space:
mode:
authorYohei Yukawa <yukawa@google.com>2017-02-13 12:04:41 -0800
committerYohei Yukawa <yukawa@google.com>2017-02-13 12:04:41 -0800
commit6db3bfe33d92127d203ec872a0b353585a99f256 (patch)
tree81c9cc693c3b0ec854bdb33ac3855be87797c7a5 /core/java/android/inputmethodservice/InputMethodService.java
parentf7526b58960608887b064670bb42f41aa28b8f41 (diff)
Track event flow to IMMS#setImeWindowStatus
This is part of work to introduce historical debugging infrastructure for Android IME. In this CL, we will focus on the following two event flows. A1. IMMS#attachNewInputLocked() queues MSG_(RE)START_INPUT to deliver new InputConnection/EditorInfo to the current IME A2. The IME triggers IMS#onStartInput()/IMS#onRestartInput() and updates the following fields: - InputMethodService#mStartedInputConnection - InputMethodService#mInputEditorInfo B1. IME is expected to call back IMM#setImeWindowStatus() to notify its window visibility change to IMMS. B2. IMMS updates the following field if the caller is still the current IME. - InputMethodManagerService#mImeWindowVis What this CL aims to do is to enable IMMS to access A1 state when it was in B2 state, by considering that for given a B1 the last A2 happened before B1 is the cause of B1 and B2. To do this, IMMS issues a binder token in A1 and each IME keeps it so that it can be passed in B1. By using this Binder token as a key, IMMS can keep tracking state snapshot taken from each A1. Note that those state snapshots keep alive until the Binder token's proxy in the IME process loses strong reference from its GC root. Test: Make sure `adb shell dumpsys input_method | grep mImeWindowVis` matches to the IME window visibility. Test: Make sure the current IME is not receiving any InvalidParameterException from IMMS. Bug: 35079353 Change-Id: I9921b381e02106dbffff5e0b3d13f0a1245ce807
Diffstat (limited to 'core/java/android/inputmethodservice/InputMethodService.java')
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java49
1 files changed, 41 insertions, 8 deletions
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 5ae1fd057122..7a20943e2a4b 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -24,6 +24,7 @@ import android.annotation.DrawableRes;
import android.annotation.IntDef;
import android.annotation.MainThread;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.Dialog;
import android.content.Context;
@@ -291,7 +292,20 @@ public class InputMethodService extends AbstractInputMethodService {
boolean mCandidatesViewStarted;
InputConnection mStartedInputConnection;
EditorInfo mInputEditorInfo;
-
+
+ /**
+ * A token to keep tracking the last IPC that triggered
+ * {@link #doStartInput(InputConnection, EditorInfo, boolean)}. If
+ * {@link #doStartInput(InputConnection, EditorInfo, boolean)} was not caused by IPCs from
+ * {@link com.android.server.InputMethodManagerService}, this needs to remain unchanged.
+ *
+ * <p>Some IPCs to {@link com.android.server.InputMethodManagerService} require this token to
+ * disentangle event flows for various purposes such as better window animation and providing
+ * fine-grained debugging information.</p>
+ */
+ @Nullable
+ private IBinder mStartInputToken;
+
int mShowInputFlags;
boolean mShowInputRequested;
boolean mLastShowInputRequested;
@@ -416,6 +430,23 @@ public class InputMethodService extends AbstractInputMethodService {
}
/**
+ * {@inheritDoc}
+ * @hide
+ */
+ @Override
+ public void dispatchStartInputWithToken(@Nullable InputConnection inputConnection,
+ @NonNull EditorInfo editorInfo, boolean restarting,
+ @NonNull IBinder startInputToken) {
+ mStartInputToken = startInputToken;
+
+ // This needs to be dispatched to interface methods rather than doStartInput().
+ // Otherwise IME developers who have overridden those interface methods will lose
+ // notifications.
+ super.dispatchStartInputWithToken(inputConnection, editorInfo, restarting,
+ startInputToken);
+ }
+
+ /**
* Handle a request by the system to hide the soft input area.
*/
public void hideSoftInput(int flags, ResultReceiver resultReceiver) {
@@ -454,8 +485,8 @@ public class InputMethodService extends AbstractInputMethodService {
clearInsetOfPreviousIme();
// If user uses hard keyboard, IME button should always be shown.
boolean showing = isInputViewShown();
- mImm.setImeWindowStatus(mToken, IME_ACTIVE | (showing ? IME_VISIBLE : 0),
- mBackDisposition);
+ mImm.setImeWindowStatus(mToken, mStartInputToken,
+ IME_ACTIVE | (showing ? IME_VISIBLE : 0), mBackDisposition);
if (resultReceiver != null) {
resultReceiver.send(wasVis != isInputViewShown()
? InputMethodManager.RESULT_SHOWN
@@ -926,8 +957,8 @@ public class InputMethodService extends AbstractInputMethodService {
}
// If user uses hard keyboard, IME button should always be shown.
boolean showing = onEvaluateInputViewShown();
- mImm.setImeWindowStatus(mToken, IME_ACTIVE | (showing ? IME_VISIBLE : 0),
- mBackDisposition);
+ mImm.setImeWindowStatus(mToken, mStartInputToken,
+ IME_ACTIVE | (showing ? IME_VISIBLE : 0), mBackDisposition);
}
}
@@ -1653,7 +1684,8 @@ public class InputMethodService extends AbstractInputMethodService {
final int nextImeWindowStatus = IME_ACTIVE | (isInputViewShown() ? IME_VISIBLE : 0);
if (previousImeWindowStatus != nextImeWindowStatus) {
- mImm.setImeWindowStatus(mToken, nextImeWindowStatus, mBackDisposition);
+ mImm.setImeWindowStatus(mToken, mStartInputToken, nextImeWindowStatus,
+ mBackDisposition);
}
if ((previousImeWindowStatus & IME_ACTIVE) == 0) {
if (DEBUG) Log.v(TAG, "showWindow: showing!");
@@ -1678,7 +1710,7 @@ public class InputMethodService extends AbstractInputMethodService {
}
private void doHideWindow() {
- mImm.setImeWindowStatus(mToken, 0, mBackDisposition);
+ mImm.setImeWindowStatus(mToken, mStartInputToken, 0, mBackDisposition);
hideWindow();
}
@@ -2643,7 +2675,8 @@ public class InputMethodService extends AbstractInputMethodService {
p.println(" mInputStarted=" + mInputStarted
+ " mInputViewStarted=" + mInputViewStarted
+ " mCandidatesViewStarted=" + mCandidatesViewStarted);
-
+ p.println(" mStartInputToken=" + mStartInputToken);
+
if (mInputEditorInfo != null) {
p.println(" mInputEditorInfo:");
mInputEditorInfo.dump(p, " ");