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