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