Merge "Reenable CursorAnchorInfo API with ActivityView" into qt-dev

am: 23d047ab15

Change-Id: I18cccf69c6e904d96e79b842f784bbaa94fc1a3d
This commit is contained in:
Yohei Yukawa
2019-05-03 15:18:25 -07:00
committed by android-build-merger
7 changed files with 328 additions and 13 deletions

View File

@@ -28,6 +28,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Insets;
import android.graphics.Matrix;
import android.graphics.Region;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
@@ -51,6 +52,7 @@ import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.inputmethod.InputMethodManager;
import dalvik.system.CloseGuard;
@@ -320,6 +322,14 @@ public class ActivityView extends ViewGroup {
updateLocationAndTapExcludeRegion();
}
private void clearActivityViewGeometryForIme() {
if (mVirtualDisplay == null) {
return;
}
final int displayId = mVirtualDisplay.getDisplay().getDisplayId();
mContext.getSystemService(InputMethodManager.class).reportActivityView(displayId, null);
}
@Override
public void onLayout(boolean changed, int l, int t, int r, int b) {
mSurfaceView.layout(0 /* left */, 0 /* top */, r - l /* right */, b - t /* bottom */);
@@ -347,8 +357,17 @@ public class ActivityView extends ViewGroup {
if (x != mLocationInWindow[0] || y != mLocationInWindow[1]) {
x = mLocationInWindow[0];
y = mLocationInWindow[1];
final int displayId = mVirtualDisplay.getDisplay().getDisplayId();
WindowManagerGlobal.getWindowSession().updateDisplayContentLocation(
getWindow(), x, y, mVirtualDisplay.getDisplay().getDisplayId());
getWindow(), x, y, displayId);
// Also report this geometry information to InputMethodManagerService.
// TODO(b/115693908): Unify this logic into the above WMS-based one.
final Matrix matrix = new Matrix();
matrix.set(getMatrix());
matrix.postTranslate(x, y);
mContext.getSystemService(InputMethodManager.class)
.reportActivityView(displayId, matrix);
}
updateTapExcludeRegion(x, y);
} catch (RemoteException e) {
@@ -408,6 +427,7 @@ public class ActivityView extends ViewGroup {
if (mVirtualDisplay != null) {
mVirtualDisplay.setDisplayState(false);
}
clearActivityViewGeometryForIme();
cleanTapExcludeRegion();
}
}

View File

