diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f3afdb4df..e4b6c63c0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -29,6 +29,7 @@ androidx-test-junit = "1.3.0" androidx-window = "1.5.1" androidx-window-core = "1.5.1" androidx-window-java = "1.5.1" +androidx-work-runtime = "2.11.0" androidx-xr-arcore = "1.0.0-alpha09" androidx-xr-compose = "1.0.0-alpha09" androidx-xr-scenecore = "1.0.0-alpha10" @@ -195,6 +196,7 @@ androidx-webkit = { module = "androidx.webkit:webkit", version.ref = "webkit" } androidx-window = { module = "androidx.window:window", version.ref = "androidx-window" } androidx-window-core = { module = "androidx.window:window-core", version.ref = "androidx-window-core" } androidx-window-java = { module = "androidx.window:window-java", version.ref = "androidx-window-java" } +androidx-work-runtime = { module = "androidx.work:work-runtime", version.ref = "androidx-work-runtime" } androidx-work-runtime-ktx = "androidx.work:work-runtime-ktx:2.11.0" androidx-xr-arcore = { module = "androidx.xr.arcore:arcore", version.ref = "androidx-xr-arcore" } androidx-xr-compose = { module = "androidx.xr.compose:compose", version.ref = "androidx-xr-compose" } diff --git a/misc/build.gradle.kts b/misc/build.gradle.kts index 6a2dc60d1..9784ac42a 100644 --- a/misc/build.gradle.kts +++ b/misc/build.gradle.kts @@ -61,6 +61,7 @@ dependencies { implementation(libs.androidx.media3.common) implementation(libs.androidx.media3.exoplayer) implementation(libs.androidx.tracing) + implementation(libs.androidx.work.runtime) implementation(libs.hilt.android) implementation(libs.androidx.hilt.navigation.compose) 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 2c7a1ed05..0fdac0932 100644 --- a/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerJavaSnippets.java +++ b/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerJavaSnippets.java @@ -2,8 +2,10 @@ import android.app.Activity; import android.os.Bundle; +import android.os.Build; import android.os.ProfilingManager; import android.os.ProfilingTrigger; +import android.content.Context; import android.util.Log; import java.util.List; import java.util.ArrayList; @@ -18,10 +20,20 @@ import androidx.core.os.Profiling; import androidx.core.os.SystemTraceRequestBuilder; import androidx.core.os.BufferFillPolicy; +import androidx.annotation.RequiresApi; +import androidx.work.OneTimeWorkRequest; +import androidx.work.WorkManager; +import androidx.work.Worker; +import androidx.work.WorkerParameters; +import androidx.work.Constraints; +import androidx.work.NetworkType; +import androidx.work.Data; import com.example.snippets.R; public class ProfilingManagerJavaSnippets { + public class MainActivityJava extends Activity { + // [START android_profiling_manager_anr_case_study_java_snippet_2] private static final int NETWORK_TIMEOUT_MILLISECS = 2000; // [END android_profiling_manager_anr_case_study_java_snippet_2] @@ -48,6 +60,7 @@ public void accept(ProfilingResult profilingResult) { Log.d( "ProfileTest", "Received profiling result file=" + profilingResult.getResultFilePath()); + setupProfileUploadWorker(profilingResult.getResultFilePath()); } else { Log.e( "ProfileTest", @@ -123,17 +136,13 @@ public void accept(ProfilingResult profilingResult) { } // [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] - // [START android_profiling_manager_anr_case_study_java_snippet_1] public void addANRTrigger() { - ProfilingManager profilingManager = getApplicationContext().getSystemService(ProfilingManager.class); + ProfilingManager profilingManager = getApplicationContext().getSystemService( + ProfilingManager.class); List triggers = new ArrayList<>(); - ProfilingTrigger.Builder triggerBuilder = new ProfilingTrigger.Builder(ProfilingTrigger.TRIGGER_TYPE_ANR); + ProfilingTrigger.Builder triggerBuilder = new ProfilingTrigger.Builder( + ProfilingTrigger.TRIGGER_TYPE_ANR); triggers.add(triggerBuilder.build()); Executor mainExecutor = Executors.newSingleThreadExecutor(); Consumer resultCallback = @@ -175,14 +184,15 @@ boolean performNetworkRequest(int timeoutMiliseconds) { try { if (Math.random() < 0.2) { // Simulate performing a network request by waiting a random period of time - int networkRequestTimeMs = (int)(Math.random() * timeoutMiliseconds); + int networkRequestTimeMs = (int) (Math.random() * timeoutMiliseconds); Thread.sleep(networkRequestTimeMs); return true; } else { // Simulate a timeout Thread.sleep(timeoutMiliseconds); } - } catch (InterruptedException e) {} + } catch (InterruptedException e) { + } return false; // [END_EXCLUDE] } @@ -190,7 +200,8 @@ boolean performNetworkRequest(int timeoutMiliseconds) { // [START_EXCLUDE silent] void cpuIntensiveComputation(int durationMs) { long start = System.currentTimeMillis(); - while (System.currentTimeMillis() - start < durationMs) {} + while (System.currentTimeMillis() - start < durationMs) { + } } // [END_EXCLUDE silent] @@ -208,5 +219,43 @@ public void handleNetworkResponse() { Trace.endSection(); } // [END android_profiling_manager_anr_case_study_java_snippet_2] + + // [START android_profiling_manager_trace_upload_job_java] + public static class TraceUploadWorker extends Worker { + + public TraceUploadWorker( + @androidx.annotation.NonNull Context context, + @androidx.annotation.NonNull WorkerParameters workerParams) { + super(context, workerParams); + } + + @androidx.annotation.NonNull + @Override + public Result doWork() { + // Perform your uploading work here + Log.d("ProfileTest", "Uploading trace: " + getInputData().getString("PROFILE_PATH")); + + return Result.success(); + } + } + + public void setupProfileUploadWorker(String profileFilepath) { + WorkManager workMgr = WorkManager.getInstance(getApplicationContext()); + OneTimeWorkRequest.Builder workRequestBuilder = new OneTimeWorkRequest.Builder( + TraceUploadWorker.class); + + Constraints constraints = new Constraints.Builder() + .setRequiredNetworkType(NetworkType.UNMETERED) + .setRequiresDeviceIdle(true) + .build(); + workRequestBuilder.setConstraints(constraints); + + Data.Builder inputDataBuilder = new Data.Builder(); + inputDataBuilder.putString("PROFILE_PATH", profileFilepath); + workRequestBuilder.setInputData(inputDataBuilder.build()); + + workMgr.enqueue(workRequestBuilder.build()); + } + // [END android_profiling_manager_trace_upload_job_java] } -} +} \ No newline at end of file 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 b54ba67b0..ce977c874 100644 --- a/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt +++ b/misc/src/main/java/com/example/snippets/profiling/ProfilingManagerKotlinSnippets.kt @@ -17,6 +17,7 @@ package com.example.snippets.profiling import android.app.Activity +import android.content.Context import android.os.Build import android.os.Bundle import android.os.CancellationSignal @@ -30,6 +31,13 @@ import androidx.core.os.BufferFillPolicy import androidx.core.os.SystemTraceRequestBuilder import androidx.core.os.requestProfiling import androidx.tracing.Trace +import androidx.work.Constraints +import androidx.work.Data +import androidx.work.NetworkType +import androidx.work.OneTimeWorkRequest +import androidx.work.WorkManager +import androidx.work.Worker +import androidx.work.WorkerParameters import java.util.ArrayList import java.util.concurrent.Executor import java.util.concurrent.Executors @@ -131,10 +139,33 @@ class ProfilingManagerKotlinSnippets { } // [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. + // [START android_profiling_manager_trace_upload_job_kotlin] // [START android_profiling_manager_trace_upload_job_kotlin] + class TraceUploadWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) { + override fun doWork(): Result { + // Perform your uploading work here + Log.d("ProfileTest", "Uploading trace: " + inputData.getString("PROFILE_PATH")) + + return Result.success() + } + } + + fun setupProfileUploadWorker(profileFilepath: String?) { + val workMgr = WorkManager.getInstance(applicationContext) + val workRequestBuilder = OneTimeWorkRequest.Builder(TraceUploadWorker::class) + + val constraints = Constraints.Builder() + .setRequiredNetworkType(NetworkType.UNMETERED) + .setRequiresDeviceIdle(true) + .setRequiresCharging(true) + .build() + workRequestBuilder.setConstraints(constraints) + + val inputDataBuilder = Data.Builder() + inputDataBuilder.putString("PROFILE_PATH", profileFilepath) + workRequestBuilder.setInputData(inputDataBuilder.build()) + + workMgr.enqueue(workRequestBuilder.build()) } - // [END android_profiling_manager_triggered_trace_setup_upload_job] + // [END android_profiling_manager_trace_upload_job_kotlin] } }