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:
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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}.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user