Allow IMEs to start/stop receiving onUpdateCursor callback
This CL introduces an API which allows IMEs to start/stop
receiving onUpdateCursor callback upon their request.
BUG: 13388665
Change-Id: I987326872def181dda5d9d701b762f088e0d9c39
diff --git a/api/current.txt b/api/current.txt
index 759b8d0..597e4e7 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -12469,6 +12469,7 @@
method public void setBackDisposition(int);
method public void setCandidatesView(android.view.View);
method public void setCandidatesViewShown(boolean);
+ method public void setCursorAnchorMonitorMode(int);
method public void setExtractView(android.view.View);
method public void setExtractViewShown(boolean);
method public void setInputView(android.view.View);
@@ -12480,6 +12481,8 @@
field public static final int BACK_DISPOSITION_DEFAULT = 0; // 0x0
field public static final int BACK_DISPOSITION_WILL_DISMISS = 2; // 0x2
field public static final int BACK_DISPOSITION_WILL_NOT_DISMISS = 1; // 0x1
+ field public static final int CURSOR_ANCHOR_MONITOR_MODE_CURSOR_RECT = 1; // 0x1
+ field public static final int CURSOR_ANCHOR_MONITOR_MODE_NONE = 0; // 0x0
}
public class InputMethodService.InputMethodImpl extends android.inputmethodservice.AbstractInputMethodService.AbstractInputMethodImpl {
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index a355d1e..c51d1a7 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -249,6 +249,16 @@
*/
public static final int IME_VISIBLE = 0x2;
+ /**
+ * The IME does not require cursor/anchor position.
+ */
+ public static final int CURSOR_ANCHOR_MONITOR_MODE_NONE = 0x0;
+
+ /**
+ * The IME expects that {@link #onUpdateCursor(Rect)} is called back.
+ */
+ public static final int CURSOR_ANCHOR_MONITOR_MODE_CURSOR_RECT = 0x1;
+
InputMethodManager mImm;
int mTheme = 0;
@@ -1702,6 +1712,13 @@
}
/**
+ * Update the cursor/anthor monitor mode.
+ */
+ public void setCursorAnchorMonitorMode(int monitorMode) {
+ mImm.setCursorAnchorMonitorMode(mToken, monitorMode);
+ }
+
+ /**
* Close this input method's soft input area, removing it from the display.
* The input method will continue running, but the user can no longer use
* it to generate input by touching the screen.
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index f2ce113..e3bd9fd 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -26,6 +26,7 @@
import android.content.Context;
import android.graphics.Rect;
+import android.inputmethodservice.InputMethodService;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -41,13 +42,13 @@
import android.util.Pools.SimplePool;
import android.util.PrintWriterPrinter;
import android.util.Printer;
+import android.util.SparseArray;
import android.view.InputChannel;
import android.view.InputEvent;
import android.view.InputEventSender;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewRootImpl;
-import android.util.SparseArray;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -334,6 +335,11 @@
InputChannel mCurChannel;
ImeInputEventSender mCurSender;
+ /**
+ * The current cursor/anchor monitor mode.
+ */
+ int mCursorAnchorMonitorMode = InputMethodService.CURSOR_ANCHOR_MONITOR_MODE_NONE;
+
final Pool<PendingEvent> mPendingEventPool = new SimplePool<PendingEvent>(20);
final SparseArray<PendingEvent> mPendingEvents = new SparseArray<PendingEvent>(20);
@@ -346,6 +352,7 @@
static final int MSG_SEND_INPUT_EVENT = 5;
static final int MSG_TIMEOUT_INPUT_EVENT = 6;
static final int MSG_FLUSH_INPUT_EVENT = 7;
+ static final int SET_CURSOR_ANCHOR_MONITOR_MODE = 8;
class H extends Handler {
H(Looper looper) {
@@ -476,6 +483,12 @@
finishedInputEvent(msg.arg1, false, false);
return;
}
+ case SET_CURSOR_ANCHOR_MONITOR_MODE: {
+ synchronized (mH) {
+ mCursorAnchorMonitorMode = msg.arg1;
+ }
+ return;
+ }
}
}
}
@@ -540,6 +553,11 @@
public void setActive(boolean active) {
mH.sendMessage(mH.obtainMessage(MSG_SET_ACTIVE, active ? 1 : 0, 0));
}
+
+ @Override
+ public void setCursorAnchorMonitorMode(int monitorMode) {
+ mH.sendMessage(mH.obtainMessage(SET_CURSOR_ANCHOR_MONITOR_MODE, monitorMode, 0));
+ }
};
final InputConnection mDummyInputConnection = new BaseInputConnection(this, false);
@@ -1465,9 +1483,30 @@
* of the input editor's cursor in its window.
*/
public boolean isWatchingCursor(View view) {
- return false;
+ if (!isActive(view)) {
+ return false;
+ }
+ synchronized (mH) {
+ return mCursorAnchorMonitorMode ==
+ InputMethodService.CURSOR_ANCHOR_MONITOR_MODE_CURSOR_RECT;
+ }
}
-
+
+ /**
+ * Set cursor/anchor monitor mode via {@link com.android.server.InputMethodManagerService}.
+ * This is an internal method for {@link android.inputmethodservice.InputMethodService} and
+ * should never be used from IMEs and applications.
+ *
+ * @hide
+ */
+ public void setCursorAnchorMonitorMode(IBinder imeToken, int monitorMode) {
+ try {
+ mService.setCursorAnchorMonitorMode(imeToken, monitorMode);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
/**
* Report the current cursor location in its window.
*/
diff --git a/core/java/com/android/internal/view/IInputMethodClient.aidl b/core/java/com/android/internal/view/IInputMethodClient.aidl
index ce4312d..9e8d12b 100644
--- a/core/java/com/android/internal/view/IInputMethodClient.aidl
+++ b/core/java/com/android/internal/view/IInputMethodClient.aidl
@@ -27,4 +27,5 @@
void onBindMethod(in InputBindResult res);
void onUnbindMethod(int sequence);
void setActive(boolean active);
+ void setCursorAnchorMonitorMode(int monitorMode);
}
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 45ca7fc..5336174 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -78,4 +78,5 @@
void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes);
int getInputMethodWindowVisibleHeight();
oneway void notifyTextCommitted();
+ void setCursorAnchorMonitorMode(in IBinder token, int monitorMode);
}
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index e69c9a4..6fc3e77 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -148,6 +148,7 @@
static final int MSG_UNBIND_METHOD = 3000;
static final int MSG_BIND_METHOD = 3010;
static final int MSG_SET_ACTIVE = 3020;
+ static final int MSG_SET_CURSOR_ANCHOR_MONITOR_MODE = 3030;
static final int MSG_HARD_KEYBOARD_SWITCH_CHANGED = 4000;
@@ -2275,6 +2276,27 @@
}
}
+ @Override
+ public void setCursorAnchorMonitorMode(IBinder token, int monitorMode) {
+ if (DEBUG) {
+ Slog.d(TAG, "setCursorAnchorMonitorMode: monitorMode=" + monitorMode);
+ }
+ if (!calledFromValidUser()) {
+ return;
+ }
+ synchronized (mMethodMap) {
+ if (token == null || mCurToken != token) {
+ if (DEBUG) {
+ Slog.w(TAG, "Ignoring setCursorAnchorMonitorMode from uid "
+ + Binder.getCallingUid() + " token: " + token);
+ }
+ return;
+ }
+ executeOrSendMessage(mCurMethod, mCaller.obtainMessageIO(
+ MSG_SET_CURSOR_ANCHOR_MONITOR_MODE, monitorMode, mCurClient));
+ }
+ }
+
private void setInputMethodWithSubtypeId(IBinder token, String id, int subtypeId) {
synchronized (mMethodMap) {
if (token == null) {
@@ -2506,6 +2528,15 @@
+ ((ClientState)msg.obj).uid);
}
return true;
+ case MSG_SET_CURSOR_ANCHOR_MONITOR_MODE:
+ try {
+ ((ClientState)msg.obj).client.setCursorAnchorMonitorMode(msg.arg1);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Got RemoteException sending setCursorAnchorMonitorMode "
+ + "notification to pid " + ((ClientState)msg.obj).pid
+ + " uid " + ((ClientState)msg.obj).uid);
+ }
+ return true;
// --------------------------------------------------------------
case MSG_HARD_KEYBOARD_SWITCH_CHANGED: