From 22866005923deb818b15e06ac7d1c6786ffd549f Mon Sep 17 00:00:00 2001 From: Edgar Arriaga Date: Wed, 12 Nov 2025 20:27:01 +0000 Subject: [PATCH 1/8] Add snippets for trigger based profiling section of ProfilingManager docs --- .../ProfilingManagerJavaSnippets.java | 42 +++++++++++++++++++ .../ProfilingManagerKotlinSnippets.kt | 38 +++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerJavaSnippets.java b/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerJavaSnippets.java index 4dae4d353..6b66ae367 100644 --- a/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerJavaSnippets.java +++ b/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerJavaSnippets.java @@ -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; @@ -16,6 +22,8 @@ public class ProfilingManagerJavaSnippets { public class MainActivityJava extends Activity { + public static final String TAG = "EDGAR"; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -69,5 +77,39 @@ 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 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 resultCallback = + new Consumer() { + @Override + public void accept(ProfilingResult profilingResult) { + // ... + if (profilingResult.getErrorCode() == ProfilingResult.ERROR_NONE) { + Log.d(TAG, + "Received profiling result. file: " + profilingResult.getResultFilePath()); + } + } + }; + profilingManager.registerForAllProfilingResults(mainExecutor, resultCallback); + profilingManager.addProfilingTriggers(triggers); + + Choreographer.getInstance().postFrameCallback((f) -> { + // This will cause the TRIGGER_TYPE_APP_FULLY_DRAWN to be emitted. + reportFullyDrawn(); + }); + } + // [END android_profiling_manager_triggered_trace_java] + + } } diff --git a/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt b/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt index f3f0ad99c..85600b4d5 100644 --- a/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt +++ b/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt @@ -21,19 +21,28 @@ import android.os.Build import android.os.Bundle import android.os.CancellationSignal import android.os.ProfilingResult +import android.os.ProfilingManager +import android.os.ProfilingTrigger import android.util.Log +import java.util.ArrayList import androidx.annotation.RequiresApi import androidx.core.os.BufferFillPolicy import androidx.core.os.SystemTraceRequestBuilder import androidx.core.os.requestProfiling +import android.view.Choreographer import androidx.tracing.Trace 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() @@ -81,5 +90,34 @@ 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() + + 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 -> + if (profilingResult.errorCode == ProfilingResult.ERROR_NONE) { + Log.d(TAG, "Received profiling result. file: ${profilingResult.resultFilePath}") + } + } + + profilingManager.registerForAllProfilingResults(mainExecutor, resultCallback) + profilingManager.addProfilingTriggers(triggers) + + Choreographer.getInstance().postFrameCallback { frameTimeNanos -> + // This will cause the TRIGGER_TYPE_APP_FULLY_DRAWN to be emitted. + reportFullyDrawn() + } + } + // [END android_profiling_manager_triggered_trace] } } From 47e507603d926cd9859d3166707b1d3389759b05 Mon Sep 17 00:00:00 2001 From: edgararriagag <211581399+edgararriagag@users.noreply.github.com> Date: Wed, 12 Nov 2025 20:34:21 +0000 Subject: [PATCH 2/8] Apply Spotless --- .../snippets/profiling/ProfilingManagerKotlinSnippets.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt b/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt index 85600b4d5..775c5dd3e 100644 --- a/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt +++ b/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt @@ -20,17 +20,17 @@ import android.app.Activity import android.os.Build import android.os.Bundle import android.os.CancellationSignal -import android.os.ProfilingResult import android.os.ProfilingManager +import android.os.ProfilingResult import android.os.ProfilingTrigger import android.util.Log -import java.util.ArrayList +import android.view.Choreographer import androidx.annotation.RequiresApi import androidx.core.os.BufferFillPolicy import androidx.core.os.SystemTraceRequestBuilder import androidx.core.os.requestProfiling -import android.view.Choreographer import androidx.tracing.Trace +import java.util.ArrayList import java.util.concurrent.Executor import java.util.concurrent.Executors import java.util.function.Consumer From 88e7e0a44216d8d6fbe68854f7671f84a9f7cb5e Mon Sep 17 00:00:00 2001 From: Edgar Arriaga Date: Wed, 12 Nov 2025 20:37:07 +0000 Subject: [PATCH 3/8] Fix tag name --- .../snippets/profiling/ProfilingManagerJavaSnippets.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerJavaSnippets.java b/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerJavaSnippets.java index 6b66ae367..c28114f28 100644 --- a/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerJavaSnippets.java +++ b/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerJavaSnippets.java @@ -22,7 +22,7 @@ public class ProfilingManagerJavaSnippets { public class MainActivityJava extends Activity { - public static final String TAG = "EDGAR"; + public static final String TAG = "ProfilingManager"; @Override public void onCreate(Bundle savedInstanceState) { From 416e1243f92d8339775d0bd1d7de222da0390e45 Mon Sep 17 00:00:00 2001 From: Edgar Arriaga Date: Wed, 12 Nov 2025 22:51:50 +0000 Subject: [PATCH 4/8] Bump mindSdk so that new ProfilingManager snippets compile --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3a2de6ba9..ebdd94276 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -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" From ba926c6ed265100cf82bfb30d90bfc226fe24fb0 Mon Sep 17 00:00:00 2001 From: Edgar Arriaga Date: Fri, 14 Nov 2025 01:27:09 +0000 Subject: [PATCH 5/8] add extra handling logic for trigger callback and exclude some sections --- .../ProfilingManagerJavaSnippets.java | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerJavaSnippets.java b/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerJavaSnippets.java index c28114f28..ddb18a33e 100644 --- a/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerJavaSnippets.java +++ b/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerJavaSnippets.java @@ -93,23 +93,37 @@ public void recordWithTrigger() { new Consumer() { @Override public void accept(ProfilingResult profilingResult) { - // ... if (profilingResult.getErrorCode() == ProfilingResult.ERROR_NONE) { - Log.d(TAG, - "Received profiling result. file: " + profilingResult.getResultFilePath()); + Log.d( + "ProfileTest", + "Received profiling result file=" + profilingResult.getResultFilePath()); + setupUploadJob(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 setupUploadJob(String resultFilePath) { + // Setup job to upload the profiling result file. + } + // [END android_profiling_manager_triggered_trace_setup_upload_job_java] } } From 69d3761ffd7333787a1cc0d7e1de68b110fb999d Mon Sep 17 00:00:00 2001 From: Edgar Arriaga Date: Fri, 14 Nov 2025 01:31:02 +0000 Subject: [PATCH 6/8] update kotlin snippet for handling callback --- .../ProfilingManagerKotlinSnippets.kt | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt b/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt index 775c5dd3e..0b1c1becd 100644 --- a/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt +++ b/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt @@ -106,18 +106,36 @@ class ProfilingManagerKotlinSnippets { val resultCallback = Consumer { profilingResult -> if (profilingResult.errorCode == ProfilingResult.ERROR_NONE) { - Log.d(TAG, "Received profiling result. file: ${profilingResult.resultFilePath}") + Log.d( + "ProfileTest", + "Received profiling result file=" + profilingResult.resultFilePath + ) + setupUploadJob(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 setupUploadJob(resultFilePath: String?) { + // Setup job to upload the profiling result file. + } + // [END android_profiling_manager_triggered_trace_setup_upload_job] + } } From 43c939c60b802f8df0c417404483d6d594c7e8a6 Mon Sep 17 00:00:00 2001 From: edgararriagag <211581399+edgararriagag@users.noreply.github.com> Date: Fri, 14 Nov 2025 01:35:39 +0000 Subject: [PATCH 7/8] Apply Spotless --- .../example/snippets/profiling/ProfilingManagerKotlinSnippets.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt b/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt index 0b1c1becd..26c8c4949 100644 --- a/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt +++ b/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt @@ -136,6 +136,5 @@ class ProfilingManagerKotlinSnippets { // Setup job to upload the profiling result file. } // [END android_profiling_manager_triggered_trace_setup_upload_job] - } } From 7d374a5a75128739ba95642ddb05387e7e0d6c9c Mon Sep 17 00:00:00 2001 From: Edgar Arriaga Date: Fri, 14 Nov 2025 17:44:54 +0000 Subject: [PATCH 8/8] rename upload job method --- .../snippets/profiling/ProfilingManagerJavaSnippets.java | 4 ++-- .../snippets/profiling/ProfilingManagerKotlinSnippets.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerJavaSnippets.java b/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerJavaSnippets.java index ddb18a33e..4c2d2d23b 100644 --- a/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerJavaSnippets.java +++ b/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerJavaSnippets.java @@ -97,7 +97,7 @@ public void accept(ProfilingResult profilingResult) { Log.d( "ProfileTest", "Received profiling result file=" + profilingResult.getResultFilePath()); - setupUploadJob(profilingResult.getResultFilePath()); + setupProfileUploadWorker(profilingResult.getResultFilePath()); } else { Log.e( "ProfileTest", @@ -121,7 +121,7 @@ public void accept(ProfilingResult profilingResult) { // [END android_profiling_manager_triggered_trace_java] // [START android_profiling_manager_triggered_trace_setup_upload_job_java] - public void setupUploadJob(String resultFilePath) { + public void setupProfileUploadWorker(String resultFilePath) { // Setup job to upload the profiling result file. } // [END android_profiling_manager_triggered_trace_setup_upload_job_java] diff --git a/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt b/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt index 26c8c4949..b54ba67b0 100644 --- a/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt +++ b/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt @@ -110,7 +110,7 @@ class ProfilingManagerKotlinSnippets { "ProfileTest", "Received profiling result file=" + profilingResult.resultFilePath ) - setupUploadJob(profilingResult.resultFilePath) + setupProfileUploadWorker(profilingResult.resultFilePath) } else { Log.e( "ProfileTest", @@ -132,7 +132,7 @@ class ProfilingManagerKotlinSnippets { // [END android_profiling_manager_triggered_trace] // [START android_profiling_manager_triggered_trace_setup_upload_job] - fun setupUploadJob(resultFilePath: String?) { + fun setupProfileUploadWorker(resultFilePath: String?) { // Setup job to upload the profiling result file. } // [END android_profiling_manager_triggered_trace_setup_upload_job]