1 /*
2 * Copyright (C) 2022 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 crate::{
17 ipc_binding, MsgParcel, RemoteObj, IRemoteObj, InterfaceToken, String16,
18 IpcResult, IpcStatusCode, parse_status_code,
19 };
20 use crate::parcel::{vec_to_string, allocate_vec_with_buffer};
21 use std::ffi::{CString, c_char, c_void};
22 use hilog_rust::{info, hilog, HiLogLabel, LogType};
23
24 const LOG_LABEL: HiLogLabel = HiLogLabel {
25 log_type: LogType::LogCore,
26 domain: 0xd001510,
27 tag: "RustProcess"
28 };
29
30 /// Get proxy object of samgr
get_context_object() -> Option<RemoteObj>31 pub fn get_context_object() -> Option<RemoteObj>
32 {
33 // SAFETY:
34 unsafe {
35 let samgr = ipc_binding::GetContextManager();
36 RemoteObj::from_raw(samgr)
37 }
38 }
39
40 /// Add a service to samgr
add_service(service: &RemoteObj, said: i32) -> IpcResult<()>41 pub fn add_service(service: &RemoteObj, said: i32) -> IpcResult<()>
42 {
43 let samgr = get_context_object().expect("samgr is not null");
44 let mut data = MsgParcel::new().expect("MsgParcel is not null");
45 data.write(&InterfaceToken::new("ohos.samgr.accessToken"))?;
46 data.write(&said)?;
47 data.write(service)?;
48 data.write(&false)?;
49 data.write(&0)?;
50 data.write(&String16::new(""))?;
51 data.write(&String16::new(""))?;
52 let reply = samgr.send_request(3, &data, false)?;
53 let reply_value: i32 = reply.read()?;
54 info!(LOG_LABEL, "register service result: {}", reply_value);
55 if reply_value == 0 { Ok(())} else { Err(parse_status_code(reply_value)) }
56 }
57
58 /// Get a service proxy from samgr
get_service(said: i32) -> IpcResult<RemoteObj>59 pub fn get_service(said: i32) -> IpcResult<RemoteObj>
60 {
61 let samgr = get_context_object().expect("samgr is not null");
62 let mut data = MsgParcel::new().expect("MsgParcel is not null");
63 data.write(&InterfaceToken::new("ohos.samgr.accessToken"))?;
64 data.write(&said)?;
65 let reply = samgr.send_request(2, &data, false)?;
66 let remote: RemoteObj = reply.read()?;
67 info!(LOG_LABEL, "get service success");
68 Ok(remote)
69 }
70
71 /// Make current thread join to the IPC/RPC work thread pool
72 #[inline]
join_work_thread()73 pub fn join_work_thread()
74 {
75 // SAFETY:
76 unsafe {
77 ipc_binding::JoinWorkThread();
78 }
79 }
80
81 /// Exit current thread from IPC/RPC work thread pool
82 #[inline]
stop_work_thread()83 pub fn stop_work_thread()
84 {
85 // SAFETY:
86 unsafe {
87 ipc_binding::StopWorkThread()
88 }
89 }
90
91 /// Get calling token ID of caller
92 #[inline]
get_calling_token_id() -> u6493 pub fn get_calling_token_id() -> u64
94 {
95 // SAFETY:
96 unsafe {
97 ipc_binding::GetCallingTokenId()
98 }
99 }
100
101 /// Get first calling token ID of caller
102 #[inline]
get_first_token_id() -> u64103 pub fn get_first_token_id() -> u64
104 {
105 // SAFETY:
106 unsafe {
107 ipc_binding::GetFirstToekenId()
108 }
109 }
110
111 /// Get self token id of current process
112 #[inline]
get_self_token_id() -> u64113 pub fn get_self_token_id() -> u64
114 {
115 // SAFETY:
116 unsafe {
117 ipc_binding::GetSelfToekenId()
118 }
119 }
120
121 /// Get calling process id of caller
122 #[inline]
get_calling_pid() -> u64123 pub fn get_calling_pid() -> u64
124 {
125 // SAFETY:
126 unsafe {
127 ipc_binding::GetCallingPid()
128 }
129 }
130
131 /// Get calling user id of caller
132 #[inline]
get_calling_uid() -> u64133 pub fn get_calling_uid() -> u64
134 {
135 // SAFETY:
136 unsafe {
137 ipc_binding::GetCallingUid()
138 }
139 }
140
141 /// Set the maximum number of threads
142 #[inline]
set_max_work_thread(max_thread_num: i32) -> bool143 pub fn set_max_work_thread(max_thread_num: i32) -> bool
144 {
145 // SAFETY:
146 unsafe {
147 ipc_binding::SetMaxWorkThreadNum(max_thread_num)
148 }
149 }
150
151 /// Determine whether it is a local call
152 #[inline]
is_local_calling() -> bool153 pub fn is_local_calling() -> bool
154 {
155 // SAFETY:
156 unsafe {
157 ipc_binding::IsLocalCalling()
158 }
159 }
160
161 /// Set calling identity
162 #[inline]
set_calling_identity(identity: String) -> bool163 pub fn set_calling_identity(identity: String) -> bool
164 {
165 match CString::new(identity.as_str()) {
166 Ok(name) => {
167 // SAFETY:
168 // Name is valid
169 unsafe {
170 ipc_binding::SetCallingIdentity(name.as_ptr())
171 }
172 },
173 Err(_) => false,
174 }
175 }
176
177 /// get local device id
178 #[inline]
get_local_device_id() -> IpcResult<String>179 pub fn get_local_device_id() -> IpcResult<String>
180 {
181 let mut vec: Option<Vec<u8>> = None;
182 // SAFETY:
183 let ok_status = unsafe {
184 ipc_binding::GetLocalDeviceID(
185 &mut vec as *mut _ as *mut c_void,
186 allocate_vec_with_buffer::<u8>
187 )
188 };
189
190 if ok_status {
191 vec_to_string(vec)
192 } else {
193 Err(IpcStatusCode::Failed)
194 }
195 }
196
197 /// get calling device id
198 #[inline]
get_calling_device_id() -> IpcResult<String>199 pub fn get_calling_device_id() -> IpcResult<String>
200 {
201 let mut vec: Option<Vec<u8>> = None;
202 // SAFETY:
203 let ok_status = unsafe {
204 ipc_binding::GetCallingDeviceID(
205 &mut vec as *mut _ as *mut c_void,
206 allocate_vec_with_buffer::<u8>
207 )
208 };
209
210 if ok_status {
211 vec_to_string(vec)
212 } else {
213 Err(IpcStatusCode::Failed)
214 }
215 }
216
217 /// reset calling identity
218 #[inline]
reset_calling_identity() -> IpcResult<String>219 pub fn reset_calling_identity() -> IpcResult<String>
220 {
221 let mut vec: Option<Vec<u8>> = None;
222 // SAFETY:
223 let ok_status = unsafe {
224 ipc_binding::ResetCallingIdentity(
225 &mut vec as *mut _ as *mut c_void,
226 allocate_vec_with_buffer::<u8>
227 )
228 };
229
230 if ok_status {
231 vec_to_string(vec)
232 } else {
233 Err(IpcStatusCode::Failed)
234 }
235 }