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