Snap for 11517216 from 367c96bc9b298c17327704e658e30d7a09670b75 to 24D1-release

Change-Id: Id0e0227ac5a4fd3ed62c969caaaa94615672afd9
diff --git a/framework/api/current.txt b/framework/api/current.txt
index a98f106..705a99f 100644
--- a/framework/api/current.txt
+++ b/framework/api/current.txt
@@ -2,9 +2,9 @@
 package android.os {
 
   @FlaggedApi("android.os.profiling.telemetry_apis") public final class ProfilingManager {
-    method public void registerForProfilingResults(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.os.ProfilingResult>);
+    method public void registerForAllProfilingResults(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.os.ProfilingResult>);
     method public void requestProfiling(@NonNull byte[], @Nullable String, @Nullable android.os.CancellationSignal, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<android.os.ProfilingResult>);
-    method public void unregisterForProfilingResults(@NonNull java.util.function.Consumer<android.os.ProfilingResult>);
+    method public void unregisterForAllProfilingResults(@Nullable java.util.function.Consumer<android.os.ProfilingResult>);
   }
 
   @FlaggedApi("android.os.profiling.telemetry_apis") public final class ProfilingResult implements android.os.Parcelable {
diff --git a/framework/java/android/os/ProfilingManager.java b/framework/java/android/os/ProfilingManager.java
index fc8e4d1..29b448d 100644
--- a/framework/java/android/os/ProfilingManager.java
+++ b/framework/java/android/os/ProfilingManager.java
@@ -71,7 +71,7 @@
     }
 
     /**
-     * Request profiling via perfetto.
+     * Request system profiling.
      *
      * <p class="note"> Note: use of this API directly is not recommended for most use cases.
      * Please use the higher level wrappers provided by androidx that will construct the request
@@ -79,17 +79,28 @@
      *
      * <p class="note"> Note: requests are not guaranteed to be filled.</p>
      *
-     * <p class="note"> Note: a listener must be set for the request to be considered for
-     * fulfillment. Listeners can be set in this method, with {@see #registerForProfilingResult},
-     * or both. If no listener is set the request will be discarded.</p>
+     * <p class="note"> Note: Both a listener and executor must be set for the request to be
+     * considered for fulfillment.
+     * Listeners can be set in this method, with {@link #registerForAllProfilingResults}, or both.
+     * If no listener and executor is set the request will be discarded.</p>
      *
      * @param profilingRequest byte array representation of ProfilingRequest proto containing all
-     *                         necessary information about the collection being requested.
+     *                  necessary information about the collection being requested.
+     *                  Use of androidx wrappers is recommended over generating this directly.
      * @param tag Caller defined data to help identify the output.
      * @param cancellationSignal for caller requested cancellation.
-     *                         Results will be returned if available.
-     * @param executor The executor to call back with.
-     * @param listener Listener to be triggered with result.
+     *                  Results will be returned if available.
+     *                  If this is null, the requesting app will not be able to stop the collection.
+     *                  The collection will stop after timing out with either the provided
+     *                  configurations or with system defaults
+     * @param executor  The executor to call back with.
+     *                  Will only be used for the listener provided in this method.
+     *                  If this is null, and no global executor and listener combinations are
+     *                  registered at the time of the request, the request will be dropped.
+     * @param listener  Listener to be triggered with result. Any global listeners registered via
+     *                  {@link #registerForAllProfilingResults} will also be triggered. If this is
+     *                  null, and no global listener and executor combinations are registered at
+     *                  the time of the request, the request will be dropped.
      */
     public void requestProfiling(
             @NonNull byte[] profilingRequest,
@@ -148,12 +159,13 @@
     }
 
     /**
-     * Register a listener to be called for all profiling results.
+     * Register a listener to be called for all profiling results for this uid. Listeners set here
+     * will be called in addition to any provided with the request.
      *
      * @param executor The executor to call back with.
      * @param listener Listener to be triggered with result.
      */
-    public void registerForProfilingResults(
+    public void registerForAllProfilingResults(
             @NonNull Executor executor,
             @NonNull Consumer<ProfilingResult> listener) {
         synchronized (sLock) {
@@ -162,24 +174,41 @@
     }
 
     /**
-     * Unregister a listener to be called for all profiling results. If no listener is provided,
-     * all listeners for this process that were not submitted with a currently running trace will
-     * be removed.
+     * Unregister a listener that was to be called for all profiling results. If no listener is
+     * provided, all listeners for this process that were not submitted with a profiling request
+     * will be removed.
      *
-     * @param listener Listener to unregister and no longer be triggered with the result.
+     * @param listener Listener to unregister and no longer be triggered with the results.
+     *                 Null to remove all global listeners for this uid.
      */
-    public void unregisterForProfilingResults(
-            @NonNull Consumer<ProfilingResult> listener) {
+    public void unregisterForAllProfilingResults(
+            @Nullable Consumer<ProfilingResult> listener) {
         synchronized (sLock) {
             if (mCallbacks.isEmpty()) {
                 // No callbacks, nothing to remove.
                 return;
             }
-            for (int i = 0; i < mCallbacks.size(); i++) {
-                ProfilingRequestCallbackWrapper wrapper = mCallbacks.get(i);
-                if (listener.equals(wrapper.mListener)) {
-                    mCallbacks.remove(i);
-                    return;
+
+            if (listener == null) {
+                // Remove all global listeners.
+                ArrayList<ProfilingRequestCallbackWrapper> listenersToRemove = new ArrayList<>();
+                for (int i = 0; i < mCallbacks.size(); i++) {
+                    ProfilingRequestCallbackWrapper wrapper = mCallbacks.get(i);
+                    // Only remove global listeners which are not tied to a specific request. These
+                    // can be identified by checking that they do not have an associated key.
+                    if (wrapper.mKey == null) {
+                        listenersToRemove.add(wrapper);
+                    }
+                }
+                mCallbacks.removeAll(listenersToRemove);
+            } else {
+                // Remove the provided listener only.
+                for (int i = 0; i < mCallbacks.size(); i++) {
+                    ProfilingRequestCallbackWrapper wrapper = mCallbacks.get(i);
+                    if (listener.equals(wrapper.mListener)) {
+                        mCallbacks.remove(i);
+                        return;
+                    }
                 }
             }
         }
@@ -202,7 +231,7 @@
             mProfilingService.registerResultsCallback(new IProfilingResultCallback.Stub() {
 
                 /**
-                 * Called by {@see ProfilingService} when a result is ready,
+                 * Called by {@link ProfilingService} when a result is ready,
                  * both for success and failure.
                  */
                 @Override
@@ -257,7 +286,7 @@
                 }
 
                 /**
-                 * Called by {@see ProfilingService} when a trace is ready and need to be copied
+                 * Called by {@link ProfilingService} when a trace is ready and need to be copied
                  * to callers internal storage.
                  *
                  * This method will open a new file and pass back the FileDescriptor for
@@ -309,8 +338,8 @@
         final @NonNull Consumer<ProfilingResult> mListener;
 
         /**
-         * Unique key generated with each profiling request {@see #requestProfiling}, but not with
-         * requests to register a listener only {@see #registerForProfilingResult}.
+         * Unique key generated with each profiling request {@link #requestProfiling}, but not with
+         * requests to register a listener only {@link #registerForAllProfilingResults}.
          *
          * Key is used to match the result with the listener added with the request so that it can
          * removed after being triggered while the general registered callbacks remain active.
diff --git a/service/java/com/android/os/profiling/Configs.java b/service/java/com/android/os/profiling/Configs.java
index ad3cb13..454928a 100644
--- a/service/java/com/android/os/profiling/Configs.java
+++ b/service/java/com/android/os/profiling/Configs.java
@@ -235,6 +235,8 @@
         } else if (config.hasSystemTrace()) {
             result = CONFIG_SYSTEM_TRACE.replace("{{duration}}",
                     String.valueOf(sDefaultTraceDurationMs));
+            // TODO: remove when redaction is hooked up b/327423523
+            throw new IllegalArgumentException("Trace is not supported until redaction lands");
         }
 
         if (result == null) {