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.inputmethodservice.InputMethodService; 23 import android.os.IBinder; 24 import android.view.inputmethod.InlineSuggestionsRequest; 25 import android.view.inputmethod.InputMethodInfo; 26 27 import com.android.internal.inputmethod.IAccessibilityInputMethodSession; 28 import com.android.internal.inputmethod.SoftInputShowHideReason; 29 import com.android.internal.view.IInlineSuggestionsRequestCallback; 30 import com.android.internal.view.InlineSuggestionsRequestInfo; 31 import com.android.server.LocalServices; 32 33 import java.util.Collections; 34 import java.util.List; 35 36 /** 37 * Input method manager local system service interface. 38 */ 39 public abstract class InputMethodManagerInternal { 40 /** 41 * Listener for input method list changed events. 42 */ 43 public interface InputMethodListListener { 44 /** 45 * Called with the list of the installed IMEs when it's updated. 46 */ onInputMethodListUpdated(List<InputMethodInfo> info, @UserIdInt int userId)47 void onInputMethodListUpdated(List<InputMethodInfo> info, @UserIdInt int userId); 48 } 49 50 /** 51 * Called by the power manager to tell the input method manager whether it 52 * should start watching for wake events. 53 */ setInteractive(boolean interactive)54 public abstract void setInteractive(boolean interactive); 55 56 /** 57 * Hides the current input method, if visible. 58 */ hideCurrentInputMethod(@oftInputShowHideReason int reason)59 public abstract void hideCurrentInputMethod(@SoftInputShowHideReason int reason); 60 61 /** 62 * Returns the list of installed input methods for the specified user. 63 * 64 * @param userId The user ID to be queried. 65 * @return A list of {@link InputMethodInfo}. VR-only IMEs are already excluded. 66 */ getInputMethodListAsUser(@serIdInt int userId)67 public abstract List<InputMethodInfo> getInputMethodListAsUser(@UserIdInt int userId); 68 69 /** 70 * Returns the list of installed input methods that are enabled for the specified user. 71 * 72 * @param userId The user ID to be queried. 73 * @return A list of {@link InputMethodInfo} that are enabled for {@code userId}. 74 */ getEnabledInputMethodListAsUser(@serIdInt int userId)75 public abstract List<InputMethodInfo> getEnabledInputMethodListAsUser(@UserIdInt int userId); 76 77 /** 78 * Called by the Autofill Frameworks to request an {@link InlineSuggestionsRequest} from 79 * the input method. 80 * 81 * @param requestInfo information needed to create an {@link InlineSuggestionsRequest}. 82 * @param cb {@link IInlineSuggestionsRequestCallback} used to pass back the request object. 83 */ onCreateInlineSuggestionsRequest(@serIdInt int userId, InlineSuggestionsRequestInfo requestInfo, IInlineSuggestionsRequestCallback cb)84 public abstract void onCreateInlineSuggestionsRequest(@UserIdInt int userId, 85 InlineSuggestionsRequestInfo requestInfo, IInlineSuggestionsRequestCallback cb); 86 87 /** 88 * Force switch to the enabled input method by {@code imeId} for current user. If the input 89 * method with {@code imeId} is not enabled or not installed, do nothing. 90 * 91 * @param imeId The input method ID to be switched to. 92 * @param userId The user ID to be queried. 93 * @return {@code true} if the current input method was successfully switched to the input 94 * method by {@code imeId}; {@code false} the input method with {@code imeId} is not available 95 * to be switched. 96 */ switchToInputMethod(String imeId, @UserIdInt int userId)97 public abstract boolean switchToInputMethod(String imeId, @UserIdInt int userId); 98 99 /** 100 * Force enable or disable the input method associated with {@code imeId} for given user. If 101 * the input method associated with {@code imeId} is not installed, do nothing. 102 * 103 * @param imeId The input method ID to be enabled or disabled. 104 * @param enabled {@code true} if the input method associated with {@code imeId} should be 105 * enabled. 106 * @param userId The user ID to be queried. 107 * @return {@code true} if the input method associated with {@code imeId} was successfully 108 * enabled or disabled, {@code false} if the input method specified is not installed 109 * or was unable to be enabled/disabled for some other reason. 110 */ setInputMethodEnabled(String imeId, boolean enabled, @UserIdInt int userId)111 public abstract boolean setInputMethodEnabled(String imeId, boolean enabled, 112 @UserIdInt int userId); 113 114 /** 115 * Registers a new {@link InputMethodListListener}. 116 */ registerInputMethodListListener(InputMethodListListener listener)117 public abstract void registerInputMethodListListener(InputMethodListListener listener); 118 119 /** 120 * Transfers input focus from a given input token to that of the IME window. 121 * 122 * @param sourceInputToken The source token. 123 * @param displayId The display hosting the IME window. 124 * @return {@code true} if the transfer is successful. 125 */ transferTouchFocusToImeWindow(@onNull IBinder sourceInputToken, int displayId)126 public abstract boolean transferTouchFocusToImeWindow(@NonNull IBinder sourceInputToken, 127 int displayId); 128 129 /** 130 * Reports that IME control has transferred to the given window token, or if null that 131 * control has been taken away from client windows (and is instead controlled by the policy 132 * or SystemUI). 133 * 134 * @param windowToken the window token that is now in control, or {@code null} if no client 135 * window is in control of the IME. 136 */ reportImeControl(@ullable IBinder windowToken)137 public abstract void reportImeControl(@Nullable IBinder windowToken); 138 139 /** 140 * Indicates that the IME window has re-parented to the new target when the IME control changed. 141 */ onImeParentChanged()142 public abstract void onImeParentChanged(); 143 144 /** 145 * Destroys the IME surface. 146 */ removeImeSurface()147 public abstract void removeImeSurface(); 148 149 /** 150 * Updates the IME visibility, back disposition and show IME picker status for SystemUI. 151 * TODO(b/189923292): Making SystemUI to be true IME icon controller vs. presenter that 152 * controlled by IMMS. 153 */ updateImeWindowStatus(boolean disableImeIcon)154 public abstract void updateImeWindowStatus(boolean disableImeIcon); 155 156 /** 157 * Finish stylus handwriting by calling {@link InputMethodService#finishStylusHandwriting()} if 158 * there is an ongoing handwriting session. 159 */ maybeFinishStylusHandwriting()160 public abstract void maybeFinishStylusHandwriting(); 161 162 /** 163 * Callback when the IInputMethodSession from the accessibility service with the specified 164 * accessibilityConnectionId is created. 165 * 166 * @param accessibilityConnectionId The connection id of the accessibility service. 167 * @param session The session passed back from the accessibility service. 168 */ onSessionForAccessibilityCreated(int accessibilityConnectionId, IAccessibilityInputMethodSession session)169 public abstract void onSessionForAccessibilityCreated(int accessibilityConnectionId, 170 IAccessibilityInputMethodSession session); 171 172 /** 173 * Unbind the accessibility service with the specified accessibilityConnectionId from current 174 * client. 175 * 176 * @param accessibilityConnectionId The connection id of the accessibility service. 177 */ unbindAccessibilityFromCurrentClient(int accessibilityConnectionId)178 public abstract void unbindAccessibilityFromCurrentClient(int accessibilityConnectionId); 179 180 /** 181 * Fake implementation of {@link InputMethodManagerInternal}. All the methods do nothing. 182 */ 183 private static final InputMethodManagerInternal NOP = 184 new InputMethodManagerInternal() { 185 @Override 186 public void setInteractive(boolean interactive) { 187 } 188 189 @Override 190 public void hideCurrentInputMethod(@SoftInputShowHideReason int reason) { 191 } 192 193 @Override 194 public List<InputMethodInfo> getInputMethodListAsUser(@UserIdInt int userId) { 195 return Collections.emptyList(); 196 } 197 198 @Override 199 public List<InputMethodInfo> getEnabledInputMethodListAsUser( 200 @UserIdInt int userId) { 201 return Collections.emptyList(); 202 } 203 204 @Override 205 public void onCreateInlineSuggestionsRequest(@UserIdInt int userId, 206 InlineSuggestionsRequestInfo requestInfo, 207 IInlineSuggestionsRequestCallback cb) { 208 } 209 210 @Override 211 public boolean switchToInputMethod(String imeId, @UserIdInt int userId) { 212 return false; 213 } 214 215 @Override 216 public boolean setInputMethodEnabled(String imeId, boolean enabled, 217 @UserIdInt int userId) { 218 return false; 219 } 220 221 @Override 222 public void registerInputMethodListListener(InputMethodListListener listener) { 223 } 224 225 @Override 226 public boolean transferTouchFocusToImeWindow(@NonNull IBinder sourceInputToken, 227 int displayId) { 228 return false; 229 } 230 231 @Override 232 public void reportImeControl(@Nullable IBinder windowToken) { 233 } 234 235 @Override 236 public void onImeParentChanged() { 237 } 238 239 @Override 240 public void removeImeSurface() { 241 } 242 243 @Override 244 public void updateImeWindowStatus(boolean disableImeIcon) { 245 } 246 247 @Override 248 public void onSessionForAccessibilityCreated(int accessibilityConnectionId, 249 IAccessibilityInputMethodSession session) { 250 } 251 252 @Override 253 public void unbindAccessibilityFromCurrentClient(int accessibilityConnectionId) { 254 } 255 256 @Override 257 public void maybeFinishStylusHandwriting() { 258 } 259 }; 260 261 /** 262 * @return Global instance if exists. Otherwise, a fallback no-op instance. 263 */ 264 @NonNull get()265 public static InputMethodManagerInternal get() { 266 final InputMethodManagerInternal instance = 267 LocalServices.getService(InputMethodManagerInternal.class); 268 return instance != null ? instance : NOP; 269 } 270 } 271