diff options
| author | Yohei Yukawa <yukawa@google.com> | 2017-02-09 16:55:00 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2017-02-09 16:55:04 +0000 |
| commit | efdb4289597ad1594eb906aeafd2ebdf8854bdc7 (patch) | |
| tree | 594046a80ee0a02fd90463a4f0f84a6f02bb90d7 /core/java/android | |
| parent | df185d750273ecb7b2c61e98206ee9c11d76217b (diff) | |
| parent | 2bc66171cce4d5ae7bee2c3920e82e45a9d245af (diff) | |
Merge "Eliminate out-of-sync IMM#mFullscreenMode error"
Diffstat (limited to 'core/java/android')
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); |
