[automerger skipped] Make java_sdk_library dependencies explicit am: aa1f841d6a am: fe4428cb57 -s ours
am skip reason: Merged-In Ie32d1ce49e69a25c360b1980da6fd0803bf9015f with SHA-1 056ef46efa is already in history
Original change: https://android-review.googlesource.com/c/platform/packages/modules/Profiling/+/3248209
Change-Id: Ic13019e2c86dc6efbfbb88c347f36e0f45d4c805
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/TEST_MAPPING b/TEST_MAPPING
index be1f046..728e4cf 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -1,4 +1,14 @@
{
+ "mainline-presubmit": [
+ {
+ "name": "CtsProfilingModuleTests[com.google.android.profiling.apex]",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.LargeTest"
+ }
+ ]
+ }
+ ],
"presubmit": [
{
"name": "CtsProfilingModuleTests",
diff --git a/framework/java/android/os/ProfilingManager.java b/framework/java/android/os/ProfilingManager.java
index 011738f..c0db9c7 100644
--- a/framework/java/android/os/ProfilingManager.java
+++ b/framework/java/android/os/ProfilingManager.java
@@ -38,7 +38,39 @@
import java.util.function.Consumer;
/**
- * API for apps to request and listen for app specific profiling.
+ * <p>
+ * This class allows the caller to request profiling and listen for results. Profiling types
+ * supported are: system traces, java heap dumps, heap profiles, and stack traces.
+ * </p>
+ *
+ * <p>
+ * The {@link #requestProfiling} API can be used to begin profiling. Profiling may be ended manually
+ * using the CancellationSignal provided in the request, or as a result of a timeout. The timeout
+ * may be either the system default or caller defined in the parameter bundle for select types.
+ * </p>
+ *
+ * <p>
+ * The profiling results are delivered to the requesting app's data directory and a pointer to the
+ * file will be received using the app provided listeners.
+ * </p>
+ *
+ * <p>
+ * Apps can provide listeners in one or both of two ways:
+ * - A request-specific listener included with the request. This will trigger only with a result
+ * from the request it was provided with.
+ * - A global listener provided by {@link #registerForAllProfilingResults}. This will be triggered
+ * for all results belonging to your app.
+ * </p>
+ *
+ * <p>
+ * Requests are rate limited and not guaranteed to be filled. Rate limiting can be disabled for
+ * local testing using the shell command
+ * {@code device_config put profiling_testing rate_limiter.disabled true}
+ * </p>
+ *
+ * <p>
+ * Results are redacted and contain specific information about the requesting process only.
+ * </p>
*/
@FlaggedApi(Flags.FLAG_TELEMETRY_APIS)
public final class ProfilingManager {
@@ -156,7 +188,7 @@
* <p>
* Both a listener and an executor must be set at the time of the request for the request to
* be considered for fulfillment. Listener/executor pairs can be set in this method, with
- * {@link registerForAllProfilingResults}, or both. The listener and executor must be set
+ * {@link #registerForAllProfilingResults}, or both. The listener and executor must be set
* together, in the same call. If no listener and executor combination is set, the request
* will be discarded and no callback will be received.
* </p>
@@ -168,7 +200,7 @@
* <p>
* 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 {@link cancellationSignal}
+ * we recommend starting the collection early and stopping it with {@code cancellationSignal}
* 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
@@ -178,9 +210,9 @@
* @param profilingType Type of profiling to collect.
* @param parameters Bundle of request related parameters. If the bundle contains any
* unrecognized parameters, the request will be fail with
- * {@link #ProfilingResult#ERROR_FAILED_INVALID_REQUEST}. If the values for
- * the parameters are out of supported range, the closest possible in range
- * value will be chosen.
+ * {@link android.os.ProfilingResult#ERROR_FAILED_INVALID_REQUEST}. If the
+ * values for the parameters are out of supported range, the closest possible
+ * in range value will be chosen.
* Use of androidx wrappers is recommended over generating this directly.
* @param tag Caller defined data to help identify the output.
* The first 20 alphanumeric characters, plus dashes, will be lowercased
diff --git a/tests/cts/Android.bp b/tests/cts/Android.bp
index 9fe0b01..aa9b919 100644
--- a/tests/cts/Android.bp
+++ b/tests/cts/Android.bp
@@ -24,13 +24,20 @@
"android.test.mock.stubs.system",
"junit",
],
+ // include both the 32 and 64 bit versions
+ compile_multilib: "both",
srcs: [
"src/android/profiling/cts/*.java",
],
+ jni_libs: [
+ "libcts_profiling_module_test_native",
+ ],
jarjar_rules: "jarjar-rules.txt",
test_suites: [
"cts",
"general-tests",
+ "mts-profiling",
+ "mcts-profiling",
],
min_sdk_version: "35",
sdk_version: "module_current",
diff --git a/tests/cts/AndroidTest.xml b/tests/cts/AndroidTest.xml
index 5262996..6c955a7 100644
--- a/tests/cts/AndroidTest.xml
+++ b/tests/cts/AndroidTest.xml
@@ -14,7 +14,7 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
-<configuration description="Config for Profiling service test cases">
+<configuration description="Config for Profiling test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="systems" />
<option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
diff --git a/tests/cts/jni/Android.bp b/tests/cts/jni/Android.bp
new file mode 100644
index 0000000..bae6880
--- /dev/null
+++ b/tests/cts/jni/Android.bp
@@ -0,0 +1,13 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library_shared {
+ name: "libcts_profiling_module_test_native",
+ compile_multilib: "both",
+ header_libs: ["jni_headers"],
+ srcs: [
+ "target.c",
+ ],
+ sdk_version: "current",
+}
diff --git a/tests/cts/jni/target.c b/tests/cts/jni/target.c
new file mode 100644
index 0000000..d977650
--- /dev/null
+++ b/tests/cts/jni/target.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <jni.h>
+#include <stdlib.h>
+
+JNIEXPORT void JNICALL
+Java_android_profiling_cts_ProfilingFrameworkTests_doMallocAndFree(JNIEnv* env,
+ jclass klass) {
+ (void) env;
+ (void) klass;
+ volatile char* x = malloc(4200);
+ if (x) {
+ x[0] = '\0';
+ free((char*)x);
+ }
+}
diff --git a/tests/cts/src/android/profiling/cts/ProfilingFrameworkTests.java b/tests/cts/src/android/profiling/cts/ProfilingFrameworkTests.java
index bf6def5..acf60b4 100644
--- a/tests/cts/src/android/profiling/cts/ProfilingFrameworkTests.java
+++ b/tests/cts/src/android/profiling/cts/ProfilingFrameworkTests.java
@@ -117,6 +117,10 @@
private Context mContext = null;
private Instrumentation mInstrumentation;
+ static {
+ System.loadLibrary("cts_profiling_module_test_native");
+ }
+
@Rule
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
@@ -251,9 +255,13 @@
new ProfilingTestUtils.ImmediateExecutor(),
callback);
+ MallocLoopThread mallocThread = new MallocLoopThread();
+
// Wait until callback#onAccept is triggered so we can confirm the result.
waitForCallback(callback);
+ mallocThread.stop();
+
// Assert that result matches assumptions for success.
confirmCollectionSuccess(callback.mResult, OUTPUT_FILE_HEAP_PROFILE_SUFFIX);
dumpTrace(callback.mResult);
@@ -992,6 +1000,8 @@
}
}
+ private static native void doMallocAndFree();
+
public static class AppCallback implements Consumer<ProfilingResult> {
public ProfilingResult mResult;
@@ -1025,4 +1035,30 @@
}
}
}
+
+ // Starts a thread that repeatedly issues malloc() and free().
+ private static class MallocLoopThread {
+ private Thread thread;
+ private AtomicBoolean done = new AtomicBoolean(false);
+
+ public MallocLoopThread() {
+ done.set(false);
+ thread = new Thread(() -> {
+ while (!done.get()) {
+ doMallocAndFree();
+ sleep(10);
+ }
+ });
+ thread.start();
+ }
+
+ public void stop() {
+ done.set(true);
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ throw new AssertionError("InterruptedException", e);
+ }
+ }
+ }
}