xref: /aosp_15_r20/system/server_configurable_flags/aconfigd/lib.rs (revision 207333786ba243bc7d4d69ef6b05487aa7071806)
1 //! Library for interacting with aconfigd.
2 use crate::ffi::{CppAconfigd, CppResultStatus, CppStringResult, CppVoidResult};
3 use cxx::{let_cxx_string, CxxString, UniquePtr};
4 use std::error::Error;
5 use std::fmt;
6 
7 /// Wrapper for interacting with aconfigd.
8 pub struct Aconfigd {
9     cpp_aconfigd: UniquePtr<CppAconfigd>,
10 }
11 
12 impl Aconfigd {
13     /// Create a new Aconfigd.
new(root_dir: &str, persist_storage_records: &str) -> Self14     pub fn new(root_dir: &str, persist_storage_records: &str) -> Self {
15         let_cxx_string!(root_dir_ = root_dir);
16         let_cxx_string!(persist_storage_records_ = persist_storage_records);
17         Self { cpp_aconfigd: ffi::new_cpp_aconfigd(&root_dir_, &persist_storage_records_) }
18     }
19 
20     /// Create persistent storage files for platform partition.
initialize_platform_storage(&self) -> Result<(), CppAconfigdError>21     pub fn initialize_platform_storage(&self) -> Result<(), CppAconfigdError> {
22         self.cpp_aconfigd.initialize_platform_storage().into()
23     }
24 
25     /// Create persistent storage files for mainline modules.
initialize_mainline_storage(&self) -> Result<(), CppAconfigdError>26     pub fn initialize_mainline_storage(&self) -> Result<(), CppAconfigdError> {
27         self.cpp_aconfigd.initialize_mainline_storage().into()
28     }
29 
30     /// Read storage records into memory.
initialize_in_memory_storage_records(&self) -> Result<(), CppAconfigdError>31     pub fn initialize_in_memory_storage_records(&self) -> Result<(), CppAconfigdError> {
32         self.cpp_aconfigd.initialize_in_memory_storage_records().into()
33     }
34 
35     /// Process a `StorageRequestMessages`, and return the bytes of a `StorageReturnMessages`.
36     ///
37     /// `messages_bytes` should contain the serialized bytes of a `StorageRequestMessages`.
handle_socket_request( &self, messages_bytes: &[u8], ) -> Result<Vec<u8>, CppAconfigdError>38     pub fn handle_socket_request(
39         &self,
40         messages_bytes: &[u8],
41     ) -> Result<Vec<u8>, CppAconfigdError> {
42         let_cxx_string!(messages_string_ = messages_bytes);
43         let res: Result<UniquePtr<CxxString>, CppAconfigdError> =
44             self.cpp_aconfigd.handle_socket_request(&messages_string_).into();
45         res.map(|s| s.as_bytes().to_vec())
46     }
47 }
48 
49 /// Represents an error in the C++ aconfigd.
50 ///
51 /// The C++ aconfigd uses the C++ Result type. Result errors are mapped
52 /// to this type.
53 #[derive(Debug)]
54 pub struct CppAconfigdError {
55     msg: String,
56 }
57 
58 impl CppAconfigdError {
new(msg: &str) -> Self59     pub fn new(msg: &str) -> Self {
60         Self { msg: msg.to_string() }
61     }
62 }
63 
64 impl fmt::Display for CppAconfigdError {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result65     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
66         write!(f, "CppAconfigd error: {}", self.msg)
67     }
68 }
69 
70 impl Error for CppAconfigdError {}
71 
72 #[cxx::bridge(namespace = "aconfigdwrapper")]
73 mod ffi {
74     enum CppResultStatus {
75         Ok,
76         Err,
77     }
78 
79     struct CppVoidResult {
80         error_message: String,
81         status: CppResultStatus,
82     }
83 
84     struct CppStringResult {
85         data: UniquePtr<CxxString>,
86         error_message: String,
87         status: CppResultStatus,
88     }
89 
90     unsafe extern "C++" {
91         include!("libcxx_aconfigd.hpp");
92 
93         type CppAconfigd;
94 
new_cpp_aconfigd(str1: &CxxString, str2: &CxxString) -> UniquePtr<CppAconfigd>95         fn new_cpp_aconfigd(str1: &CxxString, str2: &CxxString) -> UniquePtr<CppAconfigd>;
initialize_platform_storage(&self) -> CppVoidResult96         fn initialize_platform_storage(&self) -> CppVoidResult;
initialize_mainline_storage(&self) -> CppVoidResult97         fn initialize_mainline_storage(&self) -> CppVoidResult;
98 
initialize_in_memory_storage_records(&self) -> CppVoidResult99         fn initialize_in_memory_storage_records(&self) -> CppVoidResult;
handle_socket_request(&self, message_string: &CxxString) -> CppStringResult100         fn handle_socket_request(&self, message_string: &CxxString) -> CppStringResult;
101     }
102 }
103 
104 impl Into<Result<(), CppAconfigdError>> for CppVoidResult {
into(self) -> Result<(), CppAconfigdError>105     fn into(self) -> Result<(), CppAconfigdError> {
106         match self.status {
107             CppResultStatus::Ok => Ok(()),
108             CppResultStatus::Err => Err(CppAconfigdError::new(&self.error_message)),
109             _ => Err(CppAconfigdError::new("unknown status")),
110         }
111     }
112 }
113 
114 impl Into<Result<UniquePtr<CxxString>, CppAconfigdError>> for CppStringResult {
into(self) -> Result<UniquePtr<CxxString>, CppAconfigdError>115     fn into(self) -> Result<UniquePtr<CxxString>, CppAconfigdError> {
116         match self.status {
117             CppResultStatus::Ok => Ok(self.data),
118             CppResultStatus::Err => Err(CppAconfigdError::new(&self.error_message)),
119             _ => Err(CppAconfigdError::new("unknown status")),
120         }
121     }
122 }
123