• 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 ipc::parcel::MsgParcel;
15 use ipc::{IpcResult, IpcStatusCode};
16 
17 use crate::config::Action;
18 use crate::error::ErrorCode;
19 use crate::manage::database::RequestDb;
20 use crate::manage::events::TaskManagerEvent;
21 use crate::service::notification_bar::NotificationDispatcher;
22 use crate::service::permission::{ManagerPermission, PermissionChecker};
23 use crate::service::RequestServiceStub;
24 use crate::utils::{check_permission, is_system_api};
25 
26 impl RequestServiceStub {
create_group( &self, data: &mut MsgParcel, reply: &mut MsgParcel, ) -> IpcResult<()>27     pub(crate) fn create_group(
28         &self,
29         data: &mut MsgParcel,
30         reply: &mut MsgParcel,
31     ) -> IpcResult<()> {
32         let gauge: bool = data.read()?;
33 
34         let title = if data.read::<bool>()? {
35             Some(data.read()?)
36         } else {
37             None
38         };
39 
40         let text = if data.read::<bool>()? {
41             Some(data.read()?)
42         } else {
43             None
44         };
45 
46         let mut disable:bool = data.read()?;
47         if disable && (!is_system_api() || !check_permission("ohos.permission.REQUEST_DISABLE_NOTIFICATION")){
48             disable = false;
49         }
50 
51         let new_group_id = NotificationDispatcher::get_instance().create_group(gauge, title, text, disable);
52         reply.write(&new_group_id.to_string())?;
53         Ok(())
54     }
55 
attach_group( &self, data: &mut MsgParcel, reply: &mut MsgParcel, ) -> IpcResult<()>56     pub(crate) fn attach_group(
57         &self,
58         data: &mut MsgParcel,
59         reply: &mut MsgParcel,
60     ) -> IpcResult<()> {
61         let Ok(group_id) = data.read::<String>()?.parse::<u32>() else {
62             error!("End Service attach_group, group_id, failed: group_id not valid",);
63             sys_event!(
64                 ExecError,
65                 DfxCode::INVALID_IPC_MESSAGE_A38,
66                 "End Service attach_group, group_id, failed: group_id not valid"
67             );
68             reply.write(&(ErrorCode::GroupNotFound as i32))?;
69             return Ok(());
70         };
71         let task_ids = data.read::<Vec<String>>()?;
72 
73         let uid = ipc::Skeleton::calling_uid();
74 
75         let mut parse_ids = Vec::with_capacity(task_ids.len());
76 
77         for task_id in task_ids.iter() {
78             let Ok(task_id) = task_id.parse::<u32>() else {
79                 error!("End Service attach_group, task_id, failed: task_id not valid");
80                 sys_event!(
81                     ExecError,
82                     DfxCode::INVALID_IPC_MESSAGE_A38,
83                     "End Service attach_group, task_id, failed: task_id not valid"
84                 );
85                 reply.write(&(ErrorCode::TaskNotFound as i32))?;
86                 return Ok(());
87             };
88             if !self.check_task_uid(task_id, uid) {
89                 error!(
90                     "End Service attach_group, task_id: {}, failed: task_id not belong to uid",
91                     task_id
92                 );
93                 sys_event!(
94                     ExecError,
95                     DfxCode::INVALID_IPC_MESSAGE_A38,
96                     &format!("End Service attach_group, task_id: {}, failed: task_id not belong to uid", task_id)
97                 );
98                 reply.write(&(ErrorCode::TaskNotFound as i32))?;
99                 return Ok(());
100             }
101             parse_ids.push(task_id);
102         }
103         let (event, rx) = TaskManagerEvent::attach_group(uid, parse_ids, group_id);
104         if !self.task_manager.lock().unwrap().send_event(event) {
105             return Err(IpcStatusCode::Failed);
106         }
107 
108         let ret = match rx.get() {
109             Some(ret) => ret,
110             None => {
111                 error!(
112                     "End Service attach_group, task_id: {:?}, group_id: {}, failed: receives ret failed",
113                     task_ids, group_id
114                 );
115                 sys_event!(
116                     ExecError,
117                     DfxCode::INVALID_IPC_MESSAGE_A38,
118                     &format!("End Service attach_group, task_id: {:?}, group_id: {}, failed: receives ret failed",task_ids, group_id)
119                 );
120                 ErrorCode::Other
121             }
122         };
123         if ret != ErrorCode::ErrOk {
124             error!(
125                 "End Service attach_group, task_id: {:?}, group_id: {}, failed: ret is not ErrOk",
126                 task_ids, group_id
127             );
128             sys_event!(
129                 ExecError,
130                 DfxCode::INVALID_IPC_MESSAGE_A38,
131                 &format!("End Service attach_group, task_id: {:?}, group_id: {}, failed: ret is not ErrOk",task_ids, group_id)
132             );
133         }
134         reply.write(&(ret as i32))?;
135         Ok(())
136     }
137 
delete_group( &self, data: &mut MsgParcel, reply: &mut MsgParcel, ) -> IpcResult<()>138     pub(crate) fn delete_group(
139         &self,
140         data: &mut MsgParcel,
141         reply: &mut MsgParcel,
142     ) -> IpcResult<()> {
143         let Ok(group_id) = data.read::<String>()?.parse::<u32>() else {
144             reply.write(&(ErrorCode::GroupNotFound as i32))?;
145             return Ok(());
146         };
147         let mut ret = ErrorCode::ErrOk;
148         let uid = ipc::Skeleton::calling_uid();
149         if !NotificationDispatcher::get_instance().delete_group(group_id, uid) {
150             ret = ErrorCode::GroupNotFound;
151         }
152         reply.write(&(ret as i32))?;
153         Ok(())
154     }
155 
disable_task_notifications( &self, data: &mut MsgParcel, reply: &mut MsgParcel, ) -> IpcResult<()>156     pub(crate) fn disable_task_notifications(
157         &self,
158         data: &mut MsgParcel,
159         reply: &mut MsgParcel,
160     ) -> IpcResult<()> {
161         let mut permission = None;
162         let task_ids = data.read::<Vec<String>>()?;
163         let calling_uid = ipc::Skeleton::calling_uid();
164 
165         for task_id in task_ids.iter() {
166             match self.disable_task_notification_inner(calling_uid, task_id, &mut permission) {
167                 Ok(()) => reply.write(&(ErrorCode::ErrOk as i32)),
168                 Err(e) => {
169                     error!("End Service disable_task_notifications, failed: {:?}", e);
170                     sys_event!(
171                         ExecError,
172                         DfxCode::INVALID_IPC_MESSAGE_A46,
173                         &format!("End Service disable_task_notifications, failed: {:?}", e)
174                     );
175                     reply.write(&(e as i32))
176                 }
177             }?;
178         }
179         Ok(())
180     }
181 
disable_task_notification_inner( &self, calling_uid: u64, task_id: &str, permission: &mut Option<ManagerPermission>, ) -> Result<(), ErrorCode>182     fn disable_task_notification_inner(
183         &self,
184         calling_uid: u64,
185         task_id: &str,
186         permission: &mut Option<ManagerPermission>,
187     ) -> Result<(), ErrorCode> {
188         let Ok(task_id) = task_id.parse::<u32>() else {
189             return Err(ErrorCode::TaskNotFound);
190         };
191         let Some(task_uid) = RequestDb::get_instance().query_task_uid(task_id) else {
192             return Err(ErrorCode::TaskNotFound);
193         };
194         if task_uid != calling_uid {
195             let permission = match permission {
196                 Some(permission) => *permission,
197                 None => {
198                     *permission = Some(PermissionChecker::check_manager());
199                     permission.unwrap()
200                 }
201             };
202             match permission {
203                 ManagerPermission::ManagerAll => {}
204                 ManagerPermission::ManagerDownLoad => {
205                     let Some(action) = RequestDb::get_instance().query_task_action(task_id) else {
206                         return Err(ErrorCode::TaskNotFound);
207                     };
208                     if action != Action::Download {
209                         return Err(ErrorCode::Permission);
210                     }
211                 }
212                 ManagerPermission::ManagerUpload => {
213                     let Some(action) = RequestDb::get_instance().query_task_action(task_id) else {
214                         return Err(ErrorCode::TaskNotFound);
215                     };
216                     if action != Action::Upload {
217                         return Err(ErrorCode::Permission);
218                     }
219                 }
220                 ManagerPermission::NoPermission => {
221                     return Err(ErrorCode::Permission);
222                 }
223             }
224         }
225         NotificationDispatcher::get_instance().disable_task_notification(task_uid, task_id);
226         Ok(())
227     }
228 }
229