• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Copyright (C) 2024 Huawei Device Co., Ltd.
15 // Licensed under the Apache License, Version 2.0 (the "License");
16 // you may not use this file except in compliance with the License.
17 // You may obtain a copy of the License at
18 //
19 //     http://www.apache.org/licenses/LICENSE-2.0
20 //
21 // Unless required by applicable law or agreed to in writing, software
22 // distributed under the License is distributed on an "AS IS" BASIS,
23 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 // See the License for the specific language governing permissions and
25 // limitations under the License.
26 #![allow(unused)]
27 #![allow(missing_docs)]
28 #![cfg(feature = "oh")]
29 
30 use std::collections::HashMap;
31 use std::ffi::{c_char, CString};
32 use std::fmt::format;
33 use std::fs::File;
34 use std::os::fd::{AsRawFd, FromRawFd, IntoRawFd};
35 use std::os::unix::net::UnixDatagram;
36 use std::sync::{Arc, Mutex, Once};
37 use std::thread;
38 
39 use download_server::config::{Action, Mode, TaskConfig};
40 use download_server::info::State;
41 use download_server::interface;
42 use ipc::parcel::{Deserialize, MsgParcel};
43 use ipc::remote::RemoteObj;
44 use once_cell::sync::{Lazy, OnceCell};
45 use samgr::definition::DOWNLOAD_SERVICE_ID;
46 use samgr::manage::SystemAbilityManager;
47 
48 const SERVICE_TOKEN: &str = "OHOS.Download.RequestServiceInterface";
49 pub const CHANNEL_MAGIC_NUM: u32 = 0x43434646;
50 
51 #[allow(clippy::type_complexity)]
52 static MESSAGES: OnceCell<Arc<Mutex<HashMap<u32, Vec<MessageInfo>>>>> = OnceCell::new();
53 
test_init() -> RequestAgent54 pub fn test_init() -> RequestAgent {
55     let remote = remote();
56     RequestAgent::new(remote)
57 }
58 
59 pub struct RequestAgent {
60     remote: RemoteObj,
61     messages: Arc<Mutex<HashMap<u32, Vec<MessageInfo>>>>,
62 }
63 
64 impl RequestAgent {
new(remote: RemoteObj) -> Self65     fn new(remote: RemoteObj) -> Self {
66         static ONCE: Once = Once::new();
67         let messages = MESSAGES.get_or_init(|| Arc::new(Mutex::new(HashMap::new())));
68         ONCE.call_once(|| {
69             let mut data = MsgParcel::new();
70             data.write_interface_token(SERVICE_TOKEN).unwrap();
71             let mut reply = remote
72                 .send_request(interface::OPEN_CHANNEL, &mut data)
73                 .unwrap();
74             let ret: i32 = reply.read().unwrap();
75             assert_eq!(0, ret);
76             let raw_fd = unsafe { reply.read_raw_fd() };
77             assert!(raw_fd >= 0);
78             let file = unsafe { File::from_raw_fd(raw_fd) };
79             let channel = unsafe { UnixDatagram::from_raw_fd(file.into_raw_fd()) };
80             thread::spawn(move || loop {
81                 let mut buf = [0u8; 4096];
82                 let Ok(length) = channel.recv(&mut buf) else {
83                     std::thread::sleep(std::time::Duration::from_secs(1));
84                     continue;
85                 };
86                 channel
87                     .send((length as u32).to_le_bytes().as_slice())
88                     .unwrap();
89                 let (task_id, info) = deserialize(&buf);
90                 let mut map = messages.lock().unwrap();
91                 match map.get_mut(&task_id) {
92                     Some(v) => v.push(info),
93                     None => {
94                         map.insert(task_id, vec![info]);
95                     }
96                 };
97             });
98         });
99 
100         RequestAgent {
101             remote,
102             messages: messages.clone(),
103         }
104     }
105 
construct(&self, config: TaskConfig) -> u32106     pub fn construct(&self, config: TaskConfig) -> u32 {
107         let mut data = MsgParcel::new();
108         data.write_interface_token(SERVICE_TOKEN).unwrap();
109         data.write(&config).unwrap();
110         let mut reply = self
111             .remote
112             .send_request(interface::CONSTRUCT, &mut data)
113             .unwrap();
114         let ret: i32 = reply.read().unwrap();
115         assert_eq!(0, ret);
116         reply.read::<i32>().unwrap() as u32
117     }
118 
pause(&self, task_id: u32)119     pub fn pause(&self, task_id: u32) {
120         self.pause_version(1u32, task_id);
121     }
122 
pause_v10(&self, task_id: u32)123     pub fn pause_v10(&self, task_id: u32) {
124         self.pause_version(2u32, task_id);
125     }
126 
pause_version(&self, version: u32, task_id: u32)127     pub(crate) fn pause_version(&self, version: u32, task_id: u32) {
128         let mut data = MsgParcel::new();
129         data.write_interface_token(SERVICE_TOKEN).unwrap();
130         data.write(&version);
131         data.write(&format!("{}", task_id)).unwrap();
132         let mut reply = self
133             .remote
134             .send_request(interface::PAUSE, &mut data)
135             .unwrap();
136         let ret: i32 = reply.read().unwrap();
137         assert_eq!(ret, 0);
138     }
139 
query(&self, task_id: u32)140     pub fn query(&self, task_id: u32) {
141         let mut data = MsgParcel::new();
142         data.write_interface_token(SERVICE_TOKEN).unwrap();
143         data.write(&format!("{}", task_id)).unwrap();
144         let mut reply = self
145             .remote
146             .send_request(interface::QUERY, &mut data)
147             .unwrap();
148         let ret: i32 = reply.read().unwrap();
149         assert_eq!(ret, 0);
150     }
151 
query_mime_type(&self, task_id: u32) -> String152     pub fn query_mime_type(&self, task_id: u32) -> String {
153         let mut data = MsgParcel::new();
154         data.write_interface_token(SERVICE_TOKEN).unwrap();
155         data.write(&format!("{}", task_id)).unwrap();
156         let mut reply = self
157             .remote
158             .send_request(interface::QUERY_MIME_TYPE, &mut data)
159             .unwrap();
160         let ret: i32 = reply.read().unwrap();
161         assert_eq!(ret, 0);
162         let mime: String = reply.read().unwrap();
163         mime
164     }
165 
remove(&self, task_id: u32)166     pub fn remove(&self, task_id: u32) {
167         self.remove_version(1u32, task_id);
168     }
169 
remove_v10(&self, task_id: u32)170     pub fn remove_v10(&self, task_id: u32) {
171         self.remove_version(2u32, task_id);
172     }
173 
remove_version(&self, version: u32, task_id: u32)174     pub(crate) fn remove_version(&self, version: u32, task_id: u32) {
175         let mut data = MsgParcel::new();
176         data.write_interface_token(SERVICE_TOKEN).unwrap();
177         data.write(&version).unwrap();
178         data.write(&format!("{}", task_id)).unwrap();
179         let mut reply = self
180             .remote
181             .send_request(interface::REMOVE, &mut data)
182             .unwrap();
183         let ret: i32 = reply.read().unwrap();
184         assert_eq!(ret, 0);
185     }
186 
resume(&self, task_id: u32)187     pub fn resume(&self, task_id: u32) {
188         let mut data = MsgParcel::new();
189         data.write_interface_token(SERVICE_TOKEN).unwrap();
190         data.write(&format!("{}", task_id)).unwrap();
191         let mut reply = self
192             .remote
193             .send_request(interface::RESUME, &mut data)
194             .unwrap();
195         let ret: i32 = reply.read().unwrap();
196         assert_eq!(ret, 0);
197     }
198 
start(&self, task_id: u32)199     pub fn start(&self, task_id: u32) {
200         let mut data = MsgParcel::new();
201         data.write_interface_token(SERVICE_TOKEN).unwrap();
202         data.write(&format!("{}", task_id)).unwrap();
203         let mut reply = self
204             .remote
205             .send_request(interface::START, &mut data)
206             .unwrap();
207         let ret: i32 = reply.read().unwrap();
208         assert_eq!(ret, 0);
209     }
210 
stop(&self, task_id: u32)211     pub fn stop(&self, task_id: u32) {
212         let mut data = MsgParcel::new();
213         data.write_interface_token(SERVICE_TOKEN).unwrap();
214         data.write(&format!("{}", task_id)).unwrap();
215         let mut reply = self
216             .remote
217             .send_request(interface::STOP, &mut data)
218             .unwrap();
219         let ret: i32 = reply.read().unwrap();
220         assert_eq!(ret, 0);
221     }
222 
show(&self, task_id: u32)223     pub fn show(&self, task_id: u32) {
224         let mut data = MsgParcel::new();
225         data.write_interface_token(SERVICE_TOKEN).unwrap();
226         data.write(&format!("{}", task_id)).unwrap();
227         let mut reply = self
228             .remote
229             .send_request(interface::SHOW, &mut data)
230             .unwrap();
231         let ret: i32 = reply.read().unwrap();
232         assert_eq!(ret, 0);
233     }
234 
touch(&self, task_id: u32, token: String)235     pub fn touch(&self, task_id: u32, token: String) {
236         let mut data = MsgParcel::new();
237         data.write_interface_token(SERVICE_TOKEN).unwrap();
238         data.write(&format!("{}", task_id)).unwrap();
239         data.write(&token).unwrap();
240         let mut reply = self
241             .remote
242             .send_request(interface::TOUCH, &mut data)
243             .unwrap();
244         let ret: i32 = reply.read().unwrap();
245         assert_eq!(ret, 0);
246     }
247 
search( &self, before: i64, after: i64, state: State, action: Action, mode: Mode, ) -> Vec<u32>248     pub fn search(
249         &self,
250         before: i64,
251         after: i64,
252         state: State,
253         action: Action,
254         mode: Mode,
255     ) -> Vec<u32> {
256         let mut data = MsgParcel::new();
257         data.write_interface_token(SERVICE_TOKEN).unwrap();
258         data.write("com.example.app").unwrap();
259         data.write(&before).unwrap();
260         data.write(&after).unwrap();
261         data.write(&state.repr).unwrap();
262         data.write(&action.repr).unwrap();
263         data.write(&mode.repr).unwrap();
264 
265         let mut reply = self
266             .remote
267             .send_request(interface::SEARCH, &mut data)
268             .unwrap();
269         let len = reply.read::<u32>().unwrap();
270         let mut ans = vec![];
271         for _ in 0..len {
272             let id: String = reply.read().unwrap();
273             ans.push(id.parse::<u32>().unwrap());
274         }
275         ans
276     }
277 
get_task(&self, task_id: u32, token: String)278     pub fn get_task(&self, task_id: u32, token: String) {
279         let mut data = MsgParcel::new();
280         data.write_interface_token(SERVICE_TOKEN).unwrap();
281         data.write(&format!("{}", task_id)).unwrap();
282         data.write(&token).unwrap();
283         let mut reply = self
284             .remote
285             .send_request(interface::GET_TASK, &mut data)
286             .unwrap();
287         let ret: i32 = reply.read().unwrap();
288         assert_eq!(0, ret);
289     }
290 
open_channel(&self) -> File291     pub fn open_channel(&self) -> File {
292         let mut data = MsgParcel::new();
293         data.write_interface_token(SERVICE_TOKEN).unwrap();
294         let mut reply = self
295             .remote
296             .send_request(interface::OPEN_CHANNEL, &mut data)
297             .unwrap();
298         let ret: i32 = reply.read().unwrap();
299         assert_eq!(0, ret);
300         let raw_fd = unsafe { reply.read_raw_fd() };
301         assert!(raw_fd >= 0, "Invalid fd: {}", raw_fd);
302         unsafe { File::from_raw_fd(raw_fd) }
303     }
304 
subscribe(&self, task_id: u32)305     pub fn subscribe(&self, task_id: u32) {
306         let mut data = MsgParcel::new();
307         data.write_interface_token(SERVICE_TOKEN).unwrap();
308         data.write(&format!("{}", task_id)).unwrap();
309         let mut reply = self
310             .remote
311             .send_request(interface::SUBSCRIBE, &mut data)
312             .unwrap();
313         let ret: i32 = reply.read().unwrap();
314         assert_eq!(0, ret);
315     }
316 
unsubscribe(&self, task_id: u32)317     pub fn unsubscribe(&self, task_id: u32) {
318         let mut data = MsgParcel::new();
319         data.write_interface_token(SERVICE_TOKEN).unwrap();
320         data.write(&format!("{}", task_id)).unwrap();
321         let mut reply = self
322             .remote
323             .send_request(interface::UNSUBSCRIBE, &mut data)
324             .unwrap();
325         let ret: i32 = reply.read().unwrap();
326         assert_eq!(0, ret);
327     }
328 
sub_run_count(&self, obj: RemoteObj)329     pub fn sub_run_count(&self, obj: RemoteObj) {
330         let mut data = MsgParcel::new();
331         data.write_interface_token(SERVICE_TOKEN).unwrap();
332         let mut reply = obj
333             .send_request(interface::SUB_RUN_COUNT, &mut data)
334             .unwrap();
335         let ret: i32 = reply.read().unwrap();
336         assert_eq!(0, ret);
337     }
338 
unsub_run_count(&self)339     pub fn unsub_run_count(&self) {
340         let mut data = MsgParcel::new();
341         data.write_interface_token(SERVICE_TOKEN).unwrap();
342         let mut reply = self
343             .remote
344             .send_request(interface::UNSUB_RUN_COUNT, &mut data)
345             .unwrap();
346         let ret: i32 = reply.read().unwrap();
347         assert_eq!(0, ret);
348     }
349 
pop_task_info(&self, task_id: u32) -> Vec<MessageInfo>350     pub fn pop_task_info(&self, task_id: u32) -> Vec<MessageInfo> {
351         self.messages
352             .lock()
353             .unwrap()
354             .remove(&task_id)
355             .unwrap_or_default()
356     }
357 }
358 
359 /// test init
remote() -> RemoteObj360 fn remote() -> RemoteObj {
361     unsafe { SetAccessTokenPermission() };
362     let mut count = 0;
363     loop {
364         if let Some(download_server) =
365             SystemAbilityManager::check_system_ability(DOWNLOAD_SERVICE_ID)
366         {
367             return download_server;
368         }
369         SystemAbilityManager::load_system_ability(DOWNLOAD_SERVICE_ID, 15000).unwrap();
370         std::thread::sleep(std::time::Duration::from_secs(1));
371         count += 1;
372         println!("load download service {} seconds", count);
373     }
374 }
375 
376 #[derive(Debug)]
377 pub enum MessageInfo {
378     Http(ResponseInfo),
379     Notify(NotifyInfo),
380 }
381 
382 impl MessageInfo {
is_finished(&self) -> bool383     pub fn is_finished(&self) -> bool {
384         match self {
385             MessageInfo::Http(info) => false,
386             MessageInfo::Notify(info) => {
387                 info.state == State::Completed || info.state == State::Failed
388             }
389         }
390     }
391 
check_correct(&self)392     pub fn check_correct(&self) {
393         match self {
394             MessageInfo::Http(info) => {
395                 if info.status != 200 && info.status != 206 {
396                     panic!("http status code is {}", info.status);
397                 }
398             }
399             MessageInfo::Notify(info) => {
400                 assert_ne!(info.state, State::Removed);
401                 assert_ne!(info.state, State::Failed);
402             }
403         }
404     }
405 }
406 
407 #[derive(Debug)]
408 pub struct NotifyInfo {
409     notify_type: SubscribeType,
410     state: State,
411     index: u32,
412     processed: u64,
413     total_processed: u64,
414     sizes: Vec<u64>,
415     extras: HashMap<String, String>,
416     action: Action,
417     task_states: Vec<TaskState>,
418 }
419 
420 #[derive(Debug)]
421 pub struct ResponseInfo {
422     pub version: String,
423     pub status: u32,
424     pub reason: String,
425 }
426 
deserialize(mut input: &[u8]) -> (u32, MessageInfo)427 fn deserialize(mut input: &[u8]) -> (u32, MessageInfo) {
428     static mut MESSAGE_ID: usize = 1;
429 
430     let magic_num: u32 = input.take_value();
431     assert_eq!(magic_num, CHANNEL_MAGIC_NUM);
432 
433     let message_id: u32 = input.take_value();
434     assert_eq!(message_id as usize, unsafe { MESSAGE_ID });
435 
436     let msg_type: u16 = input.take_value();
437     let body_size: u16 = input.take_value();
438 
439     unsafe {
440         MESSAGE_ID += 1;
441     }
442 
443     if msg_type == 0 {
444         let task_id = input.take_value();
445         let version = input.take_value();
446         let status = input.take_value();
447         let reason = input.take_value();
448         (
449             task_id,
450             MessageInfo::Http(ResponseInfo {
451                 version,
452                 status,
453                 reason,
454             }),
455         )
456     } else {
457         let notify_type = input.take_value();
458         let task_id = input.take_value();
459         let state = input.take_value();
460         let index = input.take_value();
461         let processed = input.take_value();
462         let total_processed = input.take_value();
463         let sizes = input.take_value();
464         let extras = input.take_value();
465         let action = input.take_value();
466         // Currently, it is not necessary to add to NotifyInfo
467         let _version: u32 = input.take_value();
468         let task_states = input.take_value();
469         (
470             task_id,
471             MessageInfo::Notify(NotifyInfo {
472                 notify_type,
473                 state,
474                 index,
475                 processed,
476                 total_processed,
477                 sizes,
478                 extras,
479                 action,
480                 task_states,
481             }),
482         )
483     }
484 }
485 
486 trait Take<T> {
take_value(&mut self) -> T487     fn take_value(&mut self) -> T;
488 }
489 
490 impl Take<u16> for &[u8] {
take_value(&mut self) -> u16491     fn take_value(&mut self) -> u16 {
492         let (left, right) = self.split_at(std::mem::size_of::<u16>());
493         *self = right;
494         u16::from_le_bytes(left.try_into().unwrap())
495     }
496 }
497 
498 impl Take<u32> for &[u8] {
take_value(&mut self) -> u32499     fn take_value(&mut self) -> u32 {
500         let (left, right) = self.split_at(std::mem::size_of::<u32>());
501         *self = right;
502         u32::from_le_bytes(left.try_into().unwrap())
503     }
504 }
505 
506 impl Take<u64> for &[u8] {
take_value(&mut self) -> u64507     fn take_value(&mut self) -> u64 {
508         let (left, right) = self.split_at(std::mem::size_of::<u64>());
509         *self = right;
510         u64::from_le_bytes(left.try_into().unwrap())
511     }
512 }
513 
514 impl Take<Vec<u64>> for &[u8] {
take_value(&mut self) -> Vec<u64>515     fn take_value(&mut self) -> Vec<u64> {
516         let length: u32 = self.take_value();
517         let mut v = Vec::with_capacity(length as usize);
518         for _ in 0..length {
519             v.push(self.take_value());
520         }
521         v
522     }
523 }
524 
525 impl Take<HashMap<String, String>> for &[u8] {
take_value(&mut self) -> HashMap<String, String>526     fn take_value(&mut self) -> HashMap<String, String> {
527         let length: u32 = self.take_value();
528         let mut map = HashMap::with_capacity(length as usize);
529         for _ in 0..length {
530             let key = self.take_value();
531             let value = self.take_value();
532             map.insert(key, value);
533         }
534         map
535     }
536 }
537 
538 impl Take<String> for &[u8] {
take_value(&mut self) -> String539     fn take_value(&mut self) -> String {
540         let len = self.iter().position(|c| *c == b'\0').unwrap();
541         let (left, right) = self.split_at(len + 1);
542         *self = right;
543         CString::from_vec_with_nul(left.to_vec())
544             .unwrap()
545             .to_str()
546             .unwrap()
547             .to_string()
548     }
549 }
550 
551 impl Take<SubscribeType> for &[u8] {
take_value(&mut self) -> SubscribeType552     fn take_value(&mut self) -> SubscribeType {
553         let value: u32 = self.take_value();
554         match value {
555             0 => SubscribeType::Completed,
556             1 => SubscribeType::Failed,
557             2 => SubscribeType::HeaderReceive,
558             3 => SubscribeType::Pause,
559             4 => SubscribeType::Progress,
560             5 => SubscribeType::Remove,
561             6 => SubscribeType::Resume,
562             7 => SubscribeType::Response,
563             8 => SubscribeType::Butt,
564             _ => panic!("Invalid SubscribeType value"),
565         }
566     }
567 }
568 
569 impl Take<State> for &[u8] {
take_value(&mut self) -> State570     fn take_value(&mut self) -> State {
571         let value: u32 = self.take_value();
572         State::from(value as u8)
573     }
574 }
575 
576 impl Take<Action> for &[u8] {
take_value(&mut self) -> Action577     fn take_value(&mut self) -> Action {
578         let value: u32 = self.take_value();
579         Action::from(value as u8)
580     }
581 }
582 
583 impl Take<Vec<TaskState>> for &[u8] {
take_value(&mut self) -> Vec<TaskState>584     fn take_value(&mut self) -> Vec<TaskState> {
585         let length: u32 = self.take_value();
586         let mut v = Vec::with_capacity(length as usize);
587         for _ in 0..length {
588             let path = self.take_value();
589             let code = self.take_value();
590             let message = self.take_value();
591             v.push(TaskState {
592                 path,
593                 code,
594                 message,
595             });
596         }
597         v
598     }
599 }
600 
601 #[derive(Debug)]
602 pub enum SubscribeType {
603     Completed,
604     Failed,
605     HeaderReceive,
606     Pause,
607     Progress,
608     Remove,
609     Resume,
610     Response,
611     Butt,
612 }
613 
614 #[derive(Debug)]
615 pub struct TaskState {
616     path: String,
617     // Reason
618     code: u32,
619     message: String,
620 }
621 
622 extern "C" {
SetAccessTokenPermission()623     pub fn SetAccessTokenPermission();
624 }
625