Merge "Increase compos default memory" into main
diff --git a/Android.bp b/Android.bp
index 54919d4..696a963 100644
--- a/Android.bp
+++ b/Android.bp
@@ -28,6 +28,7 @@
         "release_avf_enable_multi_tenant_microdroid_vm",
         "release_avf_enable_remote_attestation",
         "release_avf_enable_vendor_modules",
+        "release_avf_enable_virt_cpufreq",
     ],
     properties: [
         "cfgs",
@@ -55,6 +56,9 @@
         release_avf_enable_vendor_modules: {
             cfgs: ["vendor_modules"],
         },
+        release_avf_enable_virt_cpufreq: {
+            cfgs: ["virt_cpufreq"],
+        },
     },
 }
 
diff --git a/tests/benchmark_hostside/java/android/avf/test/AVFHostTestCase.java b/tests/benchmark_hostside/java/android/avf/test/AVFHostTestCase.java
index b176cfc..f01a76b 100644
--- a/tests/benchmark_hostside/java/android/avf/test/AVFHostTestCase.java
+++ b/tests/benchmark_hostside/java/android/avf/test/AVFHostTestCase.java
@@ -231,7 +231,7 @@
         android.tryRun("rm", "-rf", MicrodroidHostTestCaseBase.TEST_ROOT);
 
         // Donate 80% of the available device memory to the VM
-        final String configPath = "assets/vm_config.json";
+        final String configPath = "assets/microdroid/vm_config.json";
         final int vm_mem_mb = getFreeMemoryInfoMb(android) * 80 / 100;
         ITestDevice microdroidDevice =
                 MicrodroidBuilder.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
diff --git a/tests/hostside/helper/java/com/android/microdroid/test/host/MicrodroidHostTestCaseBase.java b/tests/hostside/helper/java/com/android/microdroid/test/host/MicrodroidHostTestCaseBase.java
index 848b43b..9e19b7d 100644
--- a/tests/hostside/helper/java/com/android/microdroid/test/host/MicrodroidHostTestCaseBase.java
+++ b/tests/hostside/helper/java/com/android/microdroid/test/host/MicrodroidHostTestCaseBase.java
@@ -33,12 +33,17 @@
 import com.android.tradefed.util.CommandResult;
 import com.android.tradefed.util.RunUtil;
 
+import org.json.JSONArray;
+
 import java.io.File;
 import java.io.FileNotFoundException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 public abstract class MicrodroidHostTestCaseBase extends BaseHostJUnit4Test {
     protected static final String TEST_ROOT = "/data/local/tmp/virt/";
@@ -164,4 +169,35 @@
                 .that(pathLine).startsWith("package:");
         return pathLine.substring("package:".length());
     }
+
+    public List<String> parseStringArrayFieldsFromVmInfo(String header) throws Exception {
+        CommandRunner android = new CommandRunner(getDevice());
+        String result = android.run("/apex/com.android.virt/bin/vm", "info");
+        List<String> ret = new ArrayList<>();
+        for (String line : result.split("\n")) {
+            if (!line.startsWith(header)) continue;
+
+            JSONArray jsonArray = new JSONArray(line.substring(header.length()));
+            for (int i = 0; i < jsonArray.length(); i++) {
+                ret.add(jsonArray.getString(i));
+            }
+            break;
+        }
+        return ret;
+    }
+
+    public List<String> getAssignableDevices() throws Exception {
+        return parseStringArrayFieldsFromVmInfo("Assignable devices: ");
+    }
+
+    public List<String> getSupportedOSList() throws Exception {
+        return parseStringArrayFieldsFromVmInfo("Available OS list: ");
+    }
+
+    public List<String> getSupportedGKIVersions() throws Exception {
+        return getSupportedOSList().stream()
+                .filter(os -> os.startsWith("microdroid_gki-"))
+                .map(os -> os.replaceFirst("^microdroid_gki-", ""))
+                .collect(Collectors.toList());
+    }
 }
diff --git a/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java b/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
index 21abdaa..1739eab 100644
--- a/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
+++ b/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
@@ -1075,37 +1075,6 @@
                         && device.doesFileExist("/sys/bus/platform/drivers/vfio-platform"));
     }
 
