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