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