Merge "Relax integer limits in argument handling of native Zygote loop" into main
diff --git a/keystore/java/android/security/GateKeeper.java b/keystore/java/android/security/GateKeeper.java
index 464714f..c2792e1f 100644
--- a/keystore/java/android/security/GateKeeper.java
+++ b/keystore/java/android/security/GateKeeper.java
@@ -28,7 +28,7 @@
  *
  * @hide
  */
-public abstract class GateKeeper {
+public final class GateKeeper {
 
     public static final long INVALID_SECURE_USER_ID = 0;
 
diff --git a/keystore/java/android/security/keystore/ArrayUtils.java b/keystore/java/android/security/keystore/ArrayUtils.java
index f22b604..6472ca9 100644
--- a/keystore/java/android/security/keystore/ArrayUtils.java
+++ b/keystore/java/android/security/keystore/ArrayUtils.java
@@ -23,7 +23,7 @@
 /**
  * @hide
  */
-public abstract class ArrayUtils {
+public final class ArrayUtils {
     private ArrayUtils() {}
 
     public static String[] nullToEmpty(String[] array) {
diff --git a/keystore/java/android/security/keystore/Utils.java b/keystore/java/android/security/keystore/Utils.java
index e58b1cc..c38ce8e 100644
--- a/keystore/java/android/security/keystore/Utils.java
+++ b/keystore/java/android/security/keystore/Utils.java
@@ -23,7 +23,7 @@
  *
  * @hide
  */
-abstract class Utils {
+public final class Utils {
     private Utils() {}
 
     static Date cloneIfNotNull(Date value) {
diff --git a/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java b/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java
index 1394bd4..9d306ce 100644
--- a/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java
+++ b/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java
@@ -38,7 +38,9 @@
 /**
  * @hide
  */
-public abstract class KeyStore2ParameterUtils {
+public final class KeyStore2ParameterUtils {
+
+    private KeyStore2ParameterUtils() {}
 
     /**
      * This function constructs a {@link KeyParameter} expressing a boolean value.
diff --git a/keystore/java/android/security/keystore2/KeymasterUtils.java b/keystore/java/android/security/keystore2/KeymasterUtils.java
index 614e368..02f3f57 100644
--- a/keystore/java/android/security/keystore2/KeymasterUtils.java
+++ b/keystore/java/android/security/keystore2/KeymasterUtils.java
@@ -16,13 +16,10 @@
 
 package android.security.keystore2;
 
-import android.security.keymaster.KeymasterArguments;
 import android.security.keymaster.KeymasterDefs;
-import android.security.keystore.KeyProperties;
 
 import java.security.AlgorithmParameters;
 import java.security.NoSuchAlgorithmException;
-import java.security.ProviderException;
 import java.security.spec.ECGenParameterSpec;
 import java.security.spec.ECParameterSpec;
 import java.security.spec.InvalidParameterSpecException;
@@ -30,7 +27,7 @@
 /**
  * @hide
  */
-public abstract class KeymasterUtils {
+public final class KeymasterUtils {
 
     private KeymasterUtils() {}
 
@@ -86,47 +83,6 @@
         }
     }
 
-    /**
-     * Adds {@code KM_TAG_MIN_MAC_LENGTH} tag, if necessary, to the keymaster arguments for
-     * generating or importing a key. This tag may only be needed for symmetric keys (e.g., HMAC,
-     * AES-GCM).
-     */
-    public static void addMinMacLengthAuthorizationIfNecessary(KeymasterArguments args,
-            int keymasterAlgorithm,
-            int[] keymasterBlockModes,
-            int[] keymasterDigests) {
-        switch (keymasterAlgorithm) {
-            case KeymasterDefs.KM_ALGORITHM_AES:
-                if (com.android.internal.util.ArrayUtils.contains(
-                        keymasterBlockModes, KeymasterDefs.KM_MODE_GCM)) {
-                    // AES GCM key needs the minimum length of AEAD tag specified.
-                    args.addUnsignedInt(KeymasterDefs.KM_TAG_MIN_MAC_LENGTH,
-                            AndroidKeyStoreAuthenticatedAESCipherSpi.GCM
-                                    .MIN_SUPPORTED_TAG_LENGTH_BITS);
-                }
-                break;
-            case KeymasterDefs.KM_ALGORITHM_HMAC:
-                // HMAC key needs the minimum length of MAC set to the output size of the associated
-                // digest. This is because we do not offer a way to generate shorter MACs and
-                // don't offer a way to verify MACs (other than by generating them).
-                if (keymasterDigests.length != 1) {
-                    throw new ProviderException(
-                            "Unsupported number of authorized digests for HMAC key: "
-                                    + keymasterDigests.length
-                                    + ". Exactly one digest must be authorized");
-                }
-                int keymasterDigest = keymasterDigests[0];
-                int digestOutputSizeBits = getDigestOutputSizeBits(keymasterDigest);
-                if (digestOutputSizeBits == -1) {
-                    throw new ProviderException(
-                            "HMAC key authorized for unsupported digest: "
-                                    + KeyProperties.Digest.fromKeymaster(keymasterDigest));
-                }
-                args.addUnsignedInt(KeymasterDefs.KM_TAG_MIN_MAC_LENGTH, digestOutputSizeBits);
-                break;
-        }
-    }
-
     static String getEcCurveFromKeymaster(int ecCurve) {
         switch (ecCurve) {
             case android.hardware.security.keymint.EcCurve.P_224:
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 871fadf..0bea5a9 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -4054,6 +4054,7 @@
          * Finish building a queue request and queue the buffers with tunings.
          */
         public void queue() {
+            Trace.traceBegin(Trace.TRACE_TAG_VIDEO, "MediaCodec::queueRequest-queue#java");
             if (!isAccessible()) {
                 throw new IllegalStateException("The request is stale");
             }
@@ -4082,6 +4083,7 @@
                         mTuningKeys, mTuningValues);
             }
             clear();
+            Trace.traceEnd(Trace.TRACE_TAG_VIDEO);
         }
 
         @NonNull QueueRequest clear() {
diff --git a/ravenwood/runtime-jni/ravenwood_initializer.cpp b/ravenwood/runtime-jni/ravenwood_initializer.cpp
index 391c5d5..8a35ade 100644
--- a/ravenwood/runtime-jni/ravenwood_initializer.cpp
+++ b/ravenwood/runtime-jni/ravenwood_initializer.cpp
@@ -26,6 +26,10 @@
 #include <fcntl.h>
 
 #include <set>
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <cstdlib>
 
 #include "jni_helper.h"
 
@@ -182,17 +186,82 @@
     }
 }
 
+// Find the PPID of child_pid using /proc/N/stat. The 4th field is the PPID.
+// Also returns child_pid's process name (2nd field).
+static pid_t getppid_of(pid_t child_pid, std::string& out_process_name) {
+    if (child_pid < 0) {
+        return -1;
+    }
+    std::string stat_file = "/proc/" + std::to_string(child_pid) + "/stat";
+    std::ifstream stat_stream(stat_file);
+    if (!stat_stream.is_open()) {
+        ALOGW("Unable to open '%s': %s", stat_file.c_str(), strerror(errno));
+        return -1;
+    }
+
+    std::string field;
+    int field_count = 0;
+    while (std::getline(stat_stream, field, ' ')) {
+        if (++field_count == 4) {
+            return atoi(field.c_str());
+        }
+        if (field_count == 2) {
+            out_process_name = field;
+        }
+    }
+    ALOGW("Unexpected format in '%s'", stat_file.c_str());
+    return -1;
+}
+
+// Find atest's PID. Climb up the process tree, and find "atest-py3".
+static pid_t find_atest_pid() {
+    auto ret = getpid(); // self (isolation runner process)
+
+    while (ret != -1) {
+        std::string proc;
+        ret = getppid_of(ret, proc);
+        if (proc == "(atest-py3)") {
+            return ret;
+        }
+    }
+
+    return ret;
+}
+
+// If $RAVENWOOD_LOG_OUT is set, redirect stdout/err to this file.
+// Originally it was added to allow to monitor log in realtime, with
+// RAVENWOOD_LOG_OUT=$(tty) atest...
+//
+// As a special case, if $RAVENWOOD_LOG_OUT is set to "-", we try to find
+// atest's process and send the output to its stdout. It's sort of hacky, but
+// this allows shell redirection to work on Ravenwood output too,
+// so e.g. `atest ... |tee atest.log` would work on Ravenwood's output.
+// (which wouldn't work with `RAVENWOOD_LOG_OUT=$(tty)`).
+//
+// Otherwise -- if $RAVENWOOD_LOG_OUT isn't set -- atest/tradefed just writes
+// the test's output to its own log file.
 static void maybeRedirectLog() {
     auto ravenwoodLogOut = getenv("RAVENWOOD_LOG_OUT");
-    if (ravenwoodLogOut == NULL) {
+    if (ravenwoodLogOut == NULL || *ravenwoodLogOut == '\0') {
         return;
     }
-    ALOGI("RAVENWOOD_LOG_OUT set. Redirecting output to %s", ravenwoodLogOut);
+    std::string path;
+    if (strcmp("-", ravenwoodLogOut) == 0) {
+        pid_t ppid = find_atest_pid();
+        if (ppid < 0) {
+            ALOGI("RAVENWOOD_LOG_OUT set to '-', but unable to find atest's PID");
+            return;
+        }
+        path = std::format("/proc/{}/fd/1", ppid);
+    } else {
+        path = ravenwoodLogOut;
+    }
+    ALOGI("RAVENWOOD_LOG_OUT set. Redirecting output to '%s'", path.c_str());
 
     // Redirect stdin / stdout to /dev/tty.
-    int ttyFd = open(ravenwoodLogOut, O_WRONLY | O_APPEND);
+    int ttyFd = open(path.c_str(), O_WRONLY | O_APPEND);
     if (ttyFd == -1) {
-        ALOGW("$RAVENWOOD_LOG_OUT is set to %s, but failed to open: %s ", ravenwoodLogOut,
+        ALOGW("$RAVENWOOD_LOG_OUT is set, but failed to open '%s': %s ", path.c_str(),
                 strerror(errno));
         return;
     }