1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of 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,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.inputmethod;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.annotation.UserIdInt;
22 import android.os.IBinder;
23 import android.view.inputmethod.InlineSuggestionsRequest;
24 import android.view.inputmethod.InputMethodInfo;
25 
26 import com.android.internal.inputmethod.SoftInputShowHideReason;
27 import com.android.internal.view.IInlineSuggestionsRequestCallback;
28 import com.android.internal.view.InlineSuggestionsRequestInfo;
29 import com.android.server.LocalServices;
30 
31 import java.util.Collections;
32 import java.util.List;
33 
34 /**
35  * Input method manager local system service interface.
36  */
37 public abstract class InputMethodManagerInternal {
38     /**
39      * Listener for input method list changed events.
40      */
41     public interface InputMethodListListener {
42         /**
43          * Called with the list of the installed IMEs when it's updated.
44          */
onInputMethodListUpdated(List<InputMethodInfo> info, @UserIdInt int userId)45         void onInputMethodListUpdated(List<InputMethodInfo> info, @UserIdInt int userId);
46     }
47 
48     /**
49      * Called by the power manager to tell the input method manager whether it
50      * should start watching for wake events.
51      */
setInteractive(boolean interactive)52     public abstract void setInteractive(boolean interactive);
53 
54     /**
55      * Hides the current input method, if visible.
56      */
hideCurrentInputMethod(@oftInputShowHideReason int reason)57     public abstract void hideCurrentInputMethod(@SoftInputShowHideReason int reason);
58 
59     /**
60      * Returns the list of installed input methods for the specified user.
61      *
62      * @param userId The user ID to be queried.
63      * @return A list of {@link InputMethodInfo}.  VR-only IMEs are already excluded.
64      */
getInputMethodListAsUser(@serIdInt int userId)65     public abstract List<InputMethodInfo> getInputMethodListAsUser(@UserIdInt int userId);
66 
67     /**
68      * Returns the list of installed input methods that are enabled for the specified user.
69      *
70      * @param userId The user ID to be queried.
71      * @return A list of {@link InputMethodInfo} that are enabled for {@code userId}.
72      */
getEnabledInputMethodListAsUser(@serIdInt int userId)73     public abstract List<InputMethodInfo> getEnabledInputMethodListAsUser(@UserIdInt int userId);
74 
75     /**
76      * Called by the Autofill Frameworks to request an {@link InlineSuggestionsRequest} from
77      * the input method.
78      *
79      * @param requestInfo information needed to create an {@link InlineSuggestionsRequest}.
80      * @param cb {@link IInlineSuggestionsRequestCallback} used to pass back the request object.
81      */
onCreateInlineSuggestionsRequest(@serIdInt int userId, InlineSuggestionsRequestInfo requestInfo, IInlineSuggestionsRequestCallback cb)82     public abstract void onCreateInlineSuggestionsRequest(@UserIdInt int userId,
83             InlineSuggestionsRequestInfo requestInfo, IInlineSuggestionsRequestCallback cb);
84 
85     /**
86      * Force switch to the enabled input method by {@code imeId} for current user. If the input
87      * method with {@code imeId} is not enabled or not installed, do nothing.
88      *
89      * @param imeId  The input method ID to be switched to.
90      * @param userId The user ID to be queried.
91      * @return {@code true} if the current input method was successfully switched to the input
92      * method by {@code imeId}; {@code false} the input method with {@code imeId} is not available
93      * to be switched.
94      */
switchToInputMethod(String imeId, @UserIdInt int userId)95     public abstract boolean switchToInputMethod(String imeId, @UserIdInt int userId);
96 
97     /**
98      * Registers a new {@link InputMethodListListener}.
99      */
registerInputMethodListListener(InputMethodListListener listener)100     public abstract void registerInputMethodListListener(InputMethodListListener listener);
101 
102     /**
103      * Transfers input focus from a given input token to that of the IME window.
104      *
105      * @param sourceInputToken The source token.
106      * @param displayId The display hosting the IME window.
107      * @return {@code true} if the transfer is successful.
108      */
transferTouchFocusToImeWindow(@onNull IBinder sourceInputToken, int displayId)109     public abstract boolean transferTouchFocusToImeWindow(@NonNull IBinder sourceInputToken,
110             int displayId);
111 
112     /**
113      * Reports that IME control has transferred to the given window token, or if null that
114      * control has been taken away from client windows (and is instead controlled by the policy
115      * or SystemUI).
116      *
117      * @param windowToken the window token that is now in control, or {@code null} if no client
118      *                   window is in control of the IME.
119      */
reportImeControl(@ullable IBinder windowToken)120     public abstract void reportImeControl(@Nullable IBinder windowToken);
121 
122     /**
123      * Destroys the IME surface.
124      */
removeImeSurface()125     public abstract void removeImeSurface();
126 
127     /**
128      * Fake implementation of {@link InputMethodManagerInternal}.  All the methods do nothing.
129      */
130     private static final InputMethodManagerInternal NOP =
131             new InputMethodManagerInternal() {
132                 @Override
133                 public void setInteractive(boolean interactive) {
134                 }
135 
136                 @Override
137                 public void hideCurrentInputMethod(@SoftInputShowHideReason int reason) {
138                 }
139 
140                 @Override
141                 public List<InputMethodInfo> getInputMethodListAsUser(int userId) {
142                     return Collections.emptyList();
143                 }
144 
145                 @Override
146                 public List<InputMethodInfo> getEnabledInputMethodListAsUser(int userId) {
147                     return Collections.emptyList();
148                 }
149 
150                 @Override
151                 public void onCreateInlineSuggestionsRequest(int userId,
152                         InlineSuggestionsRequestInfo requestInfo,
153                         IInlineSuggestionsRequestCallback cb) {
154                 }
155 
156                 @Override
157                 public boolean switchToInputMethod(String imeId, int userId) {
158                     return false;
159                 }
160 
161                 @Override
162                 public void registerInputMethodListListener(InputMethodListListener listener) {
163                 }
164 
165                 @Override
166                 public boolean transferTouchFocusToImeWindow(@NonNull IBinder sourceInputToken,
167                         int displayId) {
168                     return false;
169                 }
170 
171                 @Override
172                 public void reportImeControl(@Nullable IBinder windowToken) {
173                 }
174 
175                 @Override
176                 public void removeImeSurface() {
177                 }
178             };
179 
180     /**
181      * @return Global instance if exists.  Otherwise, a dummy no-op instance.
182      */
183     @NonNull
get()184     public static InputMethodManagerInternal get() {
185         final InputMethodManagerInternal instance =
186                 LocalServices.getService(InputMethodManagerInternal.class);
187         return instance != null ? instance : NOP;
188     }
189 }
190