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 //! This create implement the request server register and publish
14
15 use std::mem::MaybeUninit;
16 use std::sync::atomic::{AtomicBool, Ordering};
17 use std::sync::{Arc, Mutex};
18
19 use hisysevent::{build_number_param, write, EventType};
20 use samgr::definition::APP_MGR_SERVICE_ID;
21 use samgr::manage::SystemAbilityManager;
22 use system_ability_fwk::ability::{Ability, Handler};
23
24 use crate::manage::app_state::AppStateListener;
25 use crate::manage::database::RequestDb;
26 use crate::manage::{account, SystemConfigManager, TaskManager};
27 use crate::service::client::ClientManager;
28 use crate::service::run_count::RunCountManager;
29 pub(crate) static mut PANIC_INFO: Option<String> = None;
30 use crate::manage::events::TaskManagerEvent;
31 use crate::manage::task_manager::TaskManagerTx;
32 use crate::service::RequestServiceStub;
33
34 /// TEST_SERVICE_ID SAID
35 pub(crate) static mut SYSTEM_CONFIG_MANAGER: MaybeUninit<SystemConfigManager> =
36 MaybeUninit::uninit();
37
service_start_fault()38 fn service_start_fault() {
39 const DOMAIN: &str = "REQUEST";
40 const SERVICE_START_FAULT: &str = "SERVICE_START_FAULT";
41 const ERROR_INFO: &str = "ERROR_INFO";
42 const DOWNLOAD_PUBLISH_FAIL: i32 = -1;
43
44 write(
45 DOMAIN,
46 SERVICE_START_FAULT,
47 EventType::Fault,
48 &[build_number_param!(ERROR_INFO, DOWNLOAD_PUBLISH_FAIL)],
49 );
50 }
51
52 /// request ability
53 pub struct RequestAbility {
54 task_manager: Mutex<Option<TaskManagerTx>>,
55 remote_busy: Arc<AtomicBool>,
56 }
57
58 impl RequestAbility {
59 /// new request ability
new() -> Self60 pub fn new() -> Self {
61 Self {
62 remote_busy: Arc::new(AtomicBool::new(false)),
63 task_manager: Mutex::new(None),
64 }
65 }
66
init(&self, handler: Handler)67 fn init(&self, handler: Handler) {
68 info!("ability init");
69
70 std::panic::set_hook(Box::new(|info| unsafe {
71 let info = info.to_string();
72 error!("{}", info);
73 PANIC_INFO = Some(info);
74 }));
75
76 ylong_runtime::builder::RuntimeBuilder::new_multi_thread()
77 .worker_num(4)
78 .build_global()
79 .unwrap();
80 info!("ylong_runtime init ok");
81
82 let runcount_manager = RunCountManager::init();
83 info!("runcount_manager init ok");
84
85 let client_manger = ClientManager::init();
86 info!("client_manger init ok");
87
88 unsafe { SYSTEM_CONFIG_MANAGER.write(SystemConfigManager::init()) };
89 info!("system_config_manager init ok");
90
91 let task_manager = TaskManager::init(runcount_manager.clone(), client_manger.clone());
92
93 *self.task_manager.lock().unwrap() = Some(task_manager.clone());
94
95 info!("task_manager init ok");
96
97 AppStateListener::init(client_manger.clone(), task_manager.clone());
98
99 SystemAbilityManager::subscribe_system_ability(
100 APP_MGR_SERVICE_ID,
101 |_, _| {
102 info!("app manager service init");
103 AppStateListener::register();
104 },
105 |_, _| {
106 error!("app manager service died");
107 },
108 );
109
110 let stub = RequestServiceStub::new(
111 handler.clone(),
112 task_manager,
113 client_manger,
114 runcount_manager,
115 self.remote_busy.clone(),
116 );
117
118 info!("ability init succeed");
119 if !handler.publish(stub) {
120 service_start_fault();
121 }
122 }
123 }
124
125 impl Ability for RequestAbility {
on_start_with_reason( &self, reason: system_ability_fwk::cxx_share::SystemAbilityOnDemandReason, handler: Handler, )126 fn on_start_with_reason(
127 &self,
128 reason: system_ability_fwk::cxx_share::SystemAbilityOnDemandReason,
129 handler: Handler,
130 ) {
131 info!("on_start_with_reason: {:?}", reason);
132 if reason.name == "usual.event.USER_REMOVED" {
133 let user_id = reason.value.parse::<i32>().unwrap();
134 account::remove_account_tasks(user_id);
135 self.init(handler);
136 } else {
137 self.init(handler);
138 }
139 }
140
on_active(&self, reason: system_ability_fwk::cxx_share::SystemAbilityOnDemandReason)141 fn on_active(&self, reason: system_ability_fwk::cxx_share::SystemAbilityOnDemandReason) {
142 info!("on_active: {:?}", reason);
143 }
144
on_idle(&self, _reason: system_ability_fwk::cxx_share::SystemAbilityOnDemandReason) -> i32145 fn on_idle(&self, _reason: system_ability_fwk::cxx_share::SystemAbilityOnDemandReason) -> i32 {
146 if self.remote_busy.load(Ordering::Acquire) {
147 info!("remote is busy reject idle");
148 -1
149 } else {
150 info!("remote is not busy, accept idle");
151 RequestDb::get_instance().delete_early_records();
152 0
153 }
154 }
155
on_device_level_changed(&self, change_type: i32, level: i32, action: String)156 fn on_device_level_changed(&self, change_type: i32, level: i32, action: String) {
157 info!(
158 "on_device_level_changed type {} level {} action {}",
159 change_type, level, action
160 );
161 if let Some(task_manager) = self.task_manager.lock().unwrap().as_ref() {
162 task_manager.send_event(TaskManagerEvent::Device(level));
163 }
164 }
165 }
166
167 #[cfg(not(test))]
168 #[used]
169 #[link_section = ".init_array"]
170 static A: extern "C" fn() = {
171 #[link_section = "..text.startup"]
init()172 extern "C" fn init() {
173 info!("begin request service init");
174 let system_ability = RequestAbility::new()
175 .build_system_ability(samgr::definition::DOWNLOAD_SERVICE_ID, false)
176 .unwrap();
177 system_ability.register();
178 info!("request service inited");
179 }
180 init
181 };
182