• 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::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