-    private List<String> parseStringArrayFieldsFromVmInfo(String header) throws Exception {
-        CommandRunner android = new CommandRunner(getDevice());
-        String result = android.run("/apex/com.android.virt/bin/vm", "info");
-        List<String> ret = new ArrayList<>();
-        for (String line : result.split("\n")) {
-            if (!line.startsWith(header)) continue;
-
-            JSONArray jsonArray = new JSONArray(line.substring(header.length()));
-            for (int i = 0; i < jsonArray.length(); i++) {
-                ret.add(jsonArray.getString(i));
-            }
-            break;
-        }
-        return ret;
-    }
-
-    private List<String> getAssignableDevices() throws Exception {
-        return parseStringArrayFieldsFromVmInfo("Assignable devices: ");
-    }
-
-    private List<String> getSupportedOSList() throws Exception {
-        return parseStringArrayFieldsFromVmInfo("Available OS list: ");
-    }
-
-    private List<String> getSupportedGKIVersions() throws Exception {
-        return getSupportedOSList().stream()
-                .filter(os -> os.startsWith("microdroid_gki-"))
-                .map(os -> os.replaceFirst("^microdroid_gki-", ""))
-                .collect(Collectors.toList());
-    }
-
     private TestDevice getAndroidDevice() {
         TestDevice androidDevice = (TestDevice) getDevice();
         assertThat(androidDevice).isNotNull();
diff --git a/virtualizationmanager/src/aidl.rs b/virtualizationmanager/src/aidl.rs
index 2603e77..34994f8 100644
--- a/virtualizationmanager/src/aidl.rs
+++ b/virtualizationmanager/src/aidl.rs
@@ -82,7 +82,7 @@
 use std::convert::TryInto;
 use std::ffi::{CStr, CString};
 use std::fs::{canonicalize, read_dir, remove_file, File, OpenOptions};
-use std::io::{BufRead, BufReader, Error, ErrorKind, Write};
+use std::io::{BufRead, BufReader, Error, ErrorKind, Seek, SeekFrom, Write};
 use std::iter;
 use std::num::{NonZeroU16, NonZeroU32};
 use std::os::unix::io::{FromRawFd, IntoRawFd};
@@ -159,6 +159,9 @@
         // We will anyway overwrite the file to the v4signature generated from input_fd.
     }
 
+    output
+        .seek(SeekFrom::Start(0))
+        .context("failed to move cursor to start on the idsig output")?;
     output.set_len(0).context("failed to set_len on the idsig output")?;
     sig.write_into(&mut output).context("failed to write idsig")?;
     Ok(())
@@ -243,9 +246,14 @@
             .with_context(|| format!("Invalid size: {}", size_bytes))
             .or_binder_exception(ExceptionCode::ILLEGAL_ARGUMENT)?;
         let size_bytes = round_up(size_bytes, PARTITION_GRANULARITY_BYTES);
-        let image = clone_file(image_fd)?;
+        let mut image = clone_file(image_fd)?;
         // initialize the file. Any data in the file will be erased.
+        image
+            .seek(SeekFrom::Start(0))
+            .context("failed to move cursor to start")
+            .or_service_specific_exception(-1)?;
         image.set_len(0).context("Failed to reset a file").or_service_specific_exception(-1)?;
+
         let mut part = QcowFile::new(image, size_bytes)
             .context("Failed to create QCOW2 image")
             .or_service_specific_exception(-1)?;
@@ -1545,6 +1553,40 @@
     }
 
     #[test]
+    fn test_create_or_update_idsig_on_non_empty_file() -> Result<()> {
+        use std::io::Read;
+
+        // Pick any APK
+        let mut apk = File::open("/system/priv-app/Shell/Shell.apk").unwrap();
+        let idsig_empty = tempfile::tempfile().unwrap();
+        let mut idsig_invalid = tempfile::tempfile().unwrap();
+        idsig_invalid.write_all(b"Oops")?;
+
+        // Create new idsig
+        create_or_update_idsig_file(
+            &ParcelFileDescriptor::new(apk.try_clone()?),
+            &ParcelFileDescriptor::new(idsig_empty.try_clone()?),
+        )?;
+        apk.rewind()?;
+
+        // Update idsig_invalid
+        create_or_update_idsig_file(
+            &ParcelFileDescriptor::new(apk.try_clone()?),
+            &ParcelFileDescriptor::new(idsig_invalid.try_clone()?),
+        )?;
+
+        // Ensure the 2 idsig files have same size!
+        assert!(
+            idsig_empty.metadata()?.len() == idsig_invalid.metadata()?.len(),
+            "idsig files differ in size"
+        );
+        // Ensure the 2 idsig files have same content!
+        for (b1, b2) in idsig_empty.bytes().zip(idsig_invalid.bytes()) {
+            assert!(b1.unwrap() == b2.unwrap(), "idsig files differ")
+        }
+        Ok(())
+    }
+    #[test]
     fn test_append_kernel_param_first_param() {
         let mut vm_config = VirtualMachineRawConfig { ..Default::default() };
         append_kernel_param("foo=1", &mut vm_config);
diff --git a/virtualizationmanager/src/crosvm.rs b/virtualizationmanager/src/crosvm.rs
index 4b3478e..fe8a587 100644
--- a/virtualizationmanager/src/crosvm.rs
+++ b/virtualizationmanager/src/crosvm.rs
@@ -810,8 +810,10 @@
     }
 
     if config.host_cpu_topology {
-        // TODO(b/266664564): replace with --host-cpu-topology once available
-        if let Some(cpus) = get_num_cpus() {
+        if cfg!(virt_cpufreq) {
+            command.arg("--host-cpu-topology");
+            command.arg("--virt-cpufreq");
+        } else if let Some(cpus) = get_num_cpus() {
             command.arg("--cpus").arg(cpus.to_string());
         } else {
             bail!("Could not determine the number of CPUs in the system");