212 lines
7.3 KiB
Java
212 lines
7.3 KiB
Java
/*
|
|
* Copyright (C) 2020 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.android.internal.inputmethod;
|
|
|
|
import android.annotation.NonNull;
|
|
import android.annotation.Nullable;
|
|
import android.annotation.RequiresPermission;
|
|
import android.app.ActivityThread;
|
|
import android.util.Log;
|
|
import android.util.proto.ProtoOutputStream;
|
|
import android.view.inputmethod.InputMethodManager;
|
|
import android.view.inputmethod.InputMethodManagerGlobal;
|
|
|
|
import java.io.PrintWriter;
|
|
|
|
/**
|
|
*
|
|
* An abstract class that declares the methods for ime trace related operations - enable trace,
|
|
* schedule trace and add new trace to buffer. Both the client and server side classes can use
|
|
* it by getting an implementation through {@link ImeTracing#getInstance()}.
|
|
*/
|
|
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;
|
|
|
|
private final boolean mIsAvailable = InputMethodManagerGlobal.isImeTraceAvailable();
|
|
|
|
protected boolean mDumpInProgress;
|
|
protected final Object mDumpInProgressLock = new Object();
|
|
|
|
/**
|
|
* Returns an instance of {@link ImeTracingServerImpl} when called from a server side class
|
|
* and an instance of {@link ImeTracingClientImpl} when called from a client side class.
|
|
* Useful to schedule a dump for next frame or save a dump when certain methods are called.
|
|
*
|
|
* @return Instance of one of the children classes of {@link ImeTracing}
|
|
*/
|
|
public static ImeTracing getInstance() {
|
|
if (sInstance == null) {
|
|
if (android.tracing.Flags.perfettoIme()) {
|
|
sInstance = new ImeTracingPerfettoImpl();
|
|
} else if (isSystemProcess()) {
|
|
sInstance = new ImeTracingServerImpl();
|
|
} else {
|
|
sInstance = new ImeTracingClientImpl();
|
|
}
|
|
}
|
|
return sInstance;
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
protected void sendToService(byte[] protoDump, int source, String where) {
|
|
InputMethodManagerGlobal.startProtoDump(protoDump, source, where,
|
|
e -> Log.e(TAG, "Exception while sending ime-related dump to server", e));
|
|
}
|
|
|
|
/**
|
|
* Start IME trace.
|
|
*/
|
|
@RequiresPermission(android.Manifest.permission.CONTROL_UI_TRACING)
|
|
public final void startImeTrace() {
|
|
InputMethodManagerGlobal.startImeTrace(e -> Log.e(TAG, "Could not start ime trace.", e));
|
|
}
|
|
|
|
/**
|
|
* Stop IME trace.
|
|
*/
|
|
@RequiresPermission(android.Manifest.permission.CONTROL_UI_TRACING)
|
|
public final void stopImeTrace() {
|
|
InputMethodManagerGlobal.stopImeTrace(e -> Log.e(TAG, "Could not stop ime trace.", e));
|
|
}
|
|
|
|
/**
|
|
* @param proto dump to be added to the buffer
|
|
*/
|
|
public abstract void addToBuffer(ProtoOutputStream proto, int source);
|
|
|
|
/**
|
|
* 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.
|
|
* @param icProto {@link android.view.inputmethod.InputConnection} call data in proto format.
|
|
*/
|
|
public abstract void triggerClientDump(String where, InputMethodManager immInstance,
|
|
@Nullable byte[] icProto);
|
|
|
|
/**
|
|
* A delegate for {@link #triggerServiceDump(String, ServiceDumper, byte[])}.
|
|
*/
|
|
@FunctionalInterface
|
|
public interface ServiceDumper {
|
|
/**
|
|
* Dumps internal data into {@link ProtoOutputStream}.
|
|
*
|
|
* @param proto {@link ProtoOutputStream} to be dumped into.
|
|
* @param icProto {@link android.view.inputmethod.InputConnection} call data in proto
|
|
* format.
|
|
*/
|
|
void dumpToProto(ProtoOutputStream proto, @Nullable byte[] icProto);
|
|
}
|
|
|
|
/**
|
|
* Starts a proto dump of the currently connected InputMethodService information.
|
|
*
|
|
* @param where Place where the trace was triggered.
|
|
* @param dumper {@link ServiceDumper} to be used to dump
|
|
* {@link android.inputmethodservice.InputMethodService}.
|
|
* @param icProto {@link android.view.inputmethod.InputConnection} call data in proto format.
|
|
*/
|
|
public abstract void triggerServiceDump(String where, ServiceDumper dumper,
|
|
@Nullable byte[] icProto);
|
|
|
|
/**
|
|
* Starts a proto dump of the InputMethodManagerService information.
|
|
*
|
|
* @param where Place where the trace was triggered.
|
|
*/
|
|
public abstract void triggerManagerServiceDump(String where, @NonNull ServiceDumper dumper);
|
|
|
|
/**
|
|
* Being called while taking a bugreport so that tracing files can be included in the bugreport
|
|
* when the IME tracing is running. Does nothing otherwise.
|
|
*
|
|
* @param pw Print writer
|
|
*/
|
|
public void saveForBugreport(@Nullable PrintWriter pw) {
|
|
// does nothing by default.
|
|
}
|
|
|
|
/**
|
|
* Sets whether ime tracing is enabled.
|
|
*
|
|
* @param enabled Tells whether ime tracing should be enabled or disabled.
|
|
*/
|
|
public void setEnabled(boolean enabled) {
|
|
sEnabled = enabled;
|
|
}
|
|
|
|
/**
|
|
* @return {@code true} if dumping is enabled, {@code false} otherwise.
|
|
*/
|
|
public boolean isEnabled() {
|
|
return sEnabled;
|
|
}
|
|
|
|
/**
|
|
* @return {@code true} if tracing is available, {@code false} otherwise.
|
|
*/
|
|
public boolean isAvailable() {
|
|
return mIsAvailable;
|
|
}
|
|
|
|
/**
|
|
* 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);
|
|
|
|
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();
|
|
}
|
|
}
|
|
|
|
}
|