1/*
2 * Copyright (C) 2007-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * 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, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
15 */
16
17package android.view.inputmethod;
18
19import android.annotation.NonNull;
20import android.annotation.Nullable;
21import android.annotation.SdkConstant;
22import android.annotation.SdkConstant.SdkConstantType;
23import android.inputmethodservice.InputMethodService;
24import android.os.IBinder;
25import android.os.ResultReceiver;
26
27/**
28 * The InputMethod interface represents an input method which can generate key
29 * events and text, such as digital, email addresses, CJK characters, other
30 * language characters, and etc., while handling various input events, and send
31 * the text back to the application that requests text input.  See
32 * {@link InputMethodManager} for more general information about the
33 * architecture.
34 *
35 * <p>Applications will not normally use this interface themselves, instead
36 * relying on the standard interaction provided by
37 * {@link android.widget.TextView} and {@link android.widget.EditText}.
38 *
39 * <p>Those implementing input methods should normally do so by deriving from
40 * {@link InputMethodService} or one of its subclasses.  When implementing
41 * an input method, the service component containing it must also supply
42 * a {@link #SERVICE_META_DATA} meta-data field, referencing an XML resource
43 * providing details about the input method.  All input methods also must
44 * require that clients hold the
45 * {@link android.Manifest.permission#BIND_INPUT_METHOD} in order to interact
46 * with the service; if this is not required, the system will not use that
47 * input method, because it can not trust that it is not compromised.
48 *
49 * <p>The InputMethod interface is actually split into two parts: the interface
50 * here is the top-level interface to the input method, providing all
51 * access to it, which only the system can access (due to the BIND_INPUT_METHOD
52 * permission requirement).  In addition its method
53 * {@link #createSession(android.view.inputmethod.InputMethod.SessionCallback)}
54 * can be called to instantate a secondary {@link InputMethodSession} interface
55 * which is what clients use to communicate with the input method.
56 */
57public interface InputMethod {
58    /**
59     * This is the interface name that a service implementing an input
60     * method should say that it supports -- that is, this is the action it
61     * uses for its intent filter.
62     * To be supported, the service must also require the
63     * {@link android.Manifest.permission#BIND_INPUT_METHOD} permission so
64     * that other applications can not abuse it.
65     */
66    @SdkConstant(SdkConstantType.SERVICE_ACTION)
67    public static final String SERVICE_INTERFACE = "android.view.InputMethod";
68
69    /**
70     * Name under which an InputMethod service component publishes information
71     * about itself.  This meta-data must reference an XML resource containing
72     * an
73     * <code>&lt;{@link android.R.styleable#InputMethod input-method}&gt;</code>
74     * tag.
75     */
76    public static final String SERVICE_META_DATA = "android.view.im";
77
78    public interface SessionCallback {
79        public void sessionCreated(InputMethodSession session);
80    }
81
82    /**
83     * Called first thing after an input method is created, this supplies a
84     * unique token for the session it has with the system service.  It is
85     * needed to identify itself with the service to validate its operations.
86     * This token <strong>must not</strong> be passed to applications, since
87     * it grants special priviledges that should not be given to applications.
88     *
89     * <p>Note: to protect yourself from malicious clients, you should only
90     * accept the first token given to you.  Any after that may come from the
91     * client.
92     */
93    public void attachToken(IBinder token);
94
95    /**
96     * Bind a new application environment in to the input method, so that it
97     * can later start and stop input processing.
98     * Typically this method is called when this input method is enabled in an
99     * application for the first time.
100     *
101     * @param binding Information about the application window that is binding
102     * to the input method.
103     *
104     * @see InputBinding
105     * @see #unbindInput()
106     */
107    public void bindInput(InputBinding binding);
108
109    /**
110     * Unbind an application environment, called when the information previously
111     * set by {@link #bindInput} is no longer valid for this input method.
112     *
113     * <p>
114     * Typically this method is called when the application changes to be
115     * non-foreground.
116     */
117    public void unbindInput();
118
119    /**
120     * This method is called when the application starts to receive text and it
121     * is ready for this input method to process received events and send result
122     * text back to the application.
123     *
124     * @param inputConnection Optional specific input connection for
125     * communicating with the text box; if null, you should use the generic
126     * bound input connection.
127     * @param info Information about the text box (typically, an EditText)
128     *        that requests input.
129     *
130     * @see EditorInfo
131     */
132    public void startInput(InputConnection inputConnection, EditorInfo info);
133
134    /**
135     * This method is called when the state of this input method needs to be
136     * reset.
137     *
138     * <p>
139     * Typically, this method is called when the input focus is moved from one
140     * text box to another.
141     *
142     * @param inputConnection Optional specific input connection for
143     * communicating with the text box; if null, you should use the generic
144     * bound input connection.
145     * @param attribute The attribute of the text box (typically, a EditText)
146     *        that requests input.
147     *
148     * @see EditorInfo
149     */
150    public void restartInput(InputConnection inputConnection, EditorInfo attribute);
151
152    /**
153     * This method is called when {@code {@link #startInput(InputConnection, EditorInfo)} or
154     * {@code {@link #restartInput(InputConnection, EditorInfo)} needs to be dispatched.
155     *
156     * <p>Note: This method is hidden because the {@code startInputToken} that this method is
157     * dealing with is one of internal details, which should not be exposed to the IME developers.
158     * If you override this method, you are responsible for not breaking existing IMEs that expect
159     * {@link #startInput(InputConnection, EditorInfo)} to be still called back.</p>
160     *
161     * @param inputConnection optional specific input connection for communicating with the text
162     *                        box; if {@code null}, you should use the generic bound input
163     *                        connection
164     * @param editorInfo information about the text box (typically, an EditText) that requests input
165     * @param restarting {@code false} if this corresponds to
166     *                   {@link #startInput(InputConnection, EditorInfo)}. Otherwise this
167     *                   corresponds to {@link #restartInput(InputConnection, EditorInfo)}.
168     * @param startInputToken a token that identifies a logical session that starts with this method
169     *                        call. Some internal IPCs such as {@link
170     *                        InputMethodManager#setImeWindowStatus(IBinder, IBinder, int, int)}
171     *                        require this token to work, and you have to keep the token alive until
172     *                        the next {@link #startInput(InputConnection, EditorInfo, IBinder)} as
173     *                        long as your implementation of {@link InputMethod} relies on such
174     *                        IPCs
175     * @see #startInput(InputConnection, EditorInfo)
176     * @see #restartInput(InputConnection, EditorInfo)
177     * @see EditorInfo
178     * @hide
179     */
180    default void dispatchStartInputWithToken(@Nullable InputConnection inputConnection,
181            @NonNull EditorInfo editorInfo, boolean restarting,
182            @NonNull IBinder startInputToken) {
183        if (restarting) {
184            restartInput(inputConnection, editorInfo);
185        } else {
186            startInput(inputConnection, editorInfo);
187        }
188    }
189
190    /**
191     * Create a new {@link InputMethodSession} that can be handed to client
192     * applications for interacting with the input method.  You can later
193     * use {@link #revokeSession(InputMethodSession)} to destroy the session
194     * so that it can no longer be used by any clients.
195     *
196     * @param callback Interface that is called with the newly created session.
197     */
198    public void createSession(SessionCallback callback);
199
200    /**
201     * Control whether a particular input method session is active.
202     *
203     * @param session The {@link InputMethodSession} previously provided through
204     * SessionCallback.sessionCreated() that is to be changed.
205     */
206    public void setSessionEnabled(InputMethodSession session, boolean enabled);
207
208    /**
209     * Disable and destroy a session that was previously created with
210     * {@link #createSession(android.view.inputmethod.InputMethod.SessionCallback)}.
211     * After this call, the given session interface is no longer active and
212     * calls on it will fail.
213     *
214     * @param session The {@link InputMethodSession} previously provided through
215     * SessionCallback.sessionCreated() that is to be revoked.
216     */
217    public void revokeSession(InputMethodSession session);
218
219    /**
220     * Flag for {@link #showSoftInput}: this show has been explicitly
221     * requested by the user.  If not set, the system has decided it may be
222     * a good idea to show the input method based on a navigation operation
223     * in the UI.
224     */
225    public static final int SHOW_EXPLICIT = 0x00001;
226
227    /**
228     * Flag for {@link #showSoftInput}: this show has been forced to
229     * happen by the user.  If set, the input method should remain visible
230     * until deliberated dismissed by the user in its UI.
231     */
232    public static final int SHOW_FORCED = 0x00002;
233
234    /**
235     * Request that any soft input part of the input method be shown to the user.
236     *
237     * @param flags Provides additional information about the show request.
238     * Currently may be 0 or have the bit {@link #SHOW_EXPLICIT} set.
239     * @param resultReceiver The client requesting the show may wish to
240     * be told the impact of their request, which should be supplied here.
241     * The result code should be
242     * {@link InputMethodManager#RESULT_UNCHANGED_SHOWN InputMethodManager.RESULT_UNCHANGED_SHOWN},
243     * {@link InputMethodManager#RESULT_UNCHANGED_HIDDEN InputMethodManager.RESULT_UNCHANGED_HIDDEN},
244     * {@link InputMethodManager#RESULT_SHOWN InputMethodManager.RESULT_SHOWN}, or
245     * {@link InputMethodManager#RESULT_HIDDEN InputMethodManager.RESULT_HIDDEN}.
246     */
247    public void showSoftInput(int flags, ResultReceiver resultReceiver);
248
249    /**
250     * Request that any soft input part of the input method be hidden from the user.
251     * @param flags Provides additional information about the show request.
252     * Currently always 0.
253     * @param resultReceiver The client requesting the show may wish to
254     * be told the impact of their request, which should be supplied here.
255     * The result code should be
256     * {@link InputMethodManager#RESULT_UNCHANGED_SHOWN InputMethodManager.RESULT_UNCHANGED_SHOWN},
257     * {@link InputMethodManager#RESULT_UNCHANGED_HIDDEN InputMethodManager.RESULT_UNCHANGED_HIDDEN},
258     * {@link InputMethodManager#RESULT_SHOWN InputMethodManager.RESULT_SHOWN}, or
259     * {@link InputMethodManager#RESULT_HIDDEN InputMethodManager.RESULT_HIDDEN}.
260     */
261    public void hideSoftInput(int flags, ResultReceiver resultReceiver);
262
263    /**
264     * Notify that the input method subtype is being changed in the same input method.
265     * @param subtype New subtype of the notified input method
266     */
267    public void changeInputMethodSubtype(InputMethodSubtype subtype);
268}
269