1 // Copyright (C) 2023 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 pub(crate) mod c_wrapper;
15 pub(crate) mod form_item;
16 use std::collections::HashMap;
17 use std::future::Future;
18 use std::io::Write;
19 use std::time::{SystemTime, UNIX_EPOCH};
20
21 pub(crate) use ffi::PublishStateChangeEvent;
22
23 cfg_oh! {
24 pub(crate) use ffi::RequestTaskMsg;
25 pub(crate) mod url_policy;
26 #[cfg(not(test))]
27 pub(crate) use ffi::GetTopUid;
28 }
29
30 pub(crate) mod task_id_generator;
31 use ylong_runtime::sync::oneshot::Receiver;
32 use ylong_runtime::task::JoinHandle;
33
34 pub(crate) struct Recv<T> {
35 rx: Receiver<T>,
36 }
37
38 impl<T> Recv<T> {
new(rx: Receiver<T>) -> Self39 pub(crate) fn new(rx: Receiver<T>) -> Self {
40 Self { rx }
41 }
42
get(self) -> Option<T>43 pub(crate) fn get(self) -> Option<T> {
44 // Here `self.rx` can never be hung up.
45 ylong_runtime::block_on(self.rx).ok()
46 }
47 }
48
build_vec<A, B, C>(ptr: *const A, len: usize, func: C) -> Vec<B> where C: Fn(&A) -> B,49 pub(crate) fn build_vec<A, B, C>(ptr: *const A, len: usize, func: C) -> Vec<B>
50 where
51 C: Fn(&A) -> B,
52 {
53 if ptr.is_null() || len == 0 {
54 return Vec::<B>::new();
55 }
56 let slice = unsafe { std::slice::from_raw_parts(ptr, len) };
57 slice.iter().map(func).collect()
58 }
59
get_current_timestamp() -> u6460 pub(crate) fn get_current_timestamp() -> u64 {
61 match SystemTime::now().duration_since(UNIX_EPOCH) {
62 Ok(n) => n.as_millis() as u64,
63 Err(_) => panic!("SystemTime before UNIX EPOCH!"),
64 }
65 }
66
hashmap_to_string(map: &HashMap<String, String>) -> String67 pub(crate) fn hashmap_to_string(map: &HashMap<String, String>) -> String {
68 let mut res = Vec::new();
69 for (n, (k, v)) in map.iter().enumerate() {
70 if n != 0 {
71 let _ = write!(res, "\r\n");
72 }
73 let _ = write!(res, "{k}\t{v}");
74 }
75 unsafe { String::from_utf8_unchecked(res) }
76 }
77
string_to_hashmap(str: &mut str) -> HashMap<String, String>78 pub(crate) fn string_to_hashmap(str: &mut str) -> HashMap<String, String> {
79 let mut map = HashMap::<String, String>::new();
80 if str.is_empty() {
81 return map;
82 }
83 for item in str.split("\r\n") {
84 let (k, v) = item.split_once('\t').unwrap();
85 map.insert(k.into(), v.into());
86 }
87 map
88 }
89
split_string(str: &mut str) -> std::str::Split<'_, &str>90 pub(crate) fn split_string(str: &mut str) -> std::str::Split<'_, &str> {
91 let pat: &[_] = &['[', ']'];
92 str.trim_matches(pat).split(", ")
93 }
94
95 #[inline(always)]
runtime_spawn<F: Future<Output = ()> + Send + Sync + 'static>( fut: F, ) -> JoinHandle<()>96 pub(crate) fn runtime_spawn<F: Future<Output = ()> + Send + Sync + 'static>(
97 fut: F,
98 ) -> JoinHandle<()> {
99 ylong_runtime::spawn(Box::into_pin(
100 Box::new(fut) as Box<dyn Future<Output = ()> + Send + Sync>
101 ))
102 }
103
104 #[cfg(feature = "oh")]
query_calling_bundle() -> String105 pub(crate) fn query_calling_bundle() -> String {
106 let token_id = ipc::Skeleton::calling_full_token_id();
107 ffi::GetCallingBundle(token_id)
108 }
109
110 #[cfg(feature = "oh")]
is_system_api() -> bool111 pub(crate) fn is_system_api() -> bool {
112 let token_id = ipc::Skeleton::calling_full_token_id();
113 ffi::IsSystemAPI(token_id)
114 }
115
116 #[cfg(feature = "oh")]
check_permission(permission: &str) -> bool117 pub(crate) fn check_permission(permission: &str) -> bool {
118 let token_id = ipc::Skeleton::calling_full_token_id();
119 ffi::CheckPermission(token_id, permission)
120 }
121
122 #[cfg(feature = "oh")]
request_background_notify( msg: RequestTaskMsg, wrapped_path: &str, wrapped_file_name: &str, percent: u32, ) -> Result<(), i32>123 pub(crate) fn request_background_notify(
124 msg: RequestTaskMsg,
125 wrapped_path: &str,
126 wrapped_file_name: &str,
127 percent: u32,
128 ) -> Result<(), i32> {
129 match ffi::RequestBackgroundNotify(msg, wrapped_path, wrapped_file_name, percent) {
130 0 => Ok(()),
131 code => Err(code),
132 }
133 }
134 #[allow(unused)]
135 #[cxx::bridge(namespace = "OHOS::Request")]
136 mod ffi {
137 struct RequestTaskMsg {
138 pub(crate) task_id: u32,
139 pub(crate) uid: i32,
140 pub(crate) action: u8,
141 }
142
143 unsafe extern "C++" {
144 include!("request_utils.h");
145
PublishStateChangeEvent(bundleName: &str, taskId: u32, state: i32, uid: i32) -> bool146 fn PublishStateChangeEvent(bundleName: &str, taskId: u32, state: i32, uid: i32) -> bool;
147
RequestBackgroundNotify( msg: RequestTaskMsg, wrapped_path: &str, wrapped_file_name: &str, percent: u32, ) -> i32148 fn RequestBackgroundNotify(
149 msg: RequestTaskMsg,
150 wrapped_path: &str,
151 wrapped_file_name: &str,
152 percent: u32,
153 ) -> i32;
154
GetTopUid(uid: &mut i32) -> i32155 fn GetTopUid(uid: &mut i32) -> i32;
GetCallingBundle(token_id: u64) -> String156 fn GetCallingBundle(token_id: u64) -> String;
IsSystemAPI(token_id: u64) -> bool157 fn IsSystemAPI(token_id: u64) -> bool;
CheckPermission(token_id: u64, permission: &str) -> bool158 fn CheckPermission(token_id: u64, permission: &str) -> bool;
159 }
160 }
161
162 #[cfg(feature = "oh")]
163 #[cfg(test)]
164 mod test {
165 use super::*;
166 use crate::tests::test_init;
167 #[test]
ut_utils_oh()168 fn ut_utils_oh() {
169 assert!(!is_system_api());
170 assert_eq!(query_calling_bundle(), "");
171 }
172
173 #[test]
ut_utils_request_background_notify()174 fn ut_utils_request_background_notify() {
175 test_init();
176 request_background_notify(
177 RequestTaskMsg {
178 task_id: 1,
179 uid: 1,
180 action: 1,
181 },
182 "path",
183 "file",
184 1,
185 )
186 .unwrap();
187 }
188
189 #[test]
ut_utils_check_permission()190 fn ut_utils_check_permission() {
191 assert!(!check_permission("ohos.permission.INTERNET"));
192 assert!(!check_permission("ohos.permission.GET_NETWORK_INFO"));
193 assert!(!check_permission("ohos.permission.READ_MEDIA"));
194 assert!(!check_permission("ohos.permission.WRITE_MEDIA"));
195 assert!(!check_permission("ohos.permission.RUNNING_STATE_OBSERVER"));
196 assert!(!check_permission("ohos.permission.GET_NETWORK_INFO"));
197 assert!(!check_permission("ohos.permission.CONNECTIVITY_INTERNAL"));
198 assert!(!check_permission(
199 "ohos.permission.SEND_TASK_COMPLETE_EVENT"
200 ));
201 assert!(!check_permission("ohos.permission.ACCESS_CERT_MANAGER"));
202 assert!(!check_permission(
203 "ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS"
204 ));
205 assert!(!check_permission("ohos.permission.MANAGE_LOCAL_ACCOUNTS"));
206 }
207
208 #[test]
ut_utils_check_permission_oh()209 fn ut_utils_check_permission_oh() {
210 test_init();
211 assert!(check_permission("ohos.permission.INTERNET"));
212 assert!(check_permission("ohos.permission.GET_NETWORK_INFO"));
213 assert!(check_permission("ohos.permission.READ_MEDIA"));
214 assert!(check_permission("ohos.permission.WRITE_MEDIA"));
215 assert!(check_permission("ohos.permission.RUNNING_STATE_OBSERVER"));
216 assert!(check_permission("ohos.permission.GET_NETWORK_INFO"));
217 assert!(check_permission("ohos.permission.CONNECTIVITY_INTERNAL"));
218 assert!(check_permission("ohos.permission.SEND_TASK_COMPLETE_EVENT"));
219 assert!(check_permission("ohos.permission.ACCESS_CERT_MANAGER"));
220 assert!(check_permission(
221 "ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS"
222 ));
223 assert!(check_permission("ohos.permission.MANAGE_LOCAL_ACCOUNTS"));
224 assert!(!check_permission(
225 "ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS_EXTENSION"
226 ));
227 }
228 }
229