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 17 package android.view.inputmethod; 18 19 import android.annotation.MainThread; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.SdkConstant; 23 import android.annotation.SdkConstant.SdkConstantType; 24 import android.inputmethodservice.InputMethodService; 25 import android.os.IBinder; 26 import android.os.RemoteException; 27 import android.os.ResultReceiver; 28 import android.util.Log; 29 import android.view.InputChannel; 30 import android.view.MotionEvent; 31 import android.view.View; 32 import android.window.ImeOnBackInvokedDispatcher; 33 34 import com.android.internal.inputmethod.IInputMethodPrivilegedOperations; 35 import com.android.internal.inputmethod.InputMethodNavButtonFlags; 36 import com.android.internal.view.IInlineSuggestionsRequestCallback; 37 import com.android.internal.view.InlineSuggestionsRequestInfo; 38 39 import java.util.List; 40 41 /** 42 * The InputMethod interface represents an input method which can generate key 43 * events and text, such as digital, email addresses, CJK characters, other 44 * language characters, and etc., while handling various input events, and send 45 * the text back to the application that requests text input. See 46 * {@link InputMethodManager} for more general information about the 47 * architecture. 48 * 49 * <p>Applications will not normally use this interface themselves, instead 50 * relying on the standard interaction provided by 51 * {@link android.widget.TextView} and {@link android.widget.EditText}. 52 * 53 * <p>Those implementing input methods should normally do so by deriving from 54 * {@link InputMethodService} or one of its subclasses. When implementing 55 * an input method, the service component containing it must also supply 56 * a {@link #SERVICE_META_DATA} meta-data field, referencing an XML resource 57 * providing details about the input method. All input methods also must 58 * require that clients hold the 59 * {@link android.Manifest.permission#BIND_INPUT_METHOD} in order to interact 60 * with the service; if this is not required, the system will not use that 61 * input method, because it can not trust that it is not compromised. 62 * 63 * <p>The InputMethod interface is actually split into two parts: the interface 64 * here is the top-level interface to the input method, providing all 65 * access to it, which only the system can access (due to the BIND_INPUT_METHOD 66 * permission requirement). In addition its method 67 * {@link #createSession(android.view.inputmethod.InputMethod.SessionCallback)} 68 * can be called to instantate a secondary {@link InputMethodSession} interface 69 * which is what clients use to communicate with the input method. 70 */ 71 public interface InputMethod { 72 /** @hide **/ 73 public static final String TAG = "InputMethod"; 74 /** 75 * This is the interface name that a service implementing an input 76 * method should say that it supports -- that is, this is the action it 77 * uses for its intent filter. 78 * To be supported, the service must also require the 79 * {@link android.Manifest.permission#BIND_INPUT_METHOD} permission so 80 * that other applications can not abuse it. 81 */ 82 @SdkConstant(SdkConstantType.SERVICE_ACTION) 83 public static final String SERVICE_INTERFACE = "android.view.InputMethod"; 84 85 /** 86 * Name under which an InputMethod service component publishes information 87 * about itself. This meta-data must reference an XML resource containing 88 * an 89 * <code><{@link android.R.styleable#InputMethod input-method}></code> 90 * tag. 91 */ 92 public static final String SERVICE_META_DATA = "android.view.im"; 93 94 public interface SessionCallback { sessionCreated(InputMethodSession session)95 public void sessionCreated(InputMethodSession session); 96 } 97 98 /** 99 * Called first thing after an input method is created, this supplies a 100 * unique token for the session it has with the system service as well as 101 * IPC endpoint to do some other privileged operations. 102 * 103 * @param token special token for the system to identify 104 * {@link InputMethodService} 105 * @param privilegedOperations IPC endpoint to do some privileged 106 * operations that are allowed only to the 107 * current IME. 108 * @param configChanges {@link InputMethodInfo#getConfigChanges()} declared by IME. 109 * @param stylusHwSupported {@link InputMethodInfo#supportsStylusHandwriting()} declared by IME. 110 * @param navButtonFlags The initial state of {@link InputMethodNavButtonFlags}. 111 * @hide 112 */ 113 @MainThread initializeInternal(IBinder token, IInputMethodPrivilegedOperations privilegedOperations, int configChanges, boolean stylusHwSupported, @InputMethodNavButtonFlags int navButtonFlags)114 default void initializeInternal(IBinder token, 115 IInputMethodPrivilegedOperations privilegedOperations, int configChanges, 116 boolean stylusHwSupported, @InputMethodNavButtonFlags int navButtonFlags) { 117 attachToken(token); 118 } 119 120 /** 121 * Called to notify the IME that Autofill Frameworks requested an inline suggestions request. 122 * 123 * @param requestInfo information needed to create an {@link InlineSuggestionsRequest}. 124 * @param cb {@link IInlineSuggestionsRequestCallback} used to pass back the request object. 125 * 126 * @hide 127 */ onCreateInlineSuggestionsRequest(InlineSuggestionsRequestInfo requestInfo, IInlineSuggestionsRequestCallback cb)128 default void onCreateInlineSuggestionsRequest(InlineSuggestionsRequestInfo requestInfo, 129 IInlineSuggestionsRequestCallback cb) { 130 try { 131 cb.onInlineSuggestionsUnsupported(); 132 } catch (RemoteException e) { 133 Log.w(TAG, "Failed to call onInlineSuggestionsUnsupported.", e); 134 } 135 } 136 137 /** 138 * Called first thing after an input method is created, this supplies a 139 * unique token for the session it has with the system service. It is 140 * needed to identify itself with the service to validate its operations. 141 * This token <strong>must not</strong> be passed to applications, since 142 * it grants special priviledges that should not be given to applications. 143 * 144 * <p>The system guarantees that this method is called back between 145 * {@link InputMethodService#onCreate()} and {@link InputMethodService#onDestroy()} 146 * at most once. 147 */ 148 @MainThread attachToken(IBinder token)149 public void attachToken(IBinder token); 150 151 /** 152 * Bind a new application environment in to the input method, so that it 153 * can later start and stop input processing. 154 * Typically this method is called when this input method is enabled in an 155 * application for the first time. 156 * 157 * @param binding Information about the application window that is binding 158 * to the input method. 159 * 160 * @see InputBinding 161 * @see #unbindInput() 162 */ 163 @MainThread bindInput(InputBinding binding)164 public void bindInput(InputBinding binding); 165 166 /** 167 * Unbind an application environment, called when the information previously 168 * set by {@link #bindInput} is no longer valid for this input method. 169 * 170 * <p> 171 * Typically this method is called when the application changes to be 172 * non-foreground. 173 */ 174 @MainThread unbindInput()175 public void unbindInput(); 176 177 /** 178 * This method is called when the application starts to receive text and it 179 * is ready for this input method to process received events and send result 180 * text back to the application. 181 * 182 * @param inputConnection Optional specific input connection for 183 * communicating with the text box; if null, you should use the generic 184 * bound input connection. 185 * @param info Information about the text box (typically, an EditText) 186 * that requests input. 187 * 188 * @see EditorInfo 189 */ 190 @MainThread startInput(InputConnection inputConnection, EditorInfo info)191 public void startInput(InputConnection inputConnection, EditorInfo info); 192 193 /** 194 * This method is called when the state of this input method needs to be 195 * reset. 196 * 197 * <p> 198 * Typically, this method is called when the input focus is moved from one 199 * text box to another. 200 * 201 * @param inputConnection Optional specific input connection for 202 * communicating with the text box; if null, you should use the generic 203 * bound input connection. 204 * @param attribute The attribute of the text box (typically, a EditText) 205 * that requests input. 206 * 207 * @see EditorInfo 208 */ 209 @MainThread restartInput(InputConnection inputConnection, EditorInfo attribute)210 public void restartInput(InputConnection inputConnection, EditorInfo attribute); 211 212 /** 213 * This method is called when {@code {@link #startInput(InputConnection, EditorInfo)} or 214 * {@code {@link #restartInput(InputConnection, EditorInfo)} needs to be dispatched. 215 * 216 * <p>Note: This method is hidden because the {@code startInputToken} that this method is 217 * dealing with is one of internal details, which should not be exposed to the IME developers. 218 * If you override this method, you are responsible for not breaking existing IMEs that expect 219 * {@link #startInput(InputConnection, EditorInfo)} to be still called back.</p> 220 * 221 * @param inputConnection optional specific input connection for communicating with the text 222 * box; if {@code null}, you should use the generic bound input 223 * connection 224 * @param editorInfo information about the text box (typically, an EditText) that requests input 225 * @param restarting {@code false} if this corresponds to 226 * {@link #startInput(InputConnection, EditorInfo)}. Otherwise this 227 * corresponds to {@link #restartInput(InputConnection, EditorInfo)}. 228 * @param startInputToken a token that identifies a logical session that starts with this method 229 * call. Some internal IPCs such as {@link 230 * InputMethodManager#setImeWindowStatus(IBinder, IBinder, int, int)} 231 * require this token to work, and you have to keep the token alive until 232 * the next {@link #startInput(InputConnection, EditorInfo, IBinder)} as 233 * long as your implementation of {@link InputMethod} relies on such 234 * IPCs 235 * @param navButtonFlags {@link InputMethodNavButtonFlags} in the initial state of this session. 236 * @param imeDispatcher The {@link ImeOnBackInvokedDispatcher }} to be set on the 237 * IME's {@link android.window.WindowOnBackInvokedDispatcher}, so that IME 238 * {@link android.window.OnBackInvokedCallback}s can be forwarded to 239 * the client requesting to start input. 240 * @see #startInput(InputConnection, EditorInfo) 241 * @see #restartInput(InputConnection, EditorInfo) 242 * @see EditorInfo 243 * @hide 244 */ 245 @MainThread dispatchStartInputWithToken(@ullable InputConnection inputConnection, @NonNull EditorInfo editorInfo, boolean restarting, @NonNull IBinder startInputToken, @InputMethodNavButtonFlags int navButtonFlags, @NonNull ImeOnBackInvokedDispatcher imeDispatcher)246 default void dispatchStartInputWithToken(@Nullable InputConnection inputConnection, 247 @NonNull EditorInfo editorInfo, boolean restarting, 248 @NonNull IBinder startInputToken, @InputMethodNavButtonFlags int navButtonFlags, 249 @NonNull ImeOnBackInvokedDispatcher imeDispatcher) { 250 if (restarting) { 251 restartInput(inputConnection, editorInfo); 252 } else { 253 startInput(inputConnection, editorInfo); 254 } 255 } 256 257 /** 258 * Notifies that {@link InputMethodNavButtonFlags} have been updated. 259 * 260 * @param navButtonFlags The new {@link InputMethodNavButtonFlags}. 261 * @hide 262 */ 263 @MainThread onNavButtonFlagsChanged(@nputMethodNavButtonFlags int navButtonFlags)264 default void onNavButtonFlagsChanged(@InputMethodNavButtonFlags int navButtonFlags) { 265 } 266 267 /** 268 * Create a new {@link InputMethodSession} that can be handed to client 269 * applications for interacting with the input method. You can later 270 * use {@link #revokeSession(InputMethodSession)} to destroy the session 271 * so that it can no longer be used by any clients. 272 * 273 * @param callback Interface that is called with the newly created session. 274 */ 275 @MainThread createSession(SessionCallback callback)276 public void createSession(SessionCallback callback); 277 278 /** 279 * Control whether a particular input method session is active. 280 * 281 * @param session The {@link InputMethodSession} previously provided through 282 * SessionCallback.sessionCreated() that is to be changed. 283 */ 284 @MainThread setSessionEnabled(InputMethodSession session, boolean enabled)285 public void setSessionEnabled(InputMethodSession session, boolean enabled); 286 287 /** 288 * Disable and destroy a session that was previously created with 289 * {@link #createSession(android.view.inputmethod.InputMethod.SessionCallback)}. 290 * After this call, the given session interface is no longer active and 291 * calls on it will fail. 292 * 293 * @param session The {@link InputMethodSession} previously provided through 294 * SessionCallback.sessionCreated() that is to be revoked. 295 */ 296 @MainThread revokeSession(InputMethodSession session)297 public void revokeSession(InputMethodSession session); 298 299 /** 300 * Flag for {@link #showSoftInput}: this show has been explicitly 301 * requested by the user. If not set, the system has decided it may be 302 * a good idea to show the input method based on a navigation operation 303 * in the UI. 304 */ 305 public static final int SHOW_EXPLICIT = 0x00001; 306 307 /** 308 * Flag for {@link #showSoftInput}: this show has been forced to 309 * happen by the user. If set, the input method should remain visible 310 * until deliberated dismissed by the user in its UI. 311 */ 312 public static final int SHOW_FORCED = 0x00002; 313 314 /** 315 * Request that any soft input part of the input method be shown to the user. 316 * 317 * @param flags Provides additional information about the show request. 318 * Currently may be 0 or have the bit {@link #SHOW_EXPLICIT} set. 319 * @param resultReceiver The client requesting the show may wish to 320 * be told the impact of their request, which should be supplied here. 321 * The result code should be 322 * {@link InputMethodManager#RESULT_UNCHANGED_SHOWN InputMethodManager.RESULT_UNCHANGED_SHOWN}, 323 * {@link InputMethodManager#RESULT_UNCHANGED_HIDDEN InputMethodManager.RESULT_UNCHANGED_HIDDEN}, 324 * {@link InputMethodManager#RESULT_SHOWN InputMethodManager.RESULT_SHOWN}, or 325 * {@link InputMethodManager#RESULT_HIDDEN InputMethodManager.RESULT_HIDDEN}. 326 * @param showInputToken an opaque {@link android.os.Binder} token to identify which API call 327 * of {@link InputMethodManager#showSoftInput(View, int)} is associated with 328 * this callback. 329 * @hide 330 */ 331 @MainThread showSoftInputWithToken(int flags, ResultReceiver resultReceiver, IBinder showInputToken)332 default public void showSoftInputWithToken(int flags, ResultReceiver resultReceiver, 333 IBinder showInputToken) { 334 showSoftInput(flags, resultReceiver); 335 } 336 337 /** 338 * Request that any soft input part of the input method be shown to the user. 339 * 340 * @param flags Provides additional information about the show request. 341 * Currently may be 0 or have the bit {@link #SHOW_EXPLICIT} set. 342 * @param resultReceiver The client requesting the show may wish to 343 * be told the impact of their request, which should be supplied here. 344 * The result code should be 345 * {@link InputMethodManager#RESULT_UNCHANGED_SHOWN InputMethodManager.RESULT_UNCHANGED_SHOWN}, 346 * {@link InputMethodManager#RESULT_UNCHANGED_HIDDEN InputMethodManager.RESULT_UNCHANGED_HIDDEN}, 347 * {@link InputMethodManager#RESULT_SHOWN InputMethodManager.RESULT_SHOWN}, or 348 * {@link InputMethodManager#RESULT_HIDDEN InputMethodManager.RESULT_HIDDEN}. 349 */ 350 @MainThread showSoftInput(int flags, ResultReceiver resultReceiver)351 public void showSoftInput(int flags, ResultReceiver resultReceiver); 352 353 /** 354 * Request that any soft input part of the input method be hidden from the user. 355 * @param flags Provides additional information about the show request. 356 * Currently always 0. 357 * @param resultReceiver The client requesting the show may wish to 358 * be told the impact of their request, which should be supplied here. 359 * The result code should be 360 * {@link InputMethodManager#RESULT_UNCHANGED_SHOWN InputMethodManager.RESULT_UNCHANGED_SHOWN}, 361 * {@link InputMethodManager#RESULT_UNCHANGED_HIDDEN InputMethodManager.RESULT_UNCHANGED_HIDDEN}, 362 * {@link InputMethodManager#RESULT_SHOWN InputMethodManager.RESULT_SHOWN}, or 363 * {@link InputMethodManager#RESULT_HIDDEN InputMethodManager.RESULT_HIDDEN}. 364 * @param hideInputToken an opaque {@link android.os.Binder} token to identify which API call 365 * of {@link InputMethodManager#hideSoftInputFromWindow(IBinder, int)}} is associated 366 * with this callback. 367 * @hide 368 */ 369 @MainThread hideSoftInputWithToken(int flags, ResultReceiver resultReceiver, IBinder hideInputToken)370 public void hideSoftInputWithToken(int flags, ResultReceiver resultReceiver, 371 IBinder hideInputToken); 372 373 /** 374 * Request that any soft input part of the input method be hidden from the user. 375 * @param flags Provides additional information about the show request. 376 * Currently always 0. 377 * @param resultReceiver The client requesting the show may wish to 378 * be told the impact of their request, which should be supplied here. 379 * The result code should be 380 * {@link InputMethodManager#RESULT_UNCHANGED_SHOWN InputMethodManager.RESULT_UNCHANGED_SHOWN}, 381 * {@link InputMethodManager#RESULT_UNCHANGED_HIDDEN 382 * InputMethodManager.RESULT_UNCHANGED_HIDDEN}, 383 * {@link InputMethodManager#RESULT_SHOWN InputMethodManager.RESULT_SHOWN}, or 384 * {@link InputMethodManager#RESULT_HIDDEN InputMethodManager.RESULT_HIDDEN}. 385 */ 386 @MainThread hideSoftInput(int flags, ResultReceiver resultReceiver)387 public void hideSoftInput(int flags, ResultReceiver resultReceiver); 388 389 /** 390 * Notify that the input method subtype is being changed in the same input method. 391 * @param subtype New subtype of the notified input method 392 */ 393 @MainThread changeInputMethodSubtype(InputMethodSubtype subtype)394 public void changeInputMethodSubtype(InputMethodSubtype subtype); 395 396 /** 397 * Checks if IME is ready to start stylus handwriting session. 398 * If yes, {@link #startStylusHandwriting(InputChannel, List)} is called. 399 * @param requestId 400 * @hide 401 */ canStartStylusHandwriting(int requestId)402 default void canStartStylusHandwriting(int requestId) { 403 // intentionally empty 404 } 405 406 /** 407 * Start stylus handwriting session. 408 * @hide 409 */ startStylusHandwriting( int requestId, @NonNull InputChannel channel, @Nullable List<MotionEvent> events)410 default void startStylusHandwriting( 411 int requestId, @NonNull InputChannel channel, @Nullable List<MotionEvent> events) { 412 // intentionally empty 413 } 414 415 /** 416 * Initialize Ink window early-on. 417 * @hide 418 */ initInkWindow()419 default void initInkWindow() { 420 // intentionally empty 421 } 422 423 /** 424 * Finish stylus handwriting session. 425 * @hide 426 */ finishStylusHandwriting()427 default void finishStylusHandwriting() { 428 // intentionally empty 429 } 430 431 } 432