diff --git a/core/java/android/inputmethodservice/AbstractInputMethodService.java b/core/java/android/inputmethodservice/AbstractInputMethodService.java index cd436374b489b..7cf0b10031acc 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 3d1755e9b0176..5cfcd667632b0 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 abc2a69a8dee1..ae260e16806fc 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 865d5608a40a1..4437191006431 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 @@ -85,6 +102,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. * diff --git a/core/java/android/util/imetracing/ImeTracingClientImpl.java b/core/java/android/util/imetracing/ImeTracingClientImpl.java index e5d7d3380d021..206006e794869 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; + } - 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; - } + 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; } } + + @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 350cf5721148a..04452b32d66da 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 06ddf3c69f8e0..75dc0c43085d3 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 bcb3a36ebe2c6..1c82619a61ade 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 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 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 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 e4a24ebfe9e42..537fd42d71358 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 c0770063beea0..33a1f228e2ad2 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) { - if (fromIme) { - ImeTracing.getInstance().triggerDump(); - } final ViewRootImpl viewAncestor = mViewAncestor.get(); + if (fromIme) { + ImeTracing.getInstance().triggerClientDump("ViewRootImpl.W#showInsets", + viewAncestor.getInsetsController().getHost().getInputMethodManager()); + } 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) { - if (fromIme) { - ImeTracing.getInstance().triggerDump(); - } + final ViewRootImpl viewAncestor = mViewAncestor.get(); + if (fromIme) { + ImeTracing.getInstance().triggerClientDump("ViewRootImpl.W#hideInsets", + viewAncestor.getInsetsController().getHost().getInputMethodManager()); + } 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 f1cbd2533a5a3..3c89a4bfad59f 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; } @@ -3248,19 +3249,6 @@ public final class InputMethodManager { return false; } - /** - * 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 5a06273bb1739..844c56bd3529f 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 856d8da1a1ea8..5c0f341cb9e46 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 6dd91e533a87a..889061b71ee63 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()) { + 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; + } + + 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; - } - 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(); - } - } - - 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); - }); + } + 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 a6ca25b0e6c12..7af27ca46f687 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; } }