• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 use std::fmt::Debug;
15 
16 use ylong_runtime::sync::oneshot::{channel, Sender};
17 
18 use super::account::AccountEvent;
19 use crate::config::{Action, Mode};
20 use crate::error::ErrorCode;
21 use crate::info::TaskInfo;
22 use crate::task::config::TaskConfig;
23 use crate::task::info::{DumpAllInfo, DumpOneInfo};
24 use crate::task::reason::Reason;
25 use crate::utils::Recv;
26 
27 mod construct;
28 mod dump;
29 mod pause;
30 mod remove;
31 mod resume;
32 mod set_max_speed;
33 mod set_mode;
34 mod start;
35 mod stop;
36 
37 #[derive(Debug)]
38 pub(crate) enum TaskManagerEvent {
39     Service(ServiceEvent),
40     State(StateEvent),
41     Schedule(ScheduleEvent),
42     Task(TaskEvent),
43     Device(i32),
44     Account(AccountEvent),
45     Query(QueryEvent),
46     Reschedule,
47 }
48 
49 impl TaskManagerEvent {
construct(config: TaskConfig) -> (Self, Recv<Result<u32, ErrorCode>>)50     pub(crate) fn construct(config: TaskConfig) -> (Self, Recv<Result<u32, ErrorCode>>) {
51         let (tx, rx) = channel::<Result<u32, ErrorCode>>();
52         (
53             Self::Service(ServiceEvent::Construct(
54                 Box::new(ConstructMessage { config }),
55                 tx,
56             )),
57             Recv::new(rx),
58         )
59     }
60 
pause(uid: u64, task_id: u32) -> (Self, Recv<ErrorCode>)61     pub(crate) fn pause(uid: u64, task_id: u32) -> (Self, Recv<ErrorCode>) {
62         let (tx, rx) = channel::<ErrorCode>();
63         (
64             Self::Service(ServiceEvent::Pause(uid, task_id, tx)),
65             Recv::new(rx),
66         )
67     }
68 
start(uid: u64, task_id: u32) -> (Self, Recv<ErrorCode>)69     pub(crate) fn start(uid: u64, task_id: u32) -> (Self, Recv<ErrorCode>) {
70         let (tx, rx) = channel::<ErrorCode>();
71         (
72             Self::Service(ServiceEvent::Start(uid, task_id, tx)),
73             Recv::new(rx),
74         )
75     }
76 
stop(uid: u64, task_id: u32) -> (Self, Recv<ErrorCode>)77     pub(crate) fn stop(uid: u64, task_id: u32) -> (Self, Recv<ErrorCode>) {
78         let (tx, rx) = channel::<ErrorCode>();
79         (
80             Self::Service(ServiceEvent::Stop(uid, task_id, tx)),
81             Recv::new(rx),
82         )
83     }
84 
remove(uid: u64, task_id: u32) -> (Self, Recv<ErrorCode>)85     pub(crate) fn remove(uid: u64, task_id: u32) -> (Self, Recv<ErrorCode>) {
86         let (tx, rx) = channel::<ErrorCode>();
87         (
88             Self::Service(ServiceEvent::Remove(uid, task_id, tx)),
89             Recv::new(rx),
90         )
91     }
92 
resume(uid: u64, task_id: u32) -> (Self, Recv<ErrorCode>)93     pub(crate) fn resume(uid: u64, task_id: u32) -> (Self, Recv<ErrorCode>) {
94         let (tx, rx) = channel::<ErrorCode>();
95         (
96             Self::Service(ServiceEvent::Resume(uid, task_id, tx)),
97             Recv::new(rx),
98         )
99     }
100 
dump_all() -> (Self, Recv<DumpAllInfo>)101     pub(crate) fn dump_all() -> (Self, Recv<DumpAllInfo>) {
102         let (tx, rx) = channel::<DumpAllInfo>();
103         (Self::Service(ServiceEvent::DumpAll(tx)), Recv::new(rx))
104     }
105 
dump_one(task_id: u32) -> (Self, Recv<Option<DumpOneInfo>>)106     pub(crate) fn dump_one(task_id: u32) -> (Self, Recv<Option<DumpOneInfo>>) {
107         let (tx, rx) = channel::<Option<DumpOneInfo>>();
108         (
109             Self::Service(ServiceEvent::DumpOne(task_id, tx)),
110             Recv::new(rx),
111         )
112     }
113 
set_mode(uid: u64, task_id: u32, mode: Mode) -> (Self, Recv<ErrorCode>)114     pub(crate) fn set_mode(uid: u64, task_id: u32, mode: Mode) -> (Self, Recv<ErrorCode>) {
115         let (tx, rx) = channel::<ErrorCode>();
116         (
117             Self::Service(ServiceEvent::SetMode(uid, task_id, mode, tx)),
118             Recv::new(rx),
119         )
120     }
121 
network() -> Self122     pub(crate) fn network() -> Self {
123         Self::State(StateEvent::Network)
124     }
125 
subscribe(task_id: u32, token_id: u64) -> (Self, Recv<ErrorCode>)126     pub(crate) fn subscribe(task_id: u32, token_id: u64) -> (Self, Recv<ErrorCode>) {
127         let (tx, rx) = channel::<ErrorCode>();
128         (
129             Self::Task(TaskEvent::Subscribe(task_id, token_id, tx)),
130             Recv::new(rx),
131         )
132     }
133 
attach_group( uid: u64, task_ids: Vec<u32>, group_id: u32, ) -> (Self, Recv<ErrorCode>)134     pub(crate) fn attach_group(
135         uid: u64,
136         task_ids: Vec<u32>,
137         group_id: u32,
138     ) -> (Self, Recv<ErrorCode>) {
139         let (tx, rx) = channel::<ErrorCode>();
140         (
141             Self::Service(ServiceEvent::AttachGroup(uid, task_ids, group_id, tx)),
142             Recv::new(rx),
143         )
144     }
145 
set_max_speed(uid: u64, task_id: u32, max_speed: i64) -> (Self, Recv<ErrorCode>)146     pub(crate) fn set_max_speed(uid: u64, task_id: u32, max_speed: i64) -> (Self, Recv<ErrorCode>) {
147         let (tx, rx) = channel::<ErrorCode>();
148         (
149             Self::Service(ServiceEvent::SetMaxSpeed(uid, task_id, max_speed, tx)),
150             Recv::new(rx),
151         )
152     }
153 }
154 
155 #[derive(Debug)]
156 pub(crate) enum QueryEvent {
157     Query(u32, Action, Sender<Option<TaskInfo>>),
158     Show(u32, u64, Sender<Option<TaskInfo>>),
159     Touch(u32, u64, String, Sender<Option<TaskInfo>>),
160 }
161 
162 #[derive(Debug)]
163 pub(crate) enum ServiceEvent {
164     Construct(Box<ConstructMessage>, Sender<Result<u32, ErrorCode>>),
165     Pause(u64, u32, Sender<ErrorCode>),
166     Start(u64, u32, Sender<ErrorCode>),
167     Stop(u64, u32, Sender<ErrorCode>),
168     Remove(u64, u32, Sender<ErrorCode>),
169     Resume(u64, u32, Sender<ErrorCode>),
170     DumpOne(u32, Sender<Option<DumpOneInfo>>),
171     DumpAll(Sender<DumpAllInfo>),
172     AttachGroup(u64, Vec<u32>, u32, Sender<ErrorCode>),
173     SetMaxSpeed(u64, u32, i64, Sender<ErrorCode>),
174     SetMode(u64, u32, Mode, Sender<ErrorCode>),
175 }
176 
177 #[derive(Debug)]
178 pub(crate) enum TaskEvent {
179     Completed(u32, u64, Mode),
180     Failed(u32, u64, Reason, Mode),
181     Offline(u32, u64, Mode),
182     Running(u32, u64, Mode),
183     Subscribe(u32, u64, Sender<ErrorCode>),
184 }
185 
186 #[derive(Debug)]
187 pub(crate) enum StateEvent {
188     Network,
189     ForegroundApp(u64),
190     Background(u64),
191     BackgroundTimeout(u64),
192     AppUninstall(u64),
193     SpecialTerminate(u64),
194 }
195 
196 pub(crate) struct ConstructMessage {
197     pub(crate) config: TaskConfig,
198 }
199 
200 impl Debug for ConstructMessage {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result201     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
202         f.debug_struct("Construct")
203             .field("uid", &self.config.common_data.uid)
204             .field("task_id", &self.config.common_data.task_id)
205             .field("title", &self.config.title)
206             .field("mode", &self.config.method)
207             .field("version", &self.config.version)
208             .finish()
209     }
210 }
211 
212 #[derive(Debug)]
213 pub(crate) enum ScheduleEvent {
214     ClearTimeoutTasks,
215     RestoreAllTasks,
216     Unload,
217 }
218 
219 #[cfg(not(feature = "oh"))]
220 #[cfg(test)]
221 mod test {
222     use core::time;
223     use std::fs::File;
224 
225     use once_cell::sync::Lazy;
226 
227     use super::TaskManagerEvent;
228     use crate::config::{Action, ConfigBuilder, Mode};
229     use crate::error::ErrorCode;
230     use crate::manage::network::Network;
231     use crate::manage::task_manager::TaskManagerTx;
232     use crate::manage::TaskManager;
233     use crate::service::client::{ClientManager, ClientManagerEntry};
234     use crate::service::run_count::{RunCountManager, RunCountManagerEntry};
235 
236     static CLIENT: Lazy<ClientManagerEntry> = Lazy::new(|| ClientManager::init());
237     static RUN_COUNT_MANAGER: Lazy<RunCountManagerEntry> = Lazy::new(|| RunCountManager::init());
238     static NETWORK: Lazy<Network> = Lazy::new(|| Network::new());
239 
240     static TASK_MANGER: Lazy<TaskManagerTx> =
241         Lazy::new(|| TaskManager::init(RUN_COUNT_MANAGER.clone(), CLIENT.clone(), NETWORK.clone()));
build_task()242     fn build_task() {}
243 
init()244     fn init() {
245         let _ = env_logger::builder().is_test(true).try_init();
246         let _ = std::fs::create_dir("test_files/");
247     }
248 
249     #[test]
ut_task_manager_construct()250     fn ut_task_manager_construct() {
251         init();
252         let file_path = "test_files/ut_task_manager_construct.txt";
253 
254         let file = File::create(file_path).unwrap();
255         let config = ConfigBuilder::new()
256         .action(Action::Download)
257         .mode(Mode::BackGround)
258         .file_spec(file)
259         .url("https://www.gitee.com/tiga-ultraman/downloadTests/releases/download/v1.01/test.txt")
260         .redirect(true)
261         .build();
262         let (event, rx) = TaskManagerEvent::construct(config);
263         TASK_MANGER.send_event(event);
264         rx.get().unwrap().unwrap();
265     }
266 
267     #[test]
ut_task_manager_start()268     fn ut_task_manager_start() {
269         init();
270         let file_path = "test_files/ut_task_manager_construct.txt";
271 
272         let file = File::create(file_path).unwrap();
273         let uid = 111;
274         let config = ConfigBuilder::new()
275         .action(Action::Download)
276         .mode(Mode::BackGround)
277         .file_spec(file)
278         .url("https://sf3-cn.feishucdn.com/obj/ee-appcenter/47273f95/Feishu-win32_ia32-7.9.7-signed.exe")
279         .redirect(true)
280         .uid(uid)
281         .build();
282         let (event, rx) = TaskManagerEvent::construct(config.clone());
283         TASK_MANGER.send_event(event);
284         let task_id = rx.get().unwrap().unwrap();
285         let (event, rx) = TaskManagerEvent::start(uid, task_id);
286         TASK_MANGER.send_event(event);
287         let res = rx.get().unwrap();
288         assert_eq!(res, ErrorCode::ErrOk);
289         std::thread::sleep(time::Duration::from_secs(10));
290     }
291 
292     #[test]
ut_task_manager_pause_resume()293     fn ut_task_manager_pause_resume() {
294         init();
295         let file_path = "test_files/ut_task_manager_pause_resume.txt";
296 
297         let file = File::create(file_path).unwrap();
298         let uid = 111;
299         let config = ConfigBuilder::new()
300         .action(Action::Download)
301         .mode(Mode::BackGround)
302         .file_spec(file)
303         .url("https://sf3-cn.feishucdn.com/obj/ee-appcenter/47273f95/Feishu-win32_ia32-7.9.7-signed.exe")
304         .redirect(true)
305         .uid(uid)
306         .build();
307         let (event, rx) = TaskManagerEvent::construct(config.clone());
308         TASK_MANGER.send_event(event);
309         let task_id = rx.get().unwrap().unwrap();
310         let (event, _rx) = TaskManagerEvent::start(uid, task_id);
311         TASK_MANGER.send_event(event);
312         let (event, _rx) = TaskManagerEvent::pause(uid, task_id);
313         TASK_MANGER.send_event(event);
314         let (event, _rx) = TaskManagerEvent::resume(uid, task_id);
315         TASK_MANGER.send_event(event);
316         std::thread::sleep(time::Duration::from_secs(20));
317     }
318 
319     #[test]
ut_task_manager_stop_resume()320     fn ut_task_manager_stop_resume() {
321         init();
322         let file_path = "test_files/ut_task_manager_pause_resume.txt";
323 
324         let file = File::create(file_path).unwrap();
325         let uid = 111;
326         let config = ConfigBuilder::new()
327         .action(Action::Download)
328         .mode(Mode::BackGround)
329         .file_spec(file)
330         .url("https://sf3-cn.feishucdn.com/obj/ee-appcenter/47273f95/Feishu-win32_ia32-7.9.7-signed.exe")
331         .redirect(true)
332         .uid(uid)
333         .build();
334         let (event, rx) = TaskManagerEvent::construct(config.clone());
335         TASK_MANGER.send_event(event);
336         let task_id = rx.get().unwrap().unwrap();
337         let (event, _rx) = TaskManagerEvent::start(uid, task_id);
338         TASK_MANGER.send_event(event);
339         let (event, _rx) = TaskManagerEvent::stop(uid, task_id);
340         TASK_MANGER.send_event(event);
341         let (event, _rx) = TaskManagerEvent::resume(uid, task_id);
342         TASK_MANGER.send_event(event);
343         std::thread::sleep(time::Duration::from_secs(20));
344     }
345 }
346