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