Skip to content
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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" }
Expand Down
1 change: 1 addition & 0 deletions misc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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]
Expand All @@ -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",
Expand Down Expand Up @@ -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<ProfilingTrigger> 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<ProfilingResult> resultCallback =
Expand Down Expand Up @@ -175,22 +184,24 @@ 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]
}

// [START_EXCLUDE silent]
void cpuIntensiveComputation(int durationMs) {
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < durationMs) {}
while (System.currentTimeMillis() - start < durationMs) {
}
}
// [END_EXCLUDE silent]

Expand All @@ -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]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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]
}
}