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::error::ErrorCode; 18 use crate::manage::database::RequestDb; 19 use crate::manage::events::TaskManagerEvent; 20 use crate::service::command::{set_code_with_index, CONTROL_MAX}; 21 use crate::service::permission::PermissionChecker; 22 use crate::service::RequestServiceStub; 23 24 impl RequestServiceStub { stop(&self, data: &mut MsgParcel, reply: &mut MsgParcel) -> IpcResult<()>25 pub(crate) fn stop(&self, data: &mut MsgParcel, reply: &mut MsgParcel) -> IpcResult<()> { 26 info!("Service stop"); 27 let permission = PermissionChecker::check_down_permission(); 28 let len: u32 = data.read()?; 29 let len = len as usize; 30 let mut vec = vec![ErrorCode::Other; len]; 31 32 if len > CONTROL_MAX { 33 info!("Service stop: out of size: {}", len); 34 reply.write(&(ErrorCode::Other as i32))?; 35 return Err(IpcStatusCode::Failed); 36 } 37 38 let uid = ipc::Skeleton::calling_uid(); 39 for i in 0..len { 40 let task_id: String = data.read()?; 41 info!("Service stop tid {}", task_id); 42 43 let Ok(task_id) = task_id.parse::<u32>() else { 44 error!("Service stop, failed: tid not valid: {}", task_id); 45 sys_event!( 46 ExecError, 47 DfxCode::INVALID_IPC_MESSAGE_A16, 48 &format!("Service stop, failed: tid not valid: {}", task_id) 49 ); 50 set_code_with_index(&mut vec, i, ErrorCode::TaskNotFound); 51 continue; 52 }; 53 54 let mut uid = uid; 55 if permission { 56 // skip uid check if task used by innerkits 57 info!("{} stop permission inner", task_id); 58 match RequestDb::get_instance().query_task_uid(task_id) { 59 Some(id) => uid = id, 60 None => { 61 set_code_with_index(&mut vec, i, ErrorCode::TaskNotFound); 62 continue; 63 } 64 }; 65 } else if !self.check_task_uid(task_id, uid) { 66 set_code_with_index(&mut vec, i, ErrorCode::TaskNotFound); 67 error!( 68 "Service stop, failed: check task uid. tid: {}, uid: {}", 69 task_id, uid 70 ); 71 sys_event!( 72 ExecError, 73 DfxCode::INVALID_IPC_MESSAGE_A16, 74 &format!( 75 "Service stop, failed: check task uid. tid: {}, uid: {}", 76 task_id, uid 77 ) 78 ); 79 continue; 80 } 81 82 let (event, rx) = TaskManagerEvent::stop(uid, task_id); 83 if !self.task_manager.lock().unwrap().send_event(event) { 84 error!("Service stop, failed: task_manager err: {}", task_id); 85 set_code_with_index(&mut vec, i, ErrorCode::Other); 86 continue; 87 } 88 let ret = match rx.get() { 89 Some(ret) => ret, 90 None => { 91 error!( 92 "Service stop, tid: {}, failed: receives ret failed", 93 task_id 94 ); 95 set_code_with_index(&mut vec, i, ErrorCode::Other); 96 continue; 97 } 98 }; 99 set_code_with_index(&mut vec, i, ret); 100 if ret != ErrorCode::ErrOk { 101 error!("Service stop, tid: {}, failed: {}", task_id, ret as i32); 102 sys_event!( 103 ExecError, 104 DfxCode::INVALID_IPC_MESSAGE_A16, 105 &format!("Service stop, tid: {}, failed: {}", task_id, ret as i32) 106 ); 107 } 108 } 109 110 reply.write(&(ErrorCode::ErrOk as i32))?; 111 for ret in vec { 112 reply.write(&(ret as i32))?; 113 } 114 Ok(()) 115 } 116 } 117