Fix potential failures in InputMethodService

It had the chance for calling into IMS but IMS
already destroyed.

Ideally we should suppress any callbacks after
InputMethodService#onDestroy() and log them.

Bug: 121269861
Bug: 211062619
Bug: 148086656
Test: presubmit
Change-Id: I10f26a92e739b60c5b8010e8476f8f5a403e0a7b
This commit is contained in:
Wilson Wu
2022-09-13 18:23:09 +08:00
parent 54ae0e2abd
commit ce98507bf3
3 changed files with 21 additions and 6 deletions

View File

@@ -147,12 +147,16 @@ class IInputMethodWrapper extends IInputMethod.Stub
@MainThread
@Override
public void executeMessage(Message msg) {
InputMethod inputMethod = mInputMethod.get();
final InputMethod inputMethod = mInputMethod.get();
// Need a valid reference to the inputMethod for everything except a dump.
if (inputMethod == null && msg.what != DO_DUMP) {
Log.w(TAG, "Input method reference was null, ignoring message: " + msg.what);
return;
}
if (inputMethod != null && inputMethod.isServiceDestroyed() && msg.what != DO_DUMP) {
Log.w(TAG, "InputMethodService was destroyed, ignoring message: " + msg.what);
return;
}
switch (msg.what) {
case DO_DUMP: {

View File

@@ -700,11 +700,6 @@ public class InputMethodService extends AbstractInputMethodService {
@MainThread
@Override
public final void initializeInternal(@NonNull IInputMethod.InitParams params) {
if (mDestroyed) {
Log.i(TAG, "The InputMethodService has already onDestroyed()."
+ "Ignore the initialization.");
return;
}
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.initializeInternal");
mConfigTracker.onInitialize(params.configChanges);
mPrivOps.set(params.privilegedOperations);
@@ -1070,6 +1065,16 @@ public class InputMethodService extends AbstractInputMethodService {
public void changeInputMethodSubtype(InputMethodSubtype subtype) {
dispatchOnCurrentInputMethodSubtypeChanged(subtype);
}
/**
* {@inheritDoc}
* @hide
*/
@MainThread
@Override
public final boolean isServiceDestroyed() {
return mDestroyed;
}
}
/**

View File

@@ -417,4 +417,10 @@ public interface InputMethod {
default void removeStylusHandwritingWindow() {
// intentionally empty
}
/**
* Return {@code true} if the {@link InputMethodService} is destroyed.
* @hide
*/
boolean isServiceDestroyed();
}