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