Implement IMM#showInputMethodAndSubtypeEnabler() in the client side

With this CL,

  InputMethodManager#showInputMethodAndSubtypeEnabler()

is fully implemented in the client side.  By not using system_server
privileged context to launch the Settings activity, we can stop
worrying about conflicts with existing security concepts such as

 * Background Activity launch blocking mechanism
 * Restrictions for instant apps

Bug: 34886274
Test: Manually verified as follows.
 1. Build aosp_coral-userdebug and flash it.
 2. adb install -r $ANDROID_TARGET_OUT_TESTCASES/ApiDemos/arm64/ApiDemos.apk
 3. adb shell am start -n com.example.android.apis/.ApiDemos
 4. View -> Input Method -> ShowInputMethodAndSubtypeEnabler
 5. Verify that the API works.
Change-Id: I5199ca4609c03900a0e86011d344b054b1df08dd
This commit is contained in:
Yohei Yukawa
2022-07-18 22:31:40 -07:00
parent 5e11ce8ca7
commit ea675ead0a
4 changed files with 23 additions and 43 deletions

View File

@@ -179,16 +179,6 @@ final class IInputMethodManagerInvoker {
}
}
@AnyThread
void showInputMethodAndSubtypeEnablerFromClient(@NonNull IInputMethodClient client,
@Nullable String imeId) {
try {
mTarget.showInputMethodAndSubtypeEnablerFromClient(client, imeId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
@AnyThread
boolean isInputMethodPickerShownForTest() {
try {

View File

@@ -53,9 +53,11 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.inputmethodservice.InputMethodService;
import android.os.Binder;
import android.os.Build;
@@ -71,6 +73,7 @@ import android.os.ServiceManager.ServiceNotFoundException;
import android.os.Trace;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
import android.text.style.SuggestionSpan;
import android.util.Log;
import android.util.Pools.Pool;
@@ -3243,7 +3246,26 @@ public final class InputMethodManager {
* subtypes of all input methods will be shown.
*/
public void showInputMethodAndSubtypeEnabler(@Nullable String imiId) {
mServiceInvoker.showInputMethodAndSubtypeEnablerFromClient(mClient, imiId);
Context context = null;
synchronized (mH) {
if (mCurRootView != null) {
context = mCurRootView.mContext;
}
}
if (context == null) {
final Context appContext = ActivityThread.currentApplication();
final DisplayManager displayManager = appContext.getSystemService(DisplayManager.class);
context = appContext.createDisplayContext(displayManager.getDisplay(mDisplayId));
}
final Intent intent = new Intent(Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
if (!TextUtils.isEmpty(imiId)) {
intent.putExtra(Settings.EXTRA_INPUT_METHOD_ID, imiId);
}
context.startActivity(intent);
}
/**

View File

@@ -82,9 +82,6 @@ interface IInputMethodManager {
void showInputMethodPickerFromSystem(in IInputMethodClient client,
int auxiliarySubtypeMode, int displayId);
void showInputMethodAndSubtypeEnablerFromClient(in IInputMethodClient client,
@nullable String topId);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ "android.Manifest.permission.TEST_INPUT_METHOD)")
boolean isInputMethodPickerShownForTest();

View File

@@ -4051,18 +4051,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
}
}
@Override
public void showInputMethodAndSubtypeEnablerFromClient(
IInputMethodClient client, String inputMethodId) {
synchronized (ImfLock.class) {
// TODO(yukawa): Should we verify the display ID?
if (!calledFromValidUserLocked()) {
return;
}
showInputMethodAndSubtypeEnabler(inputMethodId);
}
}
@BinderThread
private boolean switchToPreviousInputMethod(@NonNull IBinder token) {
synchronized (ImfLock.class) {
@@ -5219,23 +5207,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
// ----------------------------------------------------------------------
private void showInputMethodAndSubtypeEnabler(String inputMethodId) {
Intent intent = new Intent(Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
if (!TextUtils.isEmpty(inputMethodId)) {
intent.putExtra(Settings.EXTRA_INPUT_METHOD_ID, inputMethodId);
}
final int userId;
synchronized (ImfLock.class) {
userId = mSettings.getCurrentUserId();
}
mContext.startActivityAsUser(intent, null, UserHandle.of(userId));
}
// ----------------------------------------------------------------------
/**
* Enable or disable the given IME by updating {@link Settings.Secure#ENABLED_INPUT_METHODS}.
*