Snap for 13174046 from d0548f27624b987c936e83c8bfd67a771ed28c4c to 25Q2-release

Change-Id: I78602e66b2a83e6009000b2eccedf1a9e2435ec8
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt
index 4bfad62..4aac37a 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt
@@ -139,10 +139,7 @@
         val displaySize = intent.getParcelableExtra(EXTRA_DISPLAY_INFO, DisplayInfo::class.java)
 
         customImageConfigBuilder.setAudioConfig(
-            AudioConfig.Builder()
-                .setUseSpeaker(true)
-                .setUseMicrophone(true)
-                .build()
+            AudioConfig.Builder().setUseSpeaker(true).setUseMicrophone(true).build()
         )
         if (overrideConfigIfNecessary(customImageConfigBuilder, displaySize)) {
             configBuilder.setCustomImageConfig(customImageConfigBuilder.build())
@@ -258,6 +255,21 @@
             )
             Toast.makeText(this, R.string.virgl_enabled, Toast.LENGTH_SHORT).show()
             changed = true
+        } else if (Files.exists(ImageArchive.getSdcardPathForTesting().resolve("gfxstream"))) {
+            // TODO: check if the configuration is right. current config comes from cuttlefish's one
+            builder.setGpuConfig(
+                VirtualMachineCustomImageConfig.GpuConfig.Builder()
+                    .setBackend("gfxstream")
+                    .setRendererUseEgl(false)
+                    .setRendererUseGles(false)
+                    .setRendererUseGlx(false)
+                    .setRendererUseSurfaceless(true)
+                    .setRendererUseVulkan(true)
+                    .setContextTypes(arrayOf<String>("gfxstream-vulkan", "gfxstream-composer"))
+                    .build()
+            )
+            Toast.makeText(this, "gfxstream", Toast.LENGTH_SHORT).show()
+            changed = true
         }
 
         // Set the initial display size
diff --git a/android/vm_demo_native/main.cpp b/android/vm_demo_native/main.cpp
index e1acc05..8fc14bf 100644
--- a/android/vm_demo_native/main.cpp
+++ b/android/vm_demo_native/main.cpp
@@ -329,11 +329,15 @@
                                                                       &ARpcSession_free);
     ARpcSession_setMaxIncomingThreads(session.get(), 1);
 
+    auto param = std::make_unique<std::shared_ptr<IVirtualMachine>>(std::move(vm));
+    auto paramDeleteFd = [](void* param) {
+        delete static_cast<std::shared_ptr<IVirtualMachine>*>(param);
+    };
+
     AIBinder* binder = ARpcSession_setupPreconnectedClient(
             session.get(),
             [](void* param) {
-                std::shared_ptr<IVirtualMachine> vm =
-                        *static_cast<std::shared_ptr<IVirtualMachine>*>(param);
+                IVirtualMachine* vm = static_cast<std::shared_ptr<IVirtualMachine>*>(param)->get();
                 ScopedFileDescriptor sock_fd;
                 ScopedAStatus ret = vm->connectVsock(ITestService::PORT, &sock_fd);
                 if (!ret.isOk()) {
@@ -341,7 +345,7 @@
                 }
                 return sock_fd.release();
             },
-            &vm);
+            param.release(), paramDeleteFd);
     if (binder == nullptr) {
         return Error() << "Failed to connect to vm payload";
     }
diff --git a/build/apex/manifest.json b/build/apex/manifest.json
index b32aa7b..e596ce1 100644
--- a/build/apex/manifest.json
+++ b/build/apex/manifest.json
@@ -3,6 +3,7 @@
   "version": 2,
   "requireNativeLibs": [
     "libEGL.so",
-    "libGLESv2.so"
+    "libGLESv2.so",
+    "libvulkan.so"
   ]
 }
diff --git a/build/compos/CompOSPayloadApp/Android.bp b/build/compos/CompOSPayloadApp/Android.bp
index c6192b9..04465b3 100644
--- a/build/compos/CompOSPayloadApp/Android.bp
+++ b/build/compos/CompOSPayloadApp/Android.bp
@@ -5,5 +5,6 @@
 android_app {
     name: "CompOSPayloadApp",
     sdk_version: "current",
+    system_ext_specific: true,
     apex_available: ["com.android.compos"],
 }
diff --git a/guest/forwarder_guest_launcher/debian/service b/guest/forwarder_guest_launcher/debian/service
index 6824c70..ad57a26 100644
--- a/guest/forwarder_guest_launcher/debian/service
+++ b/guest/forwarder_guest_launcher/debian/service
@@ -11,6 +11,8 @@
 RestartSec=1
 User=root
 Group=root