@@ -33,6 +33,7 @@ import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.inputmethodservice.InputMethodService;
import android.os.Binder;
@@ -425,6 +426,17 @@ public final class InputMethodManager {
*/
private CursorAnchorInfo mCursorAnchorInfo = null;
/**
* A special {@link Matrix} that can be provided by the system when this instance is running
* inside a virtual display that is managed by {@link android.app.ActivityView}.
*
* <p>If this is non-{@code null}, {@link #updateCursorAnchorInfo(View, CursorAnchorInfo)}
* should be adjusted with this {@link Matrix}.</p>
*
* <p>{@code null} when not used.</p>
*/
private Matrix mActivityViewToScreenMatrix = null;
// -----------------------------------------------------------
/**
@@ -473,6 +485,7 @@ public final class InputMethodManager {
static final int MSG_REPORT_FULLSCREEN_MODE = 10;
static final int MSG_REPORT_PRE_RENDERED = 15;
static final int MSG_APPLY_IME_VISIBILITY = 20;
static final int MSG_UPDATE_ACTIVITY_VIEW_TO_SCREEN_MATRIX = 30;
private static boolean isAutofillUIShowing(View servedView) {
AutofillManager afm = servedView.getContext().getSystemService(AutofillManager.class);
@@ -579,6 +592,7 @@ public final class InputMethodManager {
mCurMethod = res.method;
mCurId = res.id;
mBindSequence = res.sequence;
mActivityViewToScreenMatrix = res.getActivityViewToScreenMatrix();
}
startInputInner(StartInputReason.BOUND_TO_IMMS, null, 0, 0, 0);
return;
@@ -686,6 +700,48 @@ public final class InputMethodManager {
}
return;
}
case MSG_UPDATE_ACTIVITY_VIEW_TO_SCREEN_MATRIX: {
final float[] matrixValues = (float[]) msg.obj;
final int bindSequence = msg.arg1;
synchronized (mH) {
if (mBindSequence != bindSequence) {
return;
}
if (matrixValues == null) {
// That this app is unbound from the parent ActivityView. In this case,
// calling updateCursorAnchorInfo() isn't safe. Only clear the matrix.
mActivityViewToScreenMatrix = null;
return;
}
final float[] currentValues = new float[9];
mActivityViewToScreenMatrix.getValues(currentValues);
if (Arrays.equals(currentValues, matrixValues)) {
return;
}
mActivityViewToScreenMatrix.setValues(matrixValues);
if (mCursorAnchorInfo == null || mCurMethod == null
|| mServedInputConnectionWrapper == null) {
return;
}
final boolean isMonitoring = (mRequestUpdateCursorAnchorInfoMonitorMode
& InputConnection.CURSOR_UPDATE_MONITOR) != 0;
if (!isMonitoring) {
return;
}
// Since the host ActivityView is moved, we need to issue
// IMS#updateCursorAnchorInfo() again.
try {
mCurMethod.updateCursorAnchorInfo(
CursorAnchorInfo.createForAdditionalParentMatrix(
mCursorAnchorInfo, mActivityViewToScreenMatrix));
} catch (RemoteException e) {
Log.w(TAG, "IME died: " + mCurId, e);
}
}
return;
}
}
}
}
@@ -777,6 +833,11 @@ public final class InputMethodManager {
.sendToTarget();
}
@Override
public void updateActivityViewToScreenMatrix(int bindSequence, float[] matrixValues) {
mH.obtainMessage(MSG_UPDATE_ACTIVITY_VIEW_TO_SCREEN_MATRIX, bindSequence, 0,
matrixValues).sendToTarget();
}
};
final InputConnection mDummyInputConnection = new BaseInputConnection(this, false);
@@ -1192,6 +1253,7 @@ public final class InputMethodManager {
@UnsupportedAppUsage
void finishInputLocked() {
mNextServedView = null;
mActivityViewToScreenMatrix = null;
if (mServedView != null) {
if (DEBUG) Log.v(TAG, "FINISH INPUT: mServedView=" + dumpViewInfo(mServedView));
mServedView = null;
@@ -1668,6 +1730,7 @@ public final class InputMethodManager {
+ InputMethodDebug.startInputFlagsToString(startInputFlags));
return false;
}
mActivityViewToScreenMatrix = res.getActivityViewToScreenMatrix();
if (res.id != null) {
setInputChannelLocked(res.channel);
mBindSequence = res.sequence;
@@ -2200,7 +2263,13 @@ public final class InputMethodManager {
}
if (DEBUG) Log.v(TAG, "updateCursorAnchorInfo: " + cursorAnchorInfo);
try {
mCurMethod.updateCursorAnchorInfo(cursorAnchorInfo);
if (mActivityViewToScreenMatrix != null) {
mCurMethod.updateCursorAnchorInfo(
CursorAnchorInfo.createForAdditionalParentMatrix(
cursorAnchorInfo, mActivityViewToScreenMatrix));
} else {
mCurMethod.updateCursorAnchorInfo(cursorAnchorInfo);
}
mCursorAnchorInfo = cursorAnchorInfo;
// Clear immediate bit (if any).
mRequestUpdateCursorAnchorInfoMonitorMode &=
@@ -2778,6 +2847,30 @@ public final class InputMethodManager {
}
}
/**
* An internal API for {@link android.app.ActivityView} to report where its embedded virtual
* display is placed.
*
* @param childDisplayId Display ID of the embedded virtual display.
* @param matrix {@link Matrix} to convert virtual display screen coordinates to
* the host screen coordinates. {@code null} to clear the relationship.
* @hide
*/
public void reportActivityView(int childDisplayId, @Nullable Matrix matrix) {
try {
final float[] matrixValues;
if (matrix == null) {
matrixValues = null;
} else {
matrixValues = new float[9];
matrix.getValues(matrixValues);
}
mService.reportActivityView(mClient, childDisplayId, matrixValues);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Force switch to the last used input method and subtype. If the last input method didn't have
* any subtypes, the framework will simply switch to the last input method with no subtype

View File

@@ -31,4 +31,5 @@ oneway interface IInputMethodClient {
void reportFullscreenMode(boolean fullscreen);
void reportPreRendered(in EditorInfo info);
void applyImeVisibility(boolean setVisible);
void updateActivityViewToScreenMatrix(int bindSequence, in float[] matrixValues);
}

View File

@@ -68,4 +68,7 @@ interface IInputMethodManager {
// This is kept due to @UnsupportedAppUsage.
// TODO(Bug 113914148): Consider removing this.
int getInputMethodWindowVisibleHeight();
void reportActivityView(in IInputMethodClient parentClient, int childDisplayId,
in float[] matrixValues);
}

View File

@@ -19,10 +19,12 @@ package com.android.internal.view;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Matrix;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
@@ -192,13 +194,37 @@ public final class InputBindResult implements Parcelable {
*/
public final int sequence;
@Nullable
private final float[] mActivityViewToScreenMatrixValues;
/**
* @return {@link Matrix} that corresponds to {@link #mActivityViewToScreenMatrixValues}.
* {@code null} if {@link #mActivityViewToScreenMatrixValues} is {@code null}.
*/
@Nullable
public Matrix getActivityViewToScreenMatrix() {
if (mActivityViewToScreenMatrixValues == null) {
return null;
}
final Matrix matrix = new Matrix();
matrix.setValues(mActivityViewToScreenMatrixValues);
return matrix;
}
public InputBindResult(@ResultCode int _result,
IInputMethodSession _method, InputChannel _channel, String _id, int _sequence) {
IInputMethodSession _method, InputChannel _channel, String _id, int _sequence,
@Nullable Matrix activityViewToScreenMatrix) {
result = _result;
method = _method;
channel = _channel;
id = _id;
sequence = _sequence;
if (activityViewToScreenMatrix == null) {
mActivityViewToScreenMatrixValues = null;
} else {
mActivityViewToScreenMatrixValues = new float[9];
activityViewToScreenMatrix.getValues(mActivityViewToScreenMatrixValues);
}
}
InputBindResult(Parcel source) {
@@ -211,12 +237,14 @@ public final class InputBindResult implements Parcelable {
}
id = source.readString();
sequence = source.readInt();
mActivityViewToScreenMatrixValues = source.createFloatArray();
}
@Override
public String toString() {
return "InputBindResult{result=" + getResultString() + " method="+ method + " id=" + id
+ " sequence=" + sequence
+ " activityViewToScreenMatrix=" + getActivityViewToScreenMatrix()
+ "}";
}
@@ -238,6 +266,7 @@ public final class InputBindResult implements Parcelable {
}
dest.writeString(id);
dest.writeInt(sequence);
dest.writeFloatArray(mActivityViewToScreenMatrixValues);
}
/**
@@ -302,7 +331,7 @@ public final class InputBindResult implements Parcelable {
}
private static InputBindResult error(@ResultCode int result) {
return new InputBindResult(result, null, null, null, -1);
return new InputBindResult(result, null, null, null, -1, null);
}
/**

View File

@@ -63,7 +63,9 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.database.ContentObserver;
import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
import android.hardware.display.DisplayManagerInternal;
import android.inputmethodservice.InputMethodService;
import android.net.Uri;
import android.os.Binder;
@@ -97,7 +99,9 @@ import android.util.Pair;
import android.util.PrintWriterPrinter;
import android.util.Printer;
import android.util.Slog;
import android.util.SparseArray;
import android.view.ContextThemeWrapper;
import android.view.DisplayInfo;
import android.view.IWindowManager;
import android.view.InputChannel;
import android.view.LayoutInflater;
@@ -300,6 +304,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
final SettingsObserver mSettingsObserver;
final IWindowManager mIWindowManager;
final WindowManagerInternal mWindowManagerInternal;
private final DisplayManagerInternal mDisplayManagerInternal;
final HandlerCaller mCaller;
final boolean mHasFeature;
private final ArrayMap<String, List<InputMethodSubtype>> mAdditionalSubtypeMap =
@@ -432,6 +437,32 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
final ArrayMap<IBinder, ClientState> mClients = new ArrayMap<>();
private static final class ActivityViewInfo {
/**
* {@link ClientState} where {@link android.app.ActivityView} is running.
*/
private final ClientState mParentClient;
/**
* {@link Matrix} to convert screen coordinates in the embedded virtual display to
* screen coordinates where {@link #mParentClient} exists.
*/
private final Matrix mMatrix;
ActivityViewInfo(ClientState parentClient, Matrix matrix) {
mParentClient = parentClient;
mMatrix = matrix;
}
}
/**
* A mapping table from virtual display IDs created for {@link android.app.ActivityView}
* to its parent IME client where {@link android.app.ActivityView} is running.
*
* <p>Note: this can be used only for virtual display IDs created by
* {@link android.app.ActivityView}.</p>
*/
private SparseArray<ActivityViewInfo> mActivityViewDisplayIdToParentMap = new SparseArray<>();
/**
* Set once the system is ready to run third party code.
*/
@@ -509,6 +540,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
*/
EditorInfo mCurAttribute;
/**
* A special {@link Matrix} to convert virtual screen coordinates to the IME target display
* coordinates.
*
* <p>Used only while the IME client is running in a virtual display inside
* {@link android.app.ActivityView}. {@code null} otherwise.</p>
*/
@Nullable
private Matrix mCurActivityViewToScreenMatrix = null;
/**
* Id obtained with {@link InputMethodInfo#getId()} for the input method that we are currently
* connected to or in the process of connecting to.
@@ -1409,6 +1450,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mIWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE));
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
mImeDisplayValidator = displayId -> mWindowManagerInternal.shouldShowIme(displayId);
mCaller = new HandlerCaller(context, null, new HandlerCaller.Callback() {
@Override
@@ -1883,6 +1925,15 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (cs != null) {
client.asBinder().unlinkToDeath(cs.clientDeathRecipient, 0);
clearClientSessionLocked(cs);
final int numItems = mActivityViewDisplayIdToParentMap.size();
for (int i = numItems - 1; i >= 0; --i) {
final ActivityViewInfo info = mActivityViewDisplayIdToParentMap.valueAt(i);
if (info.mParentClient == cs) {
mActivityViewDisplayIdToParentMap.removeAt(i);
}
}
if (mCurClient == cs) {
if (mBoundToMethod) {
mBoundToMethod = false;
@@ -1892,6 +1943,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
mCurClient = null;
mCurActivityViewToScreenMatrix = null;
}
if (mCurFocusedWindowClient == cs) {
mCurFocusedWindowClient = null;
@@ -1927,6 +1979,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
MSG_UNBIND_CLIENT, mCurSeq, unbindClientReason, mCurClient.client));
mCurClient.sessionRequested = false;
mCurClient = null;
mCurActivityViewToScreenMatrix = null;
hideInputMethodMenuLocked();
}
@@ -1980,7 +2033,31 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
return new InputBindResult(InputBindResult.ResultCode.SUCCESS_WITH_IME_SESSION,
session.session, (session.channel != null ? session.channel.dup() : null),
mCurId, mCurSeq);
mCurId, mCurSeq, mCurActivityViewToScreenMatrix);
}
@Nullable
private Matrix getActivityViewToScreenMatrixLocked(int clientDisplayId, int imeDisplayId) {
if (clientDisplayId == imeDisplayId) {
return null;
}
int displayId = clientDisplayId;
Matrix matrix = null;
while (true) {
final ActivityViewInfo info = mActivityViewDisplayIdToParentMap.get(displayId);
if (info == null) {
return null;
}
if (matrix == null) {
matrix = new Matrix(info.mMatrix);
} else {
matrix.postConcat(info.mMatrix);
}
if (info.mParentClient.selfReportedDisplayId == imeDisplayId) {
return matrix;
}
displayId = info.mParentClient.selfReportedDisplayId;
}
}
@GuardedBy("mMethodMap")
@@ -1998,7 +2075,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// party code.
return new InputBindResult(
InputBindResult.ResultCode.ERROR_SYSTEM_NOT_READY,
null, null, mCurMethodId, mCurSeq);
null, null, mCurMethodId, mCurSeq, null);
}
if (!InputMethodUtils.checkIfPackageBelongsToUid(mAppOpsManager, cs.uid,
@@ -2037,7 +2114,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (mCurSeq <= 0) mCurSeq = 1;
mCurClient = cs;
mCurInputContext = inputContext;
if (cs.selfReportedDisplayId != displayIdToShowIme) {
mCurActivityViewToScreenMatrix =
getActivityViewToScreenMatrixLocked(cs.selfReportedDisplayId, displayIdToShowIme);
if (cs.selfReportedDisplayId != displayIdToShowIme
&& mCurActivityViewToScreenMatrix == null) {
// CursorAnchorInfo API does not work as-is for cross-display scenario. Pretend that
// InputConnection#requestCursorUpdates() is not implemented in the application so that
// IMEs will always receive false from this API.
@@ -2064,7 +2144,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
requestClientSessionLocked(cs);
return new InputBindResult(
InputBindResult.ResultCode.SUCCESS_WAITING_IME_SESSION,
null, null, mCurId, mCurSeq);
null, null, mCurId, mCurSeq, null);
} else if (SystemClock.uptimeMillis()
< (mLastBindTime+TIME_TO_RECONNECT)) {
// In this case we have connected to the service, but
@@ -2076,7 +2156,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// to see if we can get back in touch with the service.
return new InputBindResult(
InputBindResult.ResultCode.SUCCESS_WAITING_IME_BINDING,
null, null, mCurId, mCurSeq);
null, null, mCurId, mCurSeq, null);
} else {
EventLog.writeEvent(EventLogTags.IMF_FORCE_RECONNECT_IME,
mCurMethodId, SystemClock.uptimeMillis()-mLastBindTime, 0);
@@ -2115,7 +2195,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
return new InputBindResult(
InputBindResult.ResultCode.SUCCESS_WAITING_IME_BINDING,
null, null, mCurId, mCurSeq);
null, null, mCurId, mCurSeq, null);
}
mCurIntent = null;
Slog.w(TAG, "Failure connecting to input method service: " + mCurIntent);
@@ -2960,7 +3040,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
return new InputBindResult(
InputBindResult.ResultCode.SUCCESS_REPORT_WINDOW_FOCUS_ONLY,
null, null, null, -1);
null, null, null, -1, null);
}
mCurFocusedWindow = windowToken;
mCurFocusedWindowSoftInputMode = softInputMode;
@@ -3387,6 +3467,88 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return mWindowManagerInternal.getInputMethodWindowVisibleHeight(mCurTokenDisplayId);
}
@Override
public void reportActivityView(IInputMethodClient parentClient, int childDisplayId,
float[] matrixValues) {
final DisplayInfo displayInfo = mDisplayManagerInternal.getDisplayInfo(childDisplayId);
if (displayInfo == null) {
throw new IllegalArgumentException(
"Cannot find display for non-existent displayId: " + childDisplayId);
}
final int callingUid = Binder.getCallingUid();
if (callingUid != displayInfo.ownerUid) {
throw new SecurityException("The caller doesn't own the display.");
}
synchronized (mMethodMap) {
final ClientState cs = mClients.get(parentClient.asBinder());
if (cs == null) {
return;
}
// null matrixValues means that the entry needs to be removed.
if (matrixValues == null) {
final ActivityViewInfo info = mActivityViewDisplayIdToParentMap.get(childDisplayId);
if (info == null) {
return;
}
if (info.mParentClient != cs) {
throw new SecurityException("Only the owner client can clear"
+ " ActivityViewGeometry for display #" + childDisplayId);
}
mActivityViewDisplayIdToParentMap.remove(childDisplayId);
return;
}
ActivityViewInfo info = mActivityViewDisplayIdToParentMap.get(childDisplayId);
if (info != null && info.mParentClient != cs) {
throw new InvalidParameterException("Display #" + childDisplayId
+ " is already registered by " + info.mParentClient);
}
if (info == null) {
if (!mWindowManagerInternal.isUidAllowedOnDisplay(childDisplayId, cs.uid)) {
throw new SecurityException(cs + " cannot access to display #"
+ childDisplayId);
}
info = new ActivityViewInfo(cs, new Matrix());
mActivityViewDisplayIdToParentMap.put(childDisplayId, info);
}
info.mMatrix.setValues(matrixValues);
if (mCurClient == null || mCurClient.curSession == null) {
return;
}
Matrix matrix = null;
int displayId = mCurClient.selfReportedDisplayId;
boolean needToNotify = false;
while (true) {
needToNotify |= (displayId == childDisplayId);
final ActivityViewInfo next = mActivityViewDisplayIdToParentMap.get(displayId);
if (next == null) {
break;
}
if (matrix == null) {
matrix = new Matrix(next.mMatrix);
} else {
matrix.postConcat(next.mMatrix);
}
if (next.mParentClient.selfReportedDisplayId == mCurTokenDisplayId) {
if (needToNotify) {
final float[] values = new float[9];
matrix.getValues(values);
try {
mCurClient.client.updateActivityViewToScreenMatrix(mCurSeq, values);
} catch (RemoteException e) {
}
}
break;
}
displayId = info.mParentClient.selfReportedDisplayId;
}
}
}
@BinderThread
private void notifyUserAction(@NonNull IBinder token) {
if (DEBUG) {

View File

@@ -1619,7 +1619,7 @@ public final class MultiClientInputMethodManagerService {
return new InputBindResult(
InputBindResult.ResultCode.SUCCESS_WAITING_IME_SESSION,
null, null, data.mCurrentInputMethodInfo.getId(),
clientInfo.mBindingSequence);
clientInfo.mBindingSequence, null);
case InputMethodClientState.READY_TO_SEND_FIRST_BIND_RESULT:
case InputMethodClientState.ALREADY_SENT_BIND_RESULT:
clientInfo.mBindingSequence++;
@@ -1642,7 +1642,7 @@ public final class MultiClientInputMethodManagerService {
clientInfo.mInputMethodSession,
clientInfo.mWriteChannel.dup(),
data.mCurrentInputMethodInfo.getId(),
clientInfo.mBindingSequence);
clientInfo.mBindingSequence, null);
case InputMethodClientState.UNREGISTERED:
Slog.e(TAG, "The client is already unregistered.");
return InputBindResult.INVALID_CLIENT;
@@ -1699,6 +1699,13 @@ public final class MultiClientInputMethodManagerService {
return 0;
}
@BinderThread
@Override
public void reportActivityView(IInputMethodClient parentClient, int childDisplayId,
float[] matrixValues) {
reportNotSupported();
}
@BinderThread
@Override
public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,