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