Loading services/core/java/com/android/server/InputMethodManagerService.java +92 −8 Original line number Diff line number Diff line Loading @@ -617,6 +617,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub @HardKeyboardBehavior private final int mHardKeyboardBehavior; /** * Whether we temporarily allow IMEs implemented in instant apps to run for testing. * * <p>Note: This is quite dangerous. Don't forget to reset after you finish testing.</p> */ private boolean mBindInstantServiceAllowed = false; /** * Internal state snapshot when {@link #MSG_START_INPUT} message is about to be posted to the * internal message queue. Any subsequent state change inside {@link InputMethodManagerService} Loading Loading @@ -1065,7 +1072,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub final PackageManager pm = mContext.getPackageManager(); final List<ResolveInfo> services = pm.queryIntentServicesAsUser( new Intent(InputMethod.SERVICE_INTERFACE).setPackage(packageName), PackageManager.MATCH_DISABLED_COMPONENTS, getChangingUserId()); getComponentMatchingFlags(PackageManager.MATCH_DISABLED_COMPONENTS), getChangingUserId()); // No need to lock this because we access it only on getRegisteredHandler(). if (!services.isEmpty()) { mImePackageAppeared = true; Loading Loading @@ -1609,12 +1617,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return true; } private boolean bindCurrentInputMethodService( @GuardedBy("mMethodMap") private boolean bindCurrentInputMethodServiceLocked( Intent service, ServiceConnection conn, int flags) { if (service == null || conn == null) { Slog.e(TAG, "--- bind failed: service = " + service + ", conn = " + conn); return false; } if (mBindInstantServiceAllowed) { flags |= Context.BIND_ALLOW_INSTANT; } return mContext.bindServiceAsUser(service, conn, flags, new UserHandle(mSettings.getCurrentUserId())); } Loading Loading @@ -1956,7 +1968,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub com.android.internal.R.string.input_method_binding_label); mCurIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity( mContext, 0, new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), 0)); if (bindCurrentInputMethodService(mCurIntent, this, IME_CONNECTION_BIND_FLAGS)) { if (bindCurrentInputMethodServiceLocked(mCurIntent, this, IME_CONNECTION_BIND_FLAGS)) { mLastBindTime = SystemClock.uptimeMillis(); mHaveConnection = true; mCurId = info.getId(); Loading Loading @@ -2608,7 +2620,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub resultReceiver)); mInputShown = true; if (mHaveConnection && !mVisibleBound) { bindCurrentInputMethodService( bindCurrentInputMethodServiceLocked( mCurIntent, mVisibleConnection, IME_VISIBLE_BIND_FLAGS); mVisibleBound = true; } Loading @@ -2623,7 +2635,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub SystemClock.uptimeMillis()-mLastBindTime,1); Slog.w(TAG, "Force disconnect/connect to the IME in showCurrentInputLocked()"); mContext.unbindService(this); bindCurrentInputMethodService(mCurIntent, this, IME_CONNECTION_BIND_FLAGS); bindCurrentInputMethodServiceLocked(mCurIntent, this, IME_CONNECTION_BIND_FLAGS); } else { if (DEBUG) { Slog.d(TAG, "Can't show input: connection = " + mHaveConnection + ", time = " Loading Loading @@ -3555,6 +3567,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return false; } @PackageManager.ResolveInfoFlags private int getComponentMatchingFlags(@PackageManager.ResolveInfoFlags int baseFlags) { synchronized (mMethodMap) { if (mBindInstantServiceAllowed) { baseFlags |= PackageManager.MATCH_INSTANT; } return baseFlags; } } @GuardedBy("mMethodMap") void buildInputMethodListLocked(boolean resetDefaultEnabledIme) { if (DEBUG) { Loading @@ -3578,7 +3600,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // services depending on the unlock state for the specified user. final List<ResolveInfo> services = pm.queryIntentServicesAsUser( new Intent(InputMethod.SERVICE_INTERFACE), PackageManager.GET_META_DATA | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, getComponentMatchingFlags(PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS), mSettings.getCurrentUserId()); final HashMap<String, List<InputMethodSubtype>> additionalSubtypeMap = Loading Loading @@ -3620,7 +3643,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // conservative, but it seems we cannot use it for now (Issue 35176630). final List<ResolveInfo> allInputMethodServices = pm.queryIntentServicesAsUser( new Intent(InputMethod.SERVICE_INTERFACE), PackageManager.MATCH_DISABLED_COMPONENTS, mSettings.getCurrentUserId()); getComponentMatchingFlags(PackageManager.MATCH_DISABLED_COMPONENTS), mSettings.getCurrentUserId()); final int N = allInputMethodServices.size(); for (int i = 0; i < N; ++i) { final ServiceInfo si = allInputMethodServices.get(i).serviceInfo; Loading Loading @@ -4540,7 +4564,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub synchronized (mMethodMap) { p.println("Current Input Method Manager state:"); int N = mMethodList.size(); p.println(" Input Methods: mMethodMapUpdateCount=" + mMethodMapUpdateCount); p.println(" Input Methods: mMethodMapUpdateCount=" + mMethodMapUpdateCount + " mBindInstantServiceAllowed=" + mBindInstantServiceAllowed); for (int i=0; i<N; i++) { InputMethodInfo info = mMethodList.get(i); p.println(" InputMethod #" + i + ":"); Loading Loading @@ -4651,6 +4676,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if ("refresh_debug_properties".equals(cmd)) { return refreshDebugProperties(); } if ("set-bind-instant-service-allowed".equals(cmd)) { return setBindInstantServiceAllowed(); } // For existing "adb shell ime <command>". if ("ime".equals(cmd)) { Loading Loading @@ -4679,6 +4707,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return handleDefaultCommands(cmd); } @BinderThread @ShellCommandResult private int setBindInstantServiceAllowed() { return mService.handleSetBindInstantServiceAllowed(this); } @BinderThread @ShellCommandResult private int refreshDebugProperties() { Loading @@ -4697,6 +4731,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub pw.println(" Synonym of dumpsys."); pw.println(" ime <command> [options]"); pw.println(" Manipulate IMEs. Run \"ime help\" for details."); pw.println(" set-bind-instant-service-allowed true|false "); pw.println(" Set whether binding to services provided by instant apps is " + "allowed."); } } Loading Loading @@ -4744,6 +4781,53 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // ---------------------------------------------------------------------- // Shell command handlers: /** * Handles {@code adb shell cmd input_method set-bind-instant-service-allowed}. * * @param shellCommand {@link ShellCommand} object that is handling this command. * @return Exit code of the command. */ @BinderThread @RequiresPermission(android.Manifest.permission.MANAGE_BIND_INSTANT_SERVICE) @ShellCommandResult private int handleSetBindInstantServiceAllowed(@NonNull ShellCommand shellCommand) { final String allowedString = shellCommand.getNextArgRequired(); if (allowedString == null) { shellCommand.getErrPrintWriter().println("Error: no true/false specified"); return ShellCommandResult.FAILURE; } final boolean allowed = Boolean.parseBoolean(allowedString); synchronized (mMethodMap) { if (mContext.checkCallingOrSelfPermission( android.Manifest.permission.MANAGE_BIND_INSTANT_SERVICE) != PackageManager.PERMISSION_GRANTED) { shellCommand.getErrPrintWriter().print( "Caller must have MANAGE_BIND_INSTANT_SERVICE permission"); return ShellCommandResult.FAILURE; } if (mBindInstantServiceAllowed == allowed) { // Nothing to do. return ShellCommandResult.SUCCESS; } mBindInstantServiceAllowed = allowed; // Rebuild everything. final long ident = Binder.clearCallingIdentity(); try { // Reset the current IME resetSelectedInputMethodAndSubtypeLocked(null); // Also reset the settings of the current IME mSettings.putSelectedInputMethod(null); buildInputMethodListLocked(false /* resetDefaultEnabledIme */); updateInputMethodsFromSettingsLocked(true /* enabledMayChange */); } finally { Binder.restoreCallingIdentity(ident); } } return ShellCommandResult.SUCCESS; } /** * Handles {@code adb shell ime list}. * @param shellCommand {@link ShellCommand} object that is handling this command. Loading Loading
services/core/java/com/android/server/InputMethodManagerService.java +92 −8 Original line number Diff line number Diff line Loading @@ -617,6 +617,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub @HardKeyboardBehavior private final int mHardKeyboardBehavior; /** * Whether we temporarily allow IMEs implemented in instant apps to run for testing. * * <p>Note: This is quite dangerous. Don't forget to reset after you finish testing.</p> */ private boolean mBindInstantServiceAllowed = false; /** * Internal state snapshot when {@link #MSG_START_INPUT} message is about to be posted to the * internal message queue. Any subsequent state change inside {@link InputMethodManagerService} Loading Loading @@ -1065,7 +1072,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub final PackageManager pm = mContext.getPackageManager(); final List<ResolveInfo> services = pm.queryIntentServicesAsUser( new Intent(InputMethod.SERVICE_INTERFACE).setPackage(packageName), PackageManager.MATCH_DISABLED_COMPONENTS, getChangingUserId()); getComponentMatchingFlags(PackageManager.MATCH_DISABLED_COMPONENTS), getChangingUserId()); // No need to lock this because we access it only on getRegisteredHandler(). if (!services.isEmpty()) { mImePackageAppeared = true; Loading Loading @@ -1609,12 +1617,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return true; } private boolean bindCurrentInputMethodService( @GuardedBy("mMethodMap") private boolean bindCurrentInputMethodServiceLocked( Intent service, ServiceConnection conn, int flags) { if (service == null || conn == null) { Slog.e(TAG, "--- bind failed: service = " + service + ", conn = " + conn); return false; } if (mBindInstantServiceAllowed) { flags |= Context.BIND_ALLOW_INSTANT; } return mContext.bindServiceAsUser(service, conn, flags, new UserHandle(mSettings.getCurrentUserId())); } Loading Loading @@ -1956,7 +1968,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub com.android.internal.R.string.input_method_binding_label); mCurIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity( mContext, 0, new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), 0)); if (bindCurrentInputMethodService(mCurIntent, this, IME_CONNECTION_BIND_FLAGS)) { if (bindCurrentInputMethodServiceLocked(mCurIntent, this, IME_CONNECTION_BIND_FLAGS)) { mLastBindTime = SystemClock.uptimeMillis(); mHaveConnection = true; mCurId = info.getId(); Loading Loading @@ -2608,7 +2620,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub resultReceiver)); mInputShown = true; if (mHaveConnection && !mVisibleBound) { bindCurrentInputMethodService( bindCurrentInputMethodServiceLocked( mCurIntent, mVisibleConnection, IME_VISIBLE_BIND_FLAGS); mVisibleBound = true; } Loading @@ -2623,7 +2635,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub SystemClock.uptimeMillis()-mLastBindTime,1); Slog.w(TAG, "Force disconnect/connect to the IME in showCurrentInputLocked()"); mContext.unbindService(this); bindCurrentInputMethodService(mCurIntent, this, IME_CONNECTION_BIND_FLAGS); bindCurrentInputMethodServiceLocked(mCurIntent, this, IME_CONNECTION_BIND_FLAGS); } else { if (DEBUG) { Slog.d(TAG, "Can't show input: connection = " + mHaveConnection + ", time = " Loading Loading @@ -3555,6 +3567,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return false; } @PackageManager.ResolveInfoFlags private int getComponentMatchingFlags(@PackageManager.ResolveInfoFlags int baseFlags) { synchronized (mMethodMap) { if (mBindInstantServiceAllowed) { baseFlags |= PackageManager.MATCH_INSTANT; } return baseFlags; } } @GuardedBy("mMethodMap") void buildInputMethodListLocked(boolean resetDefaultEnabledIme) { if (DEBUG) { Loading @@ -3578,7 +3600,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // services depending on the unlock state for the specified user. final List<ResolveInfo> services = pm.queryIntentServicesAsUser( new Intent(InputMethod.SERVICE_INTERFACE), PackageManager.GET_META_DATA | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, getComponentMatchingFlags(PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS), mSettings.getCurrentUserId()); final HashMap<String, List<InputMethodSubtype>> additionalSubtypeMap = Loading Loading @@ -3620,7 +3643,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // conservative, but it seems we cannot use it for now (Issue 35176630). final List<ResolveInfo> allInputMethodServices = pm.queryIntentServicesAsUser( new Intent(InputMethod.SERVICE_INTERFACE), PackageManager.MATCH_DISABLED_COMPONENTS, mSettings.getCurrentUserId()); getComponentMatchingFlags(PackageManager.MATCH_DISABLED_COMPONENTS), mSettings.getCurrentUserId()); final int N = allInputMethodServices.size(); for (int i = 0; i < N; ++i) { final ServiceInfo si = allInputMethodServices.get(i).serviceInfo; Loading Loading @@ -4540,7 +4564,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub synchronized (mMethodMap) { p.println("Current Input Method Manager state:"); int N = mMethodList.size(); p.println(" Input Methods: mMethodMapUpdateCount=" + mMethodMapUpdateCount); p.println(" Input Methods: mMethodMapUpdateCount=" + mMethodMapUpdateCount + " mBindInstantServiceAllowed=" + mBindInstantServiceAllowed); for (int i=0; i<N; i++) { InputMethodInfo info = mMethodList.get(i); p.println(" InputMethod #" + i + ":"); Loading Loading @@ -4651,6 +4676,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if ("refresh_debug_properties".equals(cmd)) { return refreshDebugProperties(); } if ("set-bind-instant-service-allowed".equals(cmd)) { return setBindInstantServiceAllowed(); } // For existing "adb shell ime <command>". if ("ime".equals(cmd)) { Loading Loading @@ -4679,6 +4707,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return handleDefaultCommands(cmd); } @BinderThread @ShellCommandResult private int setBindInstantServiceAllowed() { return mService.handleSetBindInstantServiceAllowed(this); } @BinderThread @ShellCommandResult private int refreshDebugProperties() { Loading @@ -4697,6 +4731,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub pw.println(" Synonym of dumpsys."); pw.println(" ime <command> [options]"); pw.println(" Manipulate IMEs. Run \"ime help\" for details."); pw.println(" set-bind-instant-service-allowed true|false "); pw.println(" Set whether binding to services provided by instant apps is " + "allowed."); } } Loading Loading @@ -4744,6 +4781,53 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // ---------------------------------------------------------------------- // Shell command handlers: /** * Handles {@code adb shell cmd input_method set-bind-instant-service-allowed}. * * @param shellCommand {@link ShellCommand} object that is handling this command. * @return Exit code of the command. */ @BinderThread @RequiresPermission(android.Manifest.permission.MANAGE_BIND_INSTANT_SERVICE) @ShellCommandResult private int handleSetBindInstantServiceAllowed(@NonNull ShellCommand shellCommand) { final String allowedString = shellCommand.getNextArgRequired(); if (allowedString == null) { shellCommand.getErrPrintWriter().println("Error: no true/false specified"); return ShellCommandResult.FAILURE; } final boolean allowed = Boolean.parseBoolean(allowedString); synchronized (mMethodMap) { if (mContext.checkCallingOrSelfPermission( android.Manifest.permission.MANAGE_BIND_INSTANT_SERVICE) != PackageManager.PERMISSION_GRANTED) { shellCommand.getErrPrintWriter().print( "Caller must have MANAGE_BIND_INSTANT_SERVICE permission"); return ShellCommandResult.FAILURE; } if (mBindInstantServiceAllowed == allowed) { // Nothing to do. return ShellCommandResult.SUCCESS; } mBindInstantServiceAllowed = allowed; // Rebuild everything. final long ident = Binder.clearCallingIdentity(); try { // Reset the current IME resetSelectedInputMethodAndSubtypeLocked(null); // Also reset the settings of the current IME mSettings.putSelectedInputMethod(null); buildInputMethodListLocked(false /* resetDefaultEnabledIme */); updateInputMethodsFromSettingsLocked(true /* enabledMayChange */); } finally { Binder.restoreCallingIdentity(ident); } } return ShellCommandResult.SUCCESS; } /** * Handles {@code adb shell ime list}. * @param shellCommand {@link ShellCommand} object that is handling this command. Loading