Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 32950c05 authored by Wilson Wu's avatar Wilson Wu Committed by Android (Google) Code Review
Browse files

Merge "Fix potential failures in InputMethodService (2nd try)"

parents 3fdbebcd 4bcdf9b2
Loading
Loading
Loading
Loading
+86 −48
Original line number Diff line number Diff line
@@ -147,119 +147,146 @@ class IInputMethodWrapper extends IInputMethod.Stub
    @MainThread
    @Override
    public void executeMessage(Message msg) {
        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;
        }

        final InputMethod inputMethod = mInputMethod.get();
        final InputMethodServiceInternal target = mTarget.get();
        switch (msg.what) {
            case DO_DUMP: {
                InputMethodServiceInternal target = mTarget.get();
                if (target == null) {
                    return;
                }
                SomeArgs args = (SomeArgs)msg.obj;
                if (isValid(inputMethod, target, "DO_DUMP")) {
                    final FileDescriptor fd = (FileDescriptor) args.arg1;
                    final PrintWriter fout = (PrintWriter) args.arg2;
                    final String[] dumpArgs = (String[]) args.arg3;
                    final CountDownLatch latch = (CountDownLatch) args.arg4;
                    try {
                    target.dump((FileDescriptor) args.arg1,
                            (PrintWriter) args.arg2, (String[]) args.arg3);
                        target.dump(fd, fout, dumpArgs);
                    } catch (RuntimeException e) {
                    ((PrintWriter)args.arg2).println("Exception: " + e);
                        fout.println("Exception: " + e);
                    } finally {
                        latch.countDown();
                    }
                synchronized (args.arg4) {
                    ((CountDownLatch)args.arg4).countDown();
                }
                args.recycle();
                return;
            }
            case DO_INITIALIZE_INTERNAL:
                if (isValid(inputMethod, target, "DO_INITIALIZE_INTERNAL")) {
                    inputMethod.initializeInternal((IInputMethod.InitParams) msg.obj);
                }
                return;
            case DO_SET_INPUT_CONTEXT: {
                if (isValid(inputMethod, target, "DO_SET_INPUT_CONTEXT")) {
                    inputMethod.bindInput((InputBinding) msg.obj);
                }
                return;
            }
            case DO_UNSET_INPUT_CONTEXT:
                if (isValid(inputMethod, target, "DO_UNSET_INPUT_CONTEXT")) {
                    inputMethod.unbindInput();
                }
                return;
            case DO_START_INPUT: {
                final SomeArgs args = (SomeArgs) msg.obj;
                if (isValid(inputMethod, target, "DO_START_INPUT")) {
                    final InputConnection inputConnection = (InputConnection) args.arg1;
                    final IInputMethod.StartInputParams params =
                            (IInputMethod.StartInputParams) args.arg2;
                    inputMethod.dispatchStartInput(inputConnection, params);
                }
                args.recycle();
                return;
            }
            case DO_ON_NAV_BUTTON_FLAGS_CHANGED:
                if (isValid(inputMethod, target, "DO_ON_NAV_BUTTON_FLAGS_CHANGED")) {
                    inputMethod.onNavButtonFlagsChanged(msg.arg1);
                }
                return;
            case DO_CREATE_SESSION: {
                SomeArgs args = (SomeArgs)msg.obj;
                if (isValid(inputMethod, target, "DO_CREATE_SESSION")) {
                    inputMethod.createSession(new InputMethodSessionCallbackWrapper(
                            mContext, (InputChannel) args.arg1,
                            (IInputMethodSessionCallback) args.arg2));
                }
                args.recycle();
                return;
            }
            case DO_SET_SESSION_ENABLED:
                inputMethod.setSessionEnabled((InputMethodSession)msg.obj,
                        msg.arg1 != 0);
                if (isValid(inputMethod, target, "DO_SET_SESSION_ENABLED")) {
                    inputMethod.setSessionEnabled((InputMethodSession) msg.obj, msg.arg1 != 0);
                }
                return;
            case DO_SHOW_SOFT_INPUT: {
                final SomeArgs args = (SomeArgs)msg.obj;
                if (isValid(inputMethod, target, "DO_SHOW_SOFT_INPUT")) {
                    inputMethod.showSoftInputWithToken(
                            msg.arg1, (ResultReceiver) args.arg2, (IBinder) args.arg1);
                }
                args.recycle();
                return;
            }
            case DO_HIDE_SOFT_INPUT: {
                final SomeArgs args = (SomeArgs) msg.obj;
                if (isValid(inputMethod, target, "DO_HIDE_SOFT_INPUT")) {
                    inputMethod.hideSoftInputWithToken(msg.arg1, (ResultReceiver) args.arg2,
                            (IBinder) args.arg1);
                }
                args.recycle();
                return;
            }
            case DO_CHANGE_INPUTMETHOD_SUBTYPE:
                if (isValid(inputMethod, target, "DO_CHANGE_INPUTMETHOD_SUBTYPE")) {
                    inputMethod.changeInputMethodSubtype((InputMethodSubtype) msg.obj);
                }
                return;
            case DO_CREATE_INLINE_SUGGESTIONS_REQUEST: {
                final SomeArgs args = (SomeArgs) msg.obj;
                if (isValid(inputMethod, target, "DO_CREATE_INLINE_SUGGESTIONS_REQUEST")) {
                    inputMethod.onCreateInlineSuggestionsRequest(
                            (InlineSuggestionsRequestInfo) args.arg1,
                            (IInlineSuggestionsRequestCallback) args.arg2);
                }
                args.recycle();
                return;
            }
            case DO_CAN_START_STYLUS_HANDWRITING: {
                if (isValid(inputMethod, target, "DO_CAN_START_STYLUS_HANDWRITING")) {
                    inputMethod.canStartStylusHandwriting(msg.arg1);
                }
                return;
            }
            case DO_UPDATE_TOOL_TYPE: {
                if (isValid(inputMethod, target, "DO_UPDATE_TOOL_TYPE")) {
                    inputMethod.updateEditorToolType(msg.arg1);
                }
                return;
            }
            case DO_START_STYLUS_HANDWRITING: {
                final SomeArgs args = (SomeArgs) msg.obj;
                if (isValid(inputMethod, target, "DO_START_STYLUS_HANDWRITING")) {
                    inputMethod.startStylusHandwriting(msg.arg1, (InputChannel) args.arg1,
                            (List<MotionEvent>) args.arg2);
                }
                args.recycle();
                return;
            }
            case DO_INIT_INK_WINDOW: {
                if (isValid(inputMethod, target, "DO_INIT_INK_WINDOW")) {
                    inputMethod.initInkWindow();
                }
                return;
            }
            case DO_FINISH_STYLUS_HANDWRITING: {
                if (isValid(inputMethod, target, "DO_FINISH_STYLUS_HANDWRITING")) {
                    inputMethod.finishStylusHandwriting();
                }
                return;
            }
            case DO_REMOVE_STYLUS_HANDWRITING_WINDOW: {
                if (isValid(inputMethod, target, "DO_REMOVE_STYLUS_HANDWRITING_WINDOW")) {
                    inputMethod.removeStylusHandwritingWindow();
                }
                return;
            }

        }
        Log.w(TAG, "Unhandled message code: " + msg.what);
    }
@@ -445,4 +472,15 @@ class IInputMethodWrapper extends IInputMethod.Stub
    public void removeStylusHandwritingWindow() {
        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_REMOVE_STYLUS_HANDWRITING_WINDOW));
    }

    private static boolean isValid(InputMethod inputMethod, InputMethodServiceInternal target,
            String msg) {
        if (inputMethod != null && target != null && !target.isServiceDestroyed()) {
            return true;
        } else {
            Log.w(TAG, "Ignoring " + msg + ", InputMethod:" + inputMethod
                    + ", InputMethodServiceInternal:" + target);
            return false;
        }
    }
}
+8 −5
Original line number Diff line number Diff line
@@ -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);
@@ -3938,6 +3933,14 @@ public class InputMethodService extends AbstractInputMethodService {
            public void triggerServiceDump(String where, @Nullable byte[] icProto) {
                ImeTracing.getInstance().triggerServiceDump(where, mDumper, icProto);
            }

            /**
             * {@inheritDoc}
             */
            @Override
            public boolean isServiceDestroyed() {
                return mDestroyed;
            }
        };
    }

+7 −0
Original line number Diff line number Diff line
@@ -85,4 +85,11 @@ interface InputMethodServiceInternal {
     */
    default void triggerServiceDump(@NonNull String where, @Nullable byte[] icProto) {
    }

    /**
     * @return {@code true} if {@link InputMethodService} is destroyed.
     */
    default boolean isServiceDestroyed() {
        return false;
    };
}