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

Commit 1d1c21c9 authored by Yohei Yukawa's avatar Yohei Yukawa
Browse files

Add more JavaDoc to InputConnectionWrapper.

This CL makes it clear that InputConnectionWrapper cannot be used to
emulate the behavior when a null InputConnection is passed to the
system.

We should provide some guideline for developers about how to deal with
bugs like crbug.com/571229, but as explained in the previous CL [1],
changing the behavior of InputConnectionWrapper could be a bit risky at
this point.  Hence we put more cautions in JavaDoc instead.

 [1] I8bc84d484ab0b27a02e74f11110430f70646e69a
     abc4b8f0

Bug: 27407697
Change-Id: I98d1fc096c108603647a85bb0ba045b5dd23d37b
parent 86a27f34
Loading
Loading
Loading
Loading
+125 −14
Original line number Diff line number Diff line
@@ -21,13 +21,22 @@ import android.os.Handler;
import android.view.KeyEvent;

/**
 * <p>Wrapper class for proxying calls to another InputConnection.  Subclass
 * and have fun!
 * <p>Wrapper class for proxying calls to another InputConnection.  Subclass and have fun!
 */
public class InputConnectionWrapper implements InputConnection {
    private InputConnection mTarget;
    final boolean mMutable;

    /**
     * Initializes a wrapper.
     *
     * <p><b>Caveat:</b> Although the system can accept {@code (InputConnection) null} in some
     * places, you cannot emulate such a behavior by non-null {@link InputConnectionWrapper} that
     * has {@code null} in {@code target}.</p>
     * @param target the {@link InputConnection} to be proxied.
     * @param mutable set {@code true} to protect this object from being reconfigured to target
     * another {@link InputConnection}.  Note that this is ignored while the target is {@code null}.
     */
    public InputConnectionWrapper(InputConnection target, boolean mutable) {
        mMutable = mutable;
        mTarget = target;
@@ -35,6 +44,12 @@ public class InputConnectionWrapper implements InputConnection {

    /**
     * Change the target of the input connection.
     *
     * <p><b>Caveat:</b> Although the system can accept {@code (InputConnection) null} in some
     * places, you cannot emulate such a behavior by non-null {@link InputConnectionWrapper} that
     * has {@code null} in {@code target}.</p>
     * @param target the {@link InputConnection} to be proxied.
     * @throws SecurityException when this wrapper has non-null target and is immutable.
     */
    public void setTarget(InputConnection target) {
        if (mTarget != null && !mMutable) {
@@ -43,98 +58,194 @@ public class InputConnectionWrapper implements InputConnection {
        mTarget = target;
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public CharSequence getTextBeforeCursor(int n, int flags) {
        return mTarget.getTextBeforeCursor(n, flags);
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public CharSequence getTextAfterCursor(int n, int flags) {
        return mTarget.getTextAfterCursor(n, flags);
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public CharSequence getSelectedText(int flags) {
        return mTarget.getSelectedText(flags);
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public int getCursorCapsMode(int reqModes) {
        return mTarget.getCursorCapsMode(reqModes);
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
        return mTarget.getExtractedText(request, flags);
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
        return mTarget.deleteSurroundingTextInCodePoints(beforeLength, afterLength);
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public boolean deleteSurroundingText(int beforeLength, int afterLength) {
        return mTarget.deleteSurroundingText(beforeLength, afterLength);
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public boolean setComposingText(CharSequence text, int newCursorPosition) {
        return mTarget.setComposingText(text, newCursorPosition);
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public boolean setComposingRegion(int start, int end) {
        return mTarget.setComposingRegion(start, end);
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public boolean finishComposingText() {
        return mTarget.finishComposingText();
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public boolean commitText(CharSequence text, int newCursorPosition) {
        return mTarget.commitText(text, newCursorPosition);
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public boolean commitCompletion(CompletionInfo text) {
        return mTarget.commitCompletion(text);
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public boolean commitCorrection(CorrectionInfo correctionInfo) {
        return mTarget.commitCorrection(correctionInfo);
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public boolean setSelection(int start, int end) {
        return mTarget.setSelection(start, end);
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public boolean performEditorAction(int editorAction) {
        return mTarget.performEditorAction(editorAction);
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public boolean performContextMenuAction(int id) {
        return mTarget.performContextMenuAction(id);
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public boolean beginBatchEdit() {
        return mTarget.beginBatchEdit();
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public boolean endBatchEdit() {
        return mTarget.endBatchEdit();
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public boolean sendKeyEvent(KeyEvent event) {
        return mTarget.sendKeyEvent(event);
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public boolean clearMetaKeyStates(int states) {
        return mTarget.clearMetaKeyStates(states);
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public boolean reportFullscreenMode(boolean enabled) {
        return mTarget.reportFullscreenMode(enabled);
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public boolean performPrivateCommand(String action, Bundle data) {
        return mTarget.performPrivateCommand(action, data);
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public boolean requestCursorUpdates(int cursorUpdateMode) {
        return mTarget.requestCursorUpdates(cursorUpdateMode);
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException if the target is {@code null}.
     */
    public Handler getHandler() {
        return mTarget.getHandler();
    }