diff options
4 files changed, 117 insertions, 7 deletions
diff --git a/core/java/android/util/imetracing/ImeTracing.java b/core/java/android/util/imetracing/ImeTracing.java index 443719100643..4058eef3e2a3 100644 --- a/core/java/android/util/imetracing/ImeTracing.java +++ b/core/java/android/util/imetracing/ImeTracing.java @@ -16,6 +16,7 @@ package android.util.imetracing; +import android.annotation.Nullable; import android.app.ActivityThread; import android.content.Context; import android.inputmethodservice.AbstractInputMethodService; @@ -29,6 +30,8 @@ import android.view.inputmethod.InputMethodManager; import com.android.internal.view.IInputMethodManager; +import java.io.PrintWriter; + /** * * An abstract class that declares the methods for ime trace related operations - enable trace, @@ -147,7 +150,43 @@ public abstract class ImeTracing { return mService != null; } + /** + * Writes the current tracing data to the specific output proto file. + */ + public abstract void writeTracesToFiles(); + + /** + * Starts a new IME trace if one is not already started. + * + * @param pw Print writer + */ + public abstract void startTrace(@Nullable PrintWriter pw); + + /** + * Stops the IME trace if one was previously started and writes the current buffers to disk. + * + * @param pw Print writer + */ + public abstract void stopTrace(@Nullable PrintWriter pw); + + /** + * Stops the IME trace if one was previously started. + * + * @param pw Print writer + * @param writeToFile If the current buffer should be written to disk or not + */ + public abstract void stopTrace(@Nullable PrintWriter pw, boolean writeToFile); + private static boolean isSystemProcess() { return ActivityThread.isSystem(); } + + protected void logAndPrintln(@Nullable PrintWriter pw, String msg) { + Log.i(TAG, msg); + if (pw != null) { + pw.println(msg); + pw.flush(); + } + } + } diff --git a/core/java/android/util/imetracing/ImeTracingClientImpl.java b/core/java/android/util/imetracing/ImeTracingClientImpl.java index 206006e79486..904b44da97d7 100644 --- a/core/java/android/util/imetracing/ImeTracingClientImpl.java +++ b/core/java/android/util/imetracing/ImeTracingClientImpl.java @@ -25,6 +25,8 @@ import android.util.Log; import android.util.proto.ProtoOutputStream; import android.view.inputmethod.InputMethodManager; +import java.io.PrintWriter; + /** * @hide */ @@ -94,4 +96,20 @@ class ImeTracingClientImpl extends ImeTracing { public void triggerManagerServiceDump(String where) { // Intentionally left empty, this is implemented in ImeTracingServerImpl } + + @Override + public void writeTracesToFiles() { + } + + @Override + public void startTrace(PrintWriter pw) { + } + + @Override + public void stopTrace(PrintWriter pw) { + } + + @Override + public void stopTrace(PrintWriter pw, boolean writeToFile) { + } } diff --git a/core/java/android/util/imetracing/ImeTracingServerImpl.java b/core/java/android/util/imetracing/ImeTracingServerImpl.java index 04452b32d66d..d758d77fb2f2 100644 --- a/core/java/android/util/imetracing/ImeTracingServerImpl.java +++ b/core/java/android/util/imetracing/ImeTracingServerImpl.java @@ -18,6 +18,7 @@ package android.util.imetracing; import static android.os.Build.IS_USER; +import android.annotation.Nullable; import android.inputmethodservice.AbstractInputMethodService; import android.os.RemoteException; import android.os.ServiceManager.ServiceNotFoundException; @@ -163,6 +164,14 @@ class ImeTracingServerImpl extends ImeTracing { } } + @GuardedBy("mEnabledLock") + @Override + public void writeTracesToFiles() { + synchronized (mEnabledLock) { + writeTracesToFilesLocked(); + } + } + private void writeTracesToFilesLocked() { try { ProtoOutputStream clientsProto = new ProtoOutputStream(); @@ -178,13 +187,16 @@ class ImeTracingServerImpl extends ImeTracing { immsProto.write(InputMethodManagerServiceTraceFileProto.MAGIC_NUMBER, MAGIC_NUMBER_IMMS_VALUE); mBufferImms.writeTraceToFile(mTraceFileImms, immsProto); + + resetBuffers(); } catch (IOException e) { Log.e(TAG, "Unable to write buffer to file", e); } } @GuardedBy("mEnabledLock") - private void startTrace(PrintWriter pw) { + @Override + public void startTrace(@Nullable PrintWriter pw) { if (IS_USER) { Log.w(TAG, "Warn: Tracing is not supported on user builds."); return; @@ -196,15 +208,21 @@ class ImeTracingServerImpl extends ImeTracing { return; } - pw.println("Starting tracing in " + TRACE_DIRNAME + ": " + TRACE_FILENAME_CLIENTS + logAndPrintln(pw, "Starting tracing in " + TRACE_DIRNAME + ": " + TRACE_FILENAME_CLIENTS + ", " + TRACE_FILENAME_IMS + ", " + TRACE_FILENAME_IMMS); sEnabled = true; resetBuffers(); } } + @Override + public void stopTrace(@Nullable PrintWriter pw) { + stopTrace(pw, true /* writeToFile */); + } + @GuardedBy("mEnabledLock") - private void stopTrace(PrintWriter pw) { + @Override + public void stopTrace(@Nullable PrintWriter pw, boolean writeToFile) { if (IS_USER) { Log.w(TAG, "Warn: Tracing is not supported on user builds."); return; @@ -216,12 +234,13 @@ class ImeTracingServerImpl extends ImeTracing { return; } - pw.println("Stopping tracing and writing traces in " + TRACE_DIRNAME + ": " + logAndPrintln(pw, "Stopping tracing and writing traces in " + TRACE_DIRNAME + ": " + TRACE_FILENAME_CLIENTS + ", " + TRACE_FILENAME_IMS + ", " + TRACE_FILENAME_IMMS); sEnabled = false; - writeTracesToFilesLocked(); - resetBuffers(); + if (writeToFile) { + writeTracesToFilesLocked(); + } } } diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 889061b71ee6..2d7f62d90914 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -15,6 +15,8 @@ package com.android.server.inputmethod; +import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL; +import static android.os.IServiceManager.DUMP_FLAG_PROTO; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.server.inputmethod.InputMethodManagerServiceProto.ACCESSIBILITY_REQUESTING_NO_SOFT_KEYBOARD; import static android.server.inputmethod.InputMethodManagerServiceProto.BACK_DISPOSITION; @@ -161,6 +163,7 @@ import com.android.internal.inputmethod.StartInputReason; import com.android.internal.inputmethod.UnbindReason; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; +import com.android.internal.os.BackgroundThread; import com.android.internal.os.HandlerCaller; import com.android.internal.os.SomeArgs; import com.android.internal.os.TransferPipe; @@ -208,6 +211,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub implements ServiceConnection, Handler.Callback { static final boolean DEBUG = false; static final String TAG = "InputMethodManagerService"; + public static final String PROTO_ARG = "--proto"; @Retention(SOURCE) @IntDef({ShellCommandResult.SUCCESS, ShellCommandResult.FAILURE}) @@ -1574,7 +1578,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub public void onStart() { LocalServices.addService(InputMethodManagerInternal.class, new LocalServiceImpl(mService)); - publishBinderService(Context.INPUT_METHOD_SERVICE, mService); + publishBinderService(Context.INPUT_METHOD_SERVICE, mService, false /*allowIsolated*/, + DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO); } @Override @@ -5094,8 +5099,37 @@ public class InputMethodManagerService extends IInputMethodManager.Stub @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + boolean asProto = false; + for (int argIndex = 0; argIndex < args.length; argIndex++) { + if (args[argIndex].equals(PROTO_ARG)) { + asProto = true; + break; + } + } + + if (asProto) { + final ImeTracing imeTracing = ImeTracing.getInstance(); + if (imeTracing.isEnabled()) { + imeTracing.stopTrace(null, false /* writeToFile */); + BackgroundThread.getHandler().post(() -> { + imeTracing.writeTracesToFiles(); + imeTracing.startTrace(null); + }); + } + } + doDump(fd, pw, args, asProto); + } + + private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) { if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; + if (useProto) { + final ProtoOutputStream proto = new ProtoOutputStream(fd); + dumpDebug(proto, InputMethodManagerServiceTraceProto.INPUT_METHOD_MANAGER_SERVICE); + proto.flush(); + return; + } + IInputMethod method; ClientState client; ClientState focusedWindowClient; |