1 /*
2 * Copyright (c) 2023-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 //! This module defines the interface of the Asset Rust SDK.
17
18 pub use asset_definition::*;
19 pub mod plugin_interface;
20
21 use ipc::{parcel::MsgParcel, remote::RemoteObj};
22 use samgr::manage::SystemAbilityManager;
23
24 use asset_ipc::{
25 deserialize_maps, deserialize_sync_result, ipc_err_handle, serialize_map, IpcCode, IPC_SUCCESS, SA_ID, SA_NAME,
26 };
27
28 const LOAD_TIMEOUT_IN_SECONDS: i32 = 4;
29
load_asset_service() -> Result<RemoteObj>30 fn load_asset_service() -> Result<RemoteObj> {
31 match SystemAbilityManager::load_system_ability(SA_ID, LOAD_TIMEOUT_IN_SECONDS) {
32 Some(remote) => Ok(remote),
33 None => {
34 log_throw_error!(ErrCode::ServiceUnavailable, "[FATAL][RUST SDK]get remote service failed")
35 },
36 }
37 }
38
get_remote(need_check: bool) -> Result<RemoteObj>39 fn get_remote(need_check: bool) -> Result<RemoteObj> {
40 if need_check {
41 match SystemAbilityManager::check_system_ability(SA_ID) {
42 Some(remote) => Ok(remote),
43 None => load_asset_service(),
44 }
45 } else {
46 load_asset_service()
47 }
48 }
49
50 /// This manager provides the capabilities for life cycle management of sensitive user data (Asset) such as passwords
51 /// and tokens, including adding, removing, updating, and querying.
52 pub struct Manager {
53 remote: RemoteObj,
54 }
55
56 impl Manager {
57 /// Build and initialize the Manager.
build() -> Result<Self>58 pub fn build() -> Result<Self> {
59 let remote = get_remote(true)?;
60 Ok(Self { remote })
61 }
62
63 /// Add an Asset.
add(&mut self, attributes: &AssetMap) -> Result<()>64 pub fn add(&mut self, attributes: &AssetMap) -> Result<()> {
65 self.process_one_agr_request(attributes, IpcCode::Add)?;
66 Ok(())
67 }
68
69 /// Remove one or more Assets that match a search query.
remove(&mut self, query: &AssetMap) -> Result<()>70 pub fn remove(&mut self, query: &AssetMap) -> Result<()> {
71 self.process_one_agr_request(query, IpcCode::Remove)?;
72 Ok(())
73 }
74
75 /// Update an Asset that matches a search query.
update(&mut self, query: &AssetMap, attributes_to_update: &AssetMap) -> Result<()>76 pub fn update(&mut self, query: &AssetMap, attributes_to_update: &AssetMap) -> Result<()> {
77 self.process_two_agr_request(query, attributes_to_update, IpcCode::Update)?;
78 Ok(())
79 }
80
81 /// Preprocessing for querying one or more Assets that require user authentication.
pre_query(&mut self, query: &AssetMap) -> Result<Vec<u8>>82 pub fn pre_query(&mut self, query: &AssetMap) -> Result<Vec<u8>> {
83 let mut reply = self.process_one_agr_request(query, IpcCode::PreQuery)?;
84 let res = reply.read::<Vec<u8>>().map_err(ipc_err_handle)?;
85 Ok(res)
86 }
87
88 /// Query one or more Assets that match a search query.
query(&mut self, query: &AssetMap) -> Result<Vec<AssetMap>>89 pub fn query(&mut self, query: &AssetMap) -> Result<Vec<AssetMap>> {
90 let mut reply = self.process_one_agr_request(query, IpcCode::Query)?;
91 let res = deserialize_maps(&mut reply)?;
92 Ok(res)
93 }
94
95 /// Post-processing for querying multiple Assets that require user authentication.
post_query(&mut self, query: &AssetMap) -> Result<()>96 pub fn post_query(&mut self, query: &AssetMap) -> Result<()> {
97 self.process_one_agr_request(query, IpcCode::PostQuery)?;
98 Ok(())
99 }
100
101 /// Query the result of synchronization.
query_sync_result(&mut self, query: &AssetMap) -> Result<SyncResult>102 pub fn query_sync_result(&mut self, query: &AssetMap) -> Result<SyncResult> {
103 match self.process_one_agr_request(query, IpcCode::QuerySyncResult) {
104 Ok(mut reply) => {
105 let sync_result = deserialize_sync_result(&mut reply)?;
106 Ok(sync_result)
107 },
108 Err(mut e) => {
109 if e.code == ErrCode::InvalidArgument {
110 e.code = ErrCode::ParamVerificationFailed;
111 }
112 Err(e)
113 },
114 }
115 }
116
rebuild(&mut self) -> Result<()>117 fn rebuild(&mut self) -> Result<()> {
118 self.remote = get_remote(false)?;
119 Ok(())
120 }
121
process_one_agr_request(&mut self, attributes: &AssetMap, ipc_code: IpcCode) -> Result<MsgParcel>122 fn process_one_agr_request(&mut self, attributes: &AssetMap, ipc_code: IpcCode) -> Result<MsgParcel> {
123 let mut parcel = MsgParcel::new();
124 parcel.write_interface_token(self.descriptor()).map_err(ipc_err_handle)?;
125 serialize_map(attributes, &mut parcel)?;
126 match self.send_request(parcel, ipc_code) {
127 Ok(msg) => Ok(msg),
128 Err(e) => match e.code {
129 ErrCode::ServiceUnavailable => {
130 self.rebuild()?;
131 let mut parcel = MsgParcel::new();
132 parcel.write_interface_token(self.descriptor()).map_err(ipc_err_handle)?;
133 serialize_map(attributes, &mut parcel)?;
134 self.send_request(parcel, ipc_code)
135 },
136 _ => Err(e),
137 },
138 }
139 }
140
process_two_agr_request( &mut self, query: &AssetMap, attributes_to_update: &AssetMap, ipc_code: IpcCode, ) -> Result<MsgParcel>141 fn process_two_agr_request(
142 &mut self,
143 query: &AssetMap,
144 attributes_to_update: &AssetMap,
145 ipc_code: IpcCode,
146 ) -> Result<MsgParcel> {
147 let mut parcel = MsgParcel::new();
148 parcel.write_interface_token(self.descriptor()).map_err(ipc_err_handle)?;
149 serialize_map(query, &mut parcel)?;
150 serialize_map(attributes_to_update, &mut parcel)?;
151 match self.send_request(parcel, ipc_code) {
152 Ok(msg) => Ok(msg),
153 Err(e) => match e.code {
154 ErrCode::ServiceUnavailable => {
155 self.rebuild()?;
156 let mut parcel = MsgParcel::new();
157 parcel.write_interface_token(self.descriptor()).map_err(ipc_err_handle)?;
158 serialize_map(query, &mut parcel)?;
159 serialize_map(attributes_to_update, &mut parcel)?;
160 self.send_request(parcel, ipc_code)
161 },
162 _ => Err(e),
163 },
164 }
165 }
166
send_request(&self, mut parcel: MsgParcel, ipc_code: IpcCode) -> Result<MsgParcel>167 fn send_request(&self, mut parcel: MsgParcel, ipc_code: IpcCode) -> Result<MsgParcel> {
168 let mut reply = self.remote.send_request(ipc_code as u32, &mut parcel).map_err(ipc_err_handle)?;
169 match reply.read::<u32>().map_err(ipc_err_handle)? {
170 IPC_SUCCESS => Ok(reply),
171 e => {
172 let msg = reply.read::<String>().map_err(ipc_err_handle)?;
173 throw_error!(ErrCode::try_from(e)?, "{}", msg)
174 },
175 }
176 }
177
descriptor(&self) -> &'static str178 fn descriptor(&self) -> &'static str {
179 SA_NAME
180 }
181 }
182