Skip to content

Commit

Permalink
Expose Perfetto DataSource to java
Browse files Browse the repository at this point in the history
Bug: 309630341
Test: atest CoreTracingTests
Change-Id: I9e9486ba406aa67fbc73922910ea97429ee4683c
  • Loading branch information
Pablo Gamito committed Jan 12, 2024
1 parent 72235db commit 6ecbbc7
Show file tree
Hide file tree
Showing 23 changed files with 2,242 additions and 0 deletions.
1 change: 1 addition & 0 deletions Android.bp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ filegroup {
":framework-javastream-protos",
":statslog-framework-java-gen", // FrameworkStatsLog.java
":audio_policy_configuration_V7_0",
":perfetto_trace_javastream_protos",
],
}

Expand Down
43 changes: 43 additions & 0 deletions core/java/android/tracing/perfetto/CreateIncrementalStateArgs.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2024 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.annotation.Nullable;

/**
* @hide
* @param <DataSourceInstanceType> The type of datasource instance this state applied to.
*/
public class CreateIncrementalStateArgs<DataSourceInstanceType extends DataSourceInstance> {
private final DataSource<DataSourceInstanceType, Object, Object> mDataSource;
private final int mInstanceIndex;

CreateIncrementalStateArgs(DataSource dataSource, int instanceIndex) {
this.mDataSource = dataSource;
this.mInstanceIndex = instanceIndex;
}

/**
* Gets the datasource instance for this state with a lock.
* releaseDataSourceInstanceLocked must be called before this can be called again.
* @return The data source instance for this state.
* Null if the datasource instance no longer exists.
*/
public @Nullable DataSourceInstanceType getDataSourceInstanceLocked() {
return mDataSource.getDataSourceInstanceLocked(mInstanceIndex);
}
}
43 changes: 43 additions & 0 deletions core/java/android/tracing/perfetto/CreateTlsStateArgs.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2024 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.annotation.Nullable;

/**
* @hide
* @param <DataSourceInstanceType> The type of datasource instance this state applied to.
*/
public class CreateTlsStateArgs<DataSourceInstanceType extends DataSourceInstance> {
private final DataSource<DataSourceInstanceType, Object, Object> mDataSource;
private final int mInstanceIndex;

CreateTlsStateArgs(DataSource dataSource, int instanceIndex) {
this.mDataSource = dataSource;
this.mInstanceIndex = instanceIndex;
}

/**
* Gets the datasource instance for this state with a lock.
* releaseDataSourceInstanceLocked must be called before this can be called again.
* @return The data source instance for this state.
* Null if the datasource instance no longer exists.
*/
public @Nullable DataSourceInstanceType getDataSourceInstanceLocked() {
return mDataSource.getDataSourceInstanceLocked(mInstanceIndex);
}
}
163 changes: 163 additions & 0 deletions core/java/android/tracing/perfetto/DataSource.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*
* 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) {
nativeTrace(mNativeObj, fun);
}

/**
* 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.
*
* NOTE: Should only be called from native side.
*/
protected TlsStateType createTlsState(CreateTlsStateArgs<DataSourceInstanceType> args) {
return null;
}

/**
* Override this method to create and use a custom IncrementalState object for your DataSource.
*
* NOTE: Should only be called from native side.
*/
protected 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);
}

/**
* 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);

private static native long nativeCreate(DataSource thiz, String name);
private static native void nativeTrace(
long nativeDataSourcePointer, TraceFunction traceFunction);
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);
}
72 changes: 72 additions & 0 deletions core/java/android/tracing/perfetto/DataSourceInstance.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* 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;

/**
* @hide
*/
public abstract class DataSourceInstance implements AutoCloseable {
private final DataSource mDataSource;
private final int mInstanceIndex;

public DataSourceInstance(DataSource dataSource, int instanceIndex) {
this.mDataSource = dataSource;
this.mInstanceIndex = instanceIndex;
}

/**
* Executed when the tracing instance starts running.
* <p>
* NOTE: This callback executes on the Perfetto internal thread and is blocking.
* Anything that is run in this callback should execute quickly.
*
* @param args Start arguments.
*/
protected void onStart(StartCallbackArguments args) {}

/**
* Executed when a flush is triggered.
* <p>
* NOTE: This callback executes on the Perfetto internal thread and is blocking.
* Anything that is run in this callback should execute quickly.
* @param args Flush arguments.
*/
protected void onFlush(FlushCallbackArguments args) {}

/**
* Executed when the tracing instance is stopped.
* <p>
* NOTE: This callback executes on the Perfetto internal thread and is blocking.
* Anything that is run in this callback should execute quickly.
* @param args Stop arguments.
*/
protected void onStop(StopCallbackArguments args) {}

@Override
public final void close() {
this.release();
}

/**
* Release the lock on the datasource once you are finished using it.
* Only required to be called when instance was retrieved with
* `DataSource#getDataSourceInstanceLocked`.
*/
public final void release() {
mDataSource.releaseDataSourceInstance(mInstanceIndex);
}
}
57 changes: 57 additions & 0 deletions core/java/android/tracing/perfetto/DataSourceParams.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* 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.annotation.IntDef;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
* DataSource Parameters
*
* @hide
*/
public class DataSourceParams {
/**
* @hide
*/
@IntDef(value = {
PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_DROP,
PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_STALL_AND_ABORT,
})
@Retention(RetentionPolicy.SOURCE)
public @interface PerfettoDsBufferExhausted {}

// If the data source runs out of space when trying to acquire a new chunk,
// it will drop data.
public static final int PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_DROP = 0;

// If the data source runs out of space when trying to acquire a new chunk,
// it will stall, retry and eventually abort if a free chunk is not acquired
// after a while.
public static final int PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_STALL_AND_ABORT = 1;

public static DataSourceParams DEFAULTS =
new DataSourceParams(PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_DROP);

public DataSourceParams(@PerfettoDsBufferExhausted int bufferExhaustedPolicy) {
this.bufferExhaustedPolicy = bufferExhaustedPolicy;
}

public final @PerfettoDsBufferExhausted int bufferExhaustedPolicy;
}
Loading

0 comments on commit 6ecbbc7

Please sign in to comment.