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

Commit 8608a612 authored by Antonio Kantek's avatar Antonio Kantek Committed by Android (Google) Code Review
Browse files

Merge "Reduce ClientController#mClients visibility scope" into main

parents 18e812cf eb18a691
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.inputmethod;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.pm.PackageManagerInternal;
import android.os.IBinder;
import android.os.RemoteException;
@@ -29,6 +30,7 @@ import com.android.internal.inputmethod.IRemoteInputConnection;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

/**
 * Store and manage {@link InputMethodManagerService} clients. This class was designed to be a
@@ -62,7 +64,7 @@ final class ClientController {

    // TODO(b/314150112): Make this field private when breaking the cycle with IMMS.
    @GuardedBy("ImfLock.class")
    final ArrayMap<IBinder, ClientState> mClients = new ArrayMap<>();
    private final ArrayMap<IBinder, ClientState> mClients = new ArrayMap<>();

    @GuardedBy("ImfLock.class")
    private final List<ClientControllerCallback> mCallbacks = new ArrayList<>();
@@ -144,6 +146,19 @@ final class ClientController {
        mCallbacks.add(callback);
    }

    @GuardedBy("ImfLock.class")
    @Nullable
    ClientState getClient(IBinder binder) {
        return mClients.get(binder);
    }

    @GuardedBy("ImfLock.class")
    void forAllClients(Consumer<ClientState> consumer) {
        for (int i = 0; i < mClients.size(); i++) {
            consumer.accept(mClients.valueAt(i));
        }
    }

    @GuardedBy("ImfLock.class")
    boolean verifyClientAndPackageMatch(
            @NonNull IInputMethodClient client, @NonNull String packageName) {
+86 −70
Original line number Diff line number Diff line
@@ -205,6 +205,7 @@ import java.util.WeakHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.IntConsumer;

/**
@@ -270,7 +271,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
    @NonNull
    private final String[] mNonPreemptibleInputMethods;

    // TODO(b/314150112): Move this to ClientController.
    @UserIdInt
    private int mLastSwitchUserId;

@@ -1819,10 +1819,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
        }

        mLastSwitchUserId = newUserId;

        if (mIsInteractive && clientToBeReset != null) {
            final ClientState cs =
                    mClientController.mClients.get(clientToBeReset.asBinder());
            final ClientState cs = mClientController.getClient(clientToBeReset.asBinder());
            if (cs == null) {
                // The client is already gone.
                return;
@@ -2165,8 +2163,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
    /**
     * Hide the IME if the removed user is the current user.
     */
    @GuardedBy("ImfLock.class")
    private void onClientRemoved(ClientState client) {
        synchronized (ImfLock.class) {
        clearClientSessionLocked(client);
        clearClientSessionForAccessibilityLocked(client);
        if (mCurClient == client) {
@@ -2184,7 +2182,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
            }
            mBoundToAccessibility = false;
            mCurClient = null;
            }
            if (mCurFocusedWindowClient == client) {
                mCurFocusedWindowClient = null;
                mCurFocusedWindowEditorInfo = null;
@@ -2192,7 +2189,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
        }
    }

    // TODO(b/314150112): Move this to ClientController.
    @GuardedBy("ImfLock.class")
    void unbindCurrentClientLocked(@UnbindReason int unbindClientReason) {
        if (mCurClient != null) {
@@ -2883,11 +2879,16 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
    @GuardedBy("ImfLock.class")
    void clearClientSessionsLocked() {
        if (getCurMethodLocked() != null) {
            final int numClients = mClientController.mClients.size();
            for (int i = 0; i < numClients; ++i) {
                clearClientSessionLocked(mClientController.mClients.valueAt(i));
                clearClientSessionForAccessibilityLocked(mClientController.mClients.valueAt(i));
            // TODO(b/322816970): Replace this with lambda.
            mClientController.forAllClients(new Consumer<ClientState>() {

                @GuardedBy("ImfLock.class")
                @Override
                public void accept(ClientState c) {
                    clearClientSessionLocked(c);
                    clearClientSessionForAccessibilityLocked(c);
                }
            });

            finishSessionLocked(mEnabledSession);
            for (int i = 0; i < mEnabledAccessibilitySessions.size(); i++) {
@@ -3732,9 +3733,9 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
            return InputBindResult.INVALID_USER;
        }

        final ClientState cs = mClientController.mClients.get(client.asBinder());
        final ClientState cs = mClientController.getClient(client.asBinder());
        if (cs == null) {
            throw new IllegalArgumentException("unknown client " + client.asBinder());
            throw new IllegalArgumentException("Unknown client " + client.asBinder());
        }

        final int imeClientFocus = mWindowManagerInternal.hasInputMethodClientFocus(
@@ -3906,8 +3907,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
            // We need to check if this is the current client with
            // focus in the window manager, to allow this call to
            // be made before input is started in it.
            final ClientState cs =
                    mClientController.mClients.get(client.asBinder());
            final ClientState cs = mClientController.getClient(client.asBinder());
            if (cs == null) {
                ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_SERVER_CLIENT_KNOWN);
                throw new IllegalArgumentException("unknown client " + client.asBinder());
@@ -4518,16 +4518,17 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
    @Override
    public void startImeTrace() {
        super.startImeTrace_enforcePermission();

        ImeTracing.getInstance().startTrace(null /* printwriter */);
        ArrayMap<IBinder, ClientState> clients;
        synchronized (ImfLock.class) {
            clients = new ArrayMap<>(mClientController.mClients);
        }
        for (ClientState state : clients.values()) {
            if (state != null) {
                state.mClient.setImeTraceEnabled(true /* enabled */);
            // TODO(b/322816970): Replace this with lambda.
            mClientController.forAllClients(new Consumer<ClientState>() {

                @GuardedBy("ImfLock.class")
                @Override
                public void accept(ClientState c) {
                    c.mClient.setImeTraceEnabled(true /* enabled */);
                }
            });
        }
    }

@@ -4538,14 +4539,16 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
        super.stopImeTrace_enforcePermission();

        ImeTracing.getInstance().stopTrace(null /* printwriter */);
        ArrayMap<IBinder, ClientState> clients;
        synchronized (ImfLock.class) {
            clients = new ArrayMap<>(mClientController.mClients);
        }
        for (ClientState state : clients.values()) {
            if (state != null) {
                state.mClient.setImeTraceEnabled(false /* enabled */);
            // TODO(b/322816970): Replace this with lambda.
            mClientController.forAllClients(new Consumer<ClientState>() {

                @GuardedBy("ImfLock.class")
                @Override
                public void accept(ClientState c) {
                    c.mClient.setImeTraceEnabled(false /* enabled */);
                }
            });
        }
    }

@@ -5779,11 +5782,15 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
                // We only have sessions when we bound to an input method. Remove this session
                // from all clients.
                if (getCurMethodLocked() != null) {
                    final int numClients = mClientController.mClients.size();
                    for (int i = 0; i < numClients; ++i) {
                        clearClientSessionForAccessibilityLocked(
                                mClientController.mClients.valueAt(i), accessibilityConnectionId);
                    // TODO(b/322816970): Replace this with lambda.
                    mClientController.forAllClients(new Consumer<ClientState>() {

                        @GuardedBy("ImfLock.class")
                        @Override
                        public void accept(ClientState c) {
                            clearClientSessionForAccessibilityLocked(c, accessibilityConnectionId);
                        }
                    });
                    AccessibilitySessionState session = mEnabledAccessibilitySessions.get(
                            accessibilityConnectionId);
                    if (session != null) {
@@ -5967,19 +5974,26 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
                p.println("  InputMethod #" + i + ":");
                info.dump(p, "    ");
            }
            // Dump ClientController#mClients
            p.println("  ClientStates:");
            // TODO(b/314150112): move client related dump info to ClientController#dump
            final int numClients = mClientController.mClients.size();
            for (int i = 0; i < numClients; ++i) {
                final ClientState ci = mClientController.mClients.valueAt(i);
                p.println("  " + ci + ":");
                p.println("    client=" + ci.mClient);
                p.println("    fallbackInputConnection=" + ci.mFallbackInputConnection);
                p.println("    sessionRequested=" + ci.mSessionRequested);
                p.println("    sessionRequestedForAccessibility="
                        + ci.mSessionRequestedForAccessibility);
                p.println("    curSession=" + ci.mCurSession);
            // TODO(b/322816970): Replace this with lambda.
            mClientController.forAllClients(new Consumer<ClientState>() {

                @GuardedBy("ImfLock.class")
                @Override
                public void accept(ClientState c) {
                    p.println("  " + c + ":");
                    p.println("    client=" + c.mClient);
                    p.println("    fallbackInputConnection="
                            + c.mFallbackInputConnection);
                    p.println("    sessionRequested="
                            + c.mSessionRequested);
                    p.println(
                            "    sessionRequestedForAccessibility="
                                    + c.mSessionRequestedForAccessibility);
                    p.println("    curSession=" + c.mCurSession);
                }
            });
            p.println("  mCurMethodId=" + getSelectedMethodIdLocked());
            client = mCurClient;
            p.println("  mCurClient=" + client + " mCurSeq=" + getSequenceNumberLocked());
@@ -6583,14 +6597,16 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
            }
        }
        boolean isImeTraceEnabled = ImeTracing.getInstance().isEnabled();
        ArrayMap<IBinder, ClientState> clients;
        synchronized (ImfLock.class) {
            clients = new ArrayMap<>(mClientController.mClients);
        }
        for (ClientState state : clients.values()) {
            if (state != null) {
                state.mClient.setImeTraceEnabled(isImeTraceEnabled);
            // TODO(b/322816970): Replace this with lambda.
            mClientController.forAllClients(new Consumer<ClientState>() {

                @GuardedBy("ImfLock.class")
                @Override
                public void accept(ClientState c) {
                    c.mClient.setImeTraceEnabled(isImeTraceEnabled);
                }
            });
        }
        return ShellCommandResult.SUCCESS;
    }
+2 −2
Original line number Diff line number Diff line
@@ -116,7 +116,7 @@ public final class ClientControllerTest {
                    ANY_CALLER_PID);

            verify(invoker.asBinder()).linkToDeath(any(IBinder.DeathRecipient.class), eq(0));
            assertThat(mController.mClients).containsEntry(invoker.asBinder(), added);
            assertThat(mController.getClient(invoker.asBinder())).isSameInstanceAs(added);
        }
    }

@@ -133,7 +133,7 @@ public final class ClientControllerTest {
            var invoker = IInputMethodClientInvoker.create(mClient, mHandler);
            added = mController.addClient(invoker, mConnection, ANY_DISPLAY_ID, ANY_CALLER_UID,
                    ANY_CALLER_PID);
            assertThat(mController.mClients).containsEntry(invoker.asBinder(), added);
            assertThat(mController.getClient(invoker.asBinder())).isSameInstanceAs(added);
            assertThat(mController.removeClient(mClient)).isTrue();
        }