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::collections::HashMap; 15 16 pub use ffi::State; 17 18 use super::notify::{EachFileStatus, NotifyData, Progress}; 19 use crate::task::config::{Action, Version}; 20 use crate::task::reason::Reason; 21 use crate::utils::c_wrapper::{CFileSpec, CFormItem}; 22 use crate::utils::form_item::{FileSpec, FormItem}; 23 use crate::utils::hashmap_to_string; 24 25 #[derive(Debug, Clone)] 26 pub(crate) struct TaskInfo { 27 pub(crate) bundle: String, 28 pub(crate) url: String, 29 pub(crate) data: String, 30 pub(crate) token: String, 31 pub(crate) form_items: Vec<FormItem>, 32 pub(crate) file_specs: Vec<FileSpec>, 33 pub(crate) title: String, 34 pub(crate) description: String, 35 pub(crate) mime_type: String, 36 pub(crate) progress: Progress, 37 pub(crate) extras: HashMap<String, String>, 38 pub(crate) common_data: CommonTaskInfo, 39 pub(crate) max_speed: i64, 40 } 41 42 impl TaskInfo { new() -> Self43 pub(crate) fn new() -> Self { 44 Self { 45 bundle: "".to_string(), 46 url: "".to_string(), 47 data: "".to_string(), 48 token: "".to_string(), 49 form_items: vec![], 50 file_specs: vec![], 51 title: "".to_string(), 52 description: "".to_string(), 53 mime_type: "".to_string(), 54 // Has at least one progress size. 55 progress: Progress::new(vec![0]), 56 extras: HashMap::new(), 57 common_data: CommonTaskInfo::new(), 58 max_speed: 0, 59 } 60 } 61 uid(&self) -> u6462 pub(crate) fn uid(&self) -> u64 { 63 self.common_data.uid 64 } 65 mime_type(&self) -> String66 pub(crate) fn mime_type(&self) -> String { 67 self.mime_type.clone() 68 } 69 action(&self) -> Action70 pub(crate) fn action(&self) -> Action { 71 Action::from(self.common_data.action) 72 } 73 token(&self) -> String74 pub(crate) fn token(&self) -> String { 75 self.token.clone() 76 } 77 } 78 79 #[repr(C)] 80 #[derive(Copy, Clone, Debug)] 81 pub(crate) struct CommonTaskInfo { 82 pub(crate) task_id: u32, 83 pub(crate) uid: u64, 84 pub(crate) action: u8, 85 pub(crate) mode: u8, 86 pub(crate) ctime: u64, 87 pub(crate) mtime: u64, 88 pub(crate) reason: u8, 89 pub(crate) gauge: bool, 90 pub(crate) retry: bool, 91 pub(crate) tries: u32, 92 pub(crate) version: u8, 93 pub(crate) priority: u32, 94 } 95 96 impl CommonTaskInfo { new() -> Self97 pub(crate) fn new() -> Self { 98 Self { 99 task_id: 0, 100 uid: 0, 101 action: 0, 102 mode: 0, 103 ctime: 0, 104 mtime: 0, 105 reason: 0, 106 gauge: false, 107 retry: false, 108 tries: 0, 109 version: 0, 110 priority: 0, 111 } 112 } 113 } 114 115 pub(crate) struct InfoSet { 116 pub(crate) form_items: Vec<CFormItem>, 117 pub(crate) file_specs: Vec<CFileSpec>, 118 pub(crate) sizes: String, 119 pub(crate) processed: String, 120 pub(crate) extras: String, 121 } 122 123 #[cxx::bridge(namespace = "OHOS::Request")] 124 mod ffi { 125 #[derive(Clone, Copy, PartialEq, Debug)] 126 #[repr(u8)] 127 /// Task state 128 pub enum State { 129 /// Initialized 130 Initialized = 0x00, 131 /// Waiting 132 Waiting = 0x10, 133 /// Running 134 Running = 0x20, 135 /// Retrying 136 Retrying = 0x21, 137 /// Paused 138 Paused = 0x30, 139 /// Stopped 140 Stopped = 0x31, 141 /// Completed 142 Completed = 0x40, 143 /// Failed 144 Failed = 0x41, 145 /// Removed 146 Removed = 0x50, 147 /// Any 148 Any = 0x61, 149 } 150 } 151 152 #[derive(Debug)] 153 pub(crate) struct UpdateInfo { 154 pub(crate) mtime: u64, 155 pub(crate) reason: u8, 156 pub(crate) tries: u32, 157 pub(crate) mime_type: String, 158 pub(crate) progress: Progress, 159 } 160 161 impl From<u8> for State { from(value: u8) -> Self162 fn from(value: u8) -> Self { 163 match value { 164 0 => State::Initialized, 165 16 => State::Waiting, 166 32 => State::Running, 167 33 => State::Retrying, 168 48 => State::Paused, 169 49 => State::Stopped, 170 64 => State::Completed, 171 65 => State::Failed, 172 80 => State::Removed, 173 _ => State::Any, 174 } 175 } 176 } 177 178 impl TaskInfo { build_info_set(&self) -> InfoSet179 pub(crate) fn build_info_set(&self) -> InfoSet { 180 InfoSet { 181 form_items: self.form_items.iter().map(|x| x.to_c_struct()).collect(), 182 file_specs: self.file_specs.iter().map(|x| x.to_c_struct()).collect(), 183 sizes: format!("{:?}", self.progress.sizes), 184 processed: format!("{:?}", self.progress.processed), 185 extras: hashmap_to_string(&self.extras), 186 } 187 } 188 build_each_file_status(&self) -> Vec<EachFileStatus>189 pub(crate) fn build_each_file_status(&self) -> Vec<EachFileStatus> { 190 EachFileStatus::create_each_file_status( 191 &self.file_specs, 192 self.progress.common_data.index, 193 self.common_data.reason.into(), 194 ) 195 } 196 build_notify_data(&self) -> NotifyData197 pub(crate) fn build_notify_data(&self) -> NotifyData { 198 NotifyData { 199 bundle: self.bundle.clone(), 200 progress: self.progress.clone(), 201 action: Action::from(self.common_data.action), 202 version: Version::from(self.common_data.version), 203 each_file_status: self.build_each_file_status(), 204 task_id: self.common_data.task_id, 205 uid: self.common_data.uid, 206 } 207 } 208 } 209 210 #[derive(Debug)] 211 pub(crate) struct DumpAllInfo { 212 pub(crate) vec: Vec<DumpAllEachInfo>, 213 } 214 215 #[derive(Debug)] 216 pub(crate) struct DumpAllEachInfo { 217 pub(crate) task_id: u32, 218 pub(crate) action: Action, 219 pub(crate) state: State, 220 pub(crate) reason: Reason, 221 } 222 223 #[derive(Debug)] 224 pub(crate) struct DumpOneInfo { 225 pub(crate) task_id: u32, 226 pub(crate) action: Action, 227 pub(crate) state: State, 228 pub(crate) reason: Reason, 229 } 230 231 #[cfg(test)] 232 mod test { 233 use super::*; 234 235 #[test] ut_enum_state()236 fn ut_enum_state() { 237 assert_eq!(State::Initialized.repr, 0); 238 assert_eq!(State::Waiting.repr, 16); 239 assert_eq!(State::Running.repr, 32); 240 assert_eq!(State::Retrying.repr, 33); 241 assert_eq!(State::Paused.repr, 48); 242 assert_eq!(State::Stopped.repr, 49); 243 assert_eq!(State::Completed.repr, 64); 244 assert_eq!(State::Failed.repr, 65); 245 assert_eq!(State::Removed.repr, 80); 246 assert_eq!(State::Any.repr, 97); 247 } 248 } 249