Diced: Add dice maintenance implementation

The maintenace interface allows a privileged client to demote diced to
permanently assume the identity of a child.

Test: WIP
Bug: 198197213
Change-Id: I6626d176204564d99f504a2c3b6a75c85e140d80
diff --git a/diced/src/lib.rs b/diced/src/lib.rs
index 462d2aa..9ebee28 100644
--- a/diced/src/lib.rs
+++ b/diced/src/lib.rs
@@ -24,7 +24,8 @@
     InputValues::InputValues as BinderInputValues, Mode::Mode, Signature::Signature,
 };
 use android_security_dice::aidl::android::security::dice::{
-    IDiceNode::BnDiceNode, IDiceNode::IDiceNode, ResponseCode::ResponseCode,
+    IDiceMaintenance::BnDiceMaintenance, IDiceMaintenance::IDiceMaintenance, IDiceNode::BnDiceNode,
+    IDiceNode::IDiceNode, ResponseCode::ResponseCode,
 };
 use anyhow::{Context, Result};
 use binder::{public_api::Result as BinderResult, BinderFeatures, Strong, ThreadState};
@@ -164,3 +165,37 @@
         map_or_log_err(self.demote(input_values), Ok)
     }
 }
+
+/// Wraps a DiceNodeImpl and implements the IDiceMaintenance AIDL API.
+pub struct DiceMaintenance {
+    node_impl: Arc<dyn DiceNodeImpl + Sync + Send>,
+}
+
+impl DiceMaintenance {
+    /// Constructs an instance of DiceMaintenance, wraps it with a BnDiceMaintenance object and
+    /// returns a strong pointer to the binder. The result can be used to register the service
+    /// with service manager.
+    pub fn new_as_binder(
+        node_impl: Arc<dyn DiceNodeImpl + Sync + Send>,
+    ) -> Result<Strong<dyn IDiceMaintenance>> {
+        let result = BnDiceMaintenance::new_binder(
+            DiceMaintenance { node_impl },
+            BinderFeatures { set_requesting_sid: true, ..BinderFeatures::default() },
+        );
+        Ok(result)
+    }
+
+    fn demote_self(&self, input_values: &[BinderInputValues]) -> Result<()> {
+        check_caller_permission(Permission::DemoteSelf)
+            .context("In DiceMaintenance::demote_self:")?;
+        self.node_impl.demote_self(input_values)
+    }
+}
+
+impl binder::Interface for DiceMaintenance {}
+
+impl IDiceMaintenance for DiceMaintenance {
+    fn demoteSelf(&self, input_values: &[BinderInputValues]) -> BinderResult<()> {
+        map_or_log_err(self.demote_self(input_values), Ok)
+    }
+}