+StandardOutput=journal
+StandardError=journal
 
 [Install]
 WantedBy=multi-user.target
diff --git a/guest/shutdown_runner/debian/service b/guest/shutdown_runner/debian/service
index 7188d36..2668930 100644
--- a/guest/shutdown_runner/debian/service
+++ b/guest/shutdown_runner/debian/service
@@ -10,6 +10,8 @@
 RestartSec=1
 User=root
 Group=root
+StandardOutput=journal
+StandardError=journal
 
 [Install]
 WantedBy=multi-user.target
diff --git a/libs/libservice_vm_requests/src/client_vm.rs b/libs/libservice_vm_requests/src/client_vm.rs
index 4e54510..8ad10fd 100644
--- a/libs/libservice_vm_requests/src/client_vm.rs
+++ b/libs/libservice_vm_requests/src/client_vm.rs
@@ -25,7 +25,7 @@
 use core::result;
 use coset::{AsCborValue, CborSerializable, CoseSign, CoseSign1};
 use der::{Decode, Encode};
-use diced_open_dice::{DiceArtifacts, HASH_SIZE};
+use diced_open_dice::DiceArtifacts;
 use log::{debug, error, info};
 use microdroid_kernel_hashes::{HASH_SIZE as KERNEL_HASH_SIZE, OS_HASHES};
 use service_vm_comm::{ClientVmAttestationParams, Csr, CsrPayload, RequestProcessingError};
@@ -252,7 +252,7 @@
     Ok(false)
 }
 
