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