summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java10
-rw-r--r--core/java/android/view/inputmethod/InputConnection.java21
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java71
-rw-r--r--core/java/com/android/internal/view/IInputConnectionWrapper.java44
-rw-r--r--core/java/com/android/internal/view/IInputContext.aidl4
-rw-r--r--core/java/com/android/internal/view/IInputMethodClient.aidl3
-rw-r--r--core/java/com/android/internal/view/IInputMethodManager.aidl2
-rw-r--r--core/java/com/android/internal/view/InputConnectionWrapper.java8
-rw-r--r--services/core/java/com/android/server/InputMethodManagerService.java48
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java5
10 files changed, 118 insertions, 98 deletions
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 5996fe2b14a3..5ae1fd057122 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -387,8 +387,9 @@ public class InputMethodService extends AbstractInputMethodService {
mInputConnection = binding.getConnection();
if (DEBUG) Log.v(TAG, "bindInput(): binding=" + binding
+ " ic=" + mInputConnection);
- InputConnection ic = getCurrentInputConnection();
- if (ic != null) ic.reportFullscreenMode(mIsFullscreen);
+ if (mImm != null && mToken != null) {
+ mImm.reportFullscreenMode(mToken, mIsFullscreen);
+ }
initialize();
onBindInput();
}
@@ -1027,8 +1028,9 @@ public class InputMethodService extends AbstractInputMethodService {
if (mIsFullscreen != isFullscreen || !mFullscreenApplied) {
changed = true;
mIsFullscreen = isFullscreen;
- InputConnection ic = getCurrentInputConnection();
- if (ic != null) ic.reportFullscreenMode(isFullscreen);
+ if (mImm != null && mToken != null) {
+ mImm.reportFullscreenMode(mToken, mIsFullscreen);
+ }
mFullscreenApplied = true;
initialize();
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index 71c1d624976b..57f9895f45fa 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -18,6 +18,7 @@ package android.view.inputmethod;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.inputmethodservice.InputMethodService;
import android.os.Bundle;
import android.os.Handler;
import android.view.KeyCharacterMap;
@@ -751,13 +752,19 @@ public interface InputConnection {
public boolean clearMetaKeyStates(int states);
/**
- * Called by the IME to tell the client when it switches between
- * fullscreen and normal modes. This will normally be called for
- * you by the standard implementation of
- * {@link android.inputmethodservice.InputMethodService}.
- *
- * @return true on success, false if the input connection is no longer
- * valid.
+ * Called back when the connected IME switches between fullscreen and normal modes.
+ *
+ * <p>Note: On {@link android.os.Build.VERSION_CODES#O} and later devices, input methods are no
+ * longer allowed to directly call this method at any time. To signal this event in the target
+ * application, input methods should always call
+ * {@link InputMethodService#updateFullscreenMode()} instead. This approach should work on API
+ * {@link android.os.Build.VERSION_CODES#N_MR1} and prior devices.</p>
+ *
+ * @return For editor authors, the return value will always be ignored. For IME authors, this
+ * always returns {@code true} on {@link android.os.Build.VERSION_CODES#N_MR1} and prior
+ * devices and {@code false} on {@link android.os.Build.VERSION_CODES#O} and later
+ * devices.
+ * @see InputMethodManager#isFullscreenMode()
*/
public boolean reportFullscreenMode(boolean enabled);
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 2e99092006f0..13abe7c6471d 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -34,7 +34,6 @@ import android.os.ResultReceiver;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
import android.os.Trace;
-import android.text.TextUtils;
import android.text.style.SuggestionSpan;
import android.util.Log;
import android.util.Pools.Pool;
@@ -396,6 +395,7 @@ public final class InputMethodManager {
static final int MSG_TIMEOUT_INPUT_EVENT = 6;
static final int MSG_FLUSH_INPUT_EVENT = 7;
static final int MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER = 9;
+ static final int MSG_REPORT_FULLSCREEN_MODE = 10;
class H extends Handler {
H(Looper looper) {
@@ -476,12 +476,13 @@ public final class InputMethodManager {
}
case MSG_SET_ACTIVE: {
final boolean active = msg.arg1 != 0;
+ final boolean fullscreen = msg.arg2 != 0;
if (DEBUG) {
Log.i(TAG, "handleMessage: MSG_SET_ACTIVE " + active + ", was " + mActive);
}
synchronized (mH) {
mActive = active;
- mFullscreenMode = false;
+ mFullscreenMode = fullscreen;
if (!active) {
// Some other client has starting using the IME, so note
// that this happened and make sure our own editor's
@@ -523,6 +524,21 @@ public final class InputMethodManager {
synchronized (mH) {
mNextUserActionNotificationSequenceNumber = msg.arg1;
}
+ return;
+ }
+ case MSG_REPORT_FULLSCREEN_MODE: {
+ final boolean fullscreen = msg.arg1 != 0;
+ InputConnection ic = null;
+ synchronized (mH) {
+ mFullscreenMode = fullscreen;
+ if (mServedInputConnectionWrapper != null) {
+ ic = mServedInputConnectionWrapper.getInputConnection();
+ }
+ }
+ if (ic != null) {
+ ic.reportFullscreenMode(fullscreen);
+ }
+ return;
}
}
}
@@ -557,18 +573,11 @@ public final class InputMethodManager {
}
@Override
- protected void onReportFullscreenMode(boolean enabled, boolean calledInBackground) {
- mParentInputMethodManager.onReportFullscreenMode(enabled, calledInBackground,
- getInputMethodId());
- }
-
- @Override
public String toString() {
return "ControlledInputConnectionWrapper{"
+ "connection=" + getInputConnection()
+ " finished=" + isFinished()
+ " mParentInputMethodManager.mActive=" + mParentInputMethodManager.mActive
- + " mInputMethodId=" + getInputMethodId()
+ "}";
}
}
@@ -600,24 +609,31 @@ public final class InputMethodManager {
@Override
public void onBindMethod(InputBindResult res) {
- mH.sendMessage(mH.obtainMessage(MSG_BIND, res));
+ mH.obtainMessage(MSG_BIND, res).sendToTarget();
}
@Override
public void onUnbindMethod(int sequence, @InputMethodClient.UnbindReason int unbindReason) {
- mH.sendMessage(mH.obtainMessage(MSG_UNBIND, sequence, unbindReason));
+ mH.obtainMessage(MSG_UNBIND, sequence, unbindReason).sendToTarget();
}
@Override
- public void setActive(boolean active) {
- mH.sendMessage(mH.obtainMessage(MSG_SET_ACTIVE, active ? 1 : 0, 0));
+ public void setActive(boolean active, boolean fullscreen) {
+ mH.obtainMessage(MSG_SET_ACTIVE, active ? 1 : 0, fullscreen ? 1 : 0).sendToTarget();
}
@Override
public void setUserActionNotificationSequenceNumber(int sequenceNumber) {
- mH.sendMessage(mH.obtainMessage(MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER,
- sequenceNumber, 0));
+ mH.obtainMessage(MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER, sequenceNumber, 0)
+ .sendToTarget();
+ }
+
+ @Override
+ public void reportFullscreenMode(boolean fullscreen) {
+ mH.obtainMessage(MSG_REPORT_FULLSCREEN_MODE, fullscreen ? 1 : 0, 0)
+ .sendToTarget();
}
+
};
final InputConnection mDummyInputConnection = new BaseInputConnection(this, false);
@@ -731,16 +747,6 @@ public final class InputMethodManager {
}
/** @hide */
- public void onReportFullscreenMode(boolean fullScreen, boolean calledInBackground,
- String inputMethodId) {
- synchronized (mH) {
- if (!calledInBackground || TextUtils.equals(mCurId, inputMethodId)) {
- mFullscreenMode = fullScreen;
- }
- }
- }
-
- /** @hide */
public void registerSuggestionSpansForNotification(SuggestionSpan[] spans) {
try {
mService.registerSuggestionSpansForNotification(spans);
@@ -770,6 +776,17 @@ public final class InputMethodManager {
}
/**
+ * @hide
+ */
+ public void reportFullscreenMode(IBinder token, boolean fullscreen) {
+ try {
+ mService.reportFullscreenMode(token, fullscreen);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Return true if the given view is the currently active view for the
* input method.
*/
@@ -1274,9 +1291,6 @@ public final class InputMethodManager {
mCurId = res.id;
mNextUserActionNotificationSequenceNumber =
res.userActionNotificationSequenceNumber;
- if (mServedInputConnectionWrapper != null) {
- mServedInputConnectionWrapper.setInputMethodId(mCurId);
- }
} else {
if (res.channel != null && res.channel != mCurChannel) {
res.channel.dispose();
@@ -2341,6 +2355,7 @@ public final class InputMethodManager {
+ " mHasBeenInactive=" + mHasBeenInactive
+ " mBindSequence=" + mBindSequence
+ " mCurId=" + mCurId);
+ p.println(" mFullscreenMode=" + mFullscreenMode);
p.println(" mCurMethod=" + mCurMethod);
p.println(" mCurRootView=" + mCurRootView);
p.println(" mServedView=" + mServedView);
diff --git a/core/java/com/android/internal/view/IInputConnectionWrapper.java b/core/java/com/android/internal/view/IInputConnectionWrapper.java
index 0185e306118f..cb2d88522f3b 100644
--- a/core/java/com/android/internal/view/IInputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/IInputConnectionWrapper.java
@@ -57,7 +57,6 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
private static final int DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS = 81;
private static final int DO_BEGIN_BATCH_EDIT = 90;
private static final int DO_END_BATCH_EDIT = 95;
- private static final int DO_REPORT_FULLSCREEN_MODE = 100;
private static final int DO_PERFORM_PRIVATE_COMMAND = 120;
private static final int DO_CLEAR_META_KEY_STATES = 130;
private static final int DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO = 140;
@@ -73,8 +72,6 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
private Object mLock = new Object();
@GuardedBy("mLock")
private boolean mFinished = false;
- @GuardedBy("mLock")
- private String mInputMethodId;
static class SomeArgs {
Object arg1;
@@ -113,18 +110,6 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
}
}
- public String getInputMethodId() {
- synchronized (mLock) {
- return mInputMethodId;
- }
- }
-
- public void setInputMethodId(final String inputMethodId) {
- synchronized (mLock) {
- mInputMethodId = inputMethodId;
- }
- }
-
abstract protected boolean isActive();
/**
@@ -133,14 +118,6 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
*/
abstract protected void onUserAction();
- /**
- * Called when the input method started or stopped full-screen mode.
- * @param enabled {@code true} if the input method starts full-screen mode.
- * @param calledInBackground {@code true} if this input connection is in a state when incoming
- * events are usually ignored.
- */
- abstract protected void onReportFullscreenMode(boolean enabled, boolean calledInBackground);
-
public void getTextAfterCursor(int length, int flags, int seq, IInputContextCallback callback) {
dispatchMessage(obtainMessageIISC(DO_GET_TEXT_AFTER_CURSOR, length, flags, seq, callback));
}
@@ -225,10 +202,6 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
dispatchMessage(obtainMessage(DO_END_BATCH_EDIT));
}
- public void reportFullscreenMode(boolean enabled) {
- dispatchMessage(obtainMessageII(DO_REPORT_FULLSCREEN_MODE, enabled ? 1 : 0, 0));
- }
-
public void performPrivateCommand(String action, Bundle data) {
dispatchMessage(obtainMessageOO(DO_PERFORM_PRIVATE_COMMAND, action, data));
}
@@ -486,23 +459,6 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
ic.endBatchEdit();
return;
}
- case DO_REPORT_FULLSCREEN_MODE: {
- InputConnection ic = getInputConnection();
- boolean isBackground = false;
- if (ic == null || !isActive()) {
- Log.w(TAG, "reportFullscreenMode on inexistent InputConnection");
- isBackground = true;
- }
- final boolean enabled = msg.arg1 == 1;
- if (!isBackground) {
- ic.reportFullscreenMode(enabled);
- }
- // Due to the nature of asynchronous event handling, currently InputMethodService
- // has relied on the fact that #reportFullscreenMode() can be handled even when the
- // InputConnection is inactive. We have to notify this event to InputMethodManager.
- onReportFullscreenMode(enabled, isBackground);
- return;
- }
case DO_PERFORM_PRIVATE_COMMAND: {
InputConnection ic = getInputConnection();
if (ic == null || !isActive()) {
diff --git a/core/java/com/android/internal/view/IInputContext.aidl b/core/java/com/android/internal/view/IInputContext.aidl
index 728c55786c49..c22799179b72 100644
--- a/core/java/com/android/internal/view/IInputContext.aidl
+++ b/core/java/com/android/internal/view/IInputContext.aidl
@@ -62,9 +62,7 @@ import com.android.internal.view.IInputContextCallback;
void beginBatchEdit();
void endBatchEdit();
-
- void reportFullscreenMode(boolean enabled);
-
+
void sendKeyEvent(in KeyEvent event);
void clearMetaKeyStates(int states);
diff --git a/core/java/com/android/internal/view/IInputMethodClient.aidl b/core/java/com/android/internal/view/IInputMethodClient.aidl
index 81056f2edd96..ffa9f75e4370 100644
--- a/core/java/com/android/internal/view/IInputMethodClient.aidl
+++ b/core/java/com/android/internal/view/IInputMethodClient.aidl
@@ -27,6 +27,7 @@ oneway interface IInputMethodClient {
void onBindMethod(in InputBindResult res);
// unbindReason corresponds to InputMethodClient.UnbindReason.
void onUnbindMethod(int sequence, int unbindReason);
- void setActive(boolean active);
+ void setActive(boolean active, boolean fullscreen);
void setUserActionNotificationSequenceNumber(int sequenceNumber);
+ void reportFullscreenMode(boolean fullscreen);
}
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 9e4b43b6c007..2279a6706524 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -86,5 +86,7 @@ interface IInputMethodManager {
IInputContentUriToken createInputContentUriToken(in IBinder token, in Uri contentUri,
in String packageName);
+ void reportFullscreenMode(in IBinder token, boolean fullscreen);
+
oneway void notifyUserAction(int sequenceNumber);
}
diff --git a/core/java/com/android/internal/view/InputConnectionWrapper.java b/core/java/com/android/internal/view/InputConnectionWrapper.java
index 9a09dcccd1a7..cc0ef756c6b3 100644
--- a/core/java/com/android/internal/view/InputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/InputConnectionWrapper.java
@@ -467,12 +467,8 @@ public class InputConnectionWrapper implements InputConnection {
}
public boolean reportFullscreenMode(boolean enabled) {
- try {
- mIInputContext.reportFullscreenMode(enabled);
- return true;
- } catch (RemoteException e) {
- return false;
- }
+ // Nothing should happen when called from input method.
+ return false;
}
public boolean performPrivateCommand(String action, Bundle data) {
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 22eca77c3a06..c5e91f5de80c 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -181,6 +181,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
static final int MSG_SET_ACTIVE = 3020;
static final int MSG_SET_INTERACTIVE = 3030;
static final int MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER = 3040;
+ static final int MSG_REPORT_FULLSCREEN_MODE = 3045;
static final int MSG_SWITCH_IME = 3050;
static final int MSG_HARD_KEYBOARD_SWITCH_CHANGED = 4000;
@@ -411,6 +412,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
boolean mInputShown;
/**
+ * {@code true} if the current input method is in fullscreen mode.
+ */
+ boolean mInFullscreenMode;
+
+ /**
* The Intent used to connect to the current input method.
*/
Intent mCurIntent;
@@ -1265,8 +1271,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO(
- MSG_SET_ACTIVE, 0, mCurClient));
+ executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIIO(
+ MSG_SET_ACTIVE, 0, 0, mCurClient));
executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIIO(
MSG_UNBIND_CLIENT, mCurSeq, unbindClientReason, mCurClient.client));
mCurClient.sessionRequested = false;
@@ -1646,6 +1652,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (mStatusBar != null) {
mStatusBar.setIconVisibility(mSlotIme, false);
}
+ mInFullscreenMode = false;
}
@Override
@@ -2912,7 +2919,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
case MSG_SET_ACTIVE:
try {
- ((ClientState)msg.obj).client.setActive(msg.arg1 != 0);
+ ((ClientState)msg.obj).client.setActive(msg.arg1 != 0, msg.arg2 != 0);
} catch (RemoteException e) {
Slog.w(TAG, "Got RemoteException sending setActive(false) notification to pid "
+ ((ClientState)msg.obj).pid + " uid "
@@ -2939,6 +2946,18 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
return true;
}
+ case MSG_REPORT_FULLSCREEN_MODE: {
+ final boolean fullscreen = msg.arg1 != 0;
+ final ClientState clientState = (ClientState)msg.obj;
+ try {
+ clientState.client.reportFullscreenMode(fullscreen);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Got RemoteException sending "
+ + "reportFullscreen(" + fullscreen + ") notification to pid="
+ + clientState.pid + " uid=" + clientState.uid);
+ }
+ return true;
+ }
// --------------------------------------------------------------
case MSG_HARD_KEYBOARD_SWITCH_CHANGED:
@@ -2959,8 +2978,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// Inform the current client of the change in active status
if (mCurClient != null && mCurClient.client != null) {
- executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO(
- MSG_SET_ACTIVE, mIsInteractive ? 1 : 0, mCurClient));
+ executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIIO(
+ MSG_SET_ACTIVE, mIsInteractive ? 1 : 0, mInFullscreenMode ? 1 : 0,
+ mCurClient));
}
}
}
@@ -3960,6 +3980,23 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
@Override
+ public void reportFullscreenMode(IBinder token, boolean fullscreen) {
+ if (!calledFromValidUser()) {
+ return;
+ }
+ synchronized (mMethodMap) {
+ if (!calledWithValidToken(token)) {
+ return;
+ }
+ if (mCurClient != null && mCurClient.client != null) {
+ mInFullscreenMode = fullscreen;
+ executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO(
+ MSG_REPORT_FULLSCREEN_MODE, fullscreen ? 1 : 0, mCurClient));
+ }
+ }
+ }
+
+ @Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
@@ -4011,6 +4048,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
+ " mShowExplicitlyRequested=" + mShowExplicitlyRequested
+ " mShowForced=" + mShowForced
+ " mInputShown=" + mInputShown);
+ p.println(" mInFullscreenMode=" + mInFullscreenMode);
p.println(" mCurUserActionNotificationSequenceNumber="
+ mCurUserActionNotificationSequenceNumber);
p.println(" mSystemReady=" + mSystemReady + " mInteractive=" + mIsInteractive);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
index ab73a8b820cd..468710bbb470 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
@@ -248,4 +248,9 @@ public class BridgeIInputMethodManager implements IInputMethodManager {
// TODO Auto-generated method stub
return null;
}
+
+ @Override
+ public void reportFullscreenMode(IBinder token, boolean fullscreen) {
+ // TODO Auto-generated method stub
+ }
}