summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ioana Stefan <ioanastefan@google.com> 2020-11-17 15:18:30 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-11-17 15:18:30 +0000
commit06f759835a1d4384b4dfc7fa20b7adb2e9d07828 (patch)
treeaae31b29a620cfcb9b86c94ccafb2cc2742b84ee
parent781e61d2c9fc7d8dd3f6a722d481b101a1e9cca8 (diff)
parent45296595a3c1c969e4ee801303349cf9e8f03d36 (diff)
Merge changes from topics "ime-tracing-interface", "optimized-ime-tracing-clients", "optimized-ime-tracing-imms", "optimized-ime-tracing-ims"
* changes: Log only current client data in IME tracing Optimized workflow for IME tracing on InputMethodManagerService side Optimized workflow for IME tracing on InputMethodService side Optimized workflow for IME tracing on clients side
-rw-r--r--core/java/android/inputmethodservice/AbstractInputMethodService.java9
-rw-r--r--core/java/android/inputmethodservice/IInputMethodWrapper.java17
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java21
-rw-r--r--core/java/android/util/imetracing/ImeTracing.java47
-rw-r--r--core/java/android/util/imetracing/ImeTracingClientImpl.java72
-rw-r--r--core/java/android/util/imetracing/ImeTracingServerImpl.java135
-rw-r--r--core/java/android/view/InsetsAnimationControlImpl.java5
-rw-r--r--core/java/android/view/InsetsController.java29
-rw-r--r--core/java/android/view/InsetsSourceConsumer.java5
-rw-r--r--core/java/android/view/ViewRootImpl.java15
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java36
-rw-r--r--core/java/com/android/internal/view/IInputMethodManager.aidl2
-rw-r--r--core/proto/android/view/inputmethod/inputmethodeditortrace.proto92
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java116
-rw-r--r--services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java4
15 files changed, 397 insertions, 208 deletions
diff --git a/core/java/android/inputmethodservice/AbstractInputMethodService.java b/core/java/android/inputmethodservice/AbstractInputMethodService.java
index cd436374b489..7cf0b10031ac 100644
--- a/core/java/android/inputmethodservice/AbstractInputMethodService.java
+++ b/core/java/android/inputmethodservice/AbstractInputMethodService.java
@@ -21,6 +21,7 @@ import android.annotation.NonNull;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
+import android.util.proto.ProtoOutputStream;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.inputmethod.InputConnection;
@@ -195,15 +196,13 @@ public abstract class AbstractInputMethodService extends Service
public abstract AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface();
/**
- * Dumps the internal state of IME to a protocol buffer output stream initialized using the
- * given {@link FileDescriptor}.
+ * Dumps the internal state of IME to a protocol buffer output stream.
*
- * @param fd The file descriptor to which proto dump should be written.
- * @param args The arguments passed to the dump method.
+ * @param proto ProtoOutputStream to dump data to.
* @hide
*/
@SuppressWarnings("HiddenAbstractMethod")
- abstract void dumpProtoInternal(FileDescriptor fd, String[] args);
+ public abstract void dumpProtoInternal(ProtoOutputStream proto);
/**
* Implement this to handle {@link android.os.Binder#dump Binder.dump()}
diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java
index 3d1755e9b017..5cfcd667632b 100644
--- a/core/java/android/inputmethodservice/IInputMethodWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java
@@ -16,8 +16,6 @@
package android.inputmethodservice;
-import static android.util.imetracing.ImeTracing.PROTO_ARG;
-
import android.annotation.BinderThread;
import android.annotation.MainThread;
import android.annotation.Nullable;
@@ -157,20 +155,9 @@ class IInputMethodWrapper extends IInputMethod.Stub
return;
}
SomeArgs args = (SomeArgs)msg.obj;
- String[] dumpArgs = (String[]) args.arg3;
- boolean protoDumpRequested = false;
- for (String arg : dumpArgs) {
- if (arg.equals(PROTO_ARG)) {
- protoDumpRequested = true;
- break;
- }
- }
try {
- if (protoDumpRequested) {
- target.dumpProtoInternal((FileDescriptor) args.arg1, dumpArgs);
- } else {
- target.dump((FileDescriptor) args.arg1, (PrintWriter) args.arg2, dumpArgs);
- }
+ target.dump((FileDescriptor) args.arg1,
+ (PrintWriter) args.arg2, (String[]) args.arg3);
} catch (RuntimeException e) {
((PrintWriter)args.arg2).println("Exception: " + e);
}
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index abc2a69a8dee..ae260e16806f 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -90,6 +90,7 @@ import android.text.method.MovementMethod;
import android.util.Log;
import android.util.PrintWriterPrinter;
import android.util.Printer;
+import android.util.imetracing.ImeTracing;
import android.util.proto.ProtoOutputStream;
import android.view.Gravity;
import android.view.KeyCharacterMap;
@@ -116,6 +117,7 @@ import android.view.inputmethod.InputBinding;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputContentInfo;
import android.view.inputmethod.InputMethod;
+import android.view.inputmethod.InputMethodEditorTraceProto.InputMethodServiceTraceProto;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;
import android.widget.FrameLayout;
@@ -708,6 +710,8 @@ public class InputMethodService extends AbstractInputMethodService {
+ " Use requestHideSelf(int) itself");
return;
}
+ ImeTracing.getInstance().triggerServiceDump(
+ "InputMethodService.InputMethodImpl#hideSoftInput", InputMethodService.this);
final boolean wasVisible = isInputViewShown();
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.hideSoftInput");
@@ -762,6 +766,8 @@ public class InputMethodService extends AbstractInputMethodService {
Binder.disableTracing();
}
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.showSoftInput");
+ ImeTracing.getInstance().triggerServiceDump(
+ "InputMethodService.InputMethodImpl#showSoftInput", InputMethodService.this);
final boolean wasVisible = isInputViewShown();
if (dispatchOnShowInputRequested(flags, false)) {
@@ -2133,6 +2139,8 @@ public class InputMethodService extends AbstractInputMethodService {
return;
}
+ ImeTracing.getInstance().triggerServiceDump("InputMethodService#showWindow", this);
+
mDecorViewWasVisible = mDecorViewVisible;
mInShowWindow = true;
final int previousImeWindowStatus =
@@ -2207,6 +2215,8 @@ public class InputMethodService extends AbstractInputMethodService {
* @param setVisible {@code true} to make it visible, false to hide it.
*/
private void applyVisibilityInInsetsConsumerIfNecessary(boolean setVisible) {
+ ImeTracing.getInstance().triggerServiceDump(
+ "InputMethodService#applyVisibilityInInsetsConsumerIfNecessary", this);
mPrivOps.applyImeVisibility(setVisible
? mCurShowInputToken : mCurHideInputToken, setVisible);
}
@@ -2231,6 +2241,7 @@ public class InputMethodService extends AbstractInputMethodService {
public void hideWindow() {
if (DEBUG) Log.v(TAG, "CALL: hideWindow");
+ ImeTracing.getInstance().triggerServiceDump("InputMethodService#hideWindow", this);
mWindowVisible = false;
finishViews(false /* finishingInput */);
if (mDecorViewVisible) {
@@ -2301,6 +2312,7 @@ public class InputMethodService extends AbstractInputMethodService {
void doFinishInput() {
if (DEBUG) Log.v(TAG, "CALL: doFinishInput");
+ ImeTracing.getInstance().triggerServiceDump("InputMethodService#doFinishInput", this);
finishViews(true /* finishingInput */);
if (mInputStarted) {
mInlineSuggestionSessionController.notifyOnFinishInput();
@@ -2316,6 +2328,7 @@ public class InputMethodService extends AbstractInputMethodService {
if (!restarting) {
doFinishInput();
}
+ ImeTracing.getInstance().triggerServiceDump("InputMethodService#doStartInput", this);
mInputStarted = true;
mStartedInputConnection = ic;
mInputEditorInfo = attribute;
@@ -2474,6 +2487,7 @@ public class InputMethodService extends AbstractInputMethodService {
* @param flags Provides additional operating flags.
*/
public void requestHideSelf(int flags) {
+ ImeTracing.getInstance().triggerServiceDump("InputMethodService#requestHideSelf", this);
mPrivOps.hideMySoftInput(flags);
}
@@ -2486,6 +2500,7 @@ public class InputMethodService extends AbstractInputMethodService {
* @param flags Provides additional operating flags.
*/
public final void requestShowSelf(int flags) {
+ ImeTracing.getInstance().triggerServiceDump("InputMethodService#requestShowSelf", this);
mPrivOps.showMySoftInput(flags);
}
@@ -3305,8 +3320,8 @@ public class InputMethodService extends AbstractInputMethodService {
* @hide
*/
@Override
- final void dumpProtoInternal(FileDescriptor fd, String[] args) {
- final ProtoOutputStream proto = new ProtoOutputStream(fd);
+ public final void dumpProtoInternal(ProtoOutputStream proto) {
+ final long token = proto.start(InputMethodServiceTraceProto.INPUT_METHOD_SERVICE);
mWindow.dumpDebug(proto, SOFT_INPUT_WINDOW);
proto.write(VIEWS_CREATED, mViewsCreated);
proto.write(DECOR_VIEW_VISIBLE, mDecorViewVisible);
@@ -3334,6 +3349,6 @@ public class InputMethodService extends AbstractInputMethodService {
proto.write(STATUS_ICON, mStatusIcon);
mTmpInsets.dumpDebug(proto, LAST_COMPUTED_INSETS);
proto.write(SETTINGS_OBSERVER, Objects.toString(mSettingsObserver));
- proto.flush();
+ proto.end(token);
}
}
diff --git a/core/java/android/util/imetracing/ImeTracing.java b/core/java/android/util/imetracing/ImeTracing.java
index 865d5608a40a..443719100643 100644
--- a/core/java/android/util/imetracing/ImeTracing.java
+++ b/core/java/android/util/imetracing/ImeTracing.java
@@ -18,12 +18,14 @@ package android.util.imetracing;
import android.app.ActivityThread;
import android.content.Context;
+import android.inputmethodservice.AbstractInputMethodService;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
import android.os.ShellCommand;
import android.util.Log;
import android.util.proto.ProtoOutputStream;
+import android.view.inputmethod.InputMethodManager;
import com.android.internal.view.IInputMethodManager;
@@ -40,10 +42,18 @@ public abstract class ImeTracing {
static final String TAG = "imeTracing";
public static final String PROTO_ARG = "--proto-com-android-imetracing";
+ /* Constants describing the component type that triggered a dump. */
+ public static final int IME_TRACING_FROM_CLIENT = 0;
+ public static final int IME_TRACING_FROM_IMS = 1;
+ public static final int IME_TRACING_FROM_IMMS = 2;
+
private static ImeTracing sInstance;
static boolean sEnabled = false;
IInputMethodManager mService;
+ protected boolean mDumpInProgress;
+ protected final Object mDumpInProgressLock = new Object();
+
ImeTracing() throws ServiceNotFoundException {
mService = IInputMethodManager.Stub.asInterface(
ServiceManager.getServiceOrThrow(Context.INPUT_METHOD_SERVICE));
@@ -69,15 +79,22 @@ public abstract class ImeTracing {
}
/**
- * Sends request to start proto dump to {@link ImeTracingServerImpl} when called from a
- * server process and to {@link ImeTracingClientImpl} when called from a client process.
+ * Transmits the information from client or InputMethodService side to the server, in order to
+ * be stored persistently to the current IME tracing dump.
+ *
+ * @param protoDump client or service side information to be stored by the server
+ * @param source where the information is coming from, refer to {@see #IME_TRACING_FROM_CLIENT}
+ * and {@see #IME_TRACING_FROM_IMS}
+ * @param where
*/
- public abstract void triggerDump();
+ public void sendToService(byte[] protoDump, int source, String where) throws RemoteException {
+ mService.startProtoDump(protoDump, source, where);
+ }
/**
* @param proto dump to be added to the buffer
*/
- public abstract void addToBuffer(ProtoOutputStream proto);
+ public abstract void addToBuffer(ProtoOutputStream proto, int source);
/**
* @param shell The shell command to process
@@ -86,6 +103,28 @@ public abstract class ImeTracing {
public abstract int onShellCommand(ShellCommand shell);
/**
+ * Starts a proto dump of the client side information.
+ *
+ * @param where Place where the trace was triggered.
+ * @param immInstance The {@link InputMethodManager} instance to dump.
+ */
+ public abstract void triggerClientDump(String where, InputMethodManager immInstance);
+
+ /**
+ * Starts a proto dump of the currently connected InputMethodService information.
+ *
+ * @param where Place where the trace was triggered.
+ */
+ public abstract void triggerServiceDump(String where, AbstractInputMethodService service);
+
+ /**
+ * Starts a proto dump of the InputMethodManagerService information.
+ *
+ * @param where Place where the trace was triggered.
+ */
+ public abstract void triggerManagerServiceDump(String where);
+
+ /**
* Sets whether ime tracing is enabled.
*
* @param enabled Tells whether ime tracing should be enabled or disabled.
diff --git a/core/java/android/util/imetracing/ImeTracingClientImpl.java b/core/java/android/util/imetracing/ImeTracingClientImpl.java
index e5d7d3380d02..206006e79486 100644
--- a/core/java/android/util/imetracing/ImeTracingClientImpl.java
+++ b/core/java/android/util/imetracing/ImeTracingClientImpl.java
@@ -16,6 +16,8 @@
package android.util.imetracing;
+import android.annotation.NonNull;
+import android.inputmethodservice.AbstractInputMethodService;
import android.os.RemoteException;
import android.os.ServiceManager.ServiceNotFoundException;
import android.os.ShellCommand;
@@ -27,16 +29,12 @@ import android.view.inputmethod.InputMethodManager;
* @hide
*/
class ImeTracingClientImpl extends ImeTracing {
-
- private boolean mDumpInProgress;
- private final Object mDumpInProgressLock = new Object();
-
ImeTracingClientImpl() throws ServiceNotFoundException, RemoteException {
sEnabled = mService.isImeTraceEnabled();
}
@Override
- public void addToBuffer(ProtoOutputStream proto) {
+ public void addToBuffer(ProtoOutputStream proto, int source) {
}
@Override
@@ -45,27 +43,55 @@ class ImeTracingClientImpl extends ImeTracing {
}
@Override
- public void triggerDump() {
- if (isAvailable() && isEnabled()) {
- boolean doDump = false;
- synchronized (mDumpInProgressLock) {
- if (!mDumpInProgress) {
- mDumpInProgress = true;
- doDump = true;
- }
+ public void triggerClientDump(String where, @NonNull InputMethodManager immInstance) {
+ if (!isEnabled() || !isAvailable()) {
+ return;
+ }
+
+ synchronized (mDumpInProgressLock) {
+ if (mDumpInProgress) {
+ return;
}
+ mDumpInProgress = true;
+ }
+
+ try {
+ ProtoOutputStream proto = new ProtoOutputStream();
+ immInstance.dumpDebug(proto);
+ sendToService(proto.getBytes(), IME_TRACING_FROM_CLIENT, where);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception while sending ime-related client dump to server", e);
+ } finally {
+ mDumpInProgress = false;
+ }
+ }
- if (doDump) {
- try {
- ProtoOutputStream proto = new ProtoOutputStream();
- InputMethodManager.dumpProto(proto);
- mService.startProtoDump(proto.getBytes());
- } catch (RemoteException e) {
- Log.e(TAG, "Exception while sending ime-related client dump to server", e);
- } finally {
- mDumpInProgress = false;
- }
+ @Override
+ public void triggerServiceDump(String where, @NonNull AbstractInputMethodService service) {
+ if (!isEnabled() || !isAvailable()) {
+ return;
+ }
+
+ synchronized (mDumpInProgressLock) {
+ if (mDumpInProgress) {
+ return;
}
+ mDumpInProgress = true;
+ }
+
+ try {
+ ProtoOutputStream proto = new ProtoOutputStream();
+ service.dumpProtoInternal(proto);
+ sendToService(proto.getBytes(), IME_TRACING_FROM_IMS, where);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception while sending ime-related service dump to server", e);
+ } finally {
+ mDumpInProgress = false;
}
}
+
+ @Override
+ public void triggerManagerServiceDump(String where) {
+ // Intentionally left empty, this is implemented in ImeTracingServerImpl
+ }
}
diff --git a/core/java/android/util/imetracing/ImeTracingServerImpl.java b/core/java/android/util/imetracing/ImeTracingServerImpl.java
index 350cf5721148..04452b32d66d 100644
--- a/core/java/android/util/imetracing/ImeTracingServerImpl.java
+++ b/core/java/android/util/imetracing/ImeTracingServerImpl.java
@@ -17,15 +17,17 @@
package android.util.imetracing;
import static android.os.Build.IS_USER;
-import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorTraceFileProto.MAGIC_NUMBER;
-import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorTraceFileProto.MAGIC_NUMBER_H;
-import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorTraceFileProto.MAGIC_NUMBER_L;
+import android.inputmethodservice.AbstractInputMethodService;
import android.os.RemoteException;
import android.os.ServiceManager.ServiceNotFoundException;
import android.os.ShellCommand;
import android.util.Log;
import android.util.proto.ProtoOutputStream;
+import android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceFileProto;
+import android.view.inputmethod.InputMethodEditorTraceProto.InputMethodManagerServiceTraceFileProto;
+import android.view.inputmethod.InputMethodEditorTraceProto.InputMethodServiceTraceFileProto;
+import android.view.inputmethod.InputMethodManager;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.TraceBuffer;
@@ -38,31 +40,68 @@ import java.io.PrintWriter;
* @hide
*/
class ImeTracingServerImpl extends ImeTracing {
- private static final String TRACE_FILENAME = "/data/misc/wmtrace/ime_trace.pb";
+ private static final String TRACE_DIRNAME = "/data/misc/wmtrace/";
+ private static final String TRACE_FILENAME_CLIENTS = "ime_trace_clients.pb";
+ private static final String TRACE_FILENAME_IMS = "ime_trace_service.pb";
+ private static final String TRACE_FILENAME_IMMS = "ime_trace_managerservice.pb";
private static final int BUFFER_CAPACITY = 4096 * 1024;
// Needed for winscope to auto-detect the dump type. Explained further in
- // core.proto.android.view.inputmethod.inputmethodeditortrace.proto
- private static final long MAGIC_NUMBER_VALUE = ((long) MAGIC_NUMBER_H << 32) | MAGIC_NUMBER_L;
+ // core.proto.android.view.inputmethod.inputmethodeditortrace.proto.
+ // This magic number corresponds to InputMethodClientsTraceFileProto.
+ private static final long MAGIC_NUMBER_CLIENTS_VALUE =
+ ((long) InputMethodClientsTraceFileProto.MAGIC_NUMBER_H << 32)
+ | InputMethodClientsTraceFileProto.MAGIC_NUMBER_L;
+ // This magic number corresponds to InputMethodServiceTraceFileProto.
+ private static final long MAGIC_NUMBER_IMS_VALUE =
+ ((long) InputMethodServiceTraceFileProto.MAGIC_NUMBER_H << 32)
+ | InputMethodServiceTraceFileProto.MAGIC_NUMBER_L;
+ // This magic number corresponds to InputMethodManagerServiceTraceFileProto.
+ private static final long MAGIC_NUMBER_IMMS_VALUE =
+ ((long) InputMethodManagerServiceTraceFileProto.MAGIC_NUMBER_H << 32)
+ | InputMethodManagerServiceTraceFileProto.MAGIC_NUMBER_L;
+
+ private final TraceBuffer mBufferClients;
+ private final File mTraceFileClients;
+ private final TraceBuffer mBufferIms;
+ private final File mTraceFileIms;
+ private final TraceBuffer mBufferImms;
+ private final File mTraceFileImms;
- private final TraceBuffer mBuffer;
- private final File mTraceFile;
private final Object mEnabledLock = new Object();
ImeTracingServerImpl() throws ServiceNotFoundException {
- mBuffer = new TraceBuffer<>(BUFFER_CAPACITY);
- mTraceFile = new File(TRACE_FILENAME);
+ mBufferClients = new TraceBuffer<>(BUFFER_CAPACITY);
+ mTraceFileClients = new File(TRACE_DIRNAME + TRACE_FILENAME_CLIENTS);
+ mBufferIms = new TraceBuffer<>(BUFFER_CAPACITY);
+ mTraceFileIms = new File(TRACE_DIRNAME + TRACE_FILENAME_IMS);
+ mBufferImms = new TraceBuffer<>(BUFFER_CAPACITY);
+ mTraceFileImms = new File(TRACE_DIRNAME + TRACE_FILENAME_IMMS);
}
/**
- * The provided dump is added to the current dump buffer {@link ImeTracingServerImpl#mBuffer}.
+ * The provided dump is added to the corresponding dump buffer:
+ * {@link ImeTracingServerImpl#mBufferClients} or {@link ImeTracingServerImpl#mBufferIms}.
*
* @param proto dump to be added to the buffer
*/
@Override
- public void addToBuffer(ProtoOutputStream proto) {
+ public void addToBuffer(ProtoOutputStream proto, int source) {
if (isAvailable() && isEnabled()) {
- mBuffer.add(proto);
+ switch (source) {
+ case IME_TRACING_FROM_CLIENT:
+ mBufferClients.add(proto);
+ return;
+ case IME_TRACING_FROM_IMS:
+ mBufferIms.add(proto);
+ return;
+ case IME_TRACING_FROM_IMMS:
+ mBufferImms.add(proto);
+ return;
+ default:
+ // Source not recognised.
+ Log.w(TAG, "Request to add to buffer, but source not recognised.");
+ }
}
}
@@ -93,21 +132,52 @@ class ImeTracingServerImpl extends ImeTracing {
}
@Override
- public void triggerDump() {
- if (isAvailable() && isEnabled()) {
- try {
- mService.startProtoDump(null);
- } catch (RemoteException e) {
- Log.e(TAG, "Exception while triggering proto dump", e);
+ public void triggerClientDump(String where, InputMethodManager immInstance) {
+ // Intentionally left empty, this is implemented in ImeTracingClientImpl
+ }
+
+ @Override
+ public void triggerServiceDump(String where, AbstractInputMethodService service) {
+ // Intentionally left empty, this is implemented in ImeTracingClientImpl
+ }
+
+ @Override
+ public void triggerManagerServiceDump(String where) {
+ if (!isEnabled() || !isAvailable()) {
+ return;
+ }
+
+ synchronized (mDumpInProgressLock) {
+ if (mDumpInProgress) {
+ return;
}
+ mDumpInProgress = true;
+ }
+
+ try {
+ sendToService(null, IME_TRACING_FROM_IMMS, where);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception while sending ime-related manager service dump to server", e);
+ } finally {
+ mDumpInProgress = false;
}
}
- private void writeTraceToFileLocked() {
+ private void writeTracesToFilesLocked() {
try {
- ProtoOutputStream proto = new ProtoOutputStream();
- proto.write(MAGIC_NUMBER, MAGIC_NUMBER_VALUE);
- mBuffer.writeTraceToFile(mTraceFile, proto);
+ ProtoOutputStream clientsProto = new ProtoOutputStream();
+ clientsProto.write(InputMethodClientsTraceFileProto.MAGIC_NUMBER,
+ MAGIC_NUMBER_CLIENTS_VALUE);
+ mBufferClients.writeTraceToFile(mTraceFileClients, clientsProto);
+
+ ProtoOutputStream imsProto = new ProtoOutputStream();
+ imsProto.write(InputMethodServiceTraceFileProto.MAGIC_NUMBER, MAGIC_NUMBER_IMS_VALUE);
+ mBufferIms.writeTraceToFile(mTraceFileIms, imsProto);
+
+ ProtoOutputStream immsProto = new ProtoOutputStream();
+ immsProto.write(InputMethodManagerServiceTraceFileProto.MAGIC_NUMBER,
+ MAGIC_NUMBER_IMMS_VALUE);
+ mBufferImms.writeTraceToFile(mTraceFileImms, immsProto);
} catch (IOException e) {
Log.e(TAG, "Unable to write buffer to file", e);
}
@@ -126,9 +196,10 @@ class ImeTracingServerImpl extends ImeTracing {
return;
}
- pw.println("Starting tracing to " + mTraceFile + ".");
+ pw.println("Starting tracing in " + TRACE_DIRNAME + ": " + TRACE_FILENAME_CLIENTS
+ + ", " + TRACE_FILENAME_IMS + ", " + TRACE_FILENAME_IMMS);
sEnabled = true;
- mBuffer.resetBuffer();
+ resetBuffers();
}
}
@@ -145,10 +216,18 @@ class ImeTracingServerImpl extends ImeTracing {
return;
}
- pw.println("Stopping tracing and writing traces to " + mTraceFile + ".");
+ pw.println("Stopping tracing and writing traces in " + TRACE_DIRNAME + ": "
+ + TRACE_FILENAME_CLIENTS + ", " + TRACE_FILENAME_IMS + ", "
+ + TRACE_FILENAME_IMMS);
sEnabled = false;
- writeTraceToFileLocked();
- mBuffer.resetBuffer();
+ writeTracesToFilesLocked();
+ resetBuffers();
}
}
+
+ private void resetBuffers() {
+ mBufferClients.resetBuffer();
+ mBufferIms.resetBuffer();
+ mBufferImms.resetBuffer();
+ }
}
diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java
index 06ddf3c69f8e..75dc0c43085d 100644
--- a/core/java/android/view/InsetsAnimationControlImpl.java
+++ b/core/java/android/view/InsetsAnimationControlImpl.java
@@ -47,7 +47,6 @@ import android.util.Log;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.util.SparseSetArray;
-import android.util.imetracing.ImeTracing;
import android.util.proto.ProtoOutputStream;
import android.view.InsetsState.InternalInsetsSide;
import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams;
@@ -136,10 +135,6 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
mTranslator = translator;
mController.startAnimation(this, listener, types, mAnimation,
new Bounds(mHiddenInsets, mShownInsets));
-
- if ((mTypes & WindowInsets.Type.ime()) != 0) {
- ImeTracing.getInstance().triggerDump();
- }
}
private boolean calculatePerceptible(Insets currentInsets, float currentAlpha) {
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index bcb3a36ebe2c..1c82619a61ad 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -312,10 +312,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
@Override
public void onReady(WindowInsetsAnimationController controller, int types) {
- if ((types & ime()) != 0) {
- ImeTracing.getInstance().triggerDump();
- }
-
mController = controller;
if (DEBUG) Log.d(TAG, "default animation onReady types: " + types);
@@ -832,7 +828,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
Log.d(TAG, "show(ime(), fromIme=" + fromIme + ")");
}
if (fromIme) {
- ImeTracing.getInstance().triggerDump();
+ ImeTracing.getInstance().triggerClientDump("InsetsController#show",
+ mHost.getInputMethodManager());
Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApiToImeReady", 0);
Trace.asyncTraceBegin(TRACE_TAG_VIEW, "IC.showRequestFromIme", 0);
} else {
@@ -888,7 +885,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
void hide(@InsetsType int types, boolean fromIme) {
if (fromIme) {
- ImeTracing.getInstance().triggerDump();
+ ImeTracing.getInstance().triggerClientDump("InsetsController#hide",
+ mHost.getInputMethodManager());
Trace.asyncTraceBegin(TRACE_TAG_VIEW, "IC.hideRequestFromIme", 0);
} else {
Trace.asyncTraceBegin(TRACE_TAG_VIEW, "IC.hideRequestFromApi", 0);
@@ -928,7 +926,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
return;
}
if (fromIme) {
- ImeTracing.getInstance().triggerDump();
+ ImeTracing.getInstance().triggerClientDump(
+ "InsetsController#controlWindowInsetsAnimation",
+ mHost.getInputMethodManager());
}
controlAnimationUnchecked(types, cancellationSignal, listener, mFrame, fromIme, durationMs,
@@ -1020,6 +1020,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
: new InsetsAnimationControlImpl(controls,
frame, mState, listener, typesReady, this, durationMs, interpolator,
animationType, mHost.getTranslator());
+ if ((typesReady & WindowInsets.Type.ime()) != 0) {
+ ImeTracing.getInstance().triggerClientDump("InsetsAnimationControlImpl",
+ mHost.getInputMethodManager());
+ }
mRunningAnimations.add(new RunningAnimation(runner, animationType));
if (DEBUG) Log.d(TAG, "Animation added to runner. useInsetsAnimationThread: "
+ useInsetsAnimationThread);
@@ -1193,6 +1197,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
mRunningAnimations.remove(i);
ArraySet<Integer> types = toInternalType(control.getTypes());
for (int j = types.size() - 1; j >= 0; j--) {
+ if (types.valueAt(j) == ITYPE_IME) {
+ ImeTracing.getInstance().triggerClientDump(
+ "InsetsSourceConsumer#notifyAnimationFinished",
+ mHost.getInputMethodManager());
+ }
stateChanged |= getSourceConsumer(types.valueAt(j)).notifyAnimationFinished();
}
if (invokeCallback && runningAnimation.startDispatched) {
@@ -1335,7 +1344,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
@InsetsType int types, boolean animationFinished, @AnimationType int animationType,
boolean fromIme) {
if ((types & ime()) != 0) {
- ImeTracing.getInstance().triggerDump();
+ ImeTracing.getInstance().triggerClientDump("InsetsController#hideDirectly",
+ mHost.getInputMethodManager());
}
final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types);
for (int i = internalTypes.size() - 1; i >= 0; i--) {
@@ -1350,7 +1360,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
private void showDirectly(@InsetsType int types, boolean fromIme) {
if ((types & ime()) != 0) {
- ImeTracing.getInstance().triggerDump();
+ ImeTracing.getInstance().triggerClientDump("InsetsController#showDirectly",
+ mHost.getInputMethodManager());
}
final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types);
for (int i = internalTypes.size() - 1; i >= 0; i--) {
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index e4a24ebfe9e4..537fd42d7135 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -25,7 +25,6 @@ import static android.view.InsetsSourceConsumerProto.IS_REQUESTED_VISIBLE;
import static android.view.InsetsSourceConsumerProto.PENDING_FRAME;
import static android.view.InsetsSourceConsumerProto.PENDING_VISIBLE_FRAME;
import static android.view.InsetsSourceConsumerProto.SOURCE_CONTROL;
-import static android.view.InsetsState.ITYPE_IME;
import static android.view.InsetsState.getDefaultVisibility;
import static android.view.InsetsState.toPublicType;
@@ -35,7 +34,6 @@ import android.annotation.IntDef;
import android.annotation.Nullable;
import android.graphics.Rect;
import android.util.Log;
-import android.util.imetracing.ImeTracing;
import android.util.proto.ProtoOutputStream;
import android.view.InsetsState.InternalInsetsType;
import android.view.SurfaceControl.Transaction;
@@ -328,9 +326,6 @@ public class InsetsSourceConsumer {
@VisibleForTesting(visibility = PACKAGE)
public boolean notifyAnimationFinished() {
- if (mType == ITYPE_IME) {
- ImeTracing.getInstance().triggerDump();
- }
if (mPendingFrame != null) {
InsetsSource source = mState.getSource(mType);
source.setFrame(mPendingFrame);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index c0770063beea..33a1f228e2ad 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -79,8 +79,8 @@ import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
-import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorProto.ClientSideProto.IME_FOCUS_CONTROLLER;
-import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorProto.ClientSideProto.INSETS_CONTROLLER;
+import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.IME_FOCUS_CONTROLLER;
+import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.INSETS_CONTROLLER;
import android.Manifest;
import android.animation.LayoutTransition;
@@ -9221,10 +9221,11 @@ public final class ViewRootImpl implements ViewParent,
@Override
public void showInsets(@InsetsType int types, boolean fromIme) {
+ final ViewRootImpl viewAncestor = mViewAncestor.get();
if (fromIme) {
- ImeTracing.getInstance().triggerDump();
+ ImeTracing.getInstance().triggerClientDump("ViewRootImpl.W#showInsets",
+ viewAncestor.getInsetsController().getHost().getInputMethodManager());
}
- final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {
viewAncestor.showInsets(types, fromIme);
}
@@ -9232,10 +9233,12 @@ public final class ViewRootImpl implements ViewParent,
@Override
public void hideInsets(@InsetsType int types, boolean fromIme) {
+
+ final ViewRootImpl viewAncestor = mViewAncestor.get();
if (fromIme) {
- ImeTracing.getInstance().triggerDump();
+ ImeTracing.getInstance().triggerClientDump("ViewRootImpl.W#hideInsets",
+ viewAncestor.getInsetsController().getHost().getInputMethodManager());
}
- final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {
viewAncestor.hideInsets(types, fromIme);
}
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index f1cbd2533a5a..3c89a4bfad59 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -19,12 +19,11 @@ package android.view.inputmethod;
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
import static android.util.imetracing.ImeTracing.PROTO_ARG;
-import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorProto.ClientSideProto.DISPLAY_ID;
-import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorProto.ClientSideProto.EDITOR_INFO;
-import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorProto.ClientSideProto.IME_INSETS_SOURCE_CONSUMER;
-import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorProto.ClientSideProto.INPUT_METHOD_MANAGER;
-import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorProto.ClientSideProto.VIEW_ROOT_IMPL;
-import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorProto.ClientsProto.CLIENT;
+import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.DISPLAY_ID;
+import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.EDITOR_INFO;
+import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.IME_INSETS_SOURCE_CONSUMER;
+import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.INPUT_METHOD_MANAGER;
+import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.VIEW_ROOT_IMPL;
import static android.view.inputmethod.InputMethodManagerProto.ACTIVE;
import static android.view.inputmethod.InputMethodManagerProto.CUR_ID;
import static android.view.inputmethod.InputMethodManagerProto.FULLSCREEN_MODE;
@@ -576,7 +575,8 @@ public final class InputMethodManager {
@StartInputFlags int startInputFlags, @SoftInputModeFlags int softInputMode,
int windowFlags) {
final View servedView;
- ImeTracing.getInstance().triggerDump();
+ ImeTracing.getInstance().triggerClientDump(
+ "InputMethodManager.DelegateImpl#startInput", InputMethodManager.this);
synchronized (mH) {
mCurrentTextBoxAttribute = null;
mCompletions = null;
@@ -1662,7 +1662,7 @@ public final class InputMethodManager {
* {@link #RESULT_HIDDEN}.
*/
public boolean showSoftInput(View view, int flags, ResultReceiver resultReceiver) {
- ImeTracing.getInstance().triggerDump();
+ ImeTracing.getInstance().triggerClientDump("InputMethodManager#showSoftInput", this);
// Re-dispatch if there is a context mismatch.
final InputMethodManager fallbackImm = getFallbackInputMethodManagerIfNecessary(view);
if (fallbackImm != null) {
@@ -1770,7 +1770,8 @@ public final class InputMethodManager {
*/
public boolean hideSoftInputFromWindow(IBinder windowToken, int flags,
ResultReceiver resultReceiver) {
- ImeTracing.getInstance().triggerDump();
+ ImeTracing.getInstance().triggerClientDump("InputMethodManager#hideSoftInputFromWindow",
+ this);
checkFocus();
synchronized (mH) {
final View servedView = getServedViewLocked();
@@ -3240,7 +3241,7 @@ public final class InputMethodManager {
for (String arg : args) {
if (arg.equals(PROTO_ARG)) {
final ProtoOutputStream proto = new ProtoOutputStream(fd);
- dumpProto(proto);
+ dumpDebug(proto);
proto.flush();
return true;
}
@@ -3249,19 +3250,6 @@ public final class InputMethodManager {
}
/**
- * Write the proto dump for all displays associated with this client.
- *
- * @param proto The proto stream to which the dumps are written.
- * @hide
- */
- public static void dumpProto(ProtoOutputStream proto) {
- for (int i = sInstanceMap.size() - 1; i >= 0; i--) {
- InputMethodManager imm = sInstanceMap.valueAt(i);
- imm.dumpDebug(proto);
- }
- }
-
- /**
* Write the proto dump of various client side components to the provided
* {@link ProtoOutputStream}.
*
@@ -3274,7 +3262,6 @@ public final class InputMethodManager {
return;
}
- final long clientDumpToken = proto.start(CLIENT);
proto.write(DISPLAY_ID, mDisplayId);
final long token = proto.start(INPUT_METHOD_MANAGER);
synchronized (mH) {
@@ -3293,6 +3280,5 @@ public final class InputMethodManager {
mImeInsetsConsumer.dumpDebug(proto, IME_INSETS_SOURCE_CONSUMER);
}
}
- proto.end(clientDumpToken);
}
}
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 5a06273bb173..844c56bd3529 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -77,6 +77,6 @@ interface IInputMethodManager {
void removeImeSurface();
/** Remove the IME surface. Requires passing the currently focused window. */
void removeImeSurfaceFromWindow(in IBinder windowToken);
- void startProtoDump(in byte[] clientProtoDump);
+ void startProtoDump(in byte[] protoDump, int source, String where);
boolean isImeTraceEnabled();
}
diff --git a/core/proto/android/view/inputmethod/inputmethodeditortrace.proto b/core/proto/android/view/inputmethod/inputmethodeditortrace.proto
index 856d8da1a1ea..5c0f341cb9e4 100644
--- a/core/proto/android/view/inputmethod/inputmethodeditortrace.proto
+++ b/core/proto/android/view/inputmethod/inputmethodeditortrace.proto
@@ -30,40 +30,36 @@ import "frameworks/base/core/proto/android/server/inputmethod/inputmethodmanager
import "frameworks/base/core/proto/android/inputmethodservice/inputmethodservice.proto";
/**
- * Represents a file full of input method editor trace entries.
- * Encoded, it should start with 0x9 0x49 0x4d 0x45 0x54 0x52 0x41 0x43 0x45 (.IMETRACE), such
+ * Represents a file full of trace entries for clients that use InputMethod.
+ * Encoded, it should start with 0x9 0x49 0x4d 0x43 0x54 0x52 0x41 0x43 0x45 (.IMCTRACE), such
* that they can be easily identified.
*/
-message InputMethodEditorTraceFileProto {
+message InputMethodClientsTraceFileProto {
/* constant; MAGIC_NUMBER = (long) MAGIC_NUMBER_H << 32 | MagicNumber.MAGIC_NUMBER_L
(this is needed because enums have to be 32 bits and there's no nice way to put 64bit
constants into .proto files.) */
enum MagicNumber {
INVALID = 0;
- MAGIC_NUMBER_L = 0x54454d49; /* IMET (little-endian ASCII) */
+ MAGIC_NUMBER_L = 0x54434d49; /* IMCT (little-endian ASCII) */
MAGIC_NUMBER_H = 0x45434152; /* RACE (little-endian ASCII) */
}
/* Must be the first field to allow winscope to auto-detect the dump type. Set to value
in MagicNumber */
optional fixed64 magic_number = 1;
- repeated InputMethodEditorProto entry = 2;
+ repeated InputMethodClientsTraceProto entry = 2;
}
-/* one input method editor dump entry. */
-message InputMethodEditorProto {
-
+/* One dump entry for clients that use InputMethod. */
+message InputMethodClientsTraceProto {
/* required: elapsed realtime in nanos since boot of when this entry was logged */
optional fixed64 elapsed_realtime_nanos = 1;
- optional ClientsProto clients = 2;
- optional .android.inputmethodservice.InputMethodServiceProto input_method_service = 3;
- optional .android.server.inputmethod.InputMethodManagerServiceProto input_method_manager_service = 4;
- // this wrapper helps to simplify the dumping logic
- message ClientsProto {
- repeated ClientSideProto client = 1;
- }
+ /* where the trace originated */
+ optional string where = 2;
+
+ optional ClientSideProto client = 3;
/* groups together the dump from ime related client side classes */
message ClientSideProto {
@@ -75,4 +71,70 @@ message InputMethodEditorProto {
optional EditorInfoProto editor_info = 6;
optional ImeFocusControllerProto ime_focus_controller = 7;
}
+}
+
+/**
+ * Represents a file full of InputMethodService trace entries.
+ * Encoded, it should start with 0x9 0x49 0x4d 0x53 0x54 0x52 0x41 0x43 0x45 (.IMSTRACE), such
+ * that they can be easily identified.
+ */
+message InputMethodServiceTraceFileProto {
+
+ /* constant; MAGIC_NUMBER = (long) MAGIC_NUMBER_H << 32 | MagicNumber.MAGIC_NUMBER_L
+ (this is needed because enums have to be 32 bits and there's no nice way to put 64bit
+ constants into .proto files.) */
+ enum MagicNumber {
+ INVALID = 0;
+ MAGIC_NUMBER_L = 0x54534d49; /* IMST (little-endian ASCII) */
+ MAGIC_NUMBER_H = 0x45434152; /* RACE (little-endian ASCII) */
+ }
+
+ /* Must be the first field to allow winscope to auto-detect the dump type. Set to value
+ in MagicNumber */
+ optional fixed64 magic_number = 1;
+ repeated InputMethodServiceTraceProto entry = 2;
+}
+
+/* One dump entry for InputMethodService. */
+message InputMethodServiceTraceProto {
+ /* required: elapsed realtime in nanos since boot of when this entry was logged */
+ optional fixed64 elapsed_realtime_nanos = 1;
+
+ /* where the trace originated */
+ optional string where = 2;
+
+ optional .android.inputmethodservice.InputMethodServiceProto input_method_service = 3;
+}
+
+/**
+ * Represents a file full of InputMethodManagerService trace entries.
+ * Encoded, it should start with 0x9 0x49 0x4d 0x4d 0x54 0x52 0x41 0x43 0x45 (.IMMTRACE), such
+ * that they can be easily identified.
+ */
+message InputMethodManagerServiceTraceFileProto {
+
+ /* constant; MAGIC_NUMBER = (long) MAGIC_NUMBER_H << 32 | MagicNumber.MAGIC_NUMBER_L
+ (this is needed because enums have to be 32 bits and there's no nice way to put 64bit
+ constants into .proto files.) */
+ enum MagicNumber {
+ INVALID = 0;
+ MAGIC_NUMBER_L = 0x544d4d49; /* IMMT (little-endian ASCII) */
+ MAGIC_NUMBER_H = 0x45434152; /* RACE (little-endian ASCII) */
+ }
+
+ /* Must be the first field to allow winscope to auto-detect the dump type. Set to value
+ in MagicNumber */
+ optional fixed64 magic_number = 1;
+ repeated InputMethodManagerServiceTraceProto entry = 2;
+}
+
+/* One dump entry for InputMethodManagerService. */
+message InputMethodManagerServiceTraceProto {
+ /* required: elapsed realtime in nanos since boot of when this entry was logged */
+ optional fixed64 elapsed_realtime_nanos = 1;
+
+ /* where the trace originated */
+ optional string where = 2;
+
+ optional .android.server.inputmethod.InputMethodManagerServiceProto input_method_manager_service = 3;
} \ No newline at end of file
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 6dd91e533a87..889061b71ee6 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -40,13 +40,9 @@ import static android.server.inputmethod.InputMethodManagerServiceProto.SHOW_FOR
import static android.server.inputmethod.InputMethodManagerServiceProto.SHOW_IME_WITH_HARD_KEYBOARD;
import static android.server.inputmethod.InputMethodManagerServiceProto.SHOW_REQUESTED;
import static android.server.inputmethod.InputMethodManagerServiceProto.SYSTEM_READY;
+import static android.util.imetracing.ImeTracing.IME_TRACING_FROM_IMMS;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
-import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorProto.CLIENTS;
-import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorProto.ELAPSED_REALTIME_NANOS;
-import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorProto.INPUT_METHOD_MANAGER_SERVICE;
-import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorProto.INPUT_METHOD_SERVICE;
-import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorTraceFileProto.ENTRY;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -97,7 +93,6 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
-import android.os.HandlerThread;
import android.os.IBinder;
import android.os.IInterface;
import android.os.LocaleList;
@@ -145,6 +140,12 @@ import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputConnectionInspector;
import android.view.inputmethod.InputConnectionInspector.MissingMethodFlags;
import android.view.inputmethod.InputMethod;
+import android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceFileProto;
+import android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto;
+import android.view.inputmethod.InputMethodEditorTraceProto.InputMethodManagerServiceTraceFileProto;
+import android.view.inputmethod.InputMethodEditorTraceProto.InputMethodManagerServiceTraceProto;
+import android.view.inputmethod.InputMethodEditorTraceProto.InputMethodServiceTraceFileProto;
+import android.view.inputmethod.InputMethodEditorTraceProto.InputMethodServiceTraceProto;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;
@@ -734,8 +735,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
private final IPackageManager mIPackageManager;
private final String mSlotIme;
- private HandlerThread mTracingThread;
-
/**
* Registered {@link InputMethodListListener}.
* This variable can be accessed from both of MainThread and BinderThread.
@@ -1707,9 +1706,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mSwitchingController = InputMethodSubtypeSwitchingController.createInstanceLocked(
mSettings, context);
mMenuController = new InputMethodMenuController(this);
-
- mTracingThread = new HandlerThread("android.tracing", Process.THREAD_PRIORITY_FOREGROUND);
- mTracingThread.start();
}
private void resetDefaultImeLocked(Context context) {
@@ -3110,6 +3106,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
ResultReceiver resultReceiver) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.showSoftInput");
int uid = Binder.getCallingUid();
+ ImeTracing.getInstance().triggerManagerServiceDump(
+ "InputMethodManagerService#showSoftInput");
synchronized (mMethodMap) {
if (!calledFromValidUserLocked()) {
return false;
@@ -3223,6 +3221,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
public boolean hideSoftInput(IInputMethodClient client, IBinder windowToken, int flags,
ResultReceiver resultReceiver) {
int uid = Binder.getCallingUid();
+ ImeTracing.getInstance().triggerManagerServiceDump(
+ "InputMethodManagerService#hideSoftInput");
synchronized (mMethodMap) {
if (!calledFromValidUserLocked()) {
return false;
@@ -3319,6 +3319,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
"IMMS.startInputOrWindowGainedFocus");
+ ImeTracing.getInstance().triggerManagerServiceDump(
+ "InputMethodManagerService#startInputOrWindowGainedFocus");
final int callingUserId = UserHandle.getCallingUserId();
final int userId;
if (attribute != null && attribute.targetInputMethodUser != null
@@ -4019,58 +4021,48 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@BinderThread
@Override
@GuardedBy("mMethodMap")
- public void startProtoDump(byte[] clientProtoDump) {
- mTracingThread.getThreadHandler().post(() -> {
- if (!ImeTracing.getInstance().isAvailable() || !ImeTracing.getInstance().isEnabled()) {
- return;
- }
- if (clientProtoDump == null && mCurClient == null) {
- return;
- }
-
- ProtoOutputStream proto = new ProtoOutputStream();
- final long token = proto.start(ENTRY);
- proto.write(ELAPSED_REALTIME_NANOS, SystemClock.elapsedRealtimeNanos());
- dumpDebug(proto, INPUT_METHOD_MANAGER_SERVICE);
-
- IBinder service = null;
- synchronized (mMethodMap) {
- if (mCurMethod != null) {
- service = mCurMethod.asBinder();
- }
- }
-
- if (service != null) {
- try {
- proto.write(INPUT_METHOD_SERVICE,
- TransferPipe.dumpAsync(service, ImeTracing.PROTO_ARG));
- } catch (IOException | RemoteException e) {
- Log.e(TAG, "Exception while collecting ime process dump", e);
- }
- }
-
- if (clientProtoDump != null) {
- proto.write(CLIENTS, clientProtoDump);
- } else {
- IBinder client = null;
- synchronized (mMethodMap) {
- if (mCurClient != null && mCurClient.client != null) {
- client = mCurClient.client.asBinder();
- }
- }
+ public void startProtoDump(byte[] protoDump, int source, String where) {
+ if (protoDump == null && source != IME_TRACING_FROM_IMMS) {
+ // Dump not triggered from IMMS, but no proto information provided.
+ return;
+ }
+ ImeTracing tracingInstance = ImeTracing.getInstance();
+ if (!tracingInstance.isAvailable() || !tracingInstance.isEnabled()) {
+ return;
+ }
- if (client != null) {
- try {
- proto.write(CLIENTS,
- TransferPipe.dumpAsync(client, ImeTracing.PROTO_ARG));
- } catch (IOException | RemoteException e) {
- Log.e(TAG, "Exception while collecting client side ime dump", e);
- }
- }
- }
- proto.end(token);
- ImeTracing.getInstance().addToBuffer(proto);
- });
+ ProtoOutputStream proto = new ProtoOutputStream();
+ switch (source) {
+ case ImeTracing.IME_TRACING_FROM_CLIENT:
+ final long client_token = proto.start(InputMethodClientsTraceFileProto.ENTRY);
+ proto.write(InputMethodClientsTraceProto.ELAPSED_REALTIME_NANOS,
+ SystemClock.elapsedRealtimeNanos());
+ proto.write(InputMethodClientsTraceProto.WHERE, where);
+ proto.write(InputMethodClientsTraceProto.CLIENT, protoDump);
+ proto.end(client_token);
+ break;
+ case ImeTracing.IME_TRACING_FROM_IMS:
+ final long service_token = proto.start(InputMethodServiceTraceFileProto.ENTRY);
+ proto.write(InputMethodServiceTraceProto.ELAPSED_REALTIME_NANOS,
+ SystemClock.elapsedRealtimeNanos());
+ proto.write(InputMethodServiceTraceProto.WHERE, where);
+ proto.write(InputMethodServiceTraceProto.INPUT_METHOD_SERVICE, protoDump);
+ proto.end(service_token);
+ break;
+ case IME_TRACING_FROM_IMMS:
+ final long managerservice_token =
+ proto.start(InputMethodManagerServiceTraceFileProto.ENTRY);
+ proto.write(InputMethodManagerServiceTraceProto.ELAPSED_REALTIME_NANOS,
+ SystemClock.elapsedRealtimeNanos());
+ proto.write(InputMethodManagerServiceTraceProto.WHERE, where);
+ dumpDebug(proto, InputMethodManagerServiceTraceProto.INPUT_METHOD_MANAGER_SERVICE);
+ proto.end(managerservice_token);
+ break;
+ default:
+ // Dump triggered by a source not recognised.
+ return;
+ }
+ tracingInstance.addToBuffer(proto, source);
}
@BinderThread
diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
index a6ca25b0e6c1..7af27ca46f68 100644
--- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
@@ -1808,12 +1808,12 @@ public final class MultiClientInputMethodManagerService {
@BinderThread
@Override
- public void startProtoDump(byte[] clientProtoDump) throws RemoteException {
+ public void startProtoDump(byte[] clientProtoDump, int source, String where) {
}
@BinderThread
@Override
- public boolean isImeTraceEnabled() throws RemoteException {
+ public boolean isImeTraceEnabled() {
return false;
}
}