-fn expected_kernel_authority_hash(service_vm_entry: &Value) -> Result<[u8; HASH_SIZE]> {
+fn expected_kernel_authority_hash(service_vm_entry: &Value) -> Result<Vec<u8>> {
     let cose_sign1 = CoseSign1::from_cbor_value(service_vm_entry.clone())?;
     let payload = cose_sign1.payload.ok_or_else(|| {
         error!("No payload found in the service VM DICE chain entry");
diff --git a/libs/libservice_vm_requests/src/dice.rs b/libs/libservice_vm_requests/src/dice.rs
index ef9d894..ba67450 100644
--- a/libs/libservice_vm_requests/src/dice.rs
+++ b/libs/libservice_vm_requests/src/dice.rs
@@ -19,8 +19,8 @@
 use alloc::vec::Vec;
 use bssl_avf::{ed25519_verify, Digester, EcKey};
 use cbor_util::{
-    cbor_value_type, get_label_value, get_label_value_as_bytes, value_to_array,
-    value_to_byte_array, value_to_bytes, value_to_map, value_to_num, value_to_text,
+    cbor_value_type, get_label_value, get_label_value_as_bytes, value_to_array, value_to_bytes,
+    value_to_map, value_to_num, value_to_text,
 };
 use ciborium::value::Value;
 use core::cell::OnceCell;
@@ -31,7 +31,7 @@
     Algorithm, AsCborValue, CborSerializable, CoseError, CoseKey, CoseSign1, KeyOperation, KeyType,
     Label,
 };
-use diced_open_dice::{DiceMode, HASH_SIZE};
+use diced_open_dice::DiceMode;
 use log::{debug, error, info};
 use service_vm_comm::RequestProcessingError;
 
@@ -288,8 +288,8 @@
 pub(crate) struct DiceChainEntryPayload {
     pub(crate) subject_public_key: PublicKey,
     mode: DiceMode,
-    pub(crate) code_hash: [u8; HASH_SIZE],
-    pub(crate) authority_hash: [u8; HASH_SIZE],
+    pub(crate) code_hash: Vec<u8>,
+    pub(crate) authority_hash: Vec<u8>,
     config_descriptor: ConfigDescriptor,
 }
 
@@ -327,12 +327,12 @@
                 }
                 MODE => builder.mode(to_mode(value)?)?,
                 CODE_HASH => {
-                    let code_hash = value_to_byte_array(value, "DiceChainEntryPayload code_hash")?;
+                    let code_hash = value_to_bytes(value, "DiceChainEntryPayload code_hash")?;
                     builder.code_hash(code_hash)?;
                 }
                 AUTHORITY_HASH => {
                     let authority_hash =
-                        value_to_byte_array(value, "DiceChainEntryPayload authority_hash")?;
+                        value_to_bytes(value, "DiceChainEntryPayload authority_hash")?;
                     builder.authority_hash(authority_hash)?;
                 }
                 CONFIG_DESC => {
@@ -524,8 +524,8 @@
 struct PayloadBuilder {
     subject_public_key: OnceCell<PublicKey>,
     mode: OnceCell<DiceMode>,
-    code_hash: OnceCell<[u8; HASH_SIZE]>,
-    authority_hash: OnceCell<[u8; HASH_SIZE]>,
+    code_hash: OnceCell<Vec<u8>>,
+    authority_hash: OnceCell<Vec<u8>>,
     config_descriptor: OnceCell<ConfigDescriptor>,
 }
 
@@ -552,11 +552,11 @@
         set_once(&self.mode, mode, "mode")
     }
 
-    fn code_hash(&mut self, code_hash: [u8; HASH_SIZE]) -> Result<()> {
+    fn code_hash(&mut self, code_hash: Vec<u8>) -> Result<()> {
         set_once(&self.code_hash, code_hash, "code_hash")
     }
 
-    fn authority_hash(&mut self, authority_hash: [u8; HASH_SIZE]) -> Result<()> {
+    fn authority_hash(&mut self, authority_hash: Vec<u8>) -> Result<()> {
         set_once(&self.authority_hash, authority_hash, "authority_hash")
     }
 
@@ -570,7 +570,9 @@
         // the Open Profile for DICE spec.
         let mode = self.mode.take().unwrap_or(DiceMode::kDiceModeNotInitialized);
         let code_hash = take_value(&mut self.code_hash, "code_hash")?;
+        validate_hash_size(code_hash.len(), "code_hash")?;
         let authority_hash = take_value(&mut self.authority_hash, "authority_hash")?;
+        validate_hash_size(authority_hash.len(), "authority_hash")?;
         let config_descriptor = take_value(&mut self.config_descriptor, "config_descriptor")?;
         Ok(DiceChainEntryPayload {
             subject_public_key,
@@ -581,3 +583,18 @@
         })
     }
 }
+
+fn validate_hash_size(len: usize, name: &str) -> Result<()> {
+    // According to the Android Profile for DICE specification, SHA-256, SHA-384, and SHA-512
+    // are all acceptable hash algorithms.
+    const ACCEPTABLE_HASH_SIZES: [usize; 3] = [32, 48, 64];
+    if ACCEPTABLE_HASH_SIZES.contains(&len) {
+        Ok(())
+    } else {
+        error!(
+            "Invalid hash size for {}: {}. Acceptable hash sizes are: {:?}",
+            name, len, ACCEPTABLE_HASH_SIZES
+        );
+        Err(RequestProcessingError::InvalidDiceChain)
+    }
+}
diff --git a/libs/libvirtualization_jni/android_system_virtualmachine_VirtualMachine.cpp b/libs/libvirtualization_jni/android_system_virtualmachine_VirtualMachine.cpp
index 67a4716..8452344 100644
--- a/libs/libvirtualization_jni/android_system_virtualmachine_VirtualMachine.cpp
+++ b/libs/libvirtualization_jni/android_system_virtualmachine_VirtualMachine.cpp
@@ -59,28 +59,29 @@
         JNIEnv *mEnv;
         jobject mProvider;
         jmethodID mMid;
-    } state;
+    };
 
-    state.mEnv = env;
-    state.mProvider = provider;
-    state.mMid = mid;
+    auto state = std::make_unique<State>(env, provider, mid);
 
     using RequestFun = int (*)(void *);
     RequestFun requestFunc = [](void *param) -> int {
-        State *state = reinterpret_cast<State *>(param);
+        State *state = static_cast<State *>(param);
         int ownedFd = state->mEnv->CallIntMethod(state->mProvider, state->mMid);
         // FD is owned by PFD in Java layer, need to dupe it so that
         // ARpcSession_setupPreconnectedClient can take ownership when it calls unique_fd internally
         return fcntl(ownedFd, F_DUPFD_CLOEXEC, 0);
     };
 
+    auto paramDeleteFunc = [](void *param) { delete static_cast<State *>(param); };
+
     RpcSessionHandle session;
     // We need a thread pool to be able to support linkToDeath, or callbacks
     // (b/268335700). These threads are currently created eagerly, so we don't
     // want too many. The number 1 is chosen after some discussion, and to match
     // the server-side default (mMaxThreads on RpcServer).
     ARpcSession_setMaxIncomingThreads(session.get(), 1);
-    auto client = ARpcSession_setupPreconnectedClient(session.get(), requestFunc, &state);
+    auto client = ARpcSession_setupPreconnectedClient(session.get(), requestFunc, state.release(),
+                                                      paramDeleteFunc);
     return AIBinder_toJavaBinder(env, client);
 }