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