1 /*
2  * Copyright (c) 2023 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 use ipc::parcel::{Deserialize, MsgParcel, Serialize};
17 use ipc::remote::RemoteObj;
18 use ipc::IpcResult;
19 
20 use crate::ipc_conn::error::Error;
21 use crate::ipc_conn::ffi::ConnectService;
22 use crate::ipc_conn::function::AssetLoaderFunc::{Download, Upload};
23 use crate::ipc_conn::function::CloudServiceFunc::ConnectAssetLoader;
24 use crate::ipc_conn::{vec_raw_read, vec_raw_write, AssetStatus};
25 pub(crate) type AssetLoaderResult<T> = Result<T, Error>;
26 
27 /// CloudAsset struct storing relating information to upload and download
28 /// assets.
29 #[derive(Default, PartialEq, Clone, Debug)]
30 pub struct CloudAsset {
31     pub(crate) asset_id: String,
32     pub(crate) asset_name: String,
33     pub(crate) hash: String,
34     pub(crate) uri: String,
35     pub(crate) sub_path: String,
36     pub(crate) create_time: String,
37     pub(crate) modify_time: String,
38     pub(crate) size: String,
39     pub(crate) status: AssetStatus,
40 }
41 
42 impl CloudAsset {
43     /// Get CloudAsset id.
id(&self) -> &str44     pub fn id(&self) -> &str {
45         &self.asset_id
46     }
47 
48     /// Get CloudAsset name.
name(&self) -> &str49     pub fn name(&self) -> &str {
50         &self.asset_name
51     }
52 
53     /// Get CloudAsset uri, a real path pointing to the CloudAsset.
uri(&self) -> &str54     pub fn uri(&self) -> &str {
55         &self.uri
56     }
57 
58     /// Get CloudAsset local path relative to the application sandbox.
local_path(&self) -> &str59     pub fn local_path(&self) -> &str {
60         &self.sub_path
61     }
62 
63     /// Get create time of this CloudAsset.
create_time(&self) -> &str64     pub fn create_time(&self) -> &str {
65         &self.create_time
66     }
67 
68     /// Get modify time of this CloudAsset.
modify_time(&self) -> &str69     pub fn modify_time(&self) -> &str {
70         &self.modify_time
71     }
72 
73     /// Get size of this CloudAsset in kb.
size(&self) -> &str74     pub fn size(&self) -> &str {
75         &self.size
76     }
77 
78     /// Get hash value of this CloudAsset.
hash(&self) -> &str79     pub fn hash(&self) -> &str {
80         &self.hash
81     }
82 
83     /// Set CloudAsset id.
set_id(&mut self, id: String)84     pub fn set_id(&mut self, id: String) {
85         self.asset_id = id;
86     }
87 
88     /// Set CloudAsset name.
set_name(&mut self, name: String)89     pub fn set_name(&mut self, name: String) {
90         self.asset_name = name;
91     }
92 
93     /// Set CloudAsset uri, a real path pointing to the CloudAsset.
set_uri(&mut self, uri: String)94     pub fn set_uri(&mut self, uri: String) {
95         self.uri = uri;
96     }
97 
98     /// Set CloudAsset local path relative to the application sandbox.
set_local_path(&mut self, local_path: String)99     pub fn set_local_path(&mut self, local_path: String) {
100         self.sub_path = local_path;
101     }
102 
103     /// Set create time of this CloudAsset.
set_create_time(&mut self, create_time: String)104     pub fn set_create_time(&mut self, create_time: String) {
105         self.create_time = create_time;
106     }
107 
108     /// Set modify time of this CloudAsset.
set_modify_time(&mut self, modify_time: String)109     pub fn set_modify_time(&mut self, modify_time: String) {
110         self.modify_time = modify_time;
111     }
112 
113     /// Set size of this CloudAsset in kb.
set_size(&mut self, size: String)114     pub fn set_size(&mut self, size: String) {
115         self.size = size;
116     }
117 
118     /// Set hash value of this CloudAsset.
set_hash(&mut self, hash: String)119     pub fn set_hash(&mut self, hash: String) {
120         self.hash = hash;
121     }
122 }
123 
124 impl Serialize for CloudAsset {
serialize(&self, parcel: &mut MsgParcel) -> IpcResult<()>125     fn serialize(&self, parcel: &mut MsgParcel) -> IpcResult<()> {
126         parcel.write_string16(&self.asset_name)?;
127         parcel.write_string16(&self.uri)?;
128         parcel.write_string16(&self.sub_path)?;
129         parcel.write_string16(&self.create_time)?;
130         parcel.write_string16(&self.modify_time)?;
131         parcel.write_string16(&self.size)?;
132         parcel.write(&self.status)?;
133         parcel.write_string16(&self.asset_id)?;
134         parcel.write_string16(&self.hash)?;
135         Ok(())
136     }
137 }
138 
139 impl Deserialize for CloudAsset {
deserialize(parcel: &mut MsgParcel) -> IpcResult<Self>140     fn deserialize(parcel: &mut MsgParcel) -> IpcResult<Self> {
141         let asset_name = parcel.read_string16()?;
142         let uri = parcel.read_string16()?;
143         let sub_path = parcel.read_string16()?;
144         let create_time = parcel.read_string16()?;
145         let modify_time = parcel.read_string16()?;
146         let size = parcel.read_string16()?;
147         let operation_type = parcel.read::<AssetStatus>()?;
148         let asset_id = parcel.read_string16()?;
149         let hash = parcel.read_string16()?;
150 
151         let result = CloudAsset {
152             asset_id,
153             asset_name,
154             hash,
155             uri,
156             sub_path,
157             create_time,
158             modify_time,
159             size,
160             status: operation_type,
161         };
162         Ok(result)
163     }
164 }
165 
166 /// CloudAssets.
167 #[derive(Default, PartialEq, Debug, Clone)]
168 pub struct CloudAssets(pub Vec<CloudAsset>);
169 
170 impl Serialize for CloudAssets {
serialize(&self, parcel: &mut MsgParcel) -> IpcResult<()>171     fn serialize(&self, parcel: &mut MsgParcel) -> IpcResult<()> {
172         vec_raw_write(parcel, &self.0)
173     }
174 }
175 
176 impl Deserialize for CloudAssets {
deserialize(parcel: &mut MsgParcel) -> IpcResult<Self>177     fn deserialize(parcel: &mut MsgParcel) -> IpcResult<Self> {
178         let result = CloudAssets(vec_raw_read::<CloudAsset>(parcel)?);
179         Ok(result)
180     }
181 }
182 
183 pub(crate) struct AssetLoader {
184     pub(crate) remote_obj: Option<RemoteObj>,
185 }
186 
187 impl AssetLoader {
new(user_id: i32) -> AssetLoaderResult<Self>188     pub(crate) fn new(user_id: i32) -> AssetLoaderResult<Self> {
189         let mut msg_parcel = MsgParcel::new();
190         let function_number = ConnectAssetLoader as u32;
191         let remote_obj = unsafe { RemoteObj::from_ciremote(ConnectService(user_id)) }
192             .ok_or(Error::GetProxyObjectFailed)?;
193         let mut receive = remote_obj
194             .send_request(function_number, &mut msg_parcel)
195             .map_err(|_| Error::SendRequestFailed)?;
196 
197         let result = receive
198             .read_remote()
199             .map_err(|_| Error::ReadMsgParcelFailed)?;
200         Ok(Self {
201             remote_obj: Some(result),
202         })
203     }
204 
205     // Responsible for telling the cloud to perform file downloads.
download( &self, table: &str, gid: &str, prefix: &str, assets: &CloudAssets, ) -> AssetLoaderResult<Vec<Result<CloudAsset, Error>>>206     pub(crate) fn download(
207         &self,
208         table: &str,
209         gid: &str,
210         prefix: &str,
211         assets: &CloudAssets,
212     ) -> AssetLoaderResult<Vec<Result<CloudAsset, Error>>> {
213         let mut msg_parcel = MsgParcel::new();
214         msg_parcel
215             .write_string16(table)
216             .map_err(|_| Error::WriteMsgParcelFailed)?;
217         msg_parcel
218             .write_string16(gid)
219             .map_err(|_| Error::WriteMsgParcelFailed)?;
220         msg_parcel
221             .write_string16(prefix)
222             .map_err(|_| Error::WriteMsgParcelFailed)?;
223         msg_parcel
224             .write(assets)
225             .map_err(|_| Error::WriteMsgParcelFailed)?;
226 
227         let function_number = Download as u32;
228         let remote_obj = self
229             .remote_obj
230             .as_ref()
231             .ok_or(Error::GetProxyObjectFailed)?;
232         let mut receive = remote_obj
233             .send_request(function_number, &mut msg_parcel)
234             .map_err(|_| Error::SendRequestFailed)?;
235 
236         let mut results = vec![];
237         // Deserialise the length of the returned result.
238         let length = receive
239             .read::<i32>()
240             .map_err(|_| Error::ReadMsgParcelFailed)?;
241         for _ in 0..length {
242             let error = receive
243                 .read::<Error>()
244                 .map_err(|_| Error::ReadMsgParcelFailed)?;
245             if !error.eq(&Error::Success) {
246                 results.push(Err(error));
247             } else {
248                 let asset = receive
249                     .read::<CloudAsset>()
250                     .map_err(|_| Error::ReadMsgParcelFailed)?;
251                 results.push(Ok(asset))
252             }
253         }
254         Ok(results)
255     }
256 
257     // Responsible for telling the cloud to perform file uploads.
upload( &self, table: &str, gid: &str, prefix: &str, assets: &CloudAssets, ) -> AssetLoaderResult<Vec<Result<CloudAsset, Error>>>258     pub(crate) fn upload(
259         &self,
260         table: &str,
261         gid: &str,
262         prefix: &str,
263         assets: &CloudAssets,
264     ) -> AssetLoaderResult<Vec<Result<CloudAsset, Error>>> {
265         let mut msg_parcel = MsgParcel::new();
266         msg_parcel
267             .write_string16(table)
268             .map_err(|_| Error::WriteMsgParcelFailed)?;
269         msg_parcel
270             .write_string16(gid)
271             .map_err(|_| Error::WriteMsgParcelFailed)?;
272         msg_parcel
273             .write_string16(prefix)
274             .map_err(|_| Error::WriteMsgParcelFailed)?;
275         msg_parcel
276             .write(assets)
277             .map_err(|_| Error::WriteMsgParcelFailed)?;
278 
279         let function_number = Upload as u32;
280         let remote_obj = self
281             .remote_obj
282             .as_ref()
283             .ok_or(Error::GetProxyObjectFailed)?;
284         let mut receive = remote_obj
285             .send_request(function_number, &mut msg_parcel)
286             .map_err(|_| Error::SendRequestFailed)?;
287 
288         let mut results = vec![];
289         // Deserialise the length of the returned result.
290         let length = receive
291             .read::<i32>()
292             .map_err(|_| Error::ReadMsgParcelFailed)?;
293         for _ in 0..length {
294             let error = receive
295                 .read::<Error>()
296                 .map_err(|_| Error::ReadMsgParcelFailed)?;
297             if !error.eq(&Error::Success) {
298                 results.push(Err(error));
299             } else {
300                 let asset = receive
301                     .read::<CloudAsset>()
302                     .map_err(|_| Error::ReadMsgParcelFailed)?;
303                 results.push(Ok(asset))
304             }
305         }
306         Ok(results)
307     }
308 }
309