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