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