script-astra/Android/Sdk/sources/android-35/android/tracing/perfetto/DataSource.java
localadmin 4380f00a78 init
2025-01-20 18:15:20 +03:00

186 lines
7.3 KiB
Java

/*
* Copyright (C) 2023 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.tracing.perfetto;
import android.util.proto.ProtoInputStream;
/**
* Templated base class meant to be derived by embedders to create a custom data
* source.
*
* @param <DataSourceInstanceType> The type for the DataSource instances that will be created from
* this DataSource type.
* @param <TlsStateType> The type of the custom TLS state, if any is used.
* @param <IncrementalStateType> The type of the custom incremental state, if any is used.
*
* @hide
*/
public abstract class DataSource<DataSourceInstanceType extends DataSourceInstance,
TlsStateType, IncrementalStateType> {
protected final long mNativeObj;
public final String name;
/**
* A function implemented by each datasource to create a new data source instance.
*
* @param configStream A ProtoInputStream to read the tracing instance's config.
* @return A new data source instance setup with the provided config.
*/
public abstract DataSourceInstanceType createInstance(
ProtoInputStream configStream, int instanceIndex);
/**
* Constructor for datasource base class.
*
* @param name The fully qualified name of the datasource.
*/
public DataSource(String name) {
this.name = name;
this.mNativeObj = nativeCreate(this, name);
}
/**
* The main tracing method. Tracing code should call this passing a lambda as
* argument, with the following signature: void(TraceContext).
* <p>
* The lambda will be called synchronously (i.e., always before trace()
* returns) only if tracing is enabled and the data source has been enabled in
* the tracing config.
* <p>
* The lambda can be called more than once per trace() call, in the case of
* concurrent tracing sessions (or even if the data source is instantiated
* twice within the same trace config).
*
* @param fun The tracing lambda that will be called with the tracing contexts of each active
* tracing instance.
*/
public final void trace(
TraceFunction<DataSourceInstanceType, TlsStateType, IncrementalStateType> fun) {
boolean startedIterator = nativePerfettoDsTraceIterateBegin(mNativeObj);
if (!startedIterator) {
return;
}
try {
do {
int instanceIndex = nativeGetPerfettoDsInstanceIndex(mNativeObj);
TracingContext<DataSourceInstanceType, TlsStateType, IncrementalStateType> ctx =
new TracingContext<>(this, instanceIndex);
fun.trace(ctx);
nativeWritePackets(mNativeObj, ctx.getAndClearAllPendingTracePackets());
} while (nativePerfettoDsTraceIterateNext(mNativeObj));
} finally {
nativePerfettoDsTraceIterateBreak(mNativeObj);
}
}
/**
* Flush any trace data from this datasource that has not yet been flushed.
*/
public final void flush() {
nativeFlushAll(mNativeObj);
}
/**
* Override this method to create a custom TlsState object for your DataSource. A new instance
* will be created per trace instance per thread.
*
*/
public TlsStateType createTlsState(CreateTlsStateArgs<DataSourceInstanceType> args) {
return null;
}
/**
* Override this method to create and use a custom IncrementalState object for your DataSource.
*
*/
public IncrementalStateType createIncrementalState(
CreateIncrementalStateArgs<DataSourceInstanceType> args) {
return null;
}
/**
* Registers the data source on all tracing backends, including ones that
* connect after the registration. Doing so enables the data source to receive
* Setup/Start/Stop notifications and makes the trace() method work when
* tracing is enabled and the data source is selected.
* <p>
* NOTE: Once registered, we cannot unregister the data source. Therefore, we should avoid
* creating and registering data source where not strictly required. This is a fundamental
* limitation of Perfetto itself.
*
* @param params Params to initialize the datasource with.
*/
public void register(DataSourceParams params) {
nativeRegisterDataSource(this.mNativeObj, params.bufferExhaustedPolicy,
params.willNotifyOnStop, params.noFlush);
}
/**
* Gets the datasource instance with a specified index.
* IMPORTANT: releaseDataSourceInstance must be called after using the datasource instance.
* @param instanceIndex The index of the datasource to lock and get.
* @return The DataSourceInstance at index instanceIndex.
* Null if the datasource instance at the requested index doesn't exist.
*/
public DataSourceInstanceType getDataSourceInstanceLocked(int instanceIndex) {
return (DataSourceInstanceType) nativeGetPerfettoInstanceLocked(mNativeObj, instanceIndex);
}
/**
* Unlock the datasource at the specified index.
* @param instanceIndex The index of the datasource to unlock.
*/
protected void releaseDataSourceInstance(int instanceIndex) {
nativeReleasePerfettoInstanceLocked(mNativeObj, instanceIndex);
}
/**
* Called from native side when a new tracing instance starts.
*
* @param rawConfig byte array of the PerfettoConfig encoded proto.
* @return A new Java DataSourceInstance object.
*/
private DataSourceInstanceType createInstance(byte[] rawConfig, int instanceIndex) {
final ProtoInputStream inputStream = new ProtoInputStream(rawConfig);
return this.createInstance(inputStream, instanceIndex);
}
private static native void nativeRegisterDataSource(long dataSourcePtr,
int bufferExhaustedPolicy, boolean willNotifyOnStop, boolean noFlush);
private static native long nativeCreate(DataSource thiz, String name);
private static native void nativeFlushAll(long nativeDataSourcePointer);
private static native long nativeGetFinalizer();
private static native DataSourceInstance nativeGetPerfettoInstanceLocked(
long dataSourcePtr, int dsInstanceIdx);
private static native void nativeReleasePerfettoInstanceLocked(
long dataSourcePtr, int dsInstanceIdx);
private static native boolean nativePerfettoDsTraceIterateBegin(long dataSourcePtr);
private static native boolean nativePerfettoDsTraceIterateNext(long dataSourcePtr);
private static native void nativePerfettoDsTraceIterateBreak(long dataSourcePtr);
private static native int nativeGetPerfettoDsInstanceIndex(long dataSourcePtr);
private static native void nativeWritePackets(long dataSourcePtr, byte[][] packetData);
}