[idsig] Simplify building V4Signature from idsig

Bug: 248999133
Test: libidsig.test apkdmverity.test microdroid_manager_test
Change-Id: I383a2f9827d1c292e2a2afec1e2092f60728267f
diff --git a/apkdmverity/Android.bp b/apkdmverity/Android.bp
index 97a6174..51ef4dd 100644
--- a/apkdmverity/Android.bp
+++ b/apkdmverity/Android.bp
@@ -43,4 +43,8 @@
     rustlibs: [
         "libtempfile",
     ],
+    data: [
+        "testdata/*.apk",
+        "testdata/*.idsig",
+    ],
 }
diff --git a/apkdmverity/src/main.rs b/apkdmverity/src/main.rs
index de7f5bb..b99ed1c 100644
--- a/apkdmverity/src/main.rs
+++ b/apkdmverity/src/main.rs
@@ -31,7 +31,6 @@
 use itertools::Itertools;
 use std::fmt::Debug;
 use std::fs;
-use std::fs::File;
 use std::os::unix::fs::FileTypeExt;
 use std::path::{Path, PathBuf};
 
@@ -104,9 +103,7 @@
     // Parse the idsig file to locate the merkle tree in it, then attach the file to a loop device
     // with the offset so that the start of the merkle tree becomes the beginning of the loop
     // device.
-    let sig = V4Signature::from(
-        File::open(&idsig).context(format!("Failed to open idsig file {:?}", &idsig))?,
-    )?;
+    let sig = V4Signature::from_idsig_path(&idsig)?;
     let offset = sig.merkle_tree_offset;
     let size = sig.merkle_tree_size as u64;
     // Due to unknown reason(b/191344832), we can't enable "direct IO" for the IDSIG file (backing
@@ -143,8 +140,8 @@
 #[cfg(test)]
 mod tests {
     use crate::*;
-    use std::fs::OpenOptions;
-    use std::io::{Cursor, Write};
+    use std::fs::{File, OpenOptions};
+    use std::io::Write;
     use std::os::unix::fs::FileExt;
 
     struct TestContext<'a> {
@@ -251,7 +248,9 @@
         let idsig = include_bytes!("../testdata/test.apk.idsig");
 
         // Make a single-byte change to the merkle tree
-        let offset = V4Signature::from(Cursor::new(&idsig)).unwrap().merkle_tree_offset as usize;
+        let offset = V4Signature::from_idsig_path("testdata/test.apk.idsig")
+            .unwrap()
+            .merkle_tree_offset as usize;
 
         let mut modified_idsig = Vec::new();
         modified_idsig.extend_from_slice(idsig);
@@ -354,7 +353,10 @@
     fn correct_custom_roothash() {
         let apk = include_bytes!("../testdata/test.apk");
         let idsig = include_bytes!("../testdata/test.apk.idsig");
-        let roothash = V4Signature::from(Cursor::new(&idsig)).unwrap().hashing_info.raw_root_hash;
+        let roothash = V4Signature::from_idsig_path("testdata/test.apk.idsig")
+            .unwrap()
+            .hashing_info
+            .raw_root_hash;
         run_test_with_hash(
             apk.as_ref(),
             idsig.as_ref(),
diff --git a/libs/idsig/Android.bp b/libs/idsig/Android.bp
index 9f7d377..615d70e 100644
--- a/libs/idsig/Android.bp
+++ b/libs/idsig/Android.bp
@@ -31,5 +31,7 @@
     compile_multilib: "first",
     data: [
         "testdata/input.*",
+        "testdata/*.apk",
+        "testdata/*.idsig",
     ],
 }
diff --git a/libs/idsig/src/apksigv4.rs b/libs/idsig/src/apksigv4.rs
index 29def3b..3f73df3 100644
--- a/libs/idsig/src/apksigv4.rs
+++ b/libs/idsig/src/apksigv4.rs
@@ -19,7 +19,9 @@
 use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
 use num_derive::{FromPrimitive, ToPrimitive};
 use num_traits::{FromPrimitive, ToPrimitive};
+use std::fs;
 use std::io::{copy, Cursor, Read, Seek, SeekFrom, Write};
+use std::path::Path;
 
 use crate::hashtree::*;
 
@@ -114,9 +116,17 @@
     }
 }
 
+impl V4Signature<fs::File> {
+    /// Creates a `V4Signature` struct from the given idsig path.
+    pub fn from_idsig_path<P: AsRef<Path>>(idsig_path: P) -> Result<Self> {
+        let idsig = fs::File::open(idsig_path).context("Cannot find idsig file")?;
+        Self::from_idsig(idsig)
+    }
+}
+
 impl<R: Read + Seek> V4Signature<R> {
     /// Consumes a stream for an idsig file into a `V4Signature` struct.
-    pub fn from(mut r: R) -> Result<V4Signature<R>> {
+    pub fn from_idsig(mut r: R) -> Result<V4Signature<R>> {
         Ok(V4Signature {
             version: Version::from(r.read_u32::<LittleEndian>()?)?,
             hashing_info: HashingInfo::from(&mut r)?,
@@ -293,14 +303,15 @@
     use super::*;
     use std::io::Cursor;
 
+    const TEST_APK_PATH: &str = "testdata/v4-digest-v3-Sha256withEC.apk";
+
     fn hexstring_from(s: &[u8]) -> String {
         s.iter().map(|byte| format!("{:02x}", byte)).reduce(|i, j| i + &j).unwrap_or_default()
     }
 
     #[test]
     fn parse_idsig_file() {
-        let idsig = Cursor::new(include_bytes!("../testdata/v4-digest-v3-Sha256withEC.apk.idsig"));
-        let parsed = V4Signature::from(idsig).unwrap();
+        let parsed = V4Signature::from_idsig_path(format!("{}.idsig", TEST_APK_PATH)).unwrap();
 
         assert_eq!(Version::V2, parsed.version);
 
@@ -334,13 +345,13 @@
     /// the input file.
     #[test]
     fn parse_and_compose() {
-        let input = Cursor::new(include_bytes!("../testdata/v4-digest-v3-Sha256withEC.apk.idsig"));
-        let mut parsed = V4Signature::from(input.clone()).unwrap();
+        let idsig_path = format!("{}.idsig", TEST_APK_PATH);
+        let mut v4_signature = V4Signature::from_idsig_path(&idsig_path).unwrap();
 
         let mut output = Cursor::new(Vec::new());
-        parsed.write_into(&mut output).unwrap();
+        v4_signature.write_into(&mut output).unwrap();
 
-        assert_eq!(input.get_ref().as_ref(), output.get_ref().as_slice());
+        assert_eq!(fs::read(&idsig_path).unwrap(), output.get_ref().as_slice());
     }
 
     /// Create V4Signature by hashing an APK. Merkle tree and the root hash should be the same
@@ -351,8 +362,7 @@
         let mut created =
             V4Signature::create(&mut input, 4096, &[], HashAlgorithm::SHA256).unwrap();
 
-        let golden = Cursor::new(include_bytes!("../testdata/v4-digest-v3-Sha256withEC.apk.idsig"));
-        let mut golden = V4Signature::from(golden).unwrap();
+        let mut golden = V4Signature::from_idsig_path(format!("{}.idsig", TEST_APK_PATH)).unwrap();
 
         // Compare the root hash
         assert_eq!(
diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs
index 7629291..c50bcbe 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -481,7 +481,7 @@
         .map(|(i, extra_idsig)| {
             (
                 format!("extra-apk-{}", i),
-                get_apk_root_hash_from_idsig(extra_idsig.to_str().unwrap())
+                get_apk_root_hash_from_idsig(extra_idsig)
                     .expect("Can't find root hash from extra idsig"),
             )
         })
@@ -601,10 +601,8 @@
     Ok(())
 }
 
-fn get_apk_root_hash_from_idsig(path: &str) -> Result<Box<RootHash>> {
-    let mut idsig = File::open(path)?;
-    let idsig = V4Signature::from(&mut idsig)?;
-    Ok(idsig.hashing_info.raw_root_hash)
+fn get_apk_root_hash_from_idsig<P: AsRef<Path>>(idsig_path: P) -> Result<Box<RootHash>> {
+    Ok(V4Signature::from_idsig_path(idsig_path)?.hashing_info.raw_root_hash)
 }
 
 fn get_public_key_from_apk(apk: &str, root_hash_trustful: bool) -> Result<Box<[u8]>> {