Merge "Add a shell command for IMMS to test instant apps" into pi-dev

am: 711a8f7f28

Change-Id: I7ac74ec1076ad7160475b9595e00db85eea9f818
This commit is contained in:
Yohei Yukawa
2018-05-21 12:29:13 -07:00
committed by android-build-merger

View File

@@ -620,6 +620,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}
@@ -1068,7 +1075,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;
@@ -1612,12 +1620,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()));
}
@@ -1959,7 +1971,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();
@@ -2611,7 +2623,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
resultReceiver));
mInputShown = true;
if (mHaveConnection && !mVisibleBound) {
bindCurrentInputMethodService(
bindCurrentInputMethodServiceLocked(
mCurIntent, mVisibleConnection, IME_VISIBLE_BIND_FLAGS);
mVisibleBound = true;
}
@@ -2626,7 +2638,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 = "
@@ -3589,6 +3601,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) {
@@ -3612,7 +3634,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 =
@@ -3654,7 +3677,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;
@@ -4597,7 +4621,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 + ":");
@@ -4709,6 +4734,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)) {
@@ -4737,6 +4765,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return handleDefaultCommands(cmd);
}
@BinderThread
@ShellCommandResult
private int setBindInstantServiceAllowed() {
return mService.handleSetBindInstantServiceAllowed(this);
}
@BinderThread
@ShellCommandResult
private int refreshDebugProperties() {
@@ -4755,6 +4789,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.");
}
}
@@ -4802,6 +4839,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.