Skip to content
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ material3-adaptive-navigation-suite = "1.4.0"
media3 = "1.8.0"
media3Ui = "1.8.0"
# @keep
minSdk = "35"
minSdk = "36"
okHttp = "5.2.1"
playServicesWearable = "19.0.0"
protobuf = "4.32.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@

import android.app.Activity;
import android.os.Bundle;
import android.os.ProfilingManager;
import android.os.ProfilingTrigger;
import android.util.Log;
import java.util.List;
import java.util.ArrayList;
import java.util.function.Consumer;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import android.os.ProfilingResult;
import java.util.concurrent.Executors;
import android.os.CancellationSignal;
import android.view.Choreographer;
import androidx.tracing.Trace;
import androidx.core.os.Profiling;
import androidx.core.os.SystemTraceRequestBuilder;
Expand All @@ -16,6 +22,8 @@
public class ProfilingManagerJavaSnippets {
public class MainActivityJava extends Activity {

public static final String TAG = "ProfilingManager";

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand Down Expand Up @@ -69,5 +77,53 @@ public void accept(ProfilingResult profilingResult) {
stopSignal.cancel();
}
// [END android_profiling_manager_record_system_trace_java]

// [START android_profiling_manager_triggered_trace_java]
public void recordWithTrigger() {
ProfilingManager profilingManager = getApplicationContext().getSystemService(
ProfilingManager.class);
List<ProfilingTrigger> triggers = new ArrayList<>();
ProfilingTrigger.Builder triggerBuilder = new ProfilingTrigger.Builder(
ProfilingTrigger.TRIGGER_TYPE_APP_FULLY_DRAWN);
triggerBuilder.setRateLimitingPeriodHours(1);
triggers.add(triggerBuilder.build());

Executor mainExecutor = Executors.newSingleThreadExecutor();
Consumer<ProfilingResult> resultCallback =
new Consumer<ProfilingResult>() {
@Override
public void accept(ProfilingResult profilingResult) {
if (profilingResult.getErrorCode() == ProfilingResult.ERROR_NONE) {
Log.d(
"ProfileTest",
"Received profiling result file=" + profilingResult.getResultFilePath());
setupProfileUploadWorker(profilingResult.getResultFilePath());
} else {
Log.e(
"ProfileTest",
"Profiling failed errorcode="
+ profilingResult.getErrorCode()
+ " errormsg="
+ profilingResult.getErrorMessage());
}
}
};
profilingManager.registerForAllProfilingResults(mainExecutor, resultCallback);
profilingManager.addProfilingTriggers(triggers);

// [START_EXCLUDE silent]
Choreographer.getInstance().postFrameCallback((f) -> {
// This will cause the TRIGGER_TYPE_APP_FULLY_DRAWN to be emitted.
reportFullyDrawn();
});
// [END_EXCLUDE silent]
}
// [END android_profiling_manager_triggered_trace_java]

// [START android_profiling_manager_triggered_trace_setup_upload_job_java]
public void setupProfileUploadWorker(String resultFilePath) {
// Setup job to upload the profiling result file.
}
// [END android_profiling_manager_triggered_trace_setup_upload_job_java]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,29 @@ import android.app.Activity
import android.os.Build
import android.os.Bundle
import android.os.CancellationSignal
import android.os.ProfilingManager
import android.os.ProfilingResult
import android.os.ProfilingTrigger
import android.util.Log
import android.view.Choreographer
import androidx.annotation.RequiresApi
import androidx.core.os.BufferFillPolicy
import androidx.core.os.SystemTraceRequestBuilder
import androidx.core.os.requestProfiling
import androidx.tracing.Trace
import java.util.ArrayList
import java.util.concurrent.Executor
import java.util.concurrent.Executors
import java.util.function.Consumer
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.asExecutor

class ProfilingManagerKotlinSnippets {
class MainActivity : Activity() {
companion object {
const val TAG = "MyApp"
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
sampleRecordSystemTrace()
Expand Down Expand Up @@ -81,5 +90,51 @@ class ProfilingManagerKotlinSnippets {
// Computations you want to profile
}
// [END android_profiling_manager_record_system_trace_kotlin]

// [START android_profiling_manager_triggered_trace]
fun recordWithTrigger() {
val profilingManager = applicationContext.getSystemService(ProfilingManager::class.java)

val triggers = ArrayList<ProfilingTrigger>()

val triggerBuilder = ProfilingTrigger.Builder(ProfilingTrigger.TRIGGER_TYPE_APP_FULLY_DRAWN)
.setRateLimitingPeriodHours(1)

triggers.add(triggerBuilder.build())

val mainExecutor: Executor = Executors.newSingleThreadExecutor()

val resultCallback = Consumer<ProfilingResult> { profilingResult ->
if (profilingResult.errorCode == ProfilingResult.ERROR_NONE) {
Log.d(
"ProfileTest",
"Received profiling result file=" + profilingResult.resultFilePath
)
setupProfileUploadWorker(profilingResult.resultFilePath)
} else {
Log.e(
"ProfileTest",
"Profiling failed errorcode=" + profilingResult.errorCode + " errormsg=" + profilingResult.errorMessage
)
}
}

profilingManager.registerForAllProfilingResults(mainExecutor, resultCallback)
profilingManager.addProfilingTriggers(triggers)

// [START_EXCLUDE silent]
Choreographer.getInstance().postFrameCallback { frameTimeNanos ->
// This will cause the TRIGGER_TYPE_APP_FULLY_DRAWN to be emitted.
reportFullyDrawn()
}
// [END_EXCLUDE silent]
}
// [END android_profiling_manager_triggered_trace]

// [START android_profiling_manager_triggered_trace_setup_upload_job]
fun setupProfileUploadWorker(resultFilePath: String?) {
// Setup job to upload the profiling result file.
}
// [END android_profiling_manager_triggered_trace_setup_upload_job]
}
}