blob: 4696ae325e7bc897e3c258f82f0739523586f87b [file] [log] [blame]
/*
* 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 android.util.imetracing;
import android.annotation.Nullable;
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.util.Log;
import android.util.proto.ProtoOutputStream;
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,
* 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()}.
*
* @hide
*/
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));
}
/**
* 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) {
try {
sInstance = isSystemProcess()
? new ImeTracingServerImpl() : new ImeTracingClientImpl();
} catch (RemoteException | ServiceNotFoundException e) {
Log.e(TAG, "Exception while creating ImeTracing instance", e);
}
}
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
*/
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, 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,
ProtoOutputStream icProto);
/**
* Starts a proto dump of the currently connected InputMethodService information.
*
* @param where Place where the trace was triggered.
* @param service The {@link android.inputmethodservice.InputMethodService} to be dumped.
* @param icProto {@link android.view.inputmethod.InputConnection} call data in proto format.
*/
public abstract void triggerServiceDump(String where, AbstractInputMethodService service,
ProtoOutputStream icProto);
/**
* Starts a proto dump of the InputMethodManagerService information.
*
* @param where Place where the trace was triggered.
*/
public abstract void triggerManagerServiceDump(String where);
/**
* 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 mService != null;
}
/**
* 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();
}
}
}