• 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 pub(crate) use ffi::TaskFilter;
15 
16 use super::events::QueryEvent;
17 use super::TaskManager;
18 use crate::config::{Action, Mode};
19 use crate::manage::database::RequestDb;
20 use crate::task::config::TaskConfig;
21 use crate::task::info::{State, TaskInfo};
22 
get_task(task_id: u32, token: String) -> Option<TaskConfig>23 pub(crate) fn get_task(task_id: u32, token: String) -> Option<TaskConfig> {
24     if let Some(config) = RequestDb::get_instance().get_task_config(task_id) {
25         if config.token.eq(token.as_str()) {
26             return Some(config);
27         }
28         return None;
29     }
30     None
31 }
32 
search(filter: TaskFilter, method: SearchMethod) -> Vec<u32>33 pub(crate) fn search(filter: TaskFilter, method: SearchMethod) -> Vec<u32> {
34     let database = RequestDb::get_instance();
35 
36     match method {
37         SearchMethod::User(uid) => database.search_task(filter, uid),
38         SearchMethod::System(bundle_name) => database.system_search_task(filter, bundle_name),
39     }
40 }
41 
42 impl TaskManager {
handle_query_event(&self, event: QueryEvent)43     pub(crate) fn handle_query_event(&self, event: QueryEvent) {
44         let (info, tx) = match event {
45             QueryEvent::Show(task_id, uid, tx) => {
46                 let info = self.show(uid, task_id);
47                 (info, tx)
48             }
49             QueryEvent::Query(task_id, action, tx) => {
50                 let info = self.query(task_id, action);
51                 (info, tx)
52             }
53             QueryEvent::Touch(task_id, uid, token, tx) => {
54                 let info = self.touch(uid, task_id, token);
55                 (info, tx)
56             }
57         };
58         let _ = tx.send(info);
59     }
60 
show(&self, uid: u64, task_id: u32) -> Option<TaskInfo>61     pub(crate) fn show(&self, uid: u64, task_id: u32) -> Option<TaskInfo> {
62         if let Some(task) = self.scheduler.get_task(uid, task_id) {
63             task.update_progress_in_database()
64         }
65 
66         match RequestDb::get_instance().get_task_info(task_id) {
67             Some(info) if info.uid() == uid => Some(info),
68             _ => {
69                 info!("TaskManger Show: no task found");
70                 None
71             }
72         }
73     }
74 
touch(&self, uid: u64, task_id: u32, token: String) -> Option<TaskInfo>75     pub(crate) fn touch(&self, uid: u64, task_id: u32, token: String) -> Option<TaskInfo> {
76         if let Some(task) = self.scheduler.get_task(uid, task_id) {
77             task.update_progress_in_database()
78         }
79 
80         let mut info = match RequestDb::get_instance().get_task_info(task_id) {
81             Some(info) => info,
82             None => {
83                 info!("TaskManger Touch: no task found");
84                 return None;
85             }
86         };
87 
88         if info.uid() == uid && info.token() == token {
89             info.bundle = "".to_string();
90             Some(info)
91         } else {
92             info!("TaskManger Touch: no task found");
93             None
94         }
95     }
96 
query(&self, task_id: u32, action: Action) -> Option<TaskInfo>97     pub(crate) fn query(&self, task_id: u32, action: Action) -> Option<TaskInfo> {
98         if let Some(task) = self
99             .scheduler
100             .tasks()
101             .find(|task| task.task_id() == task_id)
102         {
103             task.update_progress_in_database()
104         }
105 
106         let mut info = match RequestDb::get_instance().get_task_info(task_id) {
107             Some(info) => info,
108             None => {
109                 info!("TaskManger Query: no task found");
110                 return None;
111             }
112         };
113 
114         if info.action() == action || action == Action::Any {
115             info.data = "".to_string();
116             info.url = "".to_string();
117             Some(info)
118         } else {
119             info!("TaskManger Query: no task found");
120             None
121         }
122     }
123 }
124 
125 impl RequestDb {
search_task(&self, filter: TaskFilter, uid: u64) -> Vec<u32>126     pub(crate) fn search_task(&self, filter: TaskFilter, uid: u64) -> Vec<u32> {
127         let mut sql = format!("SELECT task_id from request_task WHERE uid = {} AND ", uid);
128         Self::search_filter(&mut sql, &filter);
129         self.query_integer(&sql)
130     }
131 
system_search_task(&self, filter: TaskFilter, bundle_name: String) -> Vec<u32>132     pub(crate) fn system_search_task(&self, filter: TaskFilter, bundle_name: String) -> Vec<u32> {
133         let mut sql = "SELECT task_id from request_task WHERE ".to_string();
134         if bundle_name != "*" {
135             sql.push_str(&format!("bundle = '{}' AND ", bundle_name));
136         }
137         Self::search_filter(&mut sql, &filter);
138         self.query_integer(&sql)
139     }
140 
search_filter(sql: &mut String, filter: &TaskFilter)141     fn search_filter(sql: &mut String, filter: &TaskFilter) {
142         sql.push_str(&format!(
143             "ctime BETWEEN {} AND {} ",
144             filter.after, filter.before
145         ));
146         if filter.state != State::Any.repr {
147             sql.push_str(&format!("AND state = {} ", filter.state));
148         }
149         if filter.action != Action::Any.repr {
150             sql.push_str(&format!("AND action = {} ", filter.action));
151         }
152         if filter.mode != Mode::Any.repr {
153             sql.push_str(&format!("AND mode = {} ", filter.mode));
154         }
155     }
156 }
157 
query_mime_type(uid: u64, task_id: u32) -> String158 pub(crate) fn query_mime_type(uid: u64, task_id: u32) -> String {
159     match RequestDb::get_instance().get_task_info(task_id) {
160         Some(info) if info.uid() == uid => info.mime_type(),
161         _ => {
162             info!("TaskManger QueryMimeType: no task found");
163             "".into()
164         }
165     }
166 }
167 
168 #[derive(Debug)]
169 pub(crate) enum SearchMethod {
170     User(u64),
171     System(String),
172 }
173 
174 #[allow(unreachable_pub)]
175 #[cxx::bridge(namespace = "OHOS::Request")]
176 mod ffi {
177     #[derive(Debug)]
178     struct TaskFilter {
179         before: i64,
180         after: i64,
181         state: u8,
182         action: u8,
183         mode: u8,
184     }
185 }
186 
187 #[cfg(test)]
188 mod test {
189     use super::*;
190     use crate::tests::{lock_database, test_init};
191     use crate::utils::get_current_timestamp;
192     use crate::utils::task_id_generator::TaskIdGenerator;
193 
194     #[test]
ut_search_user()195     fn ut_search_user() {
196         test_init();
197         let _lock = lock_database();
198         let db = RequestDb::get_instance();
199         let task_id = TaskIdGenerator::generate();
200         let uid = get_current_timestamp();
201         db.execute(&format!(
202             "INSERT INTO request_task (task_id, uid, state, ctime, action, mode) VALUES ({}, {}, {} ,{} ,{} ,{})",
203             task_id,
204             uid,
205             State::Removed.repr,
206             get_current_timestamp(),
207             Action::Upload.repr,
208             Mode::BackGround.repr
209         )).unwrap();
210 
211         let filter = TaskFilter {
212             before: get_current_timestamp() as i64,
213             after: get_current_timestamp() as i64 - 200,
214             state: State::Completed.repr,
215             action: Action::Any.repr,
216             mode: Mode::Any.repr,
217         };
218         let res = db.search_task(filter, uid);
219         assert_eq!(res, vec![]);
220 
221         let filter = TaskFilter {
222             before: get_current_timestamp() as i64,
223             after: get_current_timestamp() as i64 - 200,
224             state: State::Any.repr,
225             action: Action::Download.repr,
226             mode: Mode::Any.repr,
227         };
228         let res = db.search_task(filter, uid);
229         assert_eq!(res, vec![]);
230 
231         let filter = TaskFilter {
232             before: get_current_timestamp() as i64,
233             after: get_current_timestamp() as i64 - 200,
234             state: State::Any.repr,
235             action: Action::Any.repr,
236             mode: Mode::FrontEnd.repr,
237         };
238         let res = db.search_task(filter, uid);
239         assert_eq!(res, vec![]);
240 
241         let filter = TaskFilter {
242             before: get_current_timestamp() as i64,
243             after: get_current_timestamp() as i64 - 200,
244             state: State::Removed.repr,
245             action: Action::Upload.repr,
246             mode: Mode::BackGround.repr,
247         };
248         let res = db.search_task(filter, uid);
249         assert_eq!(res, vec![task_id as u32]);
250 
251         let filter = TaskFilter {
252             before: get_current_timestamp() as i64,
253             after: get_current_timestamp() as i64 - 200,
254             state: State::Any.repr,
255             action: Action::Any.repr,
256             mode: Mode::Any.repr,
257         };
258         let res = db.search_task(filter, uid);
259         assert_eq!(res, vec![task_id as u32]);
260 
261         let filter = TaskFilter {
262             before: get_current_timestamp() as i64,
263             after: get_current_timestamp() as i64 - 200,
264             state: State::Any.repr,
265             action: Action::Upload.repr,
266             mode: Mode::BackGround.repr,
267         };
268         let res = db.search_task(filter, uid);
269         assert_eq!(res, vec![task_id as u32]);
270     }
271 
272     #[test]
ut_search_system()273     fn ut_search_system() {
274         test_init();
275         let db = RequestDb::get_instance();
276         let _lock = lock_database();
277         let task_id = TaskIdGenerator::generate();
278         let bundle_name = "com.ohos.app";
279         db.execute(&format!(
280             "INSERT INTO request_task (task_id, bundle, state, ctime, action, mode) VALUES ({}, '{}' ,{} ,{} ,{}, {})",
281             task_id,
282             bundle_name,
283             State::Removed.repr,
284             get_current_timestamp(),
285             Action::Download.repr,
286             Mode::BackGround.repr
287         )).unwrap();
288 
289         let filter = TaskFilter {
290             before: get_current_timestamp() as i64,
291             after: get_current_timestamp() as i64 - 200,
292             state: State::Completed.repr,
293             action: Action::Any.repr,
294             mode: Mode::Any.repr,
295         };
296         let res = db.system_search_task(filter, bundle_name.to_string());
297         assert_eq!(res, vec![]);
298 
299         let filter = TaskFilter {
300             before: get_current_timestamp() as i64,
301             after: get_current_timestamp() as i64 - 200,
302             state: State::Any.repr,
303             action: Action::Any.repr,
304             mode: Mode::Any.repr,
305         };
306         let res = db.system_search_task(filter, bundle_name.to_string());
307         assert_eq!(res, vec![task_id as u32]);
308 
309         let filter = TaskFilter {
310             before: get_current_timestamp() as i64,
311             after: get_current_timestamp() as i64 - 200,
312             state: State::Any.repr,
313             action: Action::Download.repr,
314             mode: Mode::BackGround.repr,
315         };
316         let res = db.system_search_task(filter, "*".to_string());
317         assert_eq!(res, vec![task_id as u32]);
318     }
319 }
320