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
17package android.view.inputmethod;
18
19import android.os.Bundle;
20import android.os.Handler;
21import android.view.KeyEvent;
22
23/**
24 * <p>Wrapper class for proxying calls to another InputConnection.  Subclass and have fun!
25 */
26public class InputConnectionWrapper implements InputConnection {
27    private InputConnection mTarget;
28    final boolean mMutable;
29    @InputConnectionInspector.MissingMethodFlags
30    private int mMissingMethodFlags;
31
32    /**
33     * Initializes a wrapper.
34     *
35     * <p><b>Caveat:</b> Although the system can accept {@code (InputConnection) null} in some
36     * places, you cannot emulate such a behavior by non-null {@link InputConnectionWrapper} that
37     * has {@code null} in {@code target}.</p>
38     * @param target the {@link InputConnection} to be proxied.
39     * @param mutable set {@code true} to protect this object from being reconfigured to target
40     * another {@link InputConnection}.  Note that this is ignored while the target is {@code null}.
41     */
42    public InputConnectionWrapper(InputConnection target, boolean mutable) {
43        mMutable = mutable;
44        mTarget = target;
45        mMissingMethodFlags = InputConnectionInspector.getMissingMethodFlags(target);
46    }
47
48    /**
49     * Change the target of the input connection.
50     *
51     * <p><b>Caveat:</b> Although the system can accept {@code (InputConnection) null} in some
52     * places, you cannot emulate such a behavior by non-null {@link InputConnectionWrapper} that
53     * has {@code null} in {@code target}.</p>
54     * @param target the {@link InputConnection} to be proxied.
55     * @throws SecurityException when this wrapper has non-null target and is immutable.
56     */
57    public void setTarget(InputConnection target) {
58        if (mTarget != null && !mMutable) {
59            throw new SecurityException("not mutable");
60        }
61        mTarget = target;
62        mMissingMethodFlags = InputConnectionInspector.getMissingMethodFlags(target);
63    }
64
65    /**
66     * @hide
67     */
68    @InputConnectionInspector.MissingMethodFlags
69    public int getMissingMethodFlags() {
70        return mMissingMethodFlags;
71    }
72
73    /**
74     * {@inheritDoc}
75     * @throws NullPointerException if the target is {@code null}.
76     */
77    @Override
78    public CharSequence getTextBeforeCursor(int n, int flags) {
79        return mTarget.getTextBeforeCursor(n, flags);
80    }
81
82    /**
83     * {@inheritDoc}
84     * @throws NullPointerException if the target is {@code null}.
85     */
86    @Override
87    public CharSequence getTextAfterCursor(int n, int flags) {
88        return mTarget.getTextAfterCursor(n, flags);
89    }
90
91    /**
92     * {@inheritDoc}
93     * @throws NullPointerException if the target is {@code null}.
94     */
95    @Override
96    public CharSequence getSelectedText(int flags) {
97        return mTarget.getSelectedText(flags);
98    }
99
100    /**
101     * {@inheritDoc}
102     * @throws NullPointerException if the target is {@code null}.
103     */
104    @Override
105    public int getCursorCapsMode(int reqModes) {
106        return mTarget.getCursorCapsMode(reqModes);
107    }
108
109    /**
110     * {@inheritDoc}
111     * @throws NullPointerException if the target is {@code null}.
112     */
113    @Override
114    public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
115        return mTarget.getExtractedText(request, flags);
116    }
117
118    /**
119     * {@inheritDoc}
120     * @throws NullPointerException if the target is {@code null}.
121     */
122    @Override
123    public boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
124        return mTarget.deleteSurroundingTextInCodePoints(beforeLength, afterLength);
125    }
126
127    /**
128     * {@inheritDoc}
129     * @throws NullPointerException if the target is {@code null}.
130     */
131    @Override
132    public boolean deleteSurroundingText(int beforeLength, int afterLength) {
133        return mTarget.deleteSurroundingText(beforeLength, afterLength);
134    }
135
136    /**
137     * {@inheritDoc}
138     * @throws NullPointerException if the target is {@code null}.
139     */
140    @Override
141    public boolean setComposingText(CharSequence text, int newCursorPosition) {
142        return mTarget.setComposingText(text, newCursorPosition);
143    }
144
145    /**
146     * {@inheritDoc}
147     * @throws NullPointerException if the target is {@code null}.
148     */
149    @Override
150    public boolean setComposingRegion(int start, int end) {
151        return mTarget.setComposingRegion(start, end);
152    }
153
154    /**
155     * {@inheritDoc}
156     * @throws NullPointerException if the target is {@code null}.
157     */
158    @Override
159    public boolean finishComposingText() {
160        return mTarget.finishComposingText();
161    }
162
163    /**
164     * {@inheritDoc}
165     * @throws NullPointerException if the target is {@code null}.
166     */
167    @Override
168    public boolean commitText(CharSequence text, int newCursorPosition) {
169        return mTarget.commitText(text, newCursorPosition);
170    }
171
172    /**
173     * {@inheritDoc}
174     * @throws NullPointerException if the target is {@code null}.
175     */
176    @Override
177    public boolean commitCompletion(CompletionInfo text) {
178        return mTarget.commitCompletion(text);
179    }
180
181    /**
182     * {@inheritDoc}
183     * @throws NullPointerException if the target is {@code null}.
184     */
185    @Override
186    public boolean commitCorrection(CorrectionInfo correctionInfo) {
187        return mTarget.commitCorrection(correctionInfo);
188    }
189
190    /**
191     * {@inheritDoc}
192     * @throws NullPointerException if the target is {@code null}.
193     */
194    @Override
195    public boolean setSelection(int start, int end) {
196        return mTarget.setSelection(start, end);
197    }
198
199    /**
200     * {@inheritDoc}
201     * @throws NullPointerException if the target is {@code null}.
202     */
203    @Override
204    public boolean performEditorAction(int editorAction) {
205        return mTarget.performEditorAction(editorAction);
206    }
207
208    /**
209     * {@inheritDoc}
210     * @throws NullPointerException if the target is {@code null}.
211     */
212    @Override
213    public boolean performContextMenuAction(int id) {
214        return mTarget.performContextMenuAction(id);
215    }
216
217    /**
218     * {@inheritDoc}
219     * @throws NullPointerException if the target is {@code null}.
220     */
221    @Override
222    public boolean beginBatchEdit() {
223        return mTarget.beginBatchEdit();
224    }
225
226    /**
227     * {@inheritDoc}
228     * @throws NullPointerException if the target is {@code null}.
229     */
230    @Override
231    public boolean endBatchEdit() {
232        return mTarget.endBatchEdit();
233    }
234
235    /**
236     * {@inheritDoc}
237     * @throws NullPointerException if the target is {@code null}.
238     */
239    @Override
240    public boolean sendKeyEvent(KeyEvent event) {
241        return mTarget.sendKeyEvent(event);
242    }
243
244    /**
245     * {@inheritDoc}
246     * @throws NullPointerException if the target is {@code null}.
247     */
248    @Override
249    public boolean clearMetaKeyStates(int states) {
250        return mTarget.clearMetaKeyStates(states);
251    }
252
253    /**
254     * {@inheritDoc}
255     * @throws NullPointerException if the target is {@code null}.
256     */
257    @Override
258    public boolean reportFullscreenMode(boolean enabled) {
259        return mTarget.reportFullscreenMode(enabled);
260    }
261
262    /**
263     * {@inheritDoc}
264     * @throws NullPointerException if the target is {@code null}.
265     */
266    @Override
267    public boolean performPrivateCommand(String action, Bundle data) {
268        return mTarget.performPrivateCommand(action, data);
269    }
270
271    /**
272     * {@inheritDoc}
273     * @throws NullPointerException if the target is {@code null}.
274     */
275    @Override
276    public boolean requestCursorUpdates(int cursorUpdateMode) {
277        return mTarget.requestCursorUpdates(cursorUpdateMode);
278    }
279
280    /**
281     * {@inheritDoc}
282     * @throws NullPointerException if the target is {@code null}.
283     */
284    @Override
285    public Handler getHandler() {
286        return mTarget.getHandler();
287    }
288
289    /**
290     * {@inheritDoc}
291     * @throws NullPointerException if the target is {@code null}.
292     */
293    @Override
294    public void closeConnection() {
295        mTarget.closeConnection();
296    }
297
298    /**
299     * {@inheritDoc}
300     * @throws NullPointerException if the target is {@code null}.
301     */
302    @Override
303    public boolean commitContent(InputContentInfo inputContentInfo, int flags, Bundle opts) {
304        return mTarget.commitContent(inputContentInfo, flags, opts);
305    }
306}
307