• 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 use std::fs::File;
15 use std::sync::Mutex;
16 
17 use ipc::parcel::MsgParcel;
18 use ipc::remote::RemoteStub;
19 use ipc::{IpcResult, IpcStatusCode};
20 use system_ability_fwk::ability::Handler;
21 
22 use super::client::ClientManagerEntry;
23 use super::interface;
24 use super::permission::PermissionChecker;
25 use super::run_count::RunCountManagerEntry;
26 use crate::manage::database::RequestDb;
27 use crate::manage::task_manager::TaskManagerTx;
28 use crate::service::active_counter::ActiveCounter;
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) active_counter: ActiveCounter,
38 }
39 
40 impl RequestServiceStub {
new( sa_handler: Handler, task_manager: TaskManagerTx, client_manager: ClientManagerEntry, run_count_manager: RunCountManagerEntry, active_counter: ActiveCounter, ) -> Self41     pub(crate) fn new(
42         sa_handler: Handler,
43         task_manager: TaskManagerTx,
44         client_manager: ClientManagerEntry,
45         run_count_manager: RunCountManagerEntry,
46         active_counter: ActiveCounter,
47     ) -> Self {
48         Self {
49             task_manager: Mutex::new(task_manager),
50             sa_handler,
51             client_manager,
52             run_count_manager,
53             active_counter,
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.active_counter.increment();
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                 self.active_counter.decrement();
85                 return IpcStatusCode::Failed as i32;
86             }
87         };
88         let res = match code {
89             interface::CONSTRUCT => self.construct(data, reply),
90             interface::PAUSE => self.pause(data, reply),
91             interface::QUERY => self.query(data, reply),
92             interface::QUERY_MIME_TYPE => self.query_mime_type(data, reply),
93             interface::REMOVE => self.remove(data, reply),
94             interface::RESUME => self.resume(data, reply),
95             interface::START => self.start(data, reply),
96             interface::STOP => self.stop(data, reply),
97             interface::SHOW => self.show(data, reply),
98             interface::TOUCH => self.touch(data, reply),
99             interface::SEARCH => self.search(data, reply),
100             interface::GET_TASK => self.get_task(data, reply),
101             interface::CLEAR => Ok(()),
102             interface::OPEN_CHANNEL => self.open_channel(reply),
103             interface::SUBSCRIBE => self.subscribe(data, reply),
104             interface::UNSUBSCRIBE => self.unsubscribe(data, reply),
105             interface::SUB_RUN_COUNT => self.subscribe_run_count(data, reply),
106             interface::UNSUB_RUN_COUNT => self.unsubscribe_run_count(reply),
107             interface::CREATE_GROUP => self.create_group(data, reply),
108             interface::ATTACH_GROUP => self.attach_group(data, reply),
109             interface::DELETE_GROUP => self.delete_group(data, reply),
110             interface::SET_MAX_SPEED => self.set_max_speed(data, reply),
111             interface::SET_MODE => self.set_mode(data, reply),
112             interface::DISABLE_TASK_NOTIFICATION => self.disable_task_notifications(data, reply),
113             _ => Err(IpcStatusCode::Failed),
114         };
115 
116         self.active_counter.decrement();
117         match res {
118             Ok(_) => 0,
119             Err(e) => e as i32,
120         }
121     }
122 
dump(&self, file: File, args: Vec<String>) -> i32123     fn dump(&self, file: File, args: Vec<String>) -> i32 {
124         match self.dump(file, args) {
125             Ok(()) => 0,
126             Err(e) => e as i32,
127         }
128     }
129 }
130 
serialize_task_info(tf: TaskInfo, reply: &mut MsgParcel) -> IpcResult<()>131 pub(crate) fn serialize_task_info(tf: TaskInfo, reply: &mut MsgParcel) -> IpcResult<()> {
132     reply.write(&(tf.common_data.gauge))?;
133     reply.write(&(tf.common_data.retry))?;
134     reply.write(&(tf.common_data.action as u32))?;
135     reply.write(&(tf.common_data.mode as u32))?;
136     reply.write(&(tf.common_data.reason as u32))?;
137     reply.write(&(tf.common_data.tries))?;
138     reply.write(&(tf.common_data.uid.to_string()))?;
139     reply.write(&(tf.bundle))?;
140     reply.write(&(tf.url))?;
141     reply.write(&(tf.common_data.task_id.to_string()))?;
142     reply.write(&tf.title)?;
143     reply.write(&tf.mime_type)?;
144     reply.write(&(tf.common_data.ctime))?;
145     reply.write(&(tf.common_data.mtime))?;
146     reply.write(&(tf.data))?;
147     reply.write(&(tf.description))?;
148     reply.write(&(tf.common_data.priority))?;
149 
150     reply.write(&(tf.form_items.len() as u32))?;
151     for i in 0..tf.form_items.len() {
152         reply.write(&(tf.form_items[i].name))?;
153         reply.write(&(tf.form_items[i].value))?;
154     }
155 
156     reply.write(&(tf.file_specs.len() as u32))?;
157     for i in 0..tf.file_specs.len() {
158         reply.write(&(tf.file_specs[i].name))?;
159         reply.write(&(tf.file_specs[i].path))?;
160         reply.write(&(tf.file_specs[i].file_name))?;
161         reply.write(&(tf.file_specs[i].mime_type))?;
162     }
163 
164     reply.write(&(tf.progress.common_data.state as u32))?;
165     let index = tf.progress.common_data.index;
166     reply.write(&(index as u32))?;
167     reply.write(&(tf.progress.processed[index] as u64))?;
168     reply.write(&(tf.progress.common_data.total_processed as u64))?;
169     reply.write(&(tf.progress.sizes))?;
170 
171     reply.write(&(tf.progress.extras.len() as u32))?;
172     for (k, v) in tf.progress.extras.iter() {
173         reply.write(k)?;
174         reply.write(v)?;
175     }
176 
177     reply.write(&(tf.extras.len() as u32))?;
178     for (k, v) in tf.extras.iter() {
179         reply.write(k)?;
180         reply.write(v)?;
181     }
182     reply.write(&(tf.common_data.version as u32))?;
183     let each_file_status = tf.build_each_file_status();
184     reply.write(&(each_file_status.len() as u32))?;
185     for item in each_file_status.iter() {
186         reply.write(&(item.path))?;
187         reply.write(&(item.reason.repr as u32))?;
188         reply.write(&(item.message))?;
189     }
190     Ok(())
191 }
192 
serialize_task_config(config: TaskConfig, reply: &mut MsgParcel) -> IpcResult<()>193 pub(crate) fn serialize_task_config(config: TaskConfig, reply: &mut MsgParcel) -> IpcResult<()> {
194     reply.write(&(config.common_data.action.repr as u32))?;
195     reply.write(&(config.common_data.mode.repr as u32))?;
196     reply.write(&(config.bundle_type))?;
197     reply.write(&(config.common_data.cover))?;
198     reply.write(&(config.common_data.network_config as u32))?;
199     reply.write(&(config.common_data.metered))?;
200     reply.write(&(config.common_data.roaming))?;
201     reply.write(&(config.common_data.retry))?;
202     reply.write(&(config.common_data.redirect))?;
203     reply.write(&(config.common_data.index))?;
204     reply.write(&(config.common_data.begins))?;
205     reply.write(&(config.common_data.ends))?;
206     reply.write(&(config.common_data.gauge))?;
207     reply.write(&(config.common_data.precise))?;
208     reply.write(&(config.common_data.priority))?;
209     reply.write(&(config.common_data.background))?;
210     reply.write(&(config.common_data.multipart))?;
211     reply.write(&(config.bundle))?;
212     reply.write(&(config.url))?;
213     reply.write(&(config.title))?;
214     reply.write(&(config.description))?;
215     reply.write(&(config.method))?;
216     // write config.headers
217     reply.write(&(config.headers.len() as u32))?;
218     for (k, v) in config.headers.iter() {
219         reply.write(k)?;
220         reply.write(v)?;
221     }
222     reply.write(&(config.data))?;
223     reply.write(&(config.token))?;
224     // write config.extras
225     reply.write(&(config.extras.len() as u32))?;
226     for (k, v) in config.extras.iter() {
227         reply.write(k)?;
228         reply.write(v)?;
229     }
230     reply.write(&(config.version as u32))?;
231     // write config.form_items
232     reply.write(&(config.form_items.len() as u32))?;
233     for i in 0..config.form_items.len() {
234         reply.write(&(config.form_items[i].name))?;
235         reply.write(&(config.form_items[i].value))?;
236     }
237     // write config.file_specs
238     reply.write(&(config.file_specs.len() as u32))?;
239     for i in 0..config.file_specs.len() {
240         reply.write(&(config.file_specs[i].name))?;
241         reply.write(&(config.file_specs[i].path))?;
242         reply.write(&(config.file_specs[i].file_name))?;
243         reply.write(&(config.file_specs[i].mime_type))?;
244     }
245     // write config.body_file_names
246     reply.write(&(config.body_file_paths.len() as u32))?;
247     for i in 0..config.body_file_paths.len() {
248         reply.write(&(config.body_file_paths[i]))?;
249     }
250     // write min speed
251     reply.write(&(config.common_data.min_speed.speed))?;
252     reply.write(&(config.common_data.min_speed.duration))?;
253     Ok(())
254 }
255