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 file = reply.read_file().unwrap();
77             let channel = unsafe { UnixDatagram::from_raw_fd(file.into_raw_fd()) };
78             thread::spawn(move || loop {
79                 let mut buf = [0u8; 4096];
80                 let Ok(length) = channel.recv(&mut buf) else {
81                     std::thread::sleep(std::time::Duration::from_secs(1));
82                     continue;
83                 };
84                 channel
85                     .send((length as u32).to_le_bytes().as_slice())
86                     .unwrap();
87                 let (task_id, info) = deserialize(&buf);
88                 let mut map = messages.lock().unwrap();
89                 match map.get_mut(&task_id) {
90                     Some(v) => v.push(info),
91                     None => {
92                         map.insert(task_id, vec![info]);
93                     }
94                 };
95             });
96         });
97 
98         RequestAgent {
99             remote,
100             messages: messages.clone(),
101         }
102     }
103 
construct(&self, config: TaskConfig) -> u32104     pub fn construct(&self, config: TaskConfig) -> u32 {
105         let mut data = MsgParcel::new();
106         data.write_interface_token(SERVICE_TOKEN).unwrap();
107         data.write(&config).unwrap();
108         let mut reply = self
109             .remote
110             .send_request(interface::CONSTRUCT, &mut data)
111             .unwrap();
112         let ret: i32 = reply.read().unwrap();
113         assert_eq!(0, ret);
114         reply.read::<i32>().unwrap() as u32
115     }
116 
pause(&self, task_id: u32)117     pub fn pause(&self, task_id: u32) {
118         self.pause_version(1u32, task_id);
119     }
120 
pause_v10(&self, task_id: u32)121     pub fn pause_v10(&self, task_id: u32) {
122         self.pause_version(2u32, task_id);
123     }
124 
pause_version(&self, version: u32, task_id: u32)125     pub(crate) fn pause_version(&self, version: u32, task_id: u32) {
126         let mut data = MsgParcel::new();
127         data.write_interface_token(SERVICE_TOKEN).unwrap();
128         data.write(&version);
129         data.write(&format!("{}", task_id)).unwrap();
130         let mut reply = self
131             .remote
132             .send_request(interface::PAUSE, &mut data)
133             .unwrap();
134         let ret: i32 = reply.read().unwrap();
135         assert_eq!(ret, 0);
136     }
137 
query(&self, task_id: u32)138     pub fn query(&self, task_id: u32) {
139         let mut data = MsgParcel::new();
140         data.write_interface_token(SERVICE_TOKEN).unwrap();
141         data.write(&format!("{}", task_id)).unwrap();
142         let mut reply = self
143             .remote
144             .send_request(interface::QUERY, &mut data)
145             .unwrap();
146         let ret: i32 = reply.read().unwrap();
147         assert_eq!(ret, 0);
148     }
149 
query_mime_type(&self, task_id: u32) -> String150     pub fn query_mime_type(&self, task_id: u32) -> String {
151         let mut data = MsgParcel::new();
152         data.write_interface_token(SERVICE_TOKEN).unwrap();
153         data.write(&format!("{}", task_id)).unwrap();
154         let mut reply = self
155             .remote
156             .send_request(interface::QUERY_MIME_TYPE, &mut data)
157             .unwrap();
158         let ret: i32 = reply.read().unwrap();
159         assert_eq!(ret, 0);
160         let mime: String = reply.read().unwrap();
161         mime
162     }
163 
remove(&self, task_id: u32)164     pub fn remove(&self, task_id: u32) {
165         self.remove_version(1u32, task_id);
166     }
167 
remove_v10(&self, task_id: u32)168     pub fn remove_v10(&self, task_id: u32) {
169         self.remove_version(2u32, task_id);
170     }
171 
remove_version(&self, version: u32, task_id: u32)172     pub(crate) fn remove_version(&self, version: u32, task_id: u32) {
173         let mut data = MsgParcel::new();
174         data.write_interface_token(SERVICE_TOKEN).unwrap();
175         data.write(&version).unwrap();
176         data.write(&format!("{}", task_id)).unwrap();
177         let mut reply = self
178             .remote
179             .send_request(interface::REMOVE, &mut data)
180             .unwrap();
181         let ret: i32 = reply.read().unwrap();
182         assert_eq!(ret, 0);
183     }
184 
resume(&self, task_id: u32)185     pub fn resume(&self, task_id: u32) {
186         let mut data = MsgParcel::new();
187         data.write_interface_token(SERVICE_TOKEN).unwrap();
188         data.write(&format!("{}", task_id)).unwrap();
189         let mut reply = self
190             .remote
191             .send_request(interface::RESUME, &mut data)
192             .unwrap();
193         let ret: i32 = reply.read().unwrap();
194         assert_eq!(ret, 0);
195     }
196 
start(&self, task_id: u32)197     pub fn start(&self, task_id: u32) {
198         let mut data = MsgParcel::new();
199         data.write_interface_token(SERVICE_TOKEN).unwrap();
200         data.write(&format!("{}", task_id)).unwrap();
201         let mut reply = self
202             .remote
203             .send_request(interface::START, &mut data)
204             .unwrap();
205         let ret: i32 = reply.read().unwrap();
206         assert_eq!(ret, 0);
207     }
208 
stop(&self, task_id: u32)209     pub fn stop(&self, task_id: u32) {
210         let mut data = MsgParcel::new();
211         data.write_interface_token(SERVICE_TOKEN).unwrap();
212         data.write(&format!("{}", task_id)).unwrap();
213         let mut reply = self
214             .remote
215             .send_request(interface::STOP, &mut data)
216             .unwrap();
217         let ret: i32 = reply.read().unwrap();
218         assert_eq!(ret, 0);
219     }
220 
show(&self, task_id: u32)221     pub fn show(&self, task_id: u32) {
222         let mut data = MsgParcel::new();
223         data.write_interface_token(SERVICE_TOKEN).unwrap();
224         data.write(&format!("{}", task_id)).unwrap();
225         let mut reply = self
226             .remote
227             .send_request(interface::SHOW, &mut data)
228             .unwrap();
229         let ret: i32 = reply.read().unwrap();
230         assert_eq!(ret, 0);
231     }
232 
touch(&self, task_id: u32, token: String)233     pub fn touch(&self, task_id: u32, token: String) {
234         let mut data = MsgParcel::new();
235         data.write_interface_token(SERVICE_TOKEN).unwrap();
236         data.write(&format!("{}", task_id)).unwrap();
237         data.write(&token).unwrap();
238         let mut reply = self
239             .remote
240             .send_request(interface::TOUCH, &mut data)
241             .unwrap();
242         let ret: i32 = reply.read().unwrap();
243         assert_eq!(ret, 0);
244     }
245 
search( &self, before: i64, after: i64, state: State, action: Action, mode: Mode, ) -> Vec<u32>246     pub fn search(
247         &self,
248         before: i64,
249         after: i64,
250         state: State,
251         action: Action,
252         mode: Mode,
253     ) -> Vec<u32> {
254         let mut data = MsgParcel::new();
255         data.write_interface_token(SERVICE_TOKEN).unwrap();
256         data.write("com.example.app").unwrap();
257         data.write(&before).unwrap();
258         data.write(&after).unwrap();
259         data.write(&state.repr).unwrap();
260         data.write(&action.repr).unwrap();
261         data.write(&mode.repr).unwrap();
262 
263         let mut reply = self
264             .remote
265             .send_request(interface::SEARCH, &mut data)
266             .unwrap();
267         let len = reply.read::<u32>().unwrap();
268         let mut ans = vec![];
269         for _ in 0..len {
270             let id: String = reply.read().unwrap();
271             ans.push(id.parse::<u32>().unwrap());
272         }
273         ans
274     }
275 
get_task(&self, task_id: u32, token: String)276     pub fn get_task(&self, task_id: u32, token: String) {
277         let mut data = MsgParcel::new();
278         data.write_interface_token(SERVICE_TOKEN).unwrap();
279         data.write(&format!("{}", task_id)).unwrap();
280         data.write(&token).unwrap();
281         let mut reply = self
282             .remote
283             .send_request(interface::GET_TASK, &mut data)
284             .unwrap();
285         let ret: i32 = reply.read().unwrap();
286         assert_eq!(0, ret);
287     }
288 
open_channel(&self) -> File289     pub fn open_channel(&self) -> File {
290         let mut data = MsgParcel::new();
291         data.write_interface_token(SERVICE_TOKEN).unwrap();
292         let mut reply = self
293             .remote
294             .send_request(interface::OPEN_CHANNEL, &mut data)
295             .unwrap();
296         let ret: i32 = reply.read().unwrap();
297         assert_eq!(0, ret);
298         let file = reply.read_file().unwrap();
299         file
300     }
301 
subscribe(&self, task_id: u32)302     pub fn subscribe(&self, task_id: u32) {
303         let mut data = MsgParcel::new();
304         data.write_interface_token(SERVICE_TOKEN).unwrap();
305         data.write(&format!("{}", task_id)).unwrap();
306         let mut reply = self
307             .remote
308             .send_request(interface::SUBSCRIBE, &mut data)
309             .unwrap();
310         let ret: i32 = reply.read().unwrap();
311         assert_eq!(0, ret);
312     }
313 
unsubscribe(&self, task_id: u32)314     pub fn unsubscribe(&self, task_id: u32) {
315         let mut data = MsgParcel::new();
316         data.write_interface_token(SERVICE_TOKEN).unwrap();
317         data.write(&format!("{}", task_id)).unwrap();
318         let mut reply = self
319             .remote
320             .send_request(interface::UNSUBSCRIBE, &mut data)
321             .unwrap();
322         let ret: i32 = reply.read().unwrap();
323         assert_eq!(0, ret);
324     }
325 
sub_run_count(&self, obj: RemoteObj)326     pub fn sub_run_count(&self, obj: RemoteObj) {
327         let mut data = MsgParcel::new();
328         data.write_interface_token(SERVICE_TOKEN).unwrap();
329         let mut reply = obj
330             .send_request(interface::SUB_RUN_COUNT, &mut data)
331             .unwrap();
332         let ret: i32 = reply.read().unwrap();
333         assert_eq!(0, ret);
334     }
335 
unsub_run_count(&self)336     pub fn unsub_run_count(&self) {
337         let mut data = MsgParcel::new();
338         data.write_interface_token(SERVICE_TOKEN).unwrap();
339         let mut reply = self
340             .remote
341             .send_request(interface::UNSUB_RUN_COUNT, &mut data)
342             .unwrap();
343         let ret: i32 = reply.read().unwrap();
344         assert_eq!(0, ret);
345     }
346 
pop_task_info(&self, task_id: u32) -> Vec<MessageInfo>347     pub fn pop_task_info(&self, task_id: u32) -> Vec<MessageInfo> {
348         self.messages
349             .lock()
350             .unwrap()
351             .remove(&task_id)
352             .unwrap_or_default()
353     }
354 }
355 
356 /// test init
remote() -> RemoteObj357 fn remote() -> RemoteObj {
358     unsafe { SetAccessTokenPermission() };
359     let mut count = 0;
360     loop {
361         if let Some(download_server) =
362             SystemAbilityManager::check_system_ability(DOWNLOAD_SERVICE_ID)
363         {
364             return download_server;
365         }
366         SystemAbilityManager::load_system_ability(DOWNLOAD_SERVICE_ID, 15000).unwrap();
367         std::thread::sleep(std::time::Duration::from_secs(1));
368         count += 1;
369         println!("load download service {} seconds", count);
370     }
371 }
372 
373 #[derive(Debug)]
374 pub enum MessageInfo {
375     Http(ResponseInfo),
376     Notify(NotifyInfo),
377 }
378 
379 impl MessageInfo {
is_finished(&self) -> bool380     pub fn is_finished(&self) -> bool {
381         match self {
382             MessageInfo::Http(info) => false,
383             MessageInfo::Notify(info) => {
384                 info.state == State::Completed || info.state == State::Failed
385             }
386         }
387     }
388 
check_correct(&self)389     pub fn check_correct(&self) {
390         match self {
391             MessageInfo::Http(info) => {
392                 if info.status != 200 && info.status != 206 {
393                     panic!("http status code is {}", info.status);
394                 }
395             }
396             MessageInfo::Notify(info) => {
397                 assert_ne!(info.state, State::Removed);
398                 assert_ne!(info.state, State::Failed);
399             }
400         }
401     }
402 }
403 
404 #[derive(Debug)]
405 pub struct NotifyInfo {
406     notify_type: SubscribeType,
407     state: State,
408     index: u32,
409     processed: u64,
410     total_processed: u64,
411     sizes: Vec<u64>,
412     extras: HashMap<String, String>,
413     action: Action,
414     task_states: Vec<TaskState>,
415 }
416 
417 #[derive(Debug)]
418 pub struct ResponseInfo {
419     pub version: String,
420     pub status: u32,
421     pub reason: String,
422 }
423 
deserialize(mut input: &[u8]) -> (u32, MessageInfo)424 fn deserialize(mut input: &[u8]) -> (u32, MessageInfo) {
425     static mut MESSAGE_ID: usize = 1;
426 
427     let magic_num: u32 = input.take_value();
428     assert_eq!(magic_num, CHANNEL_MAGIC_NUM);
429 
430     let message_id: u32 = input.take_value();
431     assert_eq!(message_id as usize, unsafe { MESSAGE_ID });
432 
433     let msg_type: u16 = input.take_value();
434     let body_size: u16 = input.take_value();
435 
436     unsafe {
437         MESSAGE_ID += 1;
438     }
439 
440     if msg_type == 0 {
441         let task_id = input.take_value();
442         let version = input.take_value();
443         let status = input.take_value();
444         let reason = input.take_value();
445         (
446             task_id,
447             MessageInfo::Http(ResponseInfo {
448                 version,
449                 status,
450                 reason,
451             }),
452         )
453     } else {
454         let notify_type = input.take_value();
455         let task_id = input.take_value();
456         let state = input.take_value();
457         let index = input.take_value();
458         let processed = input.take_value();
459         let total_processed = input.take_value();
460         let sizes = input.take_value();
461         let extras = input.take_value();
462         let action = input.take_value();
463         // Currently, it is not necessary to add to NotifyInfo
464         let _version: u32 = input.take_value();
465         let task_states = input.take_value();
466         (
467             task_id,
468             MessageInfo::Notify(NotifyInfo {
469                 notify_type,
470                 state,
471                 index,
472                 processed,
473                 total_processed,
474                 sizes,
475                 extras,
476                 action,
477                 task_states,
478             }),
479         )
480     }
481 }
482 
483 trait Take<T> {
take_value(&mut self) -> T484     fn take_value(&mut self) -> T;
485 }
486 
487 impl Take<u16> for &[u8] {
take_value(&mut self) -> u16488     fn take_value(&mut self) -> u16 {
489         let (left, right) = self.split_at(std::mem::size_of::<u16>());
490         *self = right;
491         u16::from_le_bytes(left.try_into().unwrap())
492     }
493 }
494 
495 impl Take<u32> for &[u8] {
take_value(&mut self) -> u32496     fn take_value(&mut self) -> u32 {
497         let (left, right) = self.split_at(std::mem::size_of::<u32>());
498         *self = right;
499         u32::from_le_bytes(left.try_into().unwrap())
500     }
501 }
502 
503 impl Take<u64> for &[u8] {
take_value(&mut self) -> u64504     fn take_value(&mut self) -> u64 {
505         let (left, right) = self.split_at(std::mem::size_of::<u64>());
506         *self = right;
507         u64::from_le_bytes(left.try_into().unwrap())
508     }
509 }
510 
511 impl Take<Vec<u64>> for &[u8] {
take_value(&mut self) -> Vec<u64>512     fn take_value(&mut self) -> Vec<u64> {
513         let length: u32 = self.take_value();
514         let mut v = Vec::with_capacity(length as usize);
515         for _ in 0..length {
516             v.push(self.take_value());
517         }
518         v
519     }
520 }
521 
522 impl Take<HashMap<String, String>> for &[u8] {
take_value(&mut self) -> HashMap<String, String>523     fn take_value(&mut self) -> HashMap<String, String> {
524         let length: u32 = self.take_value();
525         let mut map = HashMap::with_capacity(length as usize);
526         for _ in 0..length {
527             let key = self.take_value();
528             let value = self.take_value();
529             map.insert(key, value);
530         }
531         map
532     }
533 }
534 
535 impl Take<String> for &[u8] {
take_value(&mut self) -> String536     fn take_value(&mut self) -> String {
537         let len = self.iter().position(|c| *c == b'\0').unwrap();
538         let (left, right) = self.split_at(len + 1);
539         *self = right;
540         CString::from_vec_with_nul(left.to_vec())
541             .unwrap()
542             .to_str()
543             .unwrap()
544             .to_string()
545     }
546 }
547 
548 impl Take<SubscribeType> for &[u8] {
take_value(&mut self) -> SubscribeType549     fn take_value(&mut self) -> SubscribeType {
550         let value: u32 = self.take_value();
551         match value {
552             0 => SubscribeType::Completed,
553             1 => SubscribeType::Failed,
554             2 => SubscribeType::HeaderReceive,
555             3 => SubscribeType::Pause,
556             4 => SubscribeType::Progress,
557             5 => SubscribeType::Remove,
558             6 => SubscribeType::Resume,
559             7 => SubscribeType::Response,
560             8 => SubscribeType::Butt,
561             _ => panic!("Invalid SubscribeType value"),
562         }
563     }
564 }
565 
566 impl Take<State> for &[u8] {
take_value(&mut self) -> State567     fn take_value(&mut self) -> State {
568         let value: u32 = self.take_value();
569         State::from(value as u8)
570     }
571 }
572 
573 impl Take<Action> for &[u8] {
take_value(&mut self) -> Action574     fn take_value(&mut self) -> Action {
575         let value: u32 = self.take_value();
576         Action::from(value as u8)
577     }
578 }
579 
580 impl Take<Vec<TaskState>> for &[u8] {
take_value(&mut self) -> Vec<TaskState>581     fn take_value(&mut self) -> Vec<TaskState> {
582         let length: u32 = self.take_value();
583         let mut v = Vec::with_capacity(length as usize);
584         for _ in 0..length {
585             let path = self.take_value();
586             let code = self.take_value();
587             let message = self.take_value();
588             v.push(TaskState {
589                 path,
590                 code,
591                 message,
592             });
593         }
594         v
595     }
596 }
597 
598 #[derive(Debug)]
599 pub enum SubscribeType {
600     Completed,
601     Failed,
602     HeaderReceive,
603     Pause,
604     Progress,
605     Remove,
606     Resume,
607     Response,
608     Butt,
609 }
610 
611 #[derive(Debug)]
612 pub struct TaskState {
613     path: String,
614     // Reason
615     code: u32,
616     message: String,
617 }
618 
619 extern "C" {
SetAccessTokenPermission()620     pub fn SetAccessTokenPermission();
621 }
622