1dfe32fa1Soh_ci/*
2dfe32fa1Soh_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3dfe32fa1Soh_ci * Licensed under the Apache License, Version 2.0 (the "License");
4dfe32fa1Soh_ci * you may not use this file except in compliance with the License.
5dfe32fa1Soh_ci * You may obtain a copy of the License at
6dfe32fa1Soh_ci *
7dfe32fa1Soh_ci *     http://www.apache.org/licenses/LICENSE-2.0
8dfe32fa1Soh_ci *
9dfe32fa1Soh_ci * Unless required by applicable law or agreed to in writing, software
10dfe32fa1Soh_ci * distributed under the License is distributed on an "AS IS" BASIS,
11dfe32fa1Soh_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12dfe32fa1Soh_ci * See the License for the specific language governing permissions and
13dfe32fa1Soh_ci * limitations under the License.
14dfe32fa1Soh_ci */
15dfe32fa1Soh_ci
16dfe32fa1Soh_ci//! This module defines the interface of the Asset Rust SDK.
17dfe32fa1Soh_ci
18dfe32fa1Soh_cipub use asset_definition::*;
19dfe32fa1Soh_cipub mod plugin_interface;
20dfe32fa1Soh_ci
21dfe32fa1Soh_ciuse ipc::{parcel::MsgParcel, remote::RemoteObj};
22dfe32fa1Soh_ciuse samgr::manage::SystemAbilityManager;
23dfe32fa1Soh_ci
24dfe32fa1Soh_ciuse asset_ipc::{deserialize_maps, ipc_err_handle, serialize_map, IpcCode, IPC_SUCCESS, SA_ID, SA_NAME};
25dfe32fa1Soh_ci
26dfe32fa1Soh_ciconst LOAD_TIMEOUT_IN_SECONDS: i32 = 4;
27dfe32fa1Soh_ci
28dfe32fa1Soh_cifn get_remote() -> Result<RemoteObj> {
29dfe32fa1Soh_ci    match SystemAbilityManager::check_system_ability(SA_ID) {
30dfe32fa1Soh_ci        Some(remote) => Ok(remote),
31dfe32fa1Soh_ci        None => match SystemAbilityManager::load_system_ability(SA_ID, LOAD_TIMEOUT_IN_SECONDS) {
32dfe32fa1Soh_ci            Some(remote) => Ok(remote),
33dfe32fa1Soh_ci            None => {
34dfe32fa1Soh_ci                log_throw_error!(ErrCode::ServiceUnavailable, "[FATAL][RUST SDK]get remote service failed")
35dfe32fa1Soh_ci            },
36dfe32fa1Soh_ci        },
37dfe32fa1Soh_ci    }
38dfe32fa1Soh_ci}
39dfe32fa1Soh_ci
40dfe32fa1Soh_ci/// This manager provides the capabilities for life cycle management of sensitive user data (Asset) such as passwords
41dfe32fa1Soh_ci/// and tokens, including adding, removing, updating, and querying.
42dfe32fa1Soh_cipub struct Manager {
43dfe32fa1Soh_ci    remote: RemoteObj,
44dfe32fa1Soh_ci}
45dfe32fa1Soh_ci
46dfe32fa1Soh_ciimpl Manager {
47dfe32fa1Soh_ci    /// Build and initialize the Manager.
48dfe32fa1Soh_ci    pub fn build() -> Result<Self> {
49dfe32fa1Soh_ci        let remote = get_remote()?;
50dfe32fa1Soh_ci        Ok(Self { remote })
51dfe32fa1Soh_ci    }
52dfe32fa1Soh_ci
53dfe32fa1Soh_ci    /// Add an Asset.
54dfe32fa1Soh_ci    pub fn add(&self, attributes: &AssetMap) -> Result<()> {
55dfe32fa1Soh_ci        let mut parcel = MsgParcel::new();
56dfe32fa1Soh_ci        parcel.write_interface_token(self.descriptor()).map_err(ipc_err_handle)?;
57dfe32fa1Soh_ci        serialize_map(attributes, &mut parcel)?;
58dfe32fa1Soh_ci        self.send_request(parcel, IpcCode::Add)?;
59dfe32fa1Soh_ci        Ok(())
60dfe32fa1Soh_ci    }
61dfe32fa1Soh_ci
62dfe32fa1Soh_ci    /// Remove one or more Assets that match a search query.
63dfe32fa1Soh_ci    pub fn remove(&self, query: &AssetMap) -> Result<()> {
64dfe32fa1Soh_ci        let mut parcel = MsgParcel::new();
65dfe32fa1Soh_ci        parcel.write_interface_token(self.descriptor()).map_err(ipc_err_handle)?;
66dfe32fa1Soh_ci        serialize_map(query, &mut parcel)?;
67dfe32fa1Soh_ci        self.send_request(parcel, IpcCode::Remove)?;
68dfe32fa1Soh_ci        Ok(())
69dfe32fa1Soh_ci    }
70dfe32fa1Soh_ci
71dfe32fa1Soh_ci    /// Update an Asset that matches a search query.
72dfe32fa1Soh_ci    pub fn update(&self, query: &AssetMap, attributes_to_update: &AssetMap) -> Result<()> {
73dfe32fa1Soh_ci        let mut parcel = MsgParcel::new();
74dfe32fa1Soh_ci        parcel.write_interface_token(self.descriptor()).map_err(ipc_err_handle)?;
75dfe32fa1Soh_ci        serialize_map(query, &mut parcel)?;
76dfe32fa1Soh_ci        serialize_map(attributes_to_update, &mut parcel)?;
77dfe32fa1Soh_ci        self.send_request(parcel, IpcCode::Update)?;
78dfe32fa1Soh_ci        Ok(())
79dfe32fa1Soh_ci    }
80dfe32fa1Soh_ci
81dfe32fa1Soh_ci    /// Preprocessing for querying one or more Assets that require user authentication.
82dfe32fa1Soh_ci    pub fn pre_query(&self, query: &AssetMap) -> Result<Vec<u8>> {
83dfe32fa1Soh_ci        let mut parcel = MsgParcel::new();
84dfe32fa1Soh_ci        parcel.write_interface_token(self.descriptor()).map_err(ipc_err_handle)?;
85dfe32fa1Soh_ci        serialize_map(query, &mut parcel)?;
86dfe32fa1Soh_ci        let mut reply = self.send_request(parcel, IpcCode::PreQuery)?;
87dfe32fa1Soh_ci        let res = reply.read::<Vec<u8>>().map_err(ipc_err_handle)?;
88dfe32fa1Soh_ci        Ok(res)
89dfe32fa1Soh_ci    }
90dfe32fa1Soh_ci
91dfe32fa1Soh_ci    /// Query one or more Assets that match a search query.
92dfe32fa1Soh_ci    pub fn query(&self, query: &AssetMap) -> Result<Vec<AssetMap>> {
93dfe32fa1Soh_ci        let mut parcel = MsgParcel::new();
94dfe32fa1Soh_ci        parcel.write_interface_token(self.descriptor()).map_err(ipc_err_handle)?;
95dfe32fa1Soh_ci        serialize_map(query, &mut parcel)?;
96dfe32fa1Soh_ci        let mut reply = self.send_request(parcel, IpcCode::Query)?;
97dfe32fa1Soh_ci        let res = deserialize_maps(&mut reply)?;
98dfe32fa1Soh_ci        Ok(res)
99dfe32fa1Soh_ci    }
100dfe32fa1Soh_ci
101dfe32fa1Soh_ci    /// Post-processing for querying multiple Assets that require user authentication.
102dfe32fa1Soh_ci    pub fn post_query(&self, query: &AssetMap) -> Result<()> {
103dfe32fa1Soh_ci        let mut parcel = MsgParcel::new();
104dfe32fa1Soh_ci        parcel.write_interface_token(self.descriptor()).map_err(ipc_err_handle)?;
105dfe32fa1Soh_ci        serialize_map(query, &mut parcel)?;
106dfe32fa1Soh_ci        self.send_request(parcel, IpcCode::PostQuery)?;
107dfe32fa1Soh_ci        Ok(())
108dfe32fa1Soh_ci    }
109dfe32fa1Soh_ci
110dfe32fa1Soh_ci    fn send_request(&self, mut parcel: MsgParcel, ipc_code: IpcCode) -> Result<MsgParcel> {
111dfe32fa1Soh_ci        let mut reply = self.remote.send_request(ipc_code as u32, &mut parcel).map_err(ipc_err_handle)?;
112dfe32fa1Soh_ci        match reply.read::<u32>().map_err(ipc_err_handle)? {
113dfe32fa1Soh_ci            IPC_SUCCESS => Ok(reply),
114dfe32fa1Soh_ci            e => {
115dfe32fa1Soh_ci                let msg = reply.read::<String>().map_err(ipc_err_handle)?;
116dfe32fa1Soh_ci                log_throw_error!(ErrCode::try_from(e)?, "{}", msg)
117dfe32fa1Soh_ci            },
118dfe32fa1Soh_ci        }
119dfe32fa1Soh_ci    }
120dfe32fa1Soh_ci
121dfe32fa1Soh_ci    fn descriptor(&self) -> &'static str {
122dfe32fa1Soh_ci        SA_NAME
123dfe32fa1Soh_ci    }
124dfe32fa1Soh_ci}
125