From 90bd36363c5738b3f526aa1f1d44f432236300a0 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Mon, 29 Feb 2016 12:45:49 -0800 Subject: [PATCH] InputConnectionWrapper never supports null target. This CL makes it clear that InputConnectionWrapper does not support null target. In other words, the semantics of null InputConnection can never be emulated by a non-null InputConnectionWrapper. This is particularly problematic when app developers are just forwarding the return value of super.onCreateInputConnection() to InputConnectionWrapper or its subclass, because there are many chance that super.onCreateInputConnection() starts returning null, e.g. when: A. the application is extending a Framework class, and the Framework class is updated by OTA. B. the application is extending system WebView, and the WebView is updated. C. the application is extending a 3rd party library, and the app developer creates a new build with a new version of the 3rd party library. To make it easy to catch these kind of bugs, this CL lets the constructor of InputMethodWrapper throw NullPointerException when target is null. Bugs like crbug.com/571229 should be caught by developers more easily. Bug: 27407697 Change-Id: I83875bea886d4784f9507c930050efc29708d9db --- .../inputmethod/InputConnectionWrapper.java | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/core/java/android/view/inputmethod/InputConnectionWrapper.java b/core/java/android/view/inputmethod/InputConnectionWrapper.java index 65c7654c671b4..afa72a21eadab 100644 --- a/core/java/android/view/inputmethod/InputConnectionWrapper.java +++ b/core/java/android/view/inputmethod/InputConnectionWrapper.java @@ -16,33 +16,47 @@ package android.view.inputmethod; +import android.annotation.NonNull; import android.os.Bundle; import android.os.Handler; import android.view.KeyEvent; +import static com.android.internal.util.Preconditions.checkNotNull; + /** *

Wrapper class for proxying calls to another InputConnection. Subclass * and have fun! */ public class InputConnectionWrapper implements InputConnection { + @NonNull private InputConnection mTarget; final boolean mMutable; - - public InputConnectionWrapper(InputConnection target, boolean mutable) { + + /** + * Initializes the wrapper for the given {@link InputConnection}. + * @param target the {@link InputConnection} to be wrapped. + * @param mutable {@code true} if the wrapper is to be mutable. + * @throws NullPointerException if {@code target} is {@code null}. + */ + public InputConnectionWrapper(@NonNull InputConnection target, boolean mutable) { + checkNotNull(target); mMutable = mutable; mTarget = target; } /** * Change the target of the input connection. + * @param target the {@link InputConnection} to be wrapped. + * @throws NullPointerException if {@code target} is {@code null}. */ - public void setTarget(InputConnection target) { + public void setTarget(@NonNull InputConnection target) { + checkNotNull(target); if (mTarget != null && !mMutable) { throw new SecurityException("not mutable"); } mTarget = target; } - + public CharSequence getTextBeforeCursor(int n, int flags) { return mTarget.getTextBeforeCursor(n, flags); }