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 extern crate ipc_rust;
17 use ipc_rust::{
18 IRemoteObj, RemoteObjRef, FromRemoteObj, IRemoteBroker, MsgParcel,
19 RemoteObj, InterfaceToken, String16, IpcResult, parse_status_code, get_context_object
20 };
21 use std::ffi::{c_char, CString};
22 use std::default::Default;
23 use hilog_rust::{info, error, hilog, HiLogLabel, LogType};
24 const LOG_LABEL: HiLogLabel = HiLogLabel {
25 log_type: LogType::LogCore,
26 domain: 0xd001800,
27 tag: "rustSA"
28 };
29
30 pub enum ISystemAbilityManagerCode {
31 /// get code
32 Get = 2,
33 /// add code
34 Add = 3,
35 /// unload code
36 Unload = 21,
37 }
38
39 /// SAExtraProp is used to add_systemability
40 pub struct SAExtraProp {
41 /// Set whether SA is distributed
42 pub is_distributed: bool,
43 /// Additional parameters for SA, default is 8
44 pub dump_flags: u32,
45 /// Additional parameters for SA, default is ""
46 pub capability: String16,
47 /// Additional parameters for SA, default is ""
48 pub permission: String16,
49 }
50
51 impl Default for SAExtraProp {
default() -> SAExtraProp52 fn default() -> SAExtraProp {
53 SAExtraProp {
54 is_distributed: false,
55 dump_flags: 8,
56 capability: String16::new(""),
57 permission: String16::new(""),
58 }
59 }
60 }
61
62 /// samgr interface
63 pub trait ISystemAbilityManager: IRemoteBroker {
64 /// add_systemability
add_systemability(&self, service: &RemoteObj, said: i32, extra_prop: SAExtraProp) -> IpcResult<()>65 fn add_systemability(&self, service: &RemoteObj, said: i32, extra_prop: SAExtraProp) -> IpcResult<()>;
66 /// get_systemability
get_systemability(&self, said: i32) -> IpcResult<RemoteObj>67 fn get_systemability(&self, said: i32) -> IpcResult<RemoteObj>;
68 /// unload_systemability
unload_systemability(&self, said: i32) -> IpcResult<()>69 fn unload_systemability(&self, said: i32) -> IpcResult<()>;
70 }
71
72 impl FromRemoteObj for dyn ISystemAbilityManager {
73 /// For example, convert RemoteObj to RemoteObjRef<dyn ITest>
try_from(object: RemoteObj) -> IpcResult<RemoteObjRef<dyn ISystemAbilityManager>>74 fn try_from(object: RemoteObj) -> IpcResult<RemoteObjRef<dyn ISystemAbilityManager>> {
75 Ok(RemoteObjRef::new(Box::new(SystemAbilityManagerProxy::from_remote_object(object)?)))
76 }
77 }
78
79 /// get_service_proxy
get_service_proxy<T: FromRemoteObj + ?Sized>(said: i32) -> IpcResult<RemoteObjRef<T>>80 pub fn get_service_proxy<T: FromRemoteObj + ?Sized>(said: i32) -> IpcResult<RemoteObjRef<T>>
81 {
82 let samgr_proxy = get_systemability_manager();
83 let object = samgr_proxy.get_systemability(said)?;
84 <T as FromRemoteObj>::try_from(object)
85 }
86
87 /// get_systemability_manager - get samgr proxy
get_systemability_manager() -> RemoteObjRef<dyn ISystemAbilityManager>88 pub fn get_systemability_manager() -> RemoteObjRef<dyn ISystemAbilityManager>
89 {
90 let object = get_context_object().expect("samgr is null");
91 let remote = <dyn ISystemAbilityManager as FromRemoteObj>::try_from(object);
92 let remote = match remote {
93 Ok(x) => x,
94 Err(error) => {
95 error!(LOG_LABEL, "convert RemoteObj to SystemAbilityManagerProxy failed: {}", error);
96 panic!();
97 }
98 };
99 remote
100 }
101
102 /// define rust samgr proxy
103 pub struct SystemAbilityManagerProxy {
104 remote: RemoteObj,
105 }
106
107 impl SystemAbilityManagerProxy {
from_remote_object(remote: RemoteObj) -> IpcResult<Self>108 fn from_remote_object(remote: RemoteObj) -> IpcResult<Self> {
109 Ok(Self {remote})
110 }
111 }
112
113 impl IRemoteBroker for SystemAbilityManagerProxy {
114 /// Get Remote object from proxy
as_object(&self) -> Option<RemoteObj>115 fn as_object(&self) -> Option<RemoteObj> {
116 Some(self.remote.clone())
117 }
118 }
119
120 impl ISystemAbilityManager for SystemAbilityManagerProxy {
add_systemability(&self, service: &RemoteObj, said: i32, extra_prop: SAExtraProp) -> IpcResult<()>121 fn add_systemability(&self, service: &RemoteObj, said: i32, extra_prop: SAExtraProp) -> IpcResult<()>
122 {
123 let mut data = MsgParcel::new().expect("MsgParcel is null");
124 data.write(&InterfaceToken::new("ohos.samgr.accessToken"))?;
125 data.write(&said)?;
126 data.write(service)?;
127 data.write(&extra_prop.is_distributed)?;
128 data.write(&extra_prop.dump_flags)?;
129 data.write(&extra_prop.capability)?;
130 data.write(&extra_prop.permission)?;
131 let reply = self.remote.send_request(
132 ISystemAbilityManagerCode::Add as u32, &data, false)?;
133 let reply_value: i32 = reply.read()?;
134 info!(LOG_LABEL, "register service result: {}", reply_value);
135 if reply_value == 0 { Ok(())} else { Err(parse_status_code(reply_value)) }
136 }
137
get_systemability(&self, said: i32) -> IpcResult<RemoteObj>138 fn get_systemability(&self, said: i32) -> IpcResult<RemoteObj>
139 {
140 let mut data = MsgParcel::new().expect("MsgParcel is null");
141 data.write(&InterfaceToken::new("ohos.samgr.accessToken"))?;
142 data.write(&said)?;
143 let reply = self.remote.send_request(
144 ISystemAbilityManagerCode::Get as u32, &data, false)?;
145 let remote: RemoteObj = reply.read()?;
146 Ok(remote)
147 }
148
unload_systemability(&self, said: i32) -> IpcResult<()>149 fn unload_systemability(&self, said: i32) -> IpcResult<()>
150 {
151 let mut data = MsgParcel::new().expect("MsgParcel is null");
152 data.write(&InterfaceToken::new("ohos.samgr.accessToken"))?;
153 data.write(&said)?;
154 let reply = self.remote.send_request(
155 ISystemAbilityManagerCode::Unload as u32, &data, false)?;
156 let reply_value: i32 = reply.read()?;
157 info!(LOG_LABEL, "unload service result: {}", reply_value);
158 if reply_value == 0 { Ok(())} else { Err(parse_status_code(reply_value)) }
159 }
160 }