• 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::service::permission::ManagerPermission;
21 use crate::task::config::TaskConfig;
22 use crate::task::info::{State, TaskInfo};
23 
get_task(task_id: u32, token: String) -> Option<TaskConfig>24 pub(crate) fn get_task(task_id: u32, token: String) -> Option<TaskConfig> {
25     if let Some(config) = RequestDb::get_instance().get_task_config(task_id) {
26         if config.token.eq(token.as_str()) {
27             return Some(config);
28         }
29         return None;
30     }
31     None
32 }
33 
search(filter: TaskFilter, method: SearchMethod) -> Vec<u32>34 pub(crate) fn search(filter: TaskFilter, method: SearchMethod) -> Vec<u32> {
35     let database = RequestDb::get_instance();
36 
37     match method {
38         SearchMethod::User(uid) => database.search_task(filter, uid),
39         SearchMethod::System(bundle_name) => database.system_search_task(filter, bundle_name),
40     }
41 }
42 
43 impl TaskManager {
handle_query_event(&self, event: QueryEvent)44     pub(crate) fn handle_query_event(&self, event: QueryEvent) {
45         let (info, tx) = match event {
46             QueryEvent::Show(task_id, uid, tx) => {
47                 let info = self.show(uid, task_id);
48                 (info, tx)
49             }
50             QueryEvent::Query(task_id, action, tx) => {
51                 let info = self.query(task_id, action);
52                 (info, tx)
53             }
54             QueryEvent::Touch(task_id, uid, token, tx) => {
55                 let info = self.touch(uid, task_id, token);
56                 (info, tx)
57             }
58         };
59         let _ = tx.send(info);
60     }
61 
show(&self, uid: u64, task_id: u32) -> Option<TaskInfo>62     pub(crate) fn show(&self, uid: u64, task_id: u32) -> Option<TaskInfo> {
63         if let Some(task) = self.scheduler.get_task(uid, task_id) {
64             task.update_progress_in_database()
65         }
66 
67         match RequestDb::get_instance().get_task_info(task_id) {
68             Some(info) if info.uid() == uid => Some(info),
69             _ => {
70                 info!("TaskManger Show: no task found");
71                 None
72             }
73         }
74     }
75 
touch(&self, uid: u64, task_id: u32, token: String) -> Option<TaskInfo>76     pub(crate) fn touch(&self, uid: u64, task_id: u32, token: String) -> Option<TaskInfo> {
77         if let Some(task) = self.scheduler.get_task(uid, task_id) {
78             task.update_progress_in_database()
79         }
80 
81         let mut info = match RequestDb::get_instance().get_task_info(task_id) {
82             Some(info) => info,
83             None => {
84                 info!("TaskManger Touch: no task found");
85                 return None;
86             }
87         };
88 
89         if info.uid() == uid && info.token() == token {
90             info.bundle = "".to_string();
91             Some(info)
92         } else {
93             info!("TaskManger Touch: no task found");
94             None
95         }
96     }
97 
query(&self, task_id: u32, action: Action) -> Option<TaskInfo>98     pub(crate) fn query(&self, task_id: u32, action: Action) -> Option<TaskInfo> {
99         if let Some(task) = self
100             .scheduler
101             .tasks()
102             .find(|task| task.task_id() == task_id)
103         {
104             task.update_progress_in_database()
105         }
106 
107         let mut info = match RequestDb::get_instance().get_task_info(task_id) {
108             Some(info) => info,
109             None => {
110                 info!("TaskManger Query: no task found");
111                 return None;
112             }
113         };
114 
115         let task_action = info.action();
116         if ManagerPermission::check_action(action, task_action) {
117             info.data = "".to_string();
118             info.url = "".to_string();
119             Some(info)
120         } else {
121             info!("TaskManger Query: no task found");
122             None
123         }
124     }
125 }
126 
127 impl RequestDb {
search_task(&self, filter: TaskFilter, uid: u64) -> Vec<u32>128     pub(crate) fn search_task(&self, filter: TaskFilter, uid: u64) -> Vec<u32> {
129         let mut sql = format!("SELECT task_id from request_task WHERE uid = {} AND ", uid);
130         Self::search_filter(&mut sql, &filter);
131         self.query_integer(&sql)
132     }
133 
system_search_task(&self, filter: TaskFilter, bundle_name: String) -> Vec<u32>134     pub(crate) fn system_search_task(&self, filter: TaskFilter, bundle_name: String) -> Vec<u32> {
135         let mut sql = "SELECT task_id from request_task WHERE ".to_string();
136         if bundle_name != "*" {
137             sql.push_str(&format!("bundle = '{}' AND ", bundle_name));
138         }
139         Self::search_filter(&mut sql, &filter);
140         self.query_integer(&sql)
141     }
142 
search_filter(sql: &mut String, filter: &TaskFilter)143     fn search_filter(sql: &mut String, filter: &TaskFilter) {
144         sql.push_str(&format!(
145             "ctime BETWEEN {} AND {} ",
146             filter.after, filter.before
147         ));
148         if filter.state != State::Any.repr {
149             sql.push_str(&format!("AND state = {} ", filter.state));
150         }
151         if filter.action != Action::Any.repr {
152             sql.push_str(&format!("AND action = {} ", filter.action));
153         }
154         if filter.mode != Mode::Any.repr {
155             sql.push_str(&format!("AND mode = {} ", filter.mode));
156         }
157     }
158 }
159 
query_mime_type(uid: u64, task_id: u32) -> String160 pub(crate) fn query_mime_type(uid: u64, task_id: u32) -> String {
161     match RequestDb::get_instance().get_task_info(task_id) {
162         Some(info) if info.uid() == uid => info.mime_type(),
163         _ => {
164             info!("TaskManger QueryMimeType: no task found");
165             "".into()
166         }
167     }
168 }
169 
170 #[derive(Debug)]
171 pub(crate) enum SearchMethod {
172     User(u64),
173     System(String),
174 }
175 
176 #[allow(unreachable_pub)]
177 #[cxx::bridge(namespace = "OHOS::Request")]
178 mod ffi {
179     #[derive(Debug)]
180     struct TaskFilter {
181         before: i64,
182         after: i64,
183         state: u8,
184         action: u8,
185         mode: u8,
186     }
187 }
188 
189 #[cfg(test)]
190 mod ut_query {
191     include!("../../tests/ut/manage/ut_query.rs");
192 }
193