summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorYohei Yukawa <yukawa@google.com>2017-02-09 16:55:00 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2017-02-09 16:55:04 +0000
commitefdb4289597ad1594eb906aeafd2ebdf8854bdc7 (patch)
tree594046a80ee0a02fd90463a4f0f84a6f02bb90d7 /core/java/android
parentdf185d750273ecb7b2c61e98206ee9c11d76217b (diff)
parent2bc66171cce4d5ae7bee2c3920e82e45a9d245af (diff)
Merge "Eliminate out-of-sync IMM#mFullscreenMode error"
Diffstat (limited to 'core/java/android')
-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
3 files changed, 63 insertions, 39 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);