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::fs::File;
15 use std::sync::atomic::{AtomicBool, Ordering};
16 use std::sync::{Arc, Mutex};
17
18 use ipc::parcel::MsgParcel;
19 use ipc::remote::RemoteStub;
20 use ipc::{IpcResult, IpcStatusCode};
21 use system_ability_fwk::ability::Handler;
22
23 use super::client::ClientManagerEntry;
24 use super::interface;
25 use super::permission::PermissionChecker;
26 use super::run_count::RunCountManagerEntry;
27 use crate::manage::database::RequestDb;
28 use crate::manage::task_manager::TaskManagerTx;
29 use crate::task::config::TaskConfig;
30 use crate::task::info::TaskInfo;
31
32 pub(crate) struct RequestServiceStub {
33 pub(crate) task_manager: Mutex<TaskManagerTx>,
34 pub(crate) sa_handler: Handler,
35 pub(crate) client_manager: ClientManagerEntry,
36 pub(crate) run_count_manager: RunCountManagerEntry,
37 pub(crate) remote_busy: Arc<AtomicBool>,
38 }
39
40 impl RequestServiceStub {
new( sa_handler: Handler, task_manager: TaskManagerTx, client_manager: ClientManagerEntry, run_count_manager: RunCountManagerEntry, remote_busy: Arc<AtomicBool>, ) -> Self41 pub(crate) fn new(
42 sa_handler: Handler,
43 task_manager: TaskManagerTx,
44 client_manager: ClientManagerEntry,
45 run_count_manager: RunCountManagerEntry,
46 remote_busy: Arc<AtomicBool>,
47 ) -> Self {
48 Self {
49 task_manager: Mutex::new(task_manager),
50 sa_handler,
51 client_manager,
52 run_count_manager,
53 remote_busy,
54 }
55 }
56
check_task_uid(&self, task_id: u32, uid: u64) -> bool57 pub(crate) fn check_task_uid(&self, task_id: u32, uid: u64) -> bool {
58 let db = RequestDb::get_instance();
59 db.query_task_uid(task_id) == Some(uid)
60 }
61
62 #[allow(dead_code)]
check_permission_or_uid(&self, task_id: u32, uid: u64) -> bool63 pub(crate) fn check_permission_or_uid(&self, task_id: u32, uid: u64) -> bool {
64 // TODO: permission should match action.
65 let permission = PermissionChecker::check_manager();
66 match permission.get_action() {
67 Some(_a) => true,
68 None => self.check_task_uid(task_id, uid),
69 }
70 }
71 }
72
73 impl RemoteStub for RequestServiceStub {
on_remote_request(&self, code: u32, data: &mut MsgParcel, reply: &mut MsgParcel) -> i3274 fn on_remote_request(&self, code: u32, data: &mut MsgParcel, reply: &mut MsgParcel) -> i32 {
75 self.sa_handler.cancel_idle();
76 self.remote_busy.store(true, Ordering::Release);
77 const SERVICE_TOKEN: &str = "OHOS.Download.RequestServiceInterface";
78 debug!("Processes on_remote_request, code: {}", code);
79 match data.read_interface_token() {
80 Ok(token) if token == SERVICE_TOKEN => {}
81 _ => {
82 error!("Gets invalid token");
83 sys_event!(ExecError, DfxCode::INVALID_IPC_MESSAGE_A00, "Gets invalid token");
84 return IpcStatusCode::Failed as i32;
85 }
86 };
87 let res = match code {
88 interface::CONSTRUCT => self.construct(data, reply),
89 interface::PAUSE => self.pause(data, reply),
90 interface::QUERY => self.query(data, reply),
91 interface::QUERY_MIME_TYPE => self.query_mime_type(data, reply),
92 interface::REMOVE => self.remove(data, reply),
93 interface::RESUME => self.resume(data, reply),
94 interface::START => self.start(data, reply),
95 interface::STOP => self.stop(data, reply),
96 interface::SHOW => self.show(data, reply),
97 interface::TOUCH => self.touch(data, reply),
98 interface::SEARCH => self.search(data, reply),
99 interface::GET_TASK => self.get_task(data, reply),
100 interface::CLEAR => Ok(()),
101 interface::OPEN_CHANNEL => self.open_channel(reply),
102 interface::SUBSCRIBE => self.subscribe(data, reply),
103 interface::UNSUBSCRIBE => self.unsubscribe(data, reply),
104 interface::SUB_RUN_COUNT => self.subscribe_run_count(data, reply),
105 interface::UNSUB_RUN_COUNT => self.unsubscribe_run_count(reply),
106 interface::CREATE_GROUP => self.create_group(data, reply),
107 interface::ATTACH_GROUP => self.attach_group(data, reply),
108 interface::DELETE_GROUP => self.delete_group(data, reply),
109 interface::SET_MAX_SPEED => self.set_max_speed(data, reply),
110 interface::SET_MODE => self.set_mode(data, reply),
111 interface::DISABLE_TASK_NOTIFICATION => self.disable_task_notifications(data, reply),
112 _ => return IpcStatusCode::Failed as i32,
113 };
114
115 self.remote_busy.store(false, Ordering::Release);
116 match res {
117 Ok(_) => 0,
118 Err(e) => e as i32,
119 }
120 }
121
dump(&self, file: File, args: Vec<String>) -> i32122 fn dump(&self, file: File, args: Vec<String>) -> i32 {
123 match self.dump(file, args) {
124 Ok(()) => 0,
125 Err(e) => e as i32,
126 }
127 }
128 }
129
serialize_task_info(tf: TaskInfo, reply: &mut MsgParcel) -> IpcResult<()>130 pub(crate) fn serialize_task_info(tf: TaskInfo, reply: &mut MsgParcel) -> IpcResult<()> {
131 reply.write(&(tf.common_data.gauge))?;
132 reply.write(&(tf.common_data.retry))?;
133 reply.write(&(tf.common_data.action as u32))?;
134 reply.write(&(tf.common_data.mode as u32))?;
135 reply.write(&(tf.common_data.reason as u32))?;
136 reply.write(&(tf.common_data.tries))?;
137 reply.write(&(tf.common_data.uid.to_string()))?;
138 reply.write(&(tf.bundle))?;
139 reply.write(&(tf.url))?;
140 reply.write(&(tf.common_data.task_id.to_string()))?;
141 reply.write(&tf.title)?;
142 reply.write(&tf.mime_type)?;
143 reply.write(&(tf.common_data.ctime))?;
144 reply.write(&(tf.common_data.mtime))?;
145 reply.write(&(tf.data))?;
146 reply.write(&(tf.description))?;
147 reply.write(&(tf.common_data.priority))?;
148
149 reply.write(&(tf.form_items.len() as u32))?;
150 for i in 0..tf.form_items.len() {
151 reply.write(&(tf.form_items[i].name))?;
152 reply.write(&(tf.form_items[i].value))?;
153 }
154
155 reply.write(&(tf.file_specs.len() as u32))?;
156 for i in 0..tf.file_specs.len() {
157 reply.write(&(tf.file_specs[i].name))?;
158 reply.write(&(tf.file_specs[i].path))?;
159 reply.write(&(tf.file_specs[i].file_name))?;
160 reply.write(&(tf.file_specs[i].mime_type))?;
161 }
162
163 reply.write(&(tf.progress.common_data.state as u32))?;
164 let index = tf.progress.common_data.index;
165 reply.write(&(index as u32))?;
166 reply.write(&(tf.progress.processed[index] as u64))?;
167 reply.write(&(tf.progress.common_data.total_processed as u64))?;
168 reply.write(&(tf.progress.sizes))?;
169
170 reply.write(&(tf.progress.extras.len() as u32))?;
171 for (k, v) in tf.progress.extras.iter() {
172 reply.write(k)?;
173 reply.write(v)?;
174 }
175
176 reply.write(&(tf.extras.len() as u32))?;
177 for (k, v) in tf.extras.iter() {
178 reply.write(k)?;
179 reply.write(v)?;
180 }
181 reply.write(&(tf.common_data.version as u32))?;
182 let each_file_status = tf.build_each_file_status();
183 reply.write(&(each_file_status.len() as u32))?;
184 for item in each_file_status.iter() {
185 reply.write(&(item.path))?;
186 reply.write(&(item.reason.repr as u32))?;
187 reply.write(&(item.message))?;
188 }
189 Ok(())
190 }
191
serialize_task_config(config: TaskConfig, reply: &mut MsgParcel) -> IpcResult<()>192 pub(crate) fn serialize_task_config(config: TaskConfig, reply: &mut MsgParcel) -> IpcResult<()> {
193 reply.write(&(config.common_data.action.repr as u32))?;
194 reply.write(&(config.common_data.mode.repr as u32))?;
195 reply.write(&(config.bundle_type))?;
196 reply.write(&(config.common_data.cover))?;
197 reply.write(&(config.common_data.network_config as u32))?;
198 reply.write(&(config.common_data.metered))?;
199 reply.write(&(config.common_data.roaming))?;
200 reply.write(&(config.common_data.retry))?;
201 reply.write(&(config.common_data.redirect))?;
202 reply.write(&(config.common_data.index))?;
203 reply.write(&(config.common_data.begins))?;
204 reply.write(&(config.common_data.ends))?;
205 reply.write(&(config.common_data.gauge))?;
206 reply.write(&(config.common_data.precise))?;
207 reply.write(&(config.common_data.priority))?;
208 reply.write(&(config.common_data.background))?;
209 reply.write(&(config.common_data.multipart))?;
210 reply.write(&(config.bundle))?;
211 reply.write(&(config.url))?;
212 reply.write(&(config.title))?;
213 reply.write(&(config.description))?;
214 reply.write(&(config.method))?;
215 // write config.headers
216 reply.write(&(config.headers.len() as u32))?;
217 for (k, v) in config.headers.iter() {
218 reply.write(k)?;
219 reply.write(v)?;
220 }
221 reply.write(&(config.data))?;
222 reply.write(&(config.token))?;
223 // write config.extras
224 reply.write(&(config.extras.len() as u32))?;
225 for (k, v) in config.extras.iter() {
226 reply.write(k)?;
227 reply.write(v)?;
228 }
229 reply.write(&(config.version as u32))?;
230 // write config.form_items
231 reply.write(&(config.form_items.len() as u32))?;
232 for i in 0..config.form_items.len() {
233 reply.write(&(config.form_items[i].name))?;
234 reply.write(&(config.form_items[i].value))?;
235 }
236 // write config.file_specs
237 reply.write(&(config.file_specs.len() as u32))?;
238 for i in 0..config.file_specs.len() {
239 reply.write(&(config.file_specs[i].name))?;
240 reply.write(&(config.file_specs[i].path))?;
241 reply.write(&(config.file_specs[i].file_name))?;
242 reply.write(&(config.file_specs[i].mime_type))?;
243 }
244 // write config.body_file_names
245 reply.write(&(config.body_file_paths.len() as u32))?;
246 for i in 0..config.body_file_paths.len() {
247 reply.write(&(config.body_file_paths[i]))?;
248 }
249 Ok(())
250 }
251