add dump to MultiClientInputMethodManagerService
Bug: 131619304
Test: adb shell dumpsys input_method
Change-Id: I163687baeaed9a6d47ef6758834a00a6f3f640ba
diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
index 580150e..e0b8e71 100644
--- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
@@ -79,6 +79,9 @@
import com.android.internal.inputmethod.UnbindReason;
import com.android.internal.messages.nano.SystemMessageProto;
import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.os.TransferPipe;
+import com.android.internal.util.DumpUtils;
+import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethodClient;
@@ -90,6 +93,8 @@
import com.android.server.wm.WindowManagerInternal;
import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.util.Collections;
import java.util.List;
@@ -645,6 +650,14 @@
mSelfReportedDisplayId = selfReportedDisplayId;
mClientId = InputMethodClientIdSource.getNext();
}
+
+ @GuardedBy("PerUserData.mLock")
+ void dumpLocked(FileDescriptor fd, IndentingPrintWriter ipw, String[] args) {
+ ipw.println("mState=" + mState + ",mBindingSequence=" + mBindingSequence
+ + ",mWriteChannel=" + mWriteChannel
+ + ",mInputMethodSession=" + mInputMethodSession
+ + ",mMSInputMethodSession=" + mMSInputMethodSession);
+ }
}
private static final class UserDataMap {
@@ -673,6 +686,22 @@
return mMap.removeReturnOld(userId);
}
}
+
+ @AnyThread
+ void dump(FileDescriptor fd, IndentingPrintWriter ipw, String[] args) {
+ synchronized (mMap) {
+ for (int i = 0; i < mMap.size(); i++) {
+ int userId = mMap.keyAt(i);
+ PerUserData data = mMap.valueAt(i);
+ ipw.println("userId=" + userId + ", data=");
+ if (data != null) {
+ ipw.increaseIndent();
+ data.dump(fd, ipw, args);
+ ipw.decreaseIndent();
+ }
+ }
+ }
+ }
}
private static final class TokenInfo {
@@ -967,6 +996,71 @@
}
}
+ @AnyThread
+ void dump(FileDescriptor fd, IndentingPrintWriter ipw, String[] args) {
+ synchronized (mLock) {
+ ipw.println("mState=" + mState
+ + ",mCurrentInputMethod=" + mCurrentInputMethod
+ + ",mCurrentInputMethodInfo=" + mCurrentInputMethodInfo);
+
+ if (mCurrentInputMethod != null) {
+ // indentation will not be kept. So add visual separator here.
+ ipw.println(">>Dump CurrentInputMethod>>");
+ ipw.flush();
+ try {
+ TransferPipe.dumpAsync(mCurrentInputMethod.asBinder(), fd, args);
+ } catch (IOException | RemoteException e) {
+ ipw.println("Failed to dump input method service: " + e);
+ }
+ ipw.println("<<Dump CurrentInputMethod<<");
+ }
+
+ ipw.println("mDisplayIdToImeWindowTokenMap=");
+ for (TokenInfo info : mDisplayIdToImeWindowTokenMap) {
+ ipw.println(" display=" + info.mDisplayId + ",token="
+ + info.mToken);
+ }
+ ipw.println("mClientMap=");
+ ipw.increaseIndent();
+ for (int i = 0; i < mClientMap.size(); i++) {
+
+ ipw.println("binder=" + mClientMap.keyAt(i));
+ ipw.println(" InputMethodClientInfo=");
+ InputMethodClientInfo info = mClientMap.valueAt(i);
+ if (info != null) {
+ ipw.increaseIndent();
+ info.dumpLocked(fd, ipw, args);
+ ipw.decreaseIndent();
+ }
+ }
+ ipw.decreaseIndent();
+ ipw.println("mClientIdToClientMap=");
+ ipw.increaseIndent();
+ for (int i = 0; i < mClientIdToClientMap.size(); i++) {
+ ipw.println("clientId=" + mClientIdToClientMap.keyAt(i));
+ ipw.println(" InputMethodClientInfo=");
+ InputMethodClientInfo info = mClientIdToClientMap.valueAt(i);
+ if (info != null) {
+ ipw.increaseIndent();
+ info.dumpLocked(fd, ipw, args);
+ ipw.decreaseIndent();
+ }
+ if (info.mClient != null) {
+ // indentation will not be kept. So add visual separator here.
+ ipw.println(">>DumpClientStart>>");
+ ipw.flush(); // all writes should be flushed to guarantee order.
+ try {
+ TransferPipe.dumpAsync(info.mClient.asBinder(), fd, args);
+ } catch (IOException | RemoteException e) {
+ ipw.println(" Failed to dump client:" + e);
+ }
+ ipw.println("<<DumpClientEnd<<");
+ }
+ }
+ ipw.decreaseIndent();
+ }
+ }
+
private static final class ClientDeathRecipient implements IBinder.DeathRecipient {
private final PerUserData mPerUserData;
private final IInputMethodClient mClient;
@@ -1106,6 +1200,16 @@
}
return Collections.singletonList(info);
}
+
+ @AnyThread
+ void dump(FileDescriptor fd, IndentingPrintWriter ipw, String[] args) {
+ synchronized (mArray) {
+ for (int i = 0; i < mArray.size(); i++) {
+ ipw.println("userId=" + mArray.keyAt(i));
+ ipw.println(" InputMethodInfo=" + mArray.valueAt(i));
+ }
+ }
+ }
}
/**
@@ -1601,5 +1705,19 @@
@Nullable FileDescriptor err, String[] args, @Nullable ShellCallback callback,
ResultReceiver resultReceiver) {
}
+
+ @BinderThread
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+ final String prefixChild = " ";
+ pw.println("Current Multi Client Input Method Manager state:");
+ IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
+ ipw.println("mUserDataMap=");
+ if (mUserDataMap != null) {
+ ipw.increaseIndent();
+ mUserDataMap.dump(fd, ipw, args);
+ }
+ }
}
}