Merge "Introduce IInputMethodInvoker"
This commit is contained in:
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.inputmethod;
|
||||
|
||||
import android.annotation.AnyThread;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.Binder;
|
||||
import android.os.DeadObjectException;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ResultReceiver;
|
||||
import android.util.Slog;
|
||||
import android.view.InputChannel;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputBinding;
|
||||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
|
||||
import com.android.internal.view.IInlineSuggestionsRequestCallback;
|
||||
import com.android.internal.view.IInputContext;
|
||||
import com.android.internal.view.IInputMethod;
|
||||
import com.android.internal.view.IInputMethodSession;
|
||||
import com.android.internal.view.IInputSessionCallback;
|
||||
import com.android.internal.view.InlineSuggestionsRequestInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A wrapper class to invoke IPCs defined in {@link IInputMethod}.
|
||||
*/
|
||||
final class IInputMethodInvoker {
|
||||
private static final String TAG = InputMethodManagerService.TAG;
|
||||
private static final boolean DEBUG = InputMethodManagerService.DEBUG;
|
||||
|
||||
@AnyThread
|
||||
@Nullable
|
||||
static IInputMethodInvoker create(@Nullable IInputMethod inputMethod) {
|
||||
if (inputMethod == null) {
|
||||
return null;
|
||||
}
|
||||
if (!Binder.isProxy(inputMethod)) {
|
||||
// IInputMethodInvoker must be used only within the system_server and InputMethodService
|
||||
// must not be running in the system_server. Therefore, "inputMethod" must be a Proxy.
|
||||
throw new UnsupportedOperationException(inputMethod + " must have been a BinderProxy.");
|
||||
}
|
||||
return new IInputMethodInvoker(inputMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
* A simplified version of {@link android.os.Debug#getCaller()}.
|
||||
*
|
||||
* @return method name of the caller.
|
||||
*/
|
||||
@AnyThread
|
||||
private static String getCallerMethodName() {
|
||||
final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
|
||||
if (callStack.length <= 4) {
|
||||
return "<bottom of call stack>";
|
||||
}
|
||||
return callStack[4].getMethodName();
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
private static void logRemoteException(@NonNull RemoteException e) {
|
||||
if (DEBUG || !(e instanceof DeadObjectException)) {
|
||||
Slog.w(TAG, "IPC failed at IInputMethodInvoker#" + getCallerMethodName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
static int getBinderIdentityHashCode(@Nullable IInputMethodInvoker obj) {
|
||||
if (obj == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return System.identityHashCode(obj.mTarget);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private final IInputMethod mTarget;
|
||||
|
||||
private IInputMethodInvoker(@NonNull IInputMethod target) {
|
||||
mTarget = target;
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
@NonNull
|
||||
IBinder asBinder() {
|
||||
return mTarget.asBinder();
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
void initializeInternal(IBinder token, IInputMethodPrivilegedOperations privOps,
|
||||
int configChanges, boolean stylusHwSupported) {
|
||||
try {
|
||||
mTarget.initializeInternal(token, privOps, configChanges, stylusHwSupported);
|
||||
} catch (RemoteException e) {
|
||||
logRemoteException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
void onCreateInlineSuggestionsRequest(InlineSuggestionsRequestInfo requestInfo,
|
||||
IInlineSuggestionsRequestCallback cb) {
|
||||
try {
|
||||
mTarget.onCreateInlineSuggestionsRequest(requestInfo, cb);
|
||||
} catch (RemoteException e) {
|
||||
logRemoteException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
void bindInput(InputBinding binding) {
|
||||
try {
|
||||
mTarget.bindInput(binding);
|
||||
} catch (RemoteException e) {
|
||||
logRemoteException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
void unbindInput() {
|
||||
try {
|
||||
mTarget.unbindInput();
|
||||
} catch (RemoteException e) {
|
||||
logRemoteException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
void startInput(IBinder startInputToken, IInputContext inputContext, EditorInfo attribute,
|
||||
boolean restarting) {
|
||||
try {
|
||||
mTarget.startInput(startInputToken, inputContext, attribute, restarting);
|
||||
} catch (RemoteException e) {
|
||||
logRemoteException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
void createSession(InputChannel channel, IInputSessionCallback callback) {
|
||||
try {
|
||||
mTarget.createSession(channel, callback);
|
||||
} catch (RemoteException e) {
|
||||
logRemoteException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
void setSessionEnabled(IInputMethodSession session, boolean enabled) {
|
||||
try {
|
||||
mTarget.setSessionEnabled(session, enabled);
|
||||
} catch (RemoteException e) {
|
||||
logRemoteException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(b/192412909): Convert this back to void method
|
||||
@AnyThread
|
||||
boolean showSoftInput(IBinder showInputToken, int flags, ResultReceiver resultReceiver) {
|
||||
try {
|
||||
mTarget.showSoftInput(showInputToken, flags, resultReceiver);
|
||||
} catch (RemoteException e) {
|
||||
logRemoteException(e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO(b/192412909): Convert this back to void method
|
||||
@AnyThread
|
||||
boolean hideSoftInput(IBinder hideInputToken, int flags, ResultReceiver resultReceiver) {
|
||||
try {
|
||||
mTarget.hideSoftInput(hideInputToken, flags, resultReceiver);
|
||||
} catch (RemoteException e) {
|
||||
logRemoteException(e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
void changeInputMethodSubtype(InputMethodSubtype subtype) {
|
||||
try {
|
||||
mTarget.changeInputMethodSubtype(subtype);
|
||||
} catch (RemoteException e) {
|
||||
logRemoteException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
void canStartStylusHandwriting(int requestId) {
|
||||
try {
|
||||
mTarget.canStartStylusHandwriting(requestId);
|
||||
} catch (RemoteException e) {
|
||||
logRemoteException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
void startStylusHandwriting(InputChannel channel, List<MotionEvent> events) {
|
||||
try {
|
||||
mTarget.startStylusHandwriting(channel, events);
|
||||
} catch (RemoteException e) {
|
||||
logRemoteException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,7 @@ final class InputMethodBindingController {
|
||||
@GuardedBy("ImfLock.class") @Nullable private String mCurId;
|
||||
@GuardedBy("ImfLock.class") @Nullable private String mSelectedMethodId;
|
||||
@GuardedBy("ImfLock.class") @Nullable private Intent mCurIntent;
|
||||
@GuardedBy("ImfLock.class") @Nullable private IInputMethod mCurMethod;
|
||||
@GuardedBy("ImfLock.class") @Nullable private IInputMethodInvoker mCurMethod;
|
||||
@GuardedBy("ImfLock.class") private int mCurMethodUid = Process.INVALID_UID;
|
||||
@GuardedBy("ImfLock.class") private IBinder mCurToken;
|
||||
@GuardedBy("ImfLock.class") private int mCurSeq;
|
||||
@@ -241,7 +241,7 @@ final class InputMethodBindingController {
|
||||
*/
|
||||
@GuardedBy("ImfLock.class")
|
||||
@Nullable
|
||||
IInputMethod getCurMethod() {
|
||||
IInputMethodInvoker getCurMethod() {
|
||||
return mCurMethod;
|
||||
}
|
||||
|
||||
@@ -298,7 +298,7 @@ final class InputMethodBindingController {
|
||||
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.onServiceConnected");
|
||||
synchronized (ImfLock.class) {
|
||||
if (mCurIntent != null && name.equals(mCurIntent.getComponent())) {
|
||||
mCurMethod = IInputMethod.Stub.asInterface(service);
|
||||
mCurMethod = IInputMethodInvoker.create(IInputMethod.Stub.asInterface(service));
|
||||
updateCurrentMethodUid();
|
||||
if (mCurToken == null) {
|
||||
Slog.w(TAG, "Service connected without a token!");
|
||||
|
||||
@@ -167,7 +167,6 @@ import com.android.internal.util.DumpUtils;
|
||||
import com.android.internal.view.IInlineSuggestionsRequestCallback;
|
||||
import com.android.internal.view.IInlineSuggestionsResponseCallback;
|
||||
import com.android.internal.view.IInputContext;
|
||||
import com.android.internal.view.IInputMethod;
|
||||
import com.android.internal.view.IInputMethodClient;
|
||||
import com.android.internal.view.IInputMethodManager;
|
||||
import com.android.internal.view.IInputMethodSession;
|
||||
@@ -329,7 +328,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
|
||||
static class SessionState {
|
||||
final ClientState client;
|
||||
final IInputMethod method;
|
||||
final IInputMethodInvoker method;
|
||||
|
||||
IInputMethodSession session;
|
||||
InputChannel channel;
|
||||
@@ -338,14 +337,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
public String toString() {
|
||||
return "SessionState{uid " + client.uid + " pid " + client.pid
|
||||
+ " method " + Integer.toHexString(
|
||||
System.identityHashCode(method))
|
||||
IInputMethodInvoker.getBinderIdentityHashCode(method))
|
||||
+ " session " + Integer.toHexString(
|
||||
System.identityHashCode(session))
|
||||
+ " channel " + channel
|
||||
+ "}";
|
||||
}
|
||||
|
||||
SessionState(ClientState _client, IInputMethod _method,
|
||||
SessionState(ClientState _client, IInputMethodInvoker _method,
|
||||
IInputMethodSession _session, InputChannel _channel) {
|
||||
client = _client;
|
||||
method = _method;
|
||||
@@ -613,7 +612,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
*/
|
||||
@GuardedBy("ImfLock.class")
|
||||
@Nullable
|
||||
private IInputMethod getCurMethodLocked() {
|
||||
private IInputMethodInvoker getCurMethodLocked() {
|
||||
return mBindingController.getCurMethod();
|
||||
}
|
||||
|
||||
@@ -692,8 +691,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
|
||||
/**
|
||||
* Internal state snapshot when
|
||||
* {@link IInputMethod#startInput(IBinder, IInputContext, EditorInfo, boolean)} is about to be
|
||||
* called.
|
||||
* {@link com.android.internal.view.IInputMethod#startInput(IBinder, IInputContext, EditorInfo,
|
||||
* boolean)} is about to be called.
|
||||
*
|
||||
* <p>Calling that IPC endpoint basically means that
|
||||
* {@link InputMethodService#doStartInput(InputConnection, EditorInfo, boolean)} will be called
|
||||
@@ -1951,18 +1950,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
InlineSuggestionsRequestInfo requestInfo, IInlineSuggestionsRequestCallback callback) {
|
||||
final InputMethodInfo imi = mMethodMap.get(getSelectedMethodIdLocked());
|
||||
try {
|
||||
IInputMethod curMethod = getCurMethodLocked();
|
||||
IInputMethodInvoker curMethod = getCurMethodLocked();
|
||||
if (userId == mSettings.getCurrentUserId() && imi != null
|
||||
&& imi.isInlineSuggestionsEnabled() && curMethod != null) {
|
||||
final IInlineSuggestionsRequestCallback callbackImpl =
|
||||
new InlineSuggestionsRequestCallbackDecorator(callback,
|
||||
imi.getPackageName(), mCurTokenDisplayId, getCurTokenLocked(),
|
||||
this);
|
||||
try {
|
||||
curMethod.onCreateInlineSuggestionsRequest(requestInfo, callbackImpl);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "RemoteException calling onCreateInlineSuggestionsRequest()", e);
|
||||
}
|
||||
curMethod.onCreateInlineSuggestionsRequest(requestInfo, callbackImpl);
|
||||
} else {
|
||||
callback.onInlineSuggestionsUnsupported();
|
||||
}
|
||||
@@ -2190,13 +2185,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
mCurFocusedWindow, 0, null, SoftInputShowHideReason.HIDE_REMOVE_CLIENT);
|
||||
if (mBoundToMethod) {
|
||||
mBoundToMethod = false;
|
||||
IInputMethod curMethod = getCurMethodLocked();
|
||||
IInputMethodInvoker curMethod = getCurMethodLocked();
|
||||
if (curMethod != null) {
|
||||
try {
|
||||
curMethod.unbindInput();
|
||||
} catch (RemoteException e) {
|
||||
// There is nothing interesting about the method dying.
|
||||
}
|
||||
curMethod.unbindInput();
|
||||
}
|
||||
}
|
||||
mCurClient = null;
|
||||
@@ -2230,13 +2221,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
+ mCurClient.client.asBinder());
|
||||
if (mBoundToMethod) {
|
||||
mBoundToMethod = false;
|
||||
IInputMethod curMethod = getCurMethodLocked();
|
||||
IInputMethodInvoker curMethod = getCurMethodLocked();
|
||||
if (curMethod != null) {
|
||||
try {
|
||||
curMethod.unbindInput();
|
||||
} catch (RemoteException e) {
|
||||
// There is nothing interesting about the method dying.
|
||||
}
|
||||
curMethod.unbindInput();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2285,11 +2272,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
@NonNull
|
||||
InputBindResult attachNewInputLocked(@StartInputReason int startInputReason, boolean initial) {
|
||||
if (!mBoundToMethod) {
|
||||
IInputMethod curMethod = getCurMethodLocked();
|
||||
try {
|
||||
curMethod.bindInput(mCurClient.binding);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
getCurMethodLocked().bindInput(mCurClient.binding);
|
||||
mBoundToMethod = true;
|
||||
}
|
||||
|
||||
@@ -2316,11 +2299,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
}
|
||||
|
||||
final SessionState session = mCurClient.curSession;
|
||||
try {
|
||||
setEnabledSessionLocked(session);
|
||||
session.method.startInput(startInputToken, mCurInputContext, mCurAttribute, restarting);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
setEnabledSessionLocked(session);
|
||||
session.method.startInput(startInputToken, mCurInputContext, mCurAttribute, restarting);
|
||||
|
||||
if (mShowRequested) {
|
||||
if (DEBUG) Slog.v(TAG, "Attach new input asks to show input");
|
||||
@@ -2514,18 +2494,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
}
|
||||
|
||||
@GuardedBy("ImfLock.class")
|
||||
void initializeImeLocked(@NonNull IInputMethod inputMethod, @NonNull IBinder token,
|
||||
void initializeImeLocked(@NonNull IInputMethodInvoker inputMethod, @NonNull IBinder token,
|
||||
@android.content.pm.ActivityInfo.Config int configChanges, boolean supportStylusHw) {
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Sending attach of token: " + token + " for display: "
|
||||
+ mCurTokenDisplayId);
|
||||
}
|
||||
try {
|
||||
inputMethod.initializeInternal(token,
|
||||
new InputMethodPrivilegedOperationsImpl(this, token), configChanges,
|
||||
supportStylusHw);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
inputMethod.initializeInternal(token, new InputMethodPrivilegedOperationsImpl(this, token),
|
||||
configChanges, supportStylusHw);
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
@@ -2535,7 +2511,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
void onSessionCreated(IInputMethod method, IInputMethodSession session, InputChannel channel) {
|
||||
void onSessionCreated(IInputMethodInvoker method, IInputMethodSession session,
|
||||
InputChannel channel) {
|
||||
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.onSessionCreated");
|
||||
try {
|
||||
synchronized (ImfLock.class) {
|
||||
@@ -2545,7 +2522,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
channel.dispose();
|
||||
return;
|
||||
}
|
||||
IInputMethod curMethod = getCurMethodLocked();
|
||||
IInputMethodInvoker curMethod = getCurMethodLocked();
|
||||
if (curMethod != null && method != null
|
||||
&& curMethod.asBinder() == method.asBinder()) {
|
||||
if (mCurClient != null) {
|
||||
@@ -2609,7 +2586,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
|
||||
cs.sessionRequested = true;
|
||||
|
||||
final IInputMethod curMethod = getCurMethodLocked();
|
||||
final IInputMethodInvoker curMethod = getCurMethodLocked();
|
||||
final IInputSessionCallback.Stub callback = new IInputSessionCallback.Stub() {
|
||||
@Override
|
||||
public void sessionCreated(IInputMethodSession session) {
|
||||
@@ -2624,7 +2601,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
|
||||
try {
|
||||
curMethod.createSession(clientChannel, callback);
|
||||
} catch (RemoteException e) {
|
||||
} finally {
|
||||
// Dispose the channel because the remote proxy will get its own copy when
|
||||
// unparceled.
|
||||
@@ -3012,14 +2988,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
}
|
||||
if (newSubtype != oldSubtype) {
|
||||
setSelectedInputMethodAndSubtypeLocked(info, subtypeId, true);
|
||||
IInputMethod curMethod = getCurMethodLocked();
|
||||
IInputMethodInvoker curMethod = getCurMethodLocked();
|
||||
if (curMethod != null) {
|
||||
try {
|
||||
updateSystemUiLocked(mImeWindowVis, mBackDisposition);
|
||||
curMethod.changeInputMethodSubtype(newSubtype);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Failed to call changeInputMethodSubtype");
|
||||
}
|
||||
updateSystemUiLocked(mImeWindowVis, mBackDisposition);
|
||||
curMethod.changeInputMethodSubtype(newSubtype);
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -3096,13 +3068,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
return;
|
||||
}
|
||||
if (DEBUG) Slog.v(TAG, "Client requesting Stylus Handwriting to be started");
|
||||
final IInputMethod curMethod = getCurMethodLocked();
|
||||
final IInputMethodInvoker curMethod = getCurMethodLocked();
|
||||
if (curMethod != null) {
|
||||
try {
|
||||
curMethod.canStartStylusHandwriting(++mHwRequestId);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "RemoteException calling canStartStylusHandwriting(): ", e);
|
||||
}
|
||||
curMethod.canStartStylusHandwriting(++mHwRequestId);
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
@@ -3153,21 +3121,20 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
}
|
||||
|
||||
mBindingController.setCurrentMethodVisible();
|
||||
final IInputMethod curMethod = getCurMethodLocked();
|
||||
final IInputMethodInvoker curMethod = getCurMethodLocked();
|
||||
if (curMethod != null) {
|
||||
// create a placeholder token for IMS so that IMS cannot inject windows into client app.
|
||||
Binder showInputToken = new Binder();
|
||||
mShowRequestWindowMap.put(showInputToken, windowToken);
|
||||
final int showFlags = getImeShowFlagsLocked();
|
||||
try {
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Calling " + curMethod + ".showSoftInput(" + showInputToken
|
||||
+ ", " + showFlags + ", " + resultReceiver + ") for reason: "
|
||||
+ InputMethodDebug.softInputDisplayReasonToString(reason));
|
||||
}
|
||||
curMethod.showSoftInput(showInputToken, showFlags, resultReceiver);
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Calling " + curMethod + ".showSoftInput(" + showInputToken
|
||||
+ ", " + showFlags + ", " + resultReceiver + ") for reason: "
|
||||
+ InputMethodDebug.softInputDisplayReasonToString(reason));
|
||||
}
|
||||
// TODO(b/192412909): Check if we can always call onShowHideSoftInputRequested() or not.
|
||||
if (curMethod.showSoftInput(showInputToken, showFlags, resultReceiver)) {
|
||||
onShowHideSoftInputRequested(true /* show */, windowToken, reason);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
mInputShown = true;
|
||||
return true;
|
||||
@@ -3236,7 +3203,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
// since Android Eclair. That's why we need to accept IMM#hideSoftInput() even when only
|
||||
// IMMS#InputShown indicates that the software keyboard is shown.
|
||||
// TODO: Clean up, IMMS#mInputShown, IMMS#mImeWindowVis and mShowRequested.
|
||||
IInputMethod curMethod = getCurMethodLocked();
|
||||
IInputMethodInvoker curMethod = getCurMethodLocked();
|
||||
final boolean shouldHideSoftInput = (curMethod != null) && (mInputShown
|
||||
|| (mImeWindowVis & InputMethodService.IME_ACTIVE) != 0);
|
||||
boolean res;
|
||||
@@ -3252,10 +3219,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
+ ", " + resultReceiver + ") for reason: "
|
||||
+ InputMethodDebug.softInputDisplayReasonToString(reason));
|
||||
}
|
||||
try {
|
||||
curMethod.hideSoftInput(hideInputToken, 0 /* flags */, resultReceiver);
|
||||
// TODO(b/192412909): Check if we can always call onShowHideSoftInputRequested() or not.
|
||||
if (curMethod.hideSoftInput(hideInputToken, 0 /* flags */, resultReceiver)) {
|
||||
onShowHideSoftInputRequested(false /* show */, windowToken, reason);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
res = true;
|
||||
} else {
|
||||
@@ -4160,7 +4126,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
/** Called right after {@link IInputMethod#showSoftInput}. */
|
||||
/** Called right after {@link com.android.internal.view.IInputMethod#showSoftInput}. */
|
||||
@GuardedBy("ImfLock.class")
|
||||
private void onShowHideSoftInputRequested(boolean show, IBinder requestToken,
|
||||
@SoftInputShowHideReason int reason) {
|
||||
@@ -4215,19 +4181,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
void setEnabledSessionLocked(SessionState session) {
|
||||
if (mEnabledSession != session) {
|
||||
if (mEnabledSession != null && mEnabledSession.session != null) {
|
||||
try {
|
||||
if (DEBUG) Slog.v(TAG, "Disabling: " + mEnabledSession);
|
||||
mEnabledSession.method.setSessionEnabled(mEnabledSession.session, false);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
if (DEBUG) Slog.v(TAG, "Disabling: " + mEnabledSession);
|
||||
mEnabledSession.method.setSessionEnabled(mEnabledSession.session, false);
|
||||
}
|
||||
mEnabledSession = session;
|
||||
if (mEnabledSession != null && mEnabledSession.session != null) {
|
||||
try {
|
||||
if (DEBUG) Slog.v(TAG, "Enabling: " + mEnabledSession);
|
||||
mEnabledSession.method.setSessionEnabled(mEnabledSession.session, true);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
if (DEBUG) Slog.v(TAG, "Enabling: " + mEnabledSession);
|
||||
mEnabledSession.method.setSessionEnabled(mEnabledSession.session, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4394,12 +4354,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// TODO: replace null with actual Channel, MotionEvents
|
||||
getCurMethodLocked().startStylusHandwriting(null, null);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "RemoteException calling startStylusHandwriting(): ", e);
|
||||
}
|
||||
// TODO: replace null with actual Channel, MotionEvents
|
||||
getCurMethodLocked().startStylusHandwriting(null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5132,7 +5088,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
@BinderThread
|
||||
private void dumpAsStringNoCheck(FileDescriptor fd, PrintWriter pw, String[] args,
|
||||
boolean isCritical) {
|
||||
IInputMethod method;
|
||||
IInputMethodInvoker method;
|
||||
ClientState client;
|
||||
ClientState focusedWindowClient;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user