Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 33451e9d authored by Pablo Gamito's avatar Pablo Gamito
Browse files

Add options to register lifecycle callbacks on a ProtoLogDataSource

Since we want to re-use the same datasource in a single process we need mechanism for different classes to listen in on the different lifecycle events of the same datasource object.

Flag: android.tracing.perfetto_protolog_tracing
Bug: 369560789
Test: atest TracingTests
Change-Id: I897c3273ee01abf93aa5801015bec8aa7cb8e5c9
parent 3e058164
Loading
Loading
Loading
Loading
+88 −15
Original line number Diff line number Diff line
@@ -46,36 +46,30 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class ProtoLogDataSource extends DataSource<ProtoLogDataSource.Instance,
        ProtoLogDataSource.TlsState,
        ProtoLogDataSource.IncrementalState> {
    private static final String DATASOURCE_NAME = "android.protolog";

    private final Map<Integer, ProtoLogConfig> mRunningInstances = new TreeMap<>();

    @NonNull
    private final Instance.TracingInstanceStartCallback mOnStart;
    private final Set<Instance.TracingInstanceStartCallback> mOnStartCallbacks = new HashSet<>();
    @NonNull
    private final Runnable mOnFlush;
    private final Set<Runnable> mOnFlushCallbacks = new HashSet<>();
    @NonNull
    private final Instance.TracingInstanceStopCallback mOnStop;
    private final Set<Instance.TracingInstanceStopCallback> mOnStopCallbacks = new HashSet<>();

    public ProtoLogDataSource(
            @NonNull Instance.TracingInstanceStartCallback onStart,
            @NonNull Runnable onFlush,
            @NonNull Instance.TracingInstanceStopCallback onStop) {
        this(onStart, onFlush, onStop, DATASOURCE_NAME);
    public ProtoLogDataSource() {
        this(DATASOURCE_NAME);
    }

    @VisibleForTesting
    public ProtoLogDataSource(
            @NonNull Instance.TracingInstanceStartCallback onStart,
            @NonNull Runnable onFlush,
            @NonNull Instance.TracingInstanceStopCallback onStop,
            @NonNull String dataSourceName) {
        super(dataSourceName);
        this.mOnStart = onStart;
        this.mOnFlush = onFlush;
        this.mOnStop = onStop;
    }

    @Override
@@ -106,7 +100,8 @@ public class ProtoLogDataSource extends DataSource<ProtoLogDataSource.Instance,
        }

        return new Instance(
                this, instanceIndex, config, mOnStart, mOnFlush, mOnStop);
                this, instanceIndex, config, this::executeOnStartCallbacks,
                this::executeOnFlushCallbacks, this::executeOnStopCallbacks);
    }

    @Override
@@ -128,6 +123,84 @@ public class ProtoLogDataSource extends DataSource<ProtoLogDataSource.Instance,
        return new IncrementalState();
    }

    /**
     * Register an onStart callback that will be called when a tracing instance is started.
     * The callback will be called immediately for all currently running tracing instances on
     * registration.
     * @param onStartCallback The callback to call on starting a tracing instance.
     */
    public synchronized void registerOnStartCallback(
            Instance.TracingInstanceStartCallback onStartCallback) {
        mOnStartCallbacks.add(onStartCallback);

        for (var instanceIndex : mRunningInstances.keySet()) {
            var config = mRunningInstances.get(instanceIndex);
            onStartCallback.run(instanceIndex, config);
        }
    }

    /**
     * Register an onFlush callback that will be called when a tracing instance is about to flush.
     * @param onFlushCallback The callback to call on flushing a tracing instance
     */
    public void registerOnFlushCallback(Runnable onFlushCallback) {
        mOnFlushCallbacks.add(onFlushCallback);
    }

    /**
     * Register an onStop callback that will be called when a tracing instance is being stopped.
     * @param onStopCallback The callback to call on stopping a tracing instance.
     */
    public void registerOnStopCallback(Instance.TracingInstanceStopCallback onStopCallback) {
        mOnStopCallbacks.add(onStopCallback);
    }

    /**
     * Unregister an onStart callback.
     * @param onStartCallback The callback object to unregister.
     */
    public void unregisterOnStartCallback(Instance.TracingInstanceStartCallback onStartCallback) {
        mOnStartCallbacks.add(onStartCallback);
    }

    /**
     * Unregister an onFlush callback.
     * @param onFlushCallback The callback object to unregister.
     */
    public void unregisterOnFlushCallback(Runnable onFlushCallback) {
        mOnFlushCallbacks.add(onFlushCallback);
    }

    /**
     * Unregister an onStop callback.
     * @param onStopCallback The callback object to unregister.
     */
    public void unregisterOnStopCallback(Instance.TracingInstanceStopCallback onStopCallback) {
        mOnStopCallbacks.add(onStopCallback);
    }

    private synchronized void executeOnStartCallbacks(int instanceIdx, ProtoLogConfig config) {
        mRunningInstances.put(instanceIdx, config);

        for (var onStart : mOnStartCallbacks) {
            onStart.run(instanceIdx, config);
        }
    }

    private void executeOnFlushCallbacks() {
        for (var onFlush : mOnFlushCallbacks) {
            onFlush.run();
        }
    }

    private synchronized void executeOnStopCallbacks(int instanceIdx, ProtoLogConfig config) {
        mRunningInstances.remove(instanceIdx, config);

        for (var onStop : mOnStopCallbacks) {
            onStop.run(instanceIdx, config);
        }
    }

    public static class TlsState {
        @NonNull
        private final ProtoLogConfig mConfig;