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

Commit bd5fed39 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Let InputMethodPrivilegedOperationsRegistry deal with its singleton-ness"

parents 3921b96e d746a7e8
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.inputmethod.IInputContentUriToken;
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
import com.android.internal.inputmethod.InputMethodPrivilegedOperations;
import com.android.internal.inputmethod.InputMethodPrivilegedOperationsRegistry;

import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -465,7 +466,7 @@ public class InputMethodService extends AbstractInputMethodService {
        public final void initializeInternal(IBinder token, int displayId,
                IInputMethodPrivilegedOperations privilegedOperations) {
            mPrivOps.set(privilegedOperations);
            mImm.registerInputMethodPrivOps(token, mPrivOps);
            InputMethodPrivilegedOperationsRegistry.put(token, mPrivOps);
            updateInputMethodDisplay(displayId);
            attachToken(token);
        }
@@ -1031,7 +1032,7 @@ public class InputMethodService extends AbstractInputMethodService {
        if (mToken != null) {
            // This is completely optional, but allows us to show more explicit error messages
            // when IME developers are doing something unsupported.
            mImm.unregisterInputMethodPrivOps(mToken);
            InputMethodPrivilegedOperationsRegistry.remove(mToken);
        }
    }

+15 −47
Original line number Diff line number Diff line
@@ -57,7 +57,6 @@ import android.view.ViewRootImpl;
import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
import android.view.autofill.AutofillManager;

import com.android.internal.inputmethod.InputMethodPrivilegedOperations;
import com.android.internal.inputmethod.InputMethodPrivilegedOperationsRegistry;
import com.android.internal.os.SomeArgs;
import com.android.internal.view.IInputConnectionWrapper;
@@ -387,9 +386,6 @@ public final class InputMethodManager {
    final Pool<PendingEvent> mPendingEventPool = new SimplePool<>(20);
    final SparseArray<PendingEvent> mPendingEvents = new SparseArray<>(20);

    private final InputMethodPrivilegedOperationsRegistry mPrivOpsRegistry =
            new InputMethodPrivilegedOperationsRegistry();

    // -----------------------------------------------------------

    static final int MSG_DUMP = 1;
@@ -741,7 +737,7 @@ public final class InputMethodManager {
     */
    @Deprecated
    public void showStatusIcon(IBinder imeToken, String packageName, @DrawableRes int iconId) {
        mPrivOpsRegistry.get(imeToken).updateStatusIcon(packageName, iconId);
        InputMethodPrivilegedOperationsRegistry.get(imeToken).updateStatusIcon(packageName, iconId);
    }

    /**
@@ -751,7 +747,7 @@ public final class InputMethodManager {
     */
    @Deprecated
    public void hideStatusIcon(IBinder imeToken) {
        mPrivOpsRegistry.get(imeToken).updateStatusIcon(null, 0);
        InputMethodPrivilegedOperationsRegistry.get(imeToken).updateStatusIcon(null, 0);
    }

    /** @hide */
@@ -1792,7 +1788,7 @@ public final class InputMethodManager {
    public void setInputMethod(IBinder token, String id) {
        if (token == null) {
            // Note: null token is allowed for callers that have WRITE_SECURE_SETTINGS permission.
            // Thus we cannot always rely on mPrivOpsRegistry unfortunately.
            // Thus we cannot always rely on InputMethodPrivilegedOperationsRegistry unfortunately.
            // TODO(Bug 114488811): Consider deprecating null token rule.
            try {
                mService.setInputMethod(token, id);
@@ -1801,7 +1797,7 @@ public final class InputMethodManager {
            }
            return;
        }
        mPrivOpsRegistry.get(token).setInputMethod(id);
        InputMethodPrivilegedOperationsRegistry.get(token).setInputMethod(id);
    }

    /**
@@ -1821,7 +1817,7 @@ public final class InputMethodManager {
    public void setInputMethodAndSubtype(IBinder token, String id, InputMethodSubtype subtype) {
        if (token == null) {
            // Note: null token is allowed for callers that have WRITE_SECURE_SETTINGS permission.
            // Thus we cannot always rely on mPrivOpsRegistry unfortunately.
            // Thus we cannot always rely on InputMethodPrivilegedOperationsRegistry unfortunately.
            // TODO(Bug 114488811): Consider deprecating null token rule.
            try {
                mService.setInputMethodAndSubtype(token, id, subtype);
@@ -1830,7 +1826,7 @@ public final class InputMethodManager {
            }
            return;
        }
        mPrivOpsRegistry.get(token).setInputMethodAndSubtype(id, subtype);
        InputMethodPrivilegedOperationsRegistry.get(token).setInputMethodAndSubtype(id, subtype);
    }

    /**
@@ -1850,7 +1846,7 @@ public final class InputMethodManager {
     */
    @Deprecated
    public void hideSoftInputFromInputMethod(IBinder token, int flags) {
        mPrivOpsRegistry.get(token).hideMySoftInput(flags);
        InputMethodPrivilegedOperationsRegistry.get(token).hideMySoftInput(flags);
    }

    /**
@@ -1871,7 +1867,7 @@ public final class InputMethodManager {
     */
    @Deprecated
    public void showSoftInputFromInputMethod(IBinder token, int flags) {
        mPrivOpsRegistry.get(token).showMySoftInput(flags);
        InputMethodPrivilegedOperationsRegistry.get(token).showMySoftInput(flags);
    }

    /**
@@ -2231,7 +2227,7 @@ public final class InputMethodManager {
    public boolean switchToLastInputMethod(IBinder imeToken) {
        if (imeToken == null) {
            // Note: null token is allowed for callers that have WRITE_SECURE_SETTINGS permission.
            // Thus we cannot always rely on mPrivOpsRegistry unfortunately.
            // Thus we cannot always rely on InputMethodPrivilegedOperationsRegistry unfortunately.
            // TODO(Bug 114488811): Consider deprecating null token rule.
            try {
                return mService.switchToPreviousInputMethod(imeToken);
@@ -2239,7 +2235,7 @@ public final class InputMethodManager {
                throw e.rethrowFromSystemServer();
            }
        }
        return mPrivOpsRegistry.get(imeToken).switchToPreviousInputMethod();
        return InputMethodPrivilegedOperationsRegistry.get(imeToken).switchToPreviousInputMethod();
    }

    /**
@@ -2259,7 +2255,7 @@ public final class InputMethodManager {
    public boolean switchToNextInputMethod(IBinder imeToken, boolean onlyCurrentIme) {
        if (imeToken == null) {
            // Note: null token is allowed for callers that have WRITE_SECURE_SETTINGS permission.
            // Thus we cannot always rely on mPrivOpsRegistry unfortunately.
            // Thus we cannot always rely on InputMethodPrivilegedOperationsRegistry unfortunately.
            // TODO(Bug 114488811): Consider deprecating null token rule.
            try {
                return mService.switchToNextInputMethod(imeToken, onlyCurrentIme);
@@ -2267,7 +2263,8 @@ public final class InputMethodManager {
                throw e.rethrowFromSystemServer();
            }
        }
        return mPrivOpsRegistry.get(imeToken).switchToNextInputMethod(onlyCurrentIme);
        return InputMethodPrivilegedOperationsRegistry.get(imeToken)
                .switchToNextInputMethod(onlyCurrentIme);
    }

    /**
@@ -2286,7 +2283,8 @@ public final class InputMethodManager {
     */
    @Deprecated
    public boolean shouldOfferSwitchingToNextInputMethod(IBinder imeToken) {
        return mPrivOpsRegistry.get(imeToken).shouldOfferSwitchingToNextInputMethod();
        return InputMethodPrivilegedOperationsRegistry.get(imeToken)
                .shouldOfferSwitchingToNextInputMethod();
    }

    /**
@@ -2422,34 +2420,4 @@ public final class InputMethodManager {
        sb.append(",temporaryDetach=" + view.isTemporarilyDetached());
        return sb.toString();
    }

    /**
     * Called by {@link InputMethodService} so that API calls to deprecated ones defined in this
     * class can be forwarded to {@link InputMethodPrivilegedOperations}.
     *
     * <p>Note: this method does not hold strong references to {@code token} and {@code ops}. The
     * registry entry will be automatically cleared after {@code token} is garbage collected.</p>
     *
     * @param token IME token that is associated with {@code ops}
     * @param ops {@link InputMethodPrivilegedOperations} that is associated with {@code token}
     * @hide
     */
    public void registerInputMethodPrivOps(IBinder token, InputMethodPrivilegedOperations ops) {
        mPrivOpsRegistry.put(token, ops);
    }

    /**
     * Called from {@link InputMethodService#onDestroy()} to make sure that deprecated IME APIs
     * defined in this class can no longer access to {@link InputMethodPrivilegedOperations}.
     *
     * <p>Note: Calling this method is optional, but at least gives more explict error message in
     * logcat when IME developers are doing something unsupported (e.g. trying to call IME APIs
     * after {@link InputMethodService#onDestroy()}).</p>
     *
     * @param token IME token to be removed.
     * @hide
     */
    public void unregisterInputMethodPrivOps(IBinder token) {
        mPrivOpsRegistry.remove(token);
    }
}
+32 −13
Original line number Diff line number Diff line
@@ -29,12 +29,19 @@ import java.util.WeakHashMap;
/**
 * A weak-reference-based mapper from IME token to {@link InputMethodPrivilegedOperations} that is
 * used only to support deprecated IME APIs in {@link android.view.inputmethod.InputMethodManager}.
 *
 * <p>This class is designed to be used as a per-process global registry.</p>
 */
public final class InputMethodPrivilegedOperationsRegistry {
    private final Object mLock = new Object();
    @GuardedBy("mLock")
    private final WeakHashMap<IBinder, WeakReference<InputMethodPrivilegedOperations>>
            mRegistry = new WeakHashMap<>();
    private InputMethodPrivilegedOperationsRegistry() {
        // Not intended to be instantiated.
    }

    private static final Object sLock = new Object();

    @Nullable
    @GuardedBy("sLock")
    private static WeakHashMap<IBinder, WeakReference<InputMethodPrivilegedOperations>> sRegistry;

    @Nullable
    private static InputMethodPrivilegedOperations sNop;
@@ -62,10 +69,13 @@ public final class InputMethodPrivilegedOperationsRegistry {
     * @param ops {@link InputMethodPrivilegedOperations} to be associated with the given IME token
     */
    @AnyThread
    public void put(IBinder token, InputMethodPrivilegedOperations ops) {
        synchronized (mLock) {
    public static void put(IBinder token, InputMethodPrivilegedOperations ops) {
        synchronized (sLock) {
            if (sRegistry == null) {
                sRegistry = new WeakHashMap<>();
            }
            final WeakReference<InputMethodPrivilegedOperations> previousOps =
                    mRegistry.put(token, new WeakReference<>(ops));
                    sRegistry.put(token, new WeakReference<>(ops));
            if (previousOps != null) {
                throw new IllegalStateException(previousOps.get() + " is already registered for "
                        + " this token=" + token + " newOps=" + ops);
@@ -84,9 +94,12 @@ public final class InputMethodPrivilegedOperationsRegistry {
     */
    @NonNull
    @AnyThread
    public InputMethodPrivilegedOperations get(IBinder token) {
        synchronized (mLock) {
            final WeakReference<InputMethodPrivilegedOperations> wrapperRef = mRegistry.get(token);
    public static InputMethodPrivilegedOperations get(IBinder token) {
        synchronized (sLock) {
            if (sRegistry == null) {
                return getNopOps();
            }
            final WeakReference<InputMethodPrivilegedOperations> wrapperRef = sRegistry.get(token);
            if (wrapperRef == null) {
                return getNopOps();
            }
@@ -108,9 +121,15 @@ public final class InputMethodPrivilegedOperationsRegistry {
     * @param token IME token to be removed.
     */
    @AnyThread
    public void remove(IBinder token) {
        synchronized (mLock) {
            mRegistry.remove(token);
    public static void remove(IBinder token) {
        synchronized (sLock) {
            if (sRegistry == null) {
                return;
            }
            sRegistry.remove(token);
            if (sRegistry.isEmpty()) {
                sRegistry = null;
            }
        }
    }
}