1 // Copyright (C) 2024 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 #![allow(unreachable_pub, missing_docs, unused)] 15 use std::collections::HashMap; 16 use std::fs::File; 17 use std::os::fd::FromRawFd; 18 use std::pin::Pin; 19 20 pub(crate) use ffi::*; 21 pub use ffi::{OnDemandReasonExtraData, OnDemandReasonId, SystemAbilityOnDemandReason}; 22 use ipc::parcel::{Deserialize, MsgParcel, Serialize}; 23 use ipc::remote::RemoteStub; 24 use ipc::IpcStatusCode; 25 26 use crate::ability::{Ability, Handler}; 27 28 // `SystemAbility` trait is not used is because their methods are not recognized 29 // by cxx. 30 #[allow(non_snake_case)] 31 impl AbilityWrapper { OnDump(&self)32 fn OnDump(&self) { 33 self.inner.on_dump() 34 } 35 OnStart(&self, system_ability: *mut ffi::SystemAbilityWrapper)36 fn OnStart(&self, system_ability: *mut ffi::SystemAbilityWrapper) { 37 let handle = Handler { 38 inner: system_ability, 39 }; 40 self.inner.on_start(handle) 41 } 42 OnStartWithReason( &self, reason: ffi::SystemAbilityOnDemandReason, system_ability: *mut ffi::SystemAbilityWrapper, )43 fn OnStartWithReason( 44 &self, 45 reason: ffi::SystemAbilityOnDemandReason, 46 system_ability: *mut ffi::SystemAbilityWrapper, 47 ) { 48 let handle = Handler { 49 inner: system_ability, 50 }; 51 self.inner.on_start_with_reason(reason, handle); 52 } 53 OnIdle(&self, reason: ffi::SystemAbilityOnDemandReason) -> i3254 fn OnIdle(&self, reason: ffi::SystemAbilityOnDemandReason) -> i32 { 55 self.inner.on_idle(reason) 56 } 57 OnActive(&self, reason: ffi::SystemAbilityOnDemandReason)58 fn OnActive(&self, reason: ffi::SystemAbilityOnDemandReason) { 59 self.inner.on_active(reason) 60 } 61 OnStop(&self)62 fn OnStop(&self) { 63 self.inner.on_stop() 64 } 65 OnStopWithReason(&self, reason: ffi::SystemAbilityOnDemandReason)66 fn OnStopWithReason(&self, reason: ffi::SystemAbilityOnDemandReason) { 67 self.inner.on_stop_with_reason(reason) 68 } 69 OnAddSystemAbility(&self, said: i32, device_id: String)70 fn OnAddSystemAbility(&self, said: i32, device_id: String) { 71 self.inner.on_system_ability_load_event(said, device_id) 72 } 73 OnRemoveSystemAbility(&self, said: i32, device_id: String)74 fn OnRemoveSystemAbility(&self, said: i32, device_id: String) { 75 self.inner.on_system_ability_remove_event(said, device_id) 76 } 77 OnDeviceLevelChanged(&self, change_type: i32, level: i32, action: String)78 fn OnDeviceLevelChanged(&self, change_type: i32, level: i32, action: String) { 79 self.inner 80 .on_device_level_changed(change_type, level, action) 81 } 82 OnExtension( &self, extension: String, data: Pin<&mut MessageParcel>, reply: Pin<&mut MessageParcel>, ) -> i3283 fn OnExtension( 84 &self, 85 extension: String, 86 data: Pin<&mut MessageParcel>, 87 reply: Pin<&mut MessageParcel>, 88 ) -> i32 { 89 unsafe { 90 let mut data = MsgParcel::from_ptr(data.get_unchecked_mut() as *mut MessageParcel); 91 let mut reply = MsgParcel::from_ptr(reply.get_unchecked_mut() as *mut MessageParcel); 92 self.inner.on_extension(extension, &mut data, &mut reply) 93 } 94 } 95 } 96 97 pub struct AbilityStub { 98 inner: Box<dyn RemoteStub>, 99 } 100 101 impl AbilityStub { new<A: RemoteStub + 'static>(remote: A) -> Self102 pub fn new<A: RemoteStub + 'static>(remote: A) -> Self { 103 Self { 104 inner: Box::new(remote), 105 } 106 } 107 on_remote_request( &mut self, code: u32, data: Pin<&mut MessageParcel>, reply: Pin<&mut MessageParcel>, ) -> i32108 pub fn on_remote_request( 109 &mut self, 110 code: u32, 111 data: Pin<&mut MessageParcel>, 112 reply: Pin<&mut MessageParcel>, 113 ) -> i32 { 114 unsafe { 115 let mut data = MsgParcel::from_ptr(data.get_unchecked_mut() as *mut MessageParcel); 116 let mut reply = MsgParcel::from_ptr(reply.get_unchecked_mut() as *mut MessageParcel); 117 self.inner.on_remote_request(code, &mut data, &mut reply) 118 } 119 } 120 dump(&mut self, fd: i32, args: Vec<String>) -> i32121 pub fn dump(&mut self, fd: i32, args: Vec<String>) -> i32 { 122 let file = unsafe { File::from_raw_fd(fd) }; 123 self.inner.dump(file, args) 124 } 125 } 126 127 pub struct AbilityWrapper { 128 pub(crate) inner: Box<dyn Ability>, 129 } 130 131 impl Serialize for OnDemandReasonId { serialize(&self, parcel: &mut MsgParcel) -> ipc::IpcResult<()>132 fn serialize(&self, parcel: &mut MsgParcel) -> ipc::IpcResult<()> { 133 parcel.write(&self.repr) 134 } 135 } 136 137 impl Deserialize for OnDemandReasonId { deserialize(parcel: &mut MsgParcel) -> ipc::IpcResult<Self>138 fn deserialize(parcel: &mut MsgParcel) -> ipc::IpcResult<Self> { 139 let res = match parcel.read::<i32>()? { 140 0 => Self::INTERFACE_CALL, 141 1 => Self::DEVICE_ONLINE, 142 2 => Self::SETTING_SWITCH, 143 3 => Self::PARAM, 144 4 => Self::COMMON_EVENT, 145 5 => Self::TIMED_EVENT, 146 _ => return Err(IpcStatusCode::Failed), 147 }; 148 Ok(res) 149 } 150 } 151 152 impl Serialize for OnDemandReasonExtraData { serialize(&self, parcel: &mut MsgParcel) -> ipc::IpcResult<()>153 fn serialize(&self, parcel: &mut MsgParcel) -> ipc::IpcResult<()> { 154 if SerializeOnDemandReasonExtraData(self, parcel.pin_mut().unwrap()) { 155 Ok(()) 156 } else { 157 Err(IpcStatusCode::Failed) 158 } 159 } 160 } 161 162 impl Deserialize for OnDemandReasonExtraData { deserialize(parcel: &mut MsgParcel) -> ipc::IpcResult<Self>163 fn deserialize(parcel: &mut MsgParcel) -> ipc::IpcResult<Self> { 164 Ok(DeserializeOnDemandReasonExtraData( 165 parcel.pin_mut().unwrap(), 166 )) 167 } 168 } 169 170 impl Serialize for SystemAbilityOnDemandReason { serialize(&self, parcel: &mut MsgParcel) -> ipc::IpcResult<()>171 fn serialize(&self, parcel: &mut MsgParcel) -> ipc::IpcResult<()> { 172 parcel.write(&self.name)?; 173 parcel.write(&self.value)?; 174 parcel.write(&self.reason_id)?; 175 parcel.write(&self.extra_data)?; 176 parcel.write(&self.extra_data_id) 177 } 178 } 179 180 impl Deserialize for SystemAbilityOnDemandReason { deserialize(parcel: &mut MsgParcel) -> ipc::IpcResult<Self>181 fn deserialize(parcel: &mut MsgParcel) -> ipc::IpcResult<Self> { 182 let name = parcel.read()?; 183 let value = parcel.read()?; 184 let reason_id = parcel.read()?; 185 let extra_data = parcel.read()?; 186 let extra_data_id = parcel.read()?; 187 Ok(Self { 188 name, 189 value, 190 reason_id, 191 extra_data, 192 extra_data_id, 193 }) 194 } 195 } 196 197 impl OnDemandReasonExtraData { want(self) -> HashMap<String, String>198 pub fn want(self) -> HashMap<String, String> { 199 let mut res = HashMap::new(); 200 let mut want = self.want.into_iter(); 201 while let Some(k) = want.next() { 202 if let Some(v) = want.next() { 203 res.insert(k, v); 204 } 205 } 206 res 207 } 208 } 209 210 /// AbilityWrapper used for cxx 211 #[cxx::bridge(namespace = "OHOS::SafwkRust")] 212 mod ffi { 213 #[repr(i32)] 214 #[derive(Debug)] 215 pub enum OnDemandReasonId { 216 INTERFACE_CALL = 0, 217 DEVICE_ONLINE = 1, 218 SETTING_SWITCH = 2, 219 PARAM = 3, 220 COMMON_EVENT = 4, 221 TIMED_EVENT = 5, 222 } 223 224 #[derive(Debug)] 225 pub struct SystemAbilityOnDemandReason { 226 pub name: String, 227 pub value: String, 228 pub reason_id: OnDemandReasonId, 229 pub extra_data: OnDemandReasonExtraData, 230 pub extra_data_id: i64, 231 } 232 233 #[derive(Debug)] 234 pub struct OnDemandReasonExtraData { 235 pub data: String, 236 pub code: i32, 237 pub want: Vec<String>, 238 } 239 240 extern "Rust" { 241 type AbilityWrapper; 242 type AbilityStub; on_remote_request( self: &mut AbilityStub, code: u32, data: Pin<&mut MessageParcel>, reply: Pin<&mut MessageParcel>, ) -> i32243 fn on_remote_request( 244 self: &mut AbilityStub, 245 code: u32, 246 data: Pin<&mut MessageParcel>, 247 reply: Pin<&mut MessageParcel>, 248 ) -> i32; 249 dump(self: &mut AbilityStub, fd: i32, args: Vec<String>) -> i32250 fn dump(self: &mut AbilityStub, fd: i32, args: Vec<String>) -> i32; 251 OnDump(self: &AbilityWrapper)252 fn OnDump(self: &AbilityWrapper); 253 OnStart(self: &AbilityWrapper, system_ability: *mut SystemAbilityWrapper)254 unsafe fn OnStart(self: &AbilityWrapper, system_ability: *mut SystemAbilityWrapper); OnStartWithReason( self: &AbilityWrapper, reason: SystemAbilityOnDemandReason, system_ability: *mut SystemAbilityWrapper, )255 unsafe fn OnStartWithReason( 256 self: &AbilityWrapper, 257 reason: SystemAbilityOnDemandReason, 258 system_ability: *mut SystemAbilityWrapper, 259 ); OnIdle(self: &AbilityWrapper, reason: SystemAbilityOnDemandReason) -> i32260 fn OnIdle(self: &AbilityWrapper, reason: SystemAbilityOnDemandReason) -> i32; OnActive(self: &AbilityWrapper, reason: SystemAbilityOnDemandReason)261 fn OnActive(self: &AbilityWrapper, reason: SystemAbilityOnDemandReason); OnStop(self: &AbilityWrapper)262 fn OnStop(self: &AbilityWrapper); OnStopWithReason(self: &AbilityWrapper, reason: SystemAbilityOnDemandReason)263 fn OnStopWithReason(self: &AbilityWrapper, reason: SystemAbilityOnDemandReason); 264 OnAddSystemAbility(self: &AbilityWrapper, said: i32, device_id: String)265 fn OnAddSystemAbility(self: &AbilityWrapper, said: i32, device_id: String); OnRemoveSystemAbility(self: &AbilityWrapper, said: i32, device_id: String)266 fn OnRemoveSystemAbility(self: &AbilityWrapper, said: i32, device_id: String); OnDeviceLevelChanged( self: &AbilityWrapper, change_type: i32, level: i32, action: String, )267 fn OnDeviceLevelChanged( 268 self: &AbilityWrapper, 269 change_type: i32, 270 level: i32, 271 action: String, 272 ); OnExtension( self: &AbilityWrapper, extension: String, data: Pin<&mut MessageParcel>, reply: Pin<&mut MessageParcel>, ) -> i32273 fn OnExtension( 274 self: &AbilityWrapper, 275 extension: String, 276 data: Pin<&mut MessageParcel>, 277 reply: Pin<&mut MessageParcel>, 278 ) -> i32; 279 } 280 281 // C++ types and signatures exposed to Rust. 282 unsafe extern "C++" { 283 include!("system_ability_wrapper.h"); 284 include!("system_ability.h"); 285 include!("system_ability_ondemand_reason.h"); 286 #[namespace = "OHOS"] 287 type OnDemandReasonId; 288 289 #[namespace = "OHOS"] 290 type MessageParcel = ipc::cxx_share::MessageParcel; 291 292 type SystemAbilityWrapper; 293 BuildSystemAbility( ability: Box<AbilityWrapper>, system_ability_id: i32, run_on_create: bool, ) -> UniquePtr<SystemAbilityWrapper>294 fn BuildSystemAbility( 295 ability: Box<AbilityWrapper>, 296 system_ability_id: i32, 297 run_on_create: bool, 298 ) -> UniquePtr<SystemAbilityWrapper>; 299 RegisterAbility(system_ability: *mut SystemAbilityWrapper) -> bool300 unsafe fn RegisterAbility(system_ability: *mut SystemAbilityWrapper) -> bool; 301 AddSystemAbilityListener( self: Pin<&mut SystemAbilityWrapper>, mut system_ability_id: i32, ) -> bool302 fn AddSystemAbilityListener( 303 self: Pin<&mut SystemAbilityWrapper>, 304 mut system_ability_id: i32, 305 ) -> bool; 306 RemoveSystemAbilityListener( self: Pin<&mut SystemAbilityWrapper>, mut system_ability_id: i32, ) -> bool307 fn RemoveSystemAbilityListener( 308 self: Pin<&mut SystemAbilityWrapper>, 309 mut system_ability_id: i32, 310 ) -> bool; 311 CancelIdleWrapper(self: Pin<&mut SystemAbilityWrapper>) -> bool312 fn CancelIdleWrapper(self: Pin<&mut SystemAbilityWrapper>) -> bool; 313 PublishWrapper(self: Pin<&mut SystemAbilityWrapper>, ability: Box<AbilityStub>) -> bool314 fn PublishWrapper(self: Pin<&mut SystemAbilityWrapper>, ability: Box<AbilityStub>) -> bool; 315 DeserializeOnDemandReasonExtraData( data: Pin<&mut MessageParcel>, ) -> OnDemandReasonExtraData316 fn DeserializeOnDemandReasonExtraData( 317 data: Pin<&mut MessageParcel>, 318 ) -> OnDemandReasonExtraData; 319 SerializeOnDemandReasonExtraData( extraData: &OnDemandReasonExtraData, data: Pin<&mut MessageParcel>, ) -> bool320 fn SerializeOnDemandReasonExtraData( 321 extraData: &OnDemandReasonExtraData, 322 data: Pin<&mut MessageParcel>, 323 ) -> bool; 324 OnExtension( self: Pin<&mut SystemAbilityWrapper>, extension: &CxxString, data: Pin<&mut MessageParcel>, reply: Pin<&mut MessageParcel>, ) -> i32325 fn OnExtension( 326 self: Pin<&mut SystemAbilityWrapper>, 327 extension: &CxxString, 328 data: Pin<&mut MessageParcel>, 329 reply: Pin<&mut MessageParcel>, 330 ) -> i32; 331 } 332 } 333 334 #[cfg(test)] 335 mod test { 336 use std::cell::RefCell; 337 use std::rc::Rc; 338 339 use cxx::let_cxx_string; 340 341 use super::*; 342 #[test] on_extension_ut()343 fn on_extension_ut() { 344 const TEST_EXTENSION: &str = "test"; 345 const TEST_RETURN: i32 = 0; 346 347 struct TestAbility { 348 inner: Rc<RefCell<String>>, 349 } 350 impl Ability for TestAbility { 351 fn on_extension( 352 &self, 353 extension: String, 354 data: &mut MsgParcel, 355 reply: &mut MsgParcel, 356 ) -> i32 { 357 self.inner.borrow_mut().push_str(&extension); 358 data.write(TEST_EXTENSION).unwrap(); 359 reply.write(TEST_EXTENSION).unwrap(); 360 TEST_RETURN 361 } 362 } 363 364 let extension = Rc::new(RefCell::new(String::new())); 365 let ability = TestAbility { 366 inner: extension.clone(), 367 }; 368 let ability = Box::new(AbilityWrapper { 369 inner: Box::new(ability), 370 }); 371 let mut sys = BuildSystemAbility(ability, 3706, true); 372 let mut data = MsgParcel::new(); 373 let mut reply = MsgParcel::new(); 374 let_cxx_string!(cxx_s = TEST_EXTENSION); 375 assert_eq!( 376 sys.pin_mut() 377 .OnExtension(&cxx_s, data.pin_mut().unwrap(), reply.pin_mut().unwrap(),), 378 TEST_RETURN 379 ); 380 assert_eq!(*extension.borrow_mut(), TEST_EXTENSION); 381 assert_eq!(data.read::<String>().unwrap(), TEST_EXTENSION); 382 assert_eq!(reply.read::<String>().unwrap(), TEST_EXTENSION); 383 } 384 } 385