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 com.android.internal.view; 18 19 import static java.lang.annotation.RetentionPolicy.SOURCE; 20 21 import android.annotation.IntDef; 22 import android.annotation.Nullable; 23 import android.compat.annotation.UnsupportedAppUsage; 24 import android.content.ComponentName; 25 import android.content.Intent; 26 import android.content.ServiceConnection; 27 import android.graphics.Matrix; 28 import android.os.IBinder; 29 import android.os.Parcel; 30 import android.os.Parcelable; 31 import android.os.UserHandle; 32 import android.view.InputChannel; 33 34 import java.lang.annotation.Retention; 35 36 /** 37 * Bundle of information returned by input method manager about a successful 38 * binding to an input method. 39 */ 40 public final class InputBindResult implements Parcelable { 41 42 @Retention(SOURCE) 43 @IntDef({ 44 ResultCode.SUCCESS_WITH_IME_SESSION, 45 ResultCode.SUCCESS_WAITING_IME_SESSION, 46 ResultCode.SUCCESS_WAITING_IME_BINDING, 47 ResultCode.SUCCESS_REPORT_WINDOW_FOCUS_ONLY, 48 ResultCode.ERROR_NULL, 49 ResultCode.ERROR_NO_IME, 50 ResultCode.ERROR_INVALID_PACKAGE_NAME, 51 ResultCode.ERROR_SYSTEM_NOT_READY, 52 ResultCode.ERROR_IME_NOT_CONNECTED, 53 ResultCode.ERROR_INVALID_USER, 54 ResultCode.ERROR_NULL_EDITOR_INFO, 55 ResultCode.ERROR_NOT_IME_TARGET_WINDOW, 56 ResultCode.ERROR_NO_EDITOR, 57 ResultCode.ERROR_DISPLAY_ID_MISMATCH, 58 ResultCode.ERROR_INVALID_DISPLAY_ID, 59 ResultCode.ERROR_INVALID_CLIENT, 60 }) 61 public @interface ResultCode { 62 /** 63 * Indicates that everything in this result object including {@link #method} is valid. 64 */ 65 int SUCCESS_WITH_IME_SESSION = 0; 66 /** 67 * Indicates that this is a temporary binding until the 68 * {@link android.inputmethodservice.InputMethodService} (IMS) establishes a valid session 69 * to {@link com.android.server.inputmethod.InputMethodManagerService} (IMMS). 70 * 71 * <p>Note that in this state the IMS is already bound to IMMS but the logical session 72 * is not yet established on top of the IPC channel.</p> 73 * 74 * <p>Some of fields such as {@link #channel} is not yet available.</p> 75 * 76 * @see android.inputmethodservice.InputMethodService##onCreateInputMethodSessionInterface() 77 **/ 78 int SUCCESS_WAITING_IME_SESSION = 1; 79 /** 80 * Indicates that this is a temporary binding until the 81 * {@link android.inputmethodservice.InputMethodService} (IMS) establishes a valid session 82 * to {@link com.android.server.inputmethod.InputMethodManagerService} (IMMS). 83 * 84 * <p>Note that in this state the IMMS has already initiated a connection to the IMS but 85 * the binding process is not completed yet.</p> 86 * 87 * <p>Some of fields such as {@link #channel} is not yet available.</p> 88 * @see android.content.ServiceConnection#onServiceConnected(ComponentName, IBinder) 89 */ 90 int SUCCESS_WAITING_IME_BINDING = 2; 91 /** 92 * Indicates that this is not intended for starting input but just for reporting window 93 * focus change from the application process. 94 * 95 * <p>All other fields do not have meaningful value.</p> 96 */ 97 int SUCCESS_REPORT_WINDOW_FOCUS_ONLY = 3; 98 /** 99 * Indicates somehow 100 * {@link 101 * com.android.server.inputmethod.InputMethodManagerService#startInputOrWindowGainedFocus} 102 * is trying to return null {@link InputBindResult}, which must never happen. 103 */ 104 int ERROR_NULL = 4; 105 /** 106 * Indicates that {@link com.android.server.inputmethod.InputMethodManagerService} 107 * recognizes no IME. 108 */ 109 int ERROR_NO_IME = 5; 110 /** 111 * Indicates that {@link android.view.inputmethod.EditorInfo#packageName} does not match 112 * the caller UID. 113 * 114 * @see android.view.inputmethod.EditorInfo#packageName 115 */ 116 int ERROR_INVALID_PACKAGE_NAME = 6; 117 /** 118 * Indicates that the system is still in an early stage of the boot process and any 3rd 119 * party application is not allowed to run. 120 * 121 * @see com.android.server.SystemService#PHASE_THIRD_PARTY_APPS_CAN_START 122 */ 123 int ERROR_SYSTEM_NOT_READY = 7; 124 /** 125 * Indicates that {@link com.android.server.inputmethod.InputMethodManagerService} tried to 126 * connect to an {@link android.inputmethodservice.InputMethodService} but failed. 127 * 128 * @see android.content.Context#bindServiceAsUser(Intent, ServiceConnection, int, UserHandle) 129 */ 130 int ERROR_IME_NOT_CONNECTED = 8; 131 /** 132 * Indicates that the caller is not the foreground user, does not have 133 * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission, or the user 134 * specified in {@link android.view.inputmethod.EditorInfo#targetInputMethodUser} is not 135 * running. 136 */ 137 int ERROR_INVALID_USER = 9; 138 /** 139 * Indicates that the caller should have specified non-null 140 * {@link android.view.inputmethod.EditorInfo}. 141 */ 142 int ERROR_NULL_EDITOR_INFO = 10; 143 /** 144 * Indicates that the target window the client specified cannot be the IME target right now. 145 * 146 * <p>Due to the asynchronous nature of Android OS, we cannot completely avoid this error. 147 * The client should try to restart input when its {@link android.view.Window} is focused 148 * again.</p> 149 * 150 * @see com.android.server.wm.WindowManagerInternal#isInputMethodClientFocus(int, int, int) 151 */ 152 int ERROR_NOT_IME_TARGET_WINDOW = 11; 153 /** 154 * Indicates that focused view in the current window is not an editor. 155 */ 156 int ERROR_NO_EDITOR = 12; 157 /** 158 * Indicates that there is a mismatch in display ID between IME client and focused Window. 159 */ 160 int ERROR_DISPLAY_ID_MISMATCH = 13; 161 /** 162 * Indicates that current IME client is no longer allowed to access to the associated 163 * display. 164 */ 165 int ERROR_INVALID_DISPLAY_ID = 14; 166 /** 167 * Indicates that the client is not recognized by the system. 168 */ 169 int ERROR_INVALID_CLIENT = 15; 170 } 171 172 @ResultCode 173 public final int result; 174 175 /** 176 * The input method service. 177 */ 178 @UnsupportedAppUsage 179 public final IInputMethodSession method; 180 181 /** 182 * The input channel used to send input events to this IME. 183 */ 184 public final InputChannel channel; 185 186 /** 187 * The ID for this input method, as found in InputMethodInfo; null if 188 * no input method will be bound. 189 */ 190 public final String id; 191 192 /** 193 * Sequence number of this binding. 194 */ 195 public final int sequence; 196 197 @Nullable 198 private final float[] mActivityViewToScreenMatrixValues; 199 200 /** 201 * @return {@link Matrix} that corresponds to {@link #mActivityViewToScreenMatrixValues}. 202 * {@code null} if {@link #mActivityViewToScreenMatrixValues} is {@code null}. 203 */ 204 @Nullable getActivityViewToScreenMatrix()205 public Matrix getActivityViewToScreenMatrix() { 206 if (mActivityViewToScreenMatrixValues == null) { 207 return null; 208 } 209 final Matrix matrix = new Matrix(); 210 matrix.setValues(mActivityViewToScreenMatrixValues); 211 return matrix; 212 } 213 InputBindResult(@esultCode int _result, IInputMethodSession _method, InputChannel _channel, String _id, int _sequence, @Nullable Matrix activityViewToScreenMatrix)214 public InputBindResult(@ResultCode int _result, 215 IInputMethodSession _method, InputChannel _channel, String _id, int _sequence, 216 @Nullable Matrix activityViewToScreenMatrix) { 217 result = _result; 218 method = _method; 219 channel = _channel; 220 id = _id; 221 sequence = _sequence; 222 if (activityViewToScreenMatrix == null) { 223 mActivityViewToScreenMatrixValues = null; 224 } else { 225 mActivityViewToScreenMatrixValues = new float[9]; 226 activityViewToScreenMatrix.getValues(mActivityViewToScreenMatrixValues); 227 } 228 } 229 InputBindResult(Parcel source)230 InputBindResult(Parcel source) { 231 result = source.readInt(); 232 method = IInputMethodSession.Stub.asInterface(source.readStrongBinder()); 233 if (source.readInt() != 0) { 234 channel = InputChannel.CREATOR.createFromParcel(source); 235 } else { 236 channel = null; 237 } 238 id = source.readString(); 239 sequence = source.readInt(); 240 mActivityViewToScreenMatrixValues = source.createFloatArray(); 241 } 242 243 @Override toString()244 public String toString() { 245 return "InputBindResult{result=" + getResultString() + " method="+ method + " id=" + id 246 + " sequence=" + sequence 247 + " activityViewToScreenMatrix=" + getActivityViewToScreenMatrix() 248 + "}"; 249 } 250 251 /** 252 * Used to package this object into a {@link Parcel}. 253 * 254 * @param dest The {@link Parcel} to be written. 255 * @param flags The flags used for parceling. 256 */ 257 @Override writeToParcel(Parcel dest, int flags)258 public void writeToParcel(Parcel dest, int flags) { 259 dest.writeInt(result); 260 dest.writeStrongInterface(method); 261 if (channel != null) { 262 dest.writeInt(1); 263 channel.writeToParcel(dest, flags); 264 } else { 265 dest.writeInt(0); 266 } 267 dest.writeString(id); 268 dest.writeInt(sequence); 269 dest.writeFloatArray(mActivityViewToScreenMatrixValues); 270 } 271 272 /** 273 * Used to make this class parcelable. 274 */ 275 @UnsupportedAppUsage 276 public static final Parcelable.Creator<InputBindResult> CREATOR = 277 new Parcelable.Creator<InputBindResult>() { 278 @Override 279 public InputBindResult createFromParcel(Parcel source) { 280 return new InputBindResult(source); 281 } 282 283 @Override 284 public InputBindResult[] newArray(int size) { 285 return new InputBindResult[size]; 286 } 287 }; 288 289 @Override describeContents()290 public int describeContents() { 291 return channel != null ? channel.describeContents() : 0; 292 } 293 getResultString()294 public String getResultString() { 295 switch (result) { 296 case ResultCode.SUCCESS_WITH_IME_SESSION: 297 return "SUCCESS_WITH_IME_SESSION"; 298 case ResultCode.SUCCESS_WAITING_IME_SESSION: 299 return "SUCCESS_WAITING_IME_SESSION"; 300 case ResultCode.SUCCESS_WAITING_IME_BINDING: 301 return "SUCCESS_WAITING_IME_BINDING"; 302 case ResultCode.SUCCESS_REPORT_WINDOW_FOCUS_ONLY: 303 return "SUCCESS_REPORT_WINDOW_FOCUS_ONLY"; 304 case ResultCode.ERROR_NULL: 305 return "ERROR_NULL"; 306 case ResultCode.ERROR_NO_IME: 307 return "ERROR_NO_IME"; 308 case ResultCode.ERROR_NO_EDITOR: 309 return "ERROR_NO_EDITOR"; 310 case ResultCode.ERROR_INVALID_PACKAGE_NAME: 311 return "ERROR_INVALID_PACKAGE_NAME"; 312 case ResultCode.ERROR_SYSTEM_NOT_READY: 313 return "ERROR_SYSTEM_NOT_READY"; 314 case ResultCode.ERROR_IME_NOT_CONNECTED: 315 return "ERROR_IME_NOT_CONNECTED"; 316 case ResultCode.ERROR_INVALID_USER: 317 return "ERROR_INVALID_USER"; 318 case ResultCode.ERROR_NULL_EDITOR_INFO: 319 return "ERROR_NULL_EDITOR_INFO"; 320 case ResultCode.ERROR_NOT_IME_TARGET_WINDOW: 321 return "ERROR_NOT_IME_TARGET_WINDOW"; 322 case ResultCode.ERROR_DISPLAY_ID_MISMATCH: 323 return "ERROR_DISPLAY_ID_MISMATCH"; 324 case ResultCode.ERROR_INVALID_DISPLAY_ID: 325 return "ERROR_INVALID_DISPLAY_ID"; 326 case ResultCode.ERROR_INVALID_CLIENT: 327 return "ERROR_INVALID_CLIENT"; 328 default: 329 return "Unknown(" + result + ")"; 330 } 331 } 332 error(@esultCode int result)333 private static InputBindResult error(@ResultCode int result) { 334 return new InputBindResult(result, null, null, null, -1, null); 335 } 336 337 /** 338 * Predefined error object for {@link ResultCode#ERROR_NULL}. 339 */ 340 public static final InputBindResult NULL = error(ResultCode.ERROR_NULL); 341 /** 342 * Predefined error object for {@link ResultCode#NO_IME}. 343 */ 344 public static final InputBindResult NO_IME = error(ResultCode.ERROR_NO_IME); 345 /** 346 * Predefined error object for {@link ResultCode#NO_EDITOR}. 347 */ 348 public static final InputBindResult NO_EDITOR = error(ResultCode.ERROR_NO_EDITOR); 349 /** 350 * Predefined error object for {@link ResultCode#ERROR_INVALID_PACKAGE_NAME}. 351 */ 352 public static final InputBindResult INVALID_PACKAGE_NAME = 353 error(ResultCode.ERROR_INVALID_PACKAGE_NAME); 354 /** 355 * Predefined error object for {@link ResultCode#ERROR_NULL_EDITOR_INFO}. 356 */ 357 public static final InputBindResult NULL_EDITOR_INFO = error(ResultCode.ERROR_NULL_EDITOR_INFO); 358 /** 359 * Predefined error object for {@link ResultCode#ERROR_NOT_IME_TARGET_WINDOW}. 360 */ 361 public static final InputBindResult NOT_IME_TARGET_WINDOW = 362 error(ResultCode.ERROR_NOT_IME_TARGET_WINDOW); 363 /** 364 * Predefined error object for {@link ResultCode#ERROR_IME_NOT_CONNECTED}. 365 */ 366 public static final InputBindResult IME_NOT_CONNECTED = 367 error(ResultCode.ERROR_IME_NOT_CONNECTED); 368 /** 369 * Predefined error object for {@link ResultCode#ERROR_INVALID_USER}. 370 */ 371 public static final InputBindResult INVALID_USER = error(ResultCode.ERROR_INVALID_USER); 372 373 /** 374 * Predefined error object for {@link ResultCode#ERROR_DISPLAY_ID_MISMATCH}. 375 */ 376 public static final InputBindResult DISPLAY_ID_MISMATCH = 377 error(ResultCode.ERROR_DISPLAY_ID_MISMATCH); 378 379 /** 380 * Predefined error object for {@link ResultCode#ERROR_INVALID_DISPLAY_ID}. 381 */ 382 public static final InputBindResult INVALID_DISPLAY_ID = 383 error(ResultCode.ERROR_INVALID_DISPLAY_ID); 384 385 /** 386 * Predefined error object for {@link ResultCode#ERROR_INVALID_CLIENT}. 387 */ 388 public static final InputBindResult INVALID_CLIENT = error(ResultCode.ERROR_INVALID_CLIENT); 389 } 390