Profiling

Added in 1.15.0-beta01

public final class Profiling


Summary

Public methods

static final @NonNull Flow<@NonNull <Error class: unknown class>>

Obtain a flow to be called with all profiling results for this UID.

static final void
@RequiresApi(api = 35)
registerForAllProfilingResults(
    @NonNull Context context,
    @NonNull Executor executor,
    @NonNull Consumer<@NonNull <Error class: unknown class>> listener
)

Register a listener to be called with all profiling results for this UID.

static final void
@RequiresApi(api = 35)
requestProfiling(
    @NonNull Context context,
    @NonNull ProfilingRequest profilingRequest,
    Executor executor,
    Consumer<@NonNull <Error class: unknown class>> listener
)

Request profiling using a ProfilingRequest generated by one of the provided builders.

static final void

Unregister a listener that was to be called for all profiling results.

Public methods

registerForAllProfilingResults

@RequiresApi(api = 35)
public static final @NonNull Flow<@NonNull <Error class: unknown class>registerForAllProfilingResults(@NonNull Context context)

Obtain a flow to be called with all profiling results for this UID.

val flow = registerForAllProfilingResults(context)

flow
    .flowOn(Dispatchers.IO) // Consume files on a background thread
    .collect { profilingResult ->
        if (profilingResult.errorCode == ProfilingResult.ERROR_NONE) {
            doSomethingWithMyFile(profilingResult.resultFilePath)
        } else {
            doSomethingWithFailure(profilingResult.errorCode, profilingResult.errorMessage)
        }
    }

registerForAllProfilingResults

@RequiresApi(api = 35)
public static final void registerForAllProfilingResults(
    @NonNull Context context,
    @NonNull Executor executor,
    @NonNull Consumer<@NonNull <Error class: unknown class>> listener
)

Register a listener to be called with all profiling results for this UID.

val listener =
    Consumer<ProfilingResult> { profilingResult ->
        if (profilingResult.errorCode == ProfilingResult.ERROR_NONE) {
            doSomethingWithMyFile(profilingResult.resultFilePath)
        } else {
            doSomethingWithFailure(profilingResult.errorCode, profilingResult.errorMessage)
        }
    }

registerForAllProfilingResults(
    context,
    Dispatchers.IO.asExecutor(), // Your choice of executor for the callback to occur on.
    listener
)

requestProfiling

@RequiresApi(api = 35)
public static final void requestProfiling(
    @NonNull Context context,
    @NonNull ProfilingRequest profilingRequest,
    Executor executor,
    Consumer<@NonNull <Error class: unknown class>> listener
)

Request profiling using a ProfilingRequest generated by one of the provided builders.

If the executor and/or listener are null, and if no global listener and executor combinations are registered using registerForAllProfilingResults, the request will be dropped.

Requests will be rate limited and are not guaranteed to be filled.

There might be a delay before profiling begins. For continuous profiling types (system tracing, stack sampling, and heap profiling), we recommend starting the collection early and stopping it with cancellationSignal, set on the profilingRequest builder, immediately after the area of interest to ensure that the section you want profiled is captured. For heap dumps, we recommend testing locally to ensure that the heap dump is collected at the proper time.

val listener =
    Consumer<ProfilingResult> { profilingResult ->
        if (profilingResult.errorCode == ProfilingResult.ERROR_NONE) {
            doSomethingWithMyFile(profilingResult.resultFilePath)
        } else {
            doSomethingWithFailure(profilingResult.errorCode, profilingResult.errorMessage)
        }
    }

requestProfiling(
    context,
    JavaHeapDumpRequestBuilder()
        .setBufferSizeKb(123 /* Requested buffer size in KB */)
        .setTag("tag" /* Caller supplied tag for identification */)
        .build(),
    Dispatchers.IO.asExecutor(), // Your choice of executor for the callback to occur on.
    listener
)
val listener =
    Consumer<ProfilingResult> { profilingResult ->
        if (profilingResult.errorCode == ProfilingResult.ERROR_NONE) {
            doSomethingWithMyFile(profilingResult.resultFilePath)
        } else {
            doSomethingWithFailure(profilingResult.errorCode, profilingResult.errorMessage)
        }
    }

val cancellationSignal = CancellationSignal()

requestProfiling(
    context,
    HeapProfileRequestBuilder()
        .setBufferSizeKb(1000 /* Requested buffer size in KB */)
        .setDurationMs(5 * 1000 /* Requested profiling duration in milliseconds */)
        .setTrackJavaAllocations(true)
        .setSamplingIntervalBytes(100 /* Requested sampling interval in bytes */)
        .setTag("tag" /* Caller supplied tag for identification */)
        .setCancellationSignal(cancellationSignal)
        .build(),
    Dispatchers.IO.asExecutor(), // Your choice of executor for the callback to occur on.
    listener
)

// Optionally, wait for something interesting to happen and then stop the profiling to receive
// the result as is.
cancellationSignal.cancel()
val listener =
    Consumer<ProfilingResult> { profilingResult ->
        if (profilingResult.errorCode == ProfilingResult.ERROR_NONE) {
            doSomethingWithMyFile(profilingResult.resultFilePath)
        } else {
            doSomethingWithFailure(profilingResult.errorCode, profilingResult.errorMessage)
        }
    }

val cancellationSignal = CancellationSignal()

requestProfiling(
    context,
    StackSamplingRequestBuilder()
        .setBufferSizeKb(1000 /* Requested buffer size in KB */)
        .setDurationMs(10 * 1000 /* Requested profiling duration in millisconds */)
        .setSamplingFrequencyHz(100 /* Requested sampling frequency */)
        .setTag("tag" /* Caller supplied tag for identification */)
        .setCancellationSignal(cancellationSignal)
        .build(),
    Dispatchers.IO.asExecutor(), // Your choice of executor for the callback to occur on.
    listener
)

// Optionally, wait for something interesting to happen and then stop the profiling to receive
// the result as is.
cancellationSignal.cancel()
val listener =
    Consumer<ProfilingResult> { profilingResult ->
        if (profilingResult.errorCode == ProfilingResult.ERROR_NONE) {
            doSomethingWithMyFile(profilingResult.resultFilePath)
        } else {
            doSomethingWithFailure(profilingResult.errorCode, profilingResult.errorMessage)
        }
    }

val cancellationSignal = CancellationSignal()

requestProfiling(
    context,
    SystemTraceRequestBuilder()
        .setBufferSizeKb(1000 /* Requested buffer size in KB */)
        .setDurationMs(60 * 1000 /* Requested profiling duration in millisconds */)
        .setBufferFillPolicy(BufferFillPolicy.RING_BUFFER /* Buffer fill policy */)
        .setTag("tag" /* Caller supplied tag for identification */)
        .setCancellationSignal(cancellationSignal)
        .build(),
    Dispatchers.IO.asExecutor(), // Your choice of executor for the callback to occur on.
    listener
)

// Optionally, wait for something interesting to happen and then stop the profiling to receive
// the result as is.
cancellationSignal.cancel()

unregisterForAllProfilingResults

@RequiresApi(api = 35)
public static final void unregisterForAllProfilingResults(
    @NonNull Context context,
    @NonNull Consumer<@NonNull <Error class: unknown class>> listener
)

Unregister a listener that was to be called for all profiling results.