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