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 attach_group( uid: u64, task_ids: Vec<u32>, group_id: u32, ) -> (Self, Recv<ErrorCode>)124 pub(crate) fn attach_group( 125 uid: u64, 126 task_ids: Vec<u32>, 127 group_id: u32, 128 ) -> (Self, Recv<ErrorCode>) { 129 let (tx, rx) = channel::<ErrorCode>(); 130 ( 131 Self::Service(ServiceEvent::AttachGroup(uid, task_ids, group_id, tx)), 132 Recv::new(rx), 133 ) 134 } 135 } 136 137 #[derive(Debug)] 138 pub(crate) enum QueryEvent { 139 Query(u32, Action, Sender<Option<TaskInfo>>), 140 Show(u32, u64, Sender<Option<TaskInfo>>), 141 Touch(u32, u64, String, Sender<Option<TaskInfo>>), 142 } 143 144 #[derive(Debug)] 145 pub(crate) enum ServiceEvent { 146 Construct(Box<ConstructMessage>, Sender<Result<u32, ErrorCode>>), 147 Pause(u64, u32, Sender<ErrorCode>), 148 Start(u64, u32, Sender<ErrorCode>), 149 Stop(u64, u32, Sender<ErrorCode>), 150 Remove(u64, u32, Sender<ErrorCode>), 151 Resume(u64, u32, Sender<ErrorCode>), 152 DumpOne(u32, Sender<Option<DumpOneInfo>>), 153 DumpAll(Sender<DumpAllInfo>), 154 AttachGroup(u64, Vec<u32>, u32, Sender<ErrorCode>), 155 } 156 157 #[derive(Debug)] 158 pub(crate) enum TaskEvent { 159 Completed(u32, u64, Mode), 160 Failed(u32, u64, Reason, Mode), 161 Offline(u32, u64, Mode), 162 Running(u32, u64, Mode), 163 Subscribe(u32, u64, Sender<ErrorCode>), 164 } 165 166 #[derive(Debug)] 167 pub(crate) enum StateEvent { 168 Network, 169 ForegroundApp(u64), 170 Background(u64), 171 BackgroundTimeout(u64), 172 SpecialTerminate(u64), 173 } 174 175 pub(crate) struct ConstructMessage { 176 pub(crate) config: TaskConfig, 177 } 178 179 impl Debug for ConstructMessage { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result180 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 181 f.debug_struct("Construct") 182 .field("uid", &self.config.common_data.uid) 183 .field("task_id", &self.config.common_data.task_id) 184 .field("title", &self.config.title) 185 .field("mode", &self.config.method) 186 .field("version", &self.config.version) 187 .finish() 188 } 189 } 190 191 #[derive(Debug)] 192 pub(crate) enum ScheduleEvent { 193 ClearTimeoutTasks, 194 LogTasks, 195 RestoreAllTasks, 196 Unload, 197 } 198 199 #[cfg(not(feature = "oh"))] 200 #[cfg(test)] 201 mod test { 202 use core::time; 203 use std::fs::File; 204 205 use once_cell::sync::Lazy; 206 207 use super::TaskManagerEvent; 208 use crate::config::{Action, ConfigBuilder, Mode}; 209 use crate::error::ErrorCode; 210 use crate::manage::network::Network; 211 use crate::manage::task_manager::TaskManagerTx; 212 use crate::manage::TaskManager; 213 use crate::service::client::{ClientManager, ClientManagerEntry}; 214 use crate::service::run_count::{RunCountManager, RunCountManagerEntry}; 215 216 static CLIENT: Lazy<ClientManagerEntry> = Lazy::new(|| ClientManager::init()); 217 static RUN_COUNT_MANAGER: Lazy<RunCountManagerEntry> = Lazy::new(|| RunCountManager::init()); 218 static NETWORK: Lazy<Network> = Lazy::new(|| Network::new()); 219 220 static TASK_MANGER: Lazy<TaskManagerTx> = 221 Lazy::new(|| TaskManager::init(RUN_COUNT_MANAGER.clone(), CLIENT.clone(), NETWORK.clone())); build_task()222 fn build_task() {} 223 init()224 fn init() { 225 let _ = env_logger::builder().is_test(true).try_init(); 226 let _ = std::fs::create_dir("test_files/"); 227 } 228 229 #[test] ut_task_manager_construct()230 fn ut_task_manager_construct() { 231 init(); 232 let file_path = "test_files/ut_task_manager_construct.txt"; 233 234 let file = File::create(file_path).unwrap(); 235 let config = ConfigBuilder::new() 236 .action(Action::Download) 237 .mode(Mode::BackGround) 238 .file_spec(file) 239 .url("https://www.gitee.com/tiga-ultraman/downloadTests/releases/download/v1.01/test.txt") 240 .redirect(true) 241 .build(); 242 let (event, rx) = TaskManagerEvent::construct(config); 243 TASK_MANGER.send_event(event); 244 rx.get().unwrap().unwrap(); 245 } 246 247 #[test] ut_task_manager_start()248 fn ut_task_manager_start() { 249 init(); 250 let file_path = "test_files/ut_task_manager_construct.txt"; 251 252 let file = File::create(file_path).unwrap(); 253 let uid = 111; 254 let config = ConfigBuilder::new() 255 .action(Action::Download) 256 .mode(Mode::BackGround) 257 .file_spec(file) 258 .url("https://sf3-cn.feishucdn.com/obj/ee-appcenter/47273f95/Feishu-win32_ia32-7.9.7-signed.exe") 259 .redirect(true) 260 .uid(uid) 261 .build(); 262 let (event, rx) = TaskManagerEvent::construct(config.clone()); 263 TASK_MANGER.send_event(event); 264 let task_id = rx.get().unwrap().unwrap(); 265 let (event, rx) = TaskManagerEvent::start(uid, task_id); 266 TASK_MANGER.send_event(event); 267 let res = rx.get().unwrap(); 268 assert_eq!(res, ErrorCode::ErrOk); 269 std::thread::sleep(time::Duration::from_secs(10)); 270 } 271 272 #[test] ut_task_manager_pause_resume()273 fn ut_task_manager_pause_resume() { 274 init(); 275 let file_path = "test_files/ut_task_manager_pause_resume.txt"; 276 277 let file = File::create(file_path).unwrap(); 278 let uid = 111; 279 let config = ConfigBuilder::new() 280 .action(Action::Download) 281 .mode(Mode::BackGround) 282 .file_spec(file) 283 .url("https://sf3-cn.feishucdn.com/obj/ee-appcenter/47273f95/Feishu-win32_ia32-7.9.7-signed.exe") 284 .redirect(true) 285 .uid(uid) 286 .build(); 287 let (event, rx) = TaskManagerEvent::construct(config.clone()); 288 TASK_MANGER.send_event(event); 289 let task_id = rx.get().unwrap().unwrap(); 290 let (event, _rx) = TaskManagerEvent::start(uid, task_id); 291 TASK_MANGER.send_event(event); 292 let (event, _rx) = TaskManagerEvent::pause(uid, task_id); 293 TASK_MANGER.send_event(event); 294 let (event, _rx) = TaskManagerEvent::resume(uid, task_id); 295 TASK_MANGER.send_event(event); 296 std::thread::sleep(time::Duration::from_secs(20)); 297 } 298 299 #[test] ut_task_manager_stop_resume()300 fn ut_task_manager_stop_resume() { 301 init(); 302 let file_path = "test_files/ut_task_manager_pause_resume.txt"; 303 304 let file = File::create(file_path).unwrap(); 305 let uid = 111; 306 let config = ConfigBuilder::new() 307 .action(Action::Download) 308 .mode(Mode::BackGround) 309 .file_spec(file) 310 .url("https://sf3-cn.feishucdn.com/obj/ee-appcenter/47273f95/Feishu-win32_ia32-7.9.7-signed.exe") 311 .redirect(true) 312 .uid(uid) 313 .build(); 314 let (event, rx) = TaskManagerEvent::construct(config.clone()); 315 TASK_MANGER.send_event(event); 316 let task_id = rx.get().unwrap().unwrap(); 317 let (event, _rx) = TaskManagerEvent::start(uid, task_id); 318 TASK_MANGER.send_event(event); 319 let (event, _rx) = TaskManagerEvent::stop(uid, task_id); 320 TASK_MANGER.send_event(event); 321 let (event, _rx) = TaskManagerEvent::resume(uid, task_id); 322 TASK_MANGER.send_event(event); 323 std::thread::sleep(time::Duration::from_secs(20)); 324 } 325 } 326