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

Commit 040f7fb3 authored by Nikolas Havrikov's avatar Nikolas Havrikov
Browse files

Change IMMS not to implement ServiceConnection

Instead, encapsulate the service connection into a member,
and use via delegation.

Bug: 205676419
Test: make
Change-Id: I4244dce35e4025d9ad779672574751728d4f544d
parent e82e9f72
Loading
Loading
Loading
Loading
+82 −60
Original line number Diff line number Diff line
@@ -208,7 +208,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 * This class provides a system service that manages input methods.
 */
public class InputMethodManagerService extends IInputMethodManager.Stub
        implements ServiceConnection, Handler.Callback {
        implements Handler.Callback {
    static final boolean DEBUG = false;
    static final String TAG = "InputMethodManagerService";
    public static final String PROTO_ARG = "--proto";
@@ -369,6 +369,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        return mBindingController.getVisibleConnection();
    }

    /**
     * Used to bind the IME while it is not currently being shown.
     */
    @NonNull
    private ServiceConnection getMainConnection() {
        return mMainConnection;
    }

    // Ongoing notification
    private NotificationManager mNotificationManager;
    KeyguardManager mKeyguardManager;
@@ -2480,7 +2488,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        Intent intent = createImeBindingIntent(info.getComponent());
        setCurIntent(intent);

        if (bindCurrentInputMethodServiceLocked(intent, this, mImeConnectionBindFlags)) {
        if (bindCurrentInputMethodServiceLocked(intent, getMainConnection(),
                mImeConnectionBindFlags)) {
            addFreshWindowTokenLocked(displayIdToShowIme, info.getId());
            return new InputBindResult(
                    InputBindResult.ResultCode.SUCCESS_WAITING_IME_BINDING,
@@ -2613,13 +2622,15 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        mCaller.obtainMessageI(MSG_NOTIFY_IME_UID_TO_AUDIO_SERVICE, uid).sendToTarget();
    }

    private final ServiceConnection mMainConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.onServiceConnected");
            synchronized (mMethodMap) {
                if (getCurIntent() != null && name.equals(getCurIntent().getComponent())) {
                    setCurMethod(IInputMethod.Stub.asInterface(service));
                final String curMethodPackage = getCurIntent().getComponent().getPackageName();
                    final String curMethodPackage =
                            getCurIntent().getComponent().getPackageName();
                    final int curMethodUid = mPackageManagerInternal.getPackageUid(
                            curMethodPackage, 0 /* flags */, mSettings.getCurrentUserId());
                    if (curMethodUid < 0) {
@@ -2636,9 +2647,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
                    }
                    if (DEBUG) Slog.v(TAG, "Initiating attach with token: " + getCurToken());
                    // Dispatch display id for InputMethodService to update context display.
                executeOrSendMessage(getCurMethod(), mCaller.obtainMessageIOO(MSG_INITIALIZE_IME,
                        mMethodMap.get(getSelectedMethodId()).getConfigChanges(), getCurMethod(),
                        getCurToken()));
                    executeOrSendMessage(getCurMethod(),
                            mCaller.obtainMessageIOO(MSG_INITIALIZE_IME,
                                    mMethodMap.get(getSelectedMethodId()).getConfigChanges(),
                                    getCurMethod(), getCurToken()));
                    scheduleNotifyImeUidToAudioService(getCurMethodUid());
                    if (mCurClient != null) {
                        clearClientSessionLocked(mCurClient);
@@ -2649,6 +2661,39 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            // Note that mContext.unbindService(this) does not trigger this.  Hence if we are
            // here the
            // disconnection is not intended by IMMS (e.g. triggered because the current IMS
            // crashed),
            // which is irregular but can eventually happen for everyone just by continuing
            // using the
            // device.  Thus it is important to make sure that all the internal states are
            // properly
            // refreshed when this method is called back.  Running
            //    adb install -r <APK that implements the current IME>
            // would be a good way to trigger such a situation.
            synchronized (mMethodMap) {
                if (DEBUG) {
                    Slog.v(TAG, "Service disconnected: " + name
                            + " mCurIntent=" + getCurIntent());
                }
                if (getCurMethod() != null && getCurIntent() != null
                        && name.equals(getCurIntent().getComponent())) {
                    clearCurMethodLocked();
                    // We consider this to be a new bind attempt, since the system
                    // should now try to restart the service for us.
                    setLastBindTime(SystemClock.uptimeMillis());
                    mShowRequested = mInputShown;
                    mInputShown = false;
                    unbindCurrentClientLocked(UnbindReason.DISCONNECT_IME);
                }
            }
        }

    };

    void onSessionCreated(IInputMethod method, IInputMethodSession session,
            InputChannel channel) {
        synchronized (mMethodMap) {
@@ -2686,7 +2731,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        }

        if (hasConnection()) {
            mContext.unbindService(this);
            mContext.unbindService(getMainConnection());
            setHasConnection(false);
        }

@@ -2775,31 +2820,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        mInFullscreenMode = false;
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        // Note that mContext.unbindService(this) does not trigger this.  Hence if we are here the
        // disconnection is not intended by IMMS (e.g. triggered because the current IMS crashed),
        // which is irregular but can eventually happen for everyone just by continuing using the
        // device.  Thus it is important to make sure that all the internal states are properly
        // refreshed when this method is called back.  Running
        //    adb install -r <APK that implements the current IME>
        // would be a good way to trigger such a situation.
        synchronized (mMethodMap) {
            if (DEBUG) Slog.v(TAG, "Service disconnected: " + name
                    + " mCurIntent=" + getCurIntent());
            if (getCurMethod() != null && getCurIntent() != null
                    && name.equals(getCurIntent().getComponent())) {
                clearCurMethodLocked();
                // We consider this to be a new bind attempt, since the system
                // should now try to restart the service for us.
                setLastBindTime(SystemClock.uptimeMillis());
                mShowRequested = mInputShown;
                mInputShown = false;
                unbindCurrentClientLocked(UnbindReason.DISCONNECT_IME);
            }
        }
    }

    @BinderThread
    private void updateStatusIcon(@NonNull IBinder token, String packageName,
            @DrawableRes int iconId) {
@@ -3270,8 +3290,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
                EventLog.writeEvent(EventLogTags.IMF_FORCE_RECONNECT_IME, getSelectedMethodId(),
                        bindingDuration, 1);
                Slog.w(TAG, "Force disconnect/connect to the IME in showCurrentInputLocked()");
                mContext.unbindService(this);
                bindCurrentInputMethodServiceLocked(getCurIntent(), this, mImeConnectionBindFlags);
                ServiceConnection connection = getMainConnection();
                mContext.unbindService(connection);
                bindCurrentInputMethodServiceLocked(getCurIntent(), connection,
                        mImeConnectionBindFlags);
            } else {
                if (DEBUG) {
                    Slog.d(TAG, "Can't show input: connection = " + hasConnection() + ", time = "