1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.view.inputmethod; 18 19 import android.annotation.IntRange; 20 import android.annotation.Nullable; 21 import android.os.Bundle; 22 import android.os.Handler; 23 import android.view.KeyEvent; 24 25 import com.android.internal.util.Preconditions; 26 27 /** 28 * <p>Wrapper class for proxying calls to another InputConnection. Subclass and have fun! 29 */ 30 public class InputConnectionWrapper implements InputConnection { 31 private InputConnection mTarget; 32 final boolean mMutable; 33 @InputConnectionInspector.MissingMethodFlags 34 private int mMissingMethodFlags; 35 36 /** 37 * Initializes a wrapper. 38 * 39 * <p><b>Caveat:</b> Although the system can accept {@code (InputConnection) null} in some 40 * places, you cannot emulate such a behavior by non-null {@link InputConnectionWrapper} that 41 * has {@code null} in {@code target}.</p> 42 * @param target the {@link InputConnection} to be proxied. 43 * @param mutable set {@code true} to protect this object from being reconfigured to target 44 * another {@link InputConnection}. Note that this is ignored while the target is {@code null}. 45 */ InputConnectionWrapper(InputConnection target, boolean mutable)46 public InputConnectionWrapper(InputConnection target, boolean mutable) { 47 mMutable = mutable; 48 mTarget = target; 49 mMissingMethodFlags = InputConnectionInspector.getMissingMethodFlags(target); 50 } 51 52 /** 53 * Change the target of the input connection. 54 * 55 * <p><b>Caveat:</b> Although the system can accept {@code (InputConnection) null} in some 56 * places, you cannot emulate such a behavior by non-null {@link InputConnectionWrapper} that 57 * has {@code null} in {@code target}.</p> 58 * @param target the {@link InputConnection} to be proxied. 59 * @throws SecurityException when this wrapper has non-null target and is immutable. 60 */ setTarget(InputConnection target)61 public void setTarget(InputConnection target) { 62 if (mTarget != null && !mMutable) { 63 throw new SecurityException("not mutable"); 64 } 65 mTarget = target; 66 mMissingMethodFlags = InputConnectionInspector.getMissingMethodFlags(target); 67 } 68 69 /** 70 * @hide 71 */ 72 @InputConnectionInspector.MissingMethodFlags getMissingMethodFlags()73 public int getMissingMethodFlags() { 74 return mMissingMethodFlags; 75 } 76 77 /** 78 * {@inheritDoc} 79 * @throws NullPointerException if the target is {@code null}. 80 * @throws IllegalArgumentException if {@code length} is negative. 81 */ 82 @Nullable 83 @Override getTextBeforeCursor(@ntRangefrom = 0) int n, int flags)84 public CharSequence getTextBeforeCursor(@IntRange(from = 0) int n, int flags) { 85 Preconditions.checkArgumentNonnegative(n); 86 return mTarget.getTextBeforeCursor(n, flags); 87 } 88 89 /** 90 * {@inheritDoc} 91 * @throws NullPointerException if the target is {@code null}. 92 * @throws IllegalArgumentException if {@code length} is negative. 93 */ 94 @Nullable 95 @Override getTextAfterCursor(@ntRangefrom = 0) int n, int flags)96 public CharSequence getTextAfterCursor(@IntRange(from = 0) int n, int flags) { 97 Preconditions.checkArgumentNonnegative(n); 98 return mTarget.getTextAfterCursor(n, flags); 99 } 100 101 /** 102 * {@inheritDoc} 103 * @throws NullPointerException if the target is {@code null}. 104 */ 105 @Override getSelectedText(int flags)106 public CharSequence getSelectedText(int flags) { 107 return mTarget.getSelectedText(flags); 108 } 109 110 /** 111 * {@inheritDoc} 112 * @throws NullPointerException if the target is {@code null}. 113 * @throws IllegalArgumentException if {@code beforeLength} or {@code afterLength} is negative. 114 */ 115 @Nullable 116 @Override getSurroundingText(int beforeLength, int afterLength, int flags)117 public SurroundingText getSurroundingText(int beforeLength, int afterLength, int flags) { 118 Preconditions.checkArgumentNonnegative(beforeLength); 119 Preconditions.checkArgumentNonnegative(afterLength); 120 return mTarget.getSurroundingText(beforeLength, afterLength, flags); 121 } 122 123 /** 124 * {@inheritDoc} 125 * @throws NullPointerException if the target is {@code null}. 126 */ 127 @Override getCursorCapsMode(int reqModes)128 public int getCursorCapsMode(int reqModes) { 129 return mTarget.getCursorCapsMode(reqModes); 130 } 131 132 /** 133 * {@inheritDoc} 134 * @throws NullPointerException if the target is {@code null}. 135 */ 136 @Override getExtractedText(ExtractedTextRequest request, int flags)137 public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) { 138 return mTarget.getExtractedText(request, flags); 139 } 140 141 /** 142 * {@inheritDoc} 143 * @throws NullPointerException if the target is {@code null}. 144 */ 145 @Override deleteSurroundingTextInCodePoints(int beforeLength, int afterLength)146 public boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) { 147 return mTarget.deleteSurroundingTextInCodePoints(beforeLength, afterLength); 148 } 149 150 /** 151 * {@inheritDoc} 152 * @throws NullPointerException if the target is {@code null}. 153 */ 154 @Override deleteSurroundingText(int beforeLength, int afterLength)155 public boolean deleteSurroundingText(int beforeLength, int afterLength) { 156 return mTarget.deleteSurroundingText(beforeLength, afterLength); 157 } 158 159 /** 160 * {@inheritDoc} 161 * @throws NullPointerException if the target is {@code null}. 162 */ 163 @Override setComposingText(CharSequence text, int newCursorPosition)164 public boolean setComposingText(CharSequence text, int newCursorPosition) { 165 return mTarget.setComposingText(text, newCursorPosition); 166 } 167 168 /** 169 * {@inheritDoc} 170 * @throws NullPointerException if the target is {@code null}. 171 */ 172 @Override setComposingRegion(int start, int end)173 public boolean setComposingRegion(int start, int end) { 174 return mTarget.setComposingRegion(start, end); 175 } 176 177 /** 178 * {@inheritDoc} 179 * @throws NullPointerException if the target is {@code null}. 180 */ 181 @Override finishComposingText()182 public boolean finishComposingText() { 183 return mTarget.finishComposingText(); 184 } 185 186 /** 187 * {@inheritDoc} 188 * @throws NullPointerException if the target is {@code null}. 189 */ 190 @Override commitText(CharSequence text, int newCursorPosition)191 public boolean commitText(CharSequence text, int newCursorPosition) { 192 return mTarget.commitText(text, newCursorPosition); 193 } 194 195 /** 196 * {@inheritDoc} 197 * @throws NullPointerException if the target is {@code null}. 198 */ 199 @Override commitCompletion(CompletionInfo text)200 public boolean commitCompletion(CompletionInfo text) { 201 return mTarget.commitCompletion(text); 202 } 203 204 /** 205 * {@inheritDoc} 206 * @throws NullPointerException if the target is {@code null}. 207 */ 208 @Override commitCorrection(CorrectionInfo correctionInfo)209 public boolean commitCorrection(CorrectionInfo correctionInfo) { 210 return mTarget.commitCorrection(correctionInfo); 211 } 212 213 /** 214 * {@inheritDoc} 215 * @throws NullPointerException if the target is {@code null}. 216 */ 217 @Override setSelection(int start, int end)218 public boolean setSelection(int start, int end) { 219 return mTarget.setSelection(start, end); 220 } 221 222 /** 223 * {@inheritDoc} 224 * @throws NullPointerException if the target is {@code null}. 225 */ 226 @Override performEditorAction(int editorAction)227 public boolean performEditorAction(int editorAction) { 228 return mTarget.performEditorAction(editorAction); 229 } 230 231 /** 232 * {@inheritDoc} 233 * @throws NullPointerException if the target is {@code null}. 234 */ 235 @Override performContextMenuAction(int id)236 public boolean performContextMenuAction(int id) { 237 return mTarget.performContextMenuAction(id); 238 } 239 240 /** 241 * {@inheritDoc} 242 * @throws NullPointerException if the target is {@code null}. 243 */ 244 @Override beginBatchEdit()245 public boolean beginBatchEdit() { 246 return mTarget.beginBatchEdit(); 247 } 248 249 /** 250 * {@inheritDoc} 251 * @throws NullPointerException if the target is {@code null}. 252 */ 253 @Override endBatchEdit()254 public boolean endBatchEdit() { 255 return mTarget.endBatchEdit(); 256 } 257 258 /** 259 * {@inheritDoc} 260 * @throws NullPointerException if the target is {@code null}. 261 */ 262 @Override sendKeyEvent(KeyEvent event)263 public boolean sendKeyEvent(KeyEvent event) { 264 return mTarget.sendKeyEvent(event); 265 } 266 267 /** 268 * {@inheritDoc} 269 * @throws NullPointerException if the target is {@code null}. 270 */ 271 @Override clearMetaKeyStates(int states)272 public boolean clearMetaKeyStates(int states) { 273 return mTarget.clearMetaKeyStates(states); 274 } 275 276 /** 277 * {@inheritDoc} 278 * @throws NullPointerException if the target is {@code null}. 279 */ 280 @Override reportFullscreenMode(boolean enabled)281 public boolean reportFullscreenMode(boolean enabled) { 282 return mTarget.reportFullscreenMode(enabled); 283 } 284 285 /** 286 * {@inheritDoc} 287 * @throws NullPointerException if the target is {@code null}. 288 */ 289 @Override performSpellCheck()290 public boolean performSpellCheck() { 291 return mTarget.performSpellCheck(); 292 } 293 294 /** 295 * {@inheritDoc} 296 * @throws NullPointerException if the target is {@code null}. 297 */ 298 @Override performPrivateCommand(String action, Bundle data)299 public boolean performPrivateCommand(String action, Bundle data) { 300 return mTarget.performPrivateCommand(action, data); 301 } 302 303 /** 304 * {@inheritDoc} 305 * @throws NullPointerException if the target is {@code null}. 306 */ 307 @Override requestCursorUpdates(int cursorUpdateMode)308 public boolean requestCursorUpdates(int cursorUpdateMode) { 309 return mTarget.requestCursorUpdates(cursorUpdateMode); 310 } 311 312 /** 313 * {@inheritDoc} 314 * @throws NullPointerException if the target is {@code null}. 315 */ 316 @Override getHandler()317 public Handler getHandler() { 318 return mTarget.getHandler(); 319 } 320 321 /** 322 * {@inheritDoc} 323 * @throws NullPointerException if the target is {@code null}. 324 */ 325 @Override closeConnection()326 public void closeConnection() { 327 mTarget.closeConnection(); 328 } 329 330 /** 331 * {@inheritDoc} 332 * @throws NullPointerException if the target is {@code null}. 333 */ 334 @Override commitContent(InputContentInfo inputContentInfo, int flags, Bundle opts)335 public boolean commitContent(InputContentInfo inputContentInfo, int flags, Bundle opts) { 336 return mTarget.commitContent(inputContentInfo, flags, opts); 337 } 338 339 /** 340 * {@inheritDoc} 341 * @throws NullPointerException if the target is {@code null}. 342 */ 343 @Override setImeConsumesInput(boolean imeConsumesInput)344 public boolean setImeConsumesInput(boolean imeConsumesInput) { 345 return mTarget.setImeConsumesInput(imeConsumesInput); 346 } 347 } 348