1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 //! This module is used to handle start event.
17 
18 use std::collections::HashMap;
19 
20 use asset_file_operator::de_operator::delete_user_de_dir;
21 use asset_log::{loge, logi};
22 use system_ability_fwk::cxx_share::SystemAbilityOnDemandReason;
23 
24 use crate::{common_event::listener, unload_handler::DELAYED_UNLOAD_TIME_IN_SEC, unload_sa};
25 
26 const USER_ID: &str = "userId";
27 const SANDBOX_APP_INDEX: &str = "sandbox_app_index";
28 const APP_ID: &str = "appId";
29 const BUNDLE_NAME: &str = "bundleName";
30 const APP_RESTORE_INDEX: &str = "index";
31 const APP_INDEX: &str = "appIndex";
32 
handle_package_removed(want: &HashMap<String, String>, is_sandbox: bool)33 fn handle_package_removed(want: &HashMap<String, String>, is_sandbox: bool) {
34     let Some(user_id) = want.get(USER_ID) else {
35         loge!("[FATIL]Get removed owner info failed, get userId fail");
36         return;
37     };
38     let Some(app_id) = want.get(APP_ID) else {
39         loge!("[FATIL]Get removed owner info failed, get appId fail");
40         return;
41     };
42 
43     let app_index_get_key = if is_sandbox { SANDBOX_APP_INDEX } else { APP_INDEX };
44     let app_index = match want.get(app_index_get_key) {
45         Some(v) => match v.parse::<i32>() {
46             Ok(parsed_value) => parsed_value,
47             Err(_) => {
48                 loge!("[FATAL]Get removed owner info failed, failed to parse appIndex");
49                 return;
50             },
51         },
52         None => {
53             loge!("[FATIL]Get removed owner info failed, get appIndex fail");
54             return;
55         },
56     };
57     let owner = format!("{}_{}", app_id, app_index);
58     let user_id = match user_id.parse::<i32>() {
59         Ok(parsed_value) => parsed_value,
60         Err(_) => {
61             loge!("[FATIL]Get removed user_id failed, failed to parse user_id");
62             return;
63         },
64     };
65     let Some(bundle_name) = want.get(BUNDLE_NAME) else {
66         loge!("[FATIL]Get restore app info failed, get bundle name failed.");
67         return;
68     };
69     let mut bundle_name = bundle_name.clone();
70     bundle_name.push('\0');
71     listener::on_package_removed(user_id, owner.as_ptr(), owner.len() as u32, bundle_name.as_ptr(), app_index);
72 }
73 
handle_common_event(reason: SystemAbilityOnDemandReason)74 pub(crate) fn handle_common_event(reason: SystemAbilityOnDemandReason) {
75     let reason_name: String = reason.name;
76     if reason_name == "usual.event.PACKAGE_REMOVED" {
77         let want = reason.extra_data.want();
78         handle_package_removed(&want, false);
79     } else if reason_name == "usual.event.SANDBOX_PACKAGE_REMOVED" {
80         let want = reason.extra_data.want();
81         handle_package_removed(&want, true);
82     } else if reason_name == "usual.event.USER_REMOVED" {
83         logi!("on_start by user remove");
84         let _ = delete_user_de_dir(reason.extra_data.code);
85         listener::notify_on_user_removed(reason.extra_data.code);
86     } else if reason_name == "usual.event.CHARGING" {
87         listener::backup_db();
88     } else if reason_name == "usual.event.RESTORE_START" {
89         let want = reason.extra_data.want();
90         let user_id = match want.get(USER_ID) {
91             Some(v) => match v.parse::<i32>() {
92                 Ok(parsed_value) => parsed_value,
93                 Err(_) => {
94                     loge!("[FATIL]Get restore app info failed, failed to parse user_id");
95                     return;
96                 },
97             },
98             None => {
99                 loge!("[FATIL]Get restore app info failed, get userId fail");
100                 return;
101             },
102         };
103         let Some(bundle_name) = want.get(BUNDLE_NAME) else {
104             loge!("[FATIL]Get restore app info failed, get bundle name failed.");
105             return;
106         };
107         let mut bundle_name = bundle_name.clone();
108         bundle_name.push('\0');
109         let app_index = match want.get(APP_RESTORE_INDEX) {
110             Some(v) => match v.parse::<i32>() {
111                 Ok(parsed_value) => parsed_value,
112                 Err(_) => {
113                     loge!("[FATAL]Get restore app info failed, failed to parse appIndex");
114                     return;
115                 },
116             },
117             None => {
118                 loge!("[FATIL]Get restore app info failed, failed to get appIndex");
119                 return;
120             },
121         };
122         listener::on_app_restore(user_id, bundle_name.as_ptr(), app_index);
123     } else if reason_name == "usual.event.USER_UNLOCKED" {
124         listener::on_user_unlocked(reason.extra_data.code);
125     } else if reason_name == "loopevent" {
126         listener::on_schedule_wakeup();
127     } else if reason_name == "USER_PIN_CREATED_EVENT" {
128         logi!("[INFO]On user -{}- pin created.", reason.extra_data.code);
129         listener::on_user_unlocked(reason.extra_data.code);
130     }
131     logi!("[INFO]Finish handle common event. [{}]", reason_name);
132     unload_sa(DELAYED_UNLOAD_TIME_IN_SEC as u64);
133 }
134