Merge "Revert "[rkp] Expose RKP Hal implementation in virtualizationservice"" into main
diff --git a/libs/libfdt/src/lib.rs b/libs/libfdt/src/lib.rs
index d800c13..96ac3f4 100644
--- a/libs/libfdt/src/lib.rs
+++ b/libs/libfdt/src/lib.rs
@@ -499,18 +499,30 @@
     }
 }
 
+impl<'a> PartialEq for FdtNode<'a> {
+    fn eq(&self, other: &Self) -> bool {
+        self.fdt.as_ptr() == other.fdt.as_ptr() && self.offset == other.offset
+    }
+}
+
 /// Phandle of a FDT node
 #[repr(transparent)]
 #[derive(Debug, Copy, Clone, PartialEq)]
 pub struct Phandle(u32);
 
 impl Phandle {
+    /// Minimum valid value for device tree phandles.
+    pub const MIN: Self = Self(1);
+    /// Maximum valid value for device tree phandles.
+    pub const MAX: Self = Self(libfdt_bindgen::FDT_MAX_PHANDLE);
+
     /// Creates a new Phandle
-    pub fn new(value: u32) -> Result<Self> {
-        if value == 0 || value > libfdt_bindgen::FDT_MAX_PHANDLE {
-            return Err(FdtError::BadPhandle);
+    pub const fn new(value: u32) -> Option<Self> {
+        if Self::MIN.0 <= value && value <= Self::MAX.0 {
+            Some(Self(value))
+        } else {
+            None
         }
-        Ok(Self(value))
     }
 }
 
@@ -520,7 +532,16 @@
     }
 }
 
+impl TryFrom<u32> for Phandle {
+    type Error = FdtError;
+
+    fn try_from(value: u32) -> Result<Self> {
+        Self::new(value).ok_or(FdtError::BadPhandle)
+    }
+}
+
 /// Mutable FDT node.
+#[derive(Debug)]
 pub struct FdtNodeMut<'a> {
     fdt: &'a mut Fdt,
     offset: c_int,
@@ -964,7 +985,7 @@
         let ret = unsafe { libfdt_bindgen::fdt_find_max_phandle(self.as_ptr(), &mut phandle) };
 
         fdt_err_expect_zero(ret)?;
-        Phandle::new(phandle)
+        phandle.try_into()
     }
 
     /// Returns a node with the phandle
diff --git a/libs/libfdt/tests/api_test.rs b/libs/libfdt/tests/api_test.rs
index 61503eb..78bb618 100644
--- a/libs/libfdt/tests/api_test.rs
+++ b/libs/libfdt/tests/api_test.rs
@@ -42,7 +42,7 @@
     const EXPECTED_FIRST_MEMORY_RANGE: Range<usize> = 0..256;
     let mut memory = fdt.memory().unwrap();
     assert_eq!(memory.next(), Some(EXPECTED_FIRST_MEMORY_RANGE));
-    assert!(memory.next().is_none());
+    assert_eq!(memory.next(), None);
     assert_eq!(fdt.first_memory_range(), Ok(EXPECTED_FIRST_MEMORY_RANGE));
 }
 
@@ -56,7 +56,7 @@
     let mut memory = fdt.memory().unwrap();
     assert_eq!(memory.next(), Some(EXPECTED_FIRST_MEMORY_RANGE));
     assert_eq!(memory.next(), Some(EXPECTED_SECOND_MEMORY_RANGE));
-    assert!(memory.next().is_none());
+    assert_eq!(memory.next(), None);
     assert_eq!(fdt.first_memory_range(), Ok(EXPECTED_FIRST_MEMORY_RANGE));
 }
 
@@ -66,7 +66,7 @@
     let fdt = Fdt::from_slice(&data).unwrap();
 
     let mut memory = fdt.memory().unwrap();
-    assert!(memory.next().is_none());
+    assert_eq!(memory.next(), None);
     assert_eq!(fdt.first_memory_range(), Err(FdtError::NotFound));
 }
 
@@ -85,14 +85,14 @@
     let fdt = Fdt::from_slice(&data).unwrap();
 
     let root = fdt.root().unwrap();
-    assert_eq!(root.name().unwrap().to_str().unwrap(), "");
+    assert_eq!(root.name(), Ok(cstr!("")));
 
     let chosen = fdt.chosen().unwrap().unwrap();
-    assert_eq!(chosen.name().unwrap().to_str().unwrap(), "chosen");
+    assert_eq!(chosen.name(), Ok(cstr!("chosen")));
 
     let nested_node_path = cstr!("/cpus/PowerPC,970@0");
     let nested_node = fdt.node(nested_node_path).unwrap().unwrap();
-    assert_eq!(nested_node.name().unwrap().to_str().unwrap(), "PowerPC,970@0");
+    assert_eq!(nested_node.name(), Ok(cstr!("PowerPC,970@0")));
 }
 
 #[test]
@@ -100,10 +100,10 @@
     let data = fs::read(TEST_TREE_WITH_NO_MEMORY_NODE_PATH).unwrap();
     let fdt = Fdt::from_slice(&data).unwrap();
     let root = fdt.root().unwrap();
-    let expected: Vec<&str> = vec!["cpus", "randomnode", "chosen"];
+    let expected = [cstr!("cpus"), cstr!("randomnode"), cstr!("chosen")];
 
     for (node, name) in root.subnodes().unwrap().zip(expected) {
-        assert_eq!(node.name().unwrap().to_str().unwrap(), name);
+        assert_eq!(node.name(), Ok(name));
     }
 }
 
@@ -113,17 +113,17 @@
     let fdt = Fdt::from_slice(&data).unwrap();
     let root = fdt.root().unwrap();
     let one_be = 0x1_u32.to_be_bytes();
-    let expected: Vec<(&str, &[u8])> = vec![
-        ("model", b"MyBoardName\0"),
-        ("compatible", b"MyBoardName\0MyBoardFamilyName\0"),
-        ("#address-cells", &one_be),
-        ("#size-cells", &one_be),
-        ("empty_prop", b""),
+    let expected = [
+        (cstr!("model"), b"MyBoardName\0".as_ref()),
+        (cstr!("compatible"), b"MyBoardName\0MyBoardFamilyName\0".as_ref()),
+        (cstr!("#address-cells"), &one_be),
+        (cstr!("#size-cells"), &one_be),
+        (cstr!("empty_prop"), &[]),
     ];
 
-    for (prop, (name, value)) in root.properties().unwrap().zip(expected) {
-        assert_eq!(prop.name().unwrap().to_str().unwrap(), name);
-        assert_eq!(prop.value().unwrap(), value);
+    let properties = root.properties().unwrap();
+    for (prop, (name, value)) in properties.zip(expected.into_iter()) {
+        assert_eq!((prop.name(), prop.value()), (Ok(name), Ok(value)));
     }
 }
 
@@ -132,28 +132,49 @@
     let data = fs::read(TEST_TREE_WITH_NO_MEMORY_NODE_PATH).unwrap();
     let fdt = Fdt::from_slice(&data).unwrap();
     let node = fdt.node(cstr!("/cpus/PowerPC,970@1")).unwrap().unwrap();
-    let expected = &["", "cpus", "PowerPC,970@1"];
+    let expected = [cstr!(""), cstr!("cpus"), cstr!("PowerPC,970@1")];
 
-    for (depth, expect) in expected.iter().enumerate() {
+    for (depth, name) in expected.into_iter().enumerate() {
         let supernode = node.supernode_at_depth(depth).unwrap();
-        assert_eq!(supernode.name().unwrap().to_str().unwrap(), *expect);
+        assert_eq!(supernode.name(), Ok(name));
     }
 }
 
 #[test]
 fn phandle_new() {
-    let phandle_u32 = 0x55;
-    let phandle = Phandle::new(phandle_u32).unwrap();
+    let valid_phandles = [
+        u32::from(Phandle::MIN),
+        u32::from(Phandle::MIN).checked_add(1).unwrap(),
+        0x55,
+        u32::from(Phandle::MAX).checked_sub(1).unwrap(),
+        u32::from(Phandle::MAX),
+    ];
 
-    assert_eq!(u32::from(phandle), phandle_u32);
+    for value in valid_phandles {
+        let phandle = Phandle::new(value).unwrap();
+
+        assert_eq!(value.try_into(), Ok(phandle));
+        assert_eq!(u32::from(phandle), value);
+    }
+
+    let bad_phandles = [
+        u32::from(Phandle::MIN).checked_sub(1).unwrap(),
+        u32::from(Phandle::MAX).checked_add(1).unwrap(),
+    ];
+
+    for value in bad_phandles {
+        assert_eq!(Phandle::new(value), None);
+        assert_eq!(Phandle::try_from(value), Err(FdtError::BadPhandle));
+    }
 }
 
 #[test]
 fn max_phandle() {
     let data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
     let fdt = Fdt::from_slice(&data).unwrap();
+    let phandle = Phandle::new(0xFF).unwrap();
 
-    assert_eq!(fdt.max_phandle().unwrap(), Phandle::new(0xFF).unwrap());
+    assert_eq!(fdt.max_phandle(), Ok(phandle));
 }
 
 #[test]
@@ -162,32 +183,36 @@
     let fdt = Fdt::from_slice(&data).unwrap();
 
     // Test linux,phandle
-    let node = fdt.node_with_phandle(Phandle::new(0xFF).unwrap()).unwrap().unwrap();
-    assert_eq!(node.name().unwrap().to_str().unwrap(), "node_zz");
+    let phandle = Phandle::new(0xFF).unwrap();
+    let node = fdt.node_with_phandle(phandle).unwrap().unwrap();
+    assert_eq!(node.name(), Ok(cstr!("node_zz")));
 
     // Test phandle
-    let node = fdt.node_with_phandle(Phandle::new(0x22).unwrap()).unwrap().unwrap();
-    assert_eq!(node.name().unwrap().to_str().unwrap(), "node_abc");
+    let phandle = Phandle::new(0x22).unwrap();
+    let node = fdt.node_with_phandle(phandle).unwrap().unwrap();
+    assert_eq!(node.name(), Ok(cstr!("node_abc")));
 }
 
 #[test]
 fn node_nop() {
     let mut data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
     let fdt = Fdt::from_mut_slice(&mut data).unwrap();
+    let phandle = Phandle::new(0xFF).unwrap();
+    let path = cstr!("/node_z/node_zz");
 
-    fdt.node_with_phandle(Phandle::new(0xFF).unwrap()).unwrap().unwrap();
-    let node = fdt.node_mut(cstr!("/node_z/node_zz")).unwrap().unwrap();
+    fdt.node_with_phandle(phandle).unwrap().unwrap();
+    let node = fdt.node_mut(path).unwrap().unwrap();
 
     node.nop().unwrap();
 
-    assert!(fdt.node_with_phandle(Phandle::new(0xFF).unwrap()).unwrap().is_none());
-    assert!(fdt.node(cstr!("/node_z/node_zz")).unwrap().is_none());
+    assert_eq!(fdt.node_with_phandle(phandle), Ok(None));
+    assert_eq!(fdt.node(path), Ok(None));
 
     fdt.unpack().unwrap();
     fdt.pack().unwrap();
 
-    assert!(fdt.node_with_phandle(Phandle::new(0xFF).unwrap()).unwrap().is_none());
-    assert!(fdt.node(cstr!("/node_z/node_zz")).unwrap().is_none());
+    assert_eq!(fdt.node_with_phandle(phandle), Ok(None));
+    assert_eq!(fdt.node(path), Ok(None));
 }
 
 #[test]
@@ -216,7 +241,8 @@
     for len in 1..subnode_name.to_bytes().len() {
         let name = String::from_utf8(subnode_name.to_bytes()[..len].to_vec()).unwrap();
         let path = CString::new(format!("{node_path}/{name}")).unwrap();
+        let name = CString::new(name).unwrap();
         let subnode = fdt.node(&path).unwrap().unwrap();
-        assert_eq!(subnode.name().unwrap().to_str().unwrap(), name);
+        assert_eq!(subnode.name(), Ok(name.as_c_str()));
     }
 }
diff --git a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
index 40c5cae..d9d9cb9 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -2019,11 +2019,10 @@
                         | OsConstants.S_IROTH
                         | OsConstants.S_IWOTH
                         | OsConstants.S_IXOTH;
-        int expectedPermissions =
-                OsConstants.S_IRUSR
-                        | OsConstants.S_IXUSR
-                        | OsConstants.S_IRGRP
-                        | OsConstants.S_IXGRP;
+        int expectedPermissions = OsConstants.S_IRUSR | OsConstants.S_IXUSR;
+        if (isFeatureEnabled(VirtualMachineManager.FEATURE_MULTI_TENANT)) {
+            expectedPermissions |= OsConstants.S_IRGRP | OsConstants.S_IXGRP;
+        }
         assertThat(testResults.mFileMode & allPermissionsMask).isEqualTo(expectedPermissions);
     }
 
diff --git a/zipfuse/src/inode.rs b/zipfuse/src/inode.rs
index 3175a30..1f74f64 100644
--- a/zipfuse/src/inode.rs
+++ b/zipfuse/src/inode.rs
@@ -31,11 +31,21 @@
 const INVALID: Inode = 0;
 const ROOT: Inode = 1;
 
-const DEFAULT_DIR_MODE: u32 = libc::S_IRUSR | libc::S_IXUSR | libc::S_IRGRP | libc::S_IXGRP;
+#[cfg(multi_tenant)]
+const READ_MODE: u32 = libc::S_IRUSR | libc::S_IRGRP;
+#[cfg(multi_tenant)]
+const EXECUTE_MODE: u32 = libc::S_IXUSR | libc::S_IXGRP;
+
+#[cfg(not(multi_tenant))]
+const READ_MODE: u32 = libc::S_IRUSR;
+#[cfg(not(multi_tenant))]
+const EXECUTE_MODE: u32 = libc::S_IXUSR;
+
+const DEFAULT_DIR_MODE: u32 = READ_MODE | EXECUTE_MODE;
 // b/264668376 some files in APK don't have unix permissions specified. Default to 400
 // otherwise those files won't be readable even by the owner.
-const DEFAULT_FILE_MODE: u32 = libc::S_IRUSR | libc::S_IRGRP;
-const EXECUTABLE_FILE_MODE: u32 = DEFAULT_FILE_MODE | libc::S_IXUSR | libc::S_IXGRP;
+const DEFAULT_FILE_MODE: u32 = READ_MODE;
+const EXECUTABLE_FILE_MODE: u32 = DEFAULT_FILE_MODE | EXECUTE_MODE;
 
 /// `InodeData` represents an inode which has metadata about a file or a directory
 #[derive(Debug)]