1// Copyright (C) 2024 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
14use cxx::{let_cxx_string, UniquePtr};
15use ipc::parcel::MsgParcel;
16use ipc::remote::{RemoteObj, RemoteStub};
17
18use crate::wrapper::{
19    GetCommonEventExtraDataIdlist,
20    AbilityStub, AddOnDemandSystemAbilityInfo, AddSystemAbility, AddSystemAbilityConfig,
21    CancelUnloadSystemAbility, CheckSystemAbility, CheckSystemAbilityWithDeviceId,
22    GetContextManager, GetOnDemandReasonExtraData, GetRunningSystemProcess, GetSystemAbility,
23    GetSystemAbilityWithDeviceId, GetSystemProcessInfo, ListSystemAbilities,
24    ListSystemAbilitiesWithDumpFlag, LoadSystemAbility, LoadSystemAbilityWithCallback,
25    RemoveSystemAbility, SendStrategy, SubscribeSystemAbility, SubscribeSystemProcess,
26    SystemProcessInfo, UnSubscribeSystemAbilityHandler, UnSubscribeSystemProcessHandler,
27    UnloadAllIdleSystemAbility, UnloadSystemAbility,
28};
29use crate::DumpFlagPriority;
30
31pub struct SystemAbilityManager;
32
33unsafe impl Sync for SystemAbilityManager {}
34unsafe impl Send for SystemAbilityManager {}
35
36impl SystemAbilityManager {
37    /// # Example
38    /// ```rust
39    /// use samgr::manage::SystemAbilityManager;
40    ///
41    /// let context = SystemAbilityManager::get_context_manager();
42    /// ```
43    pub fn get_context_manager() -> Option<RemoteObj> {
44        info!("get context manager");
45        RemoteObj::from_sptr(GetContextManager())
46    }
47
48    /// let abilities = sysm.list_system_ability();
49    ///
50    ///
51    /// # Example
52    /// ```rust
53    /// ```
54    pub fn list_system_abilities() -> Vec<String> {
55        info!("list system ability");
56        ListSystemAbilities()
57    }
58    /// let abilities = sysm.list_system_ability();
59    ///
60    ///
61    /// # Example
62    /// ```rust
63    /// ```
64    pub fn list_system_abilities_with_dump_flag(dump_flag: DumpFlagPriority) -> Vec<String> {
65        info!("list system ability");
66        ListSystemAbilitiesWithDumpFlag(dump_flag as u32)
67    }
68
69    /// # Example
70    /// ```rust
71    /// use samgr::manage::SystemAbilityManager;
72    ///
73    /// let request_abilty = SystemAbilityManager::get_system_ability(3706, None);
74    /// ```
75    pub fn get_system_ability(said: i32) -> Option<RemoteObj> {
76        info!("get system ability {}", said);
77        RemoteObj::from_sptr(GetSystemAbility(said))
78    }
79
80    /// # Example
81    /// ```rust
82    /// use samgr::manage::SystemAbilityManager;
83    /// ```
84    pub fn get_system_ability_with_device_id(said: i32, device_id: &str) -> Option<RemoteObj> {
85        info!("get system ability {} with device id", said);
86        let_cxx_string!(id = device_id);
87        RemoteObj::from_sptr(GetSystemAbilityWithDeviceId(said, &id))
88    }
89
90    /// # Example
91    /// ```rust
92    /// use samgr::definition::DOWNLOAD_SERVICE_ID;
93    /// use samgr::manage::SystemAbilityManager;
94    ///
95    /// let download_service = SystemAbilityManager::check_system_ability(DOWNLOAD_SERVICE_ID).unwrap();
96    /// ```
97    pub fn check_system_ability(said: i32) -> Option<RemoteObj> {
98        info!("check system ability {}", said);
99
100        RemoteObj::from_sptr(CheckSystemAbility(said))
101    }
102
103    pub fn check_system_ability_with_ability(said: i32, device_id: &str) -> Option<RemoteObj> {
104        info!("check system ability {} with device id", said);
105        let_cxx_string!(id = device_id);
106        RemoteObj::from_sptr(CheckSystemAbilityWithDeviceId(said, &id))
107    }
108
109    /// # Example
110    /// ```rust
111    /// use samgr::definition::DOWNLOAD_SERVICE_ID;
112    /// use samgr::manage::SystemAbilityManager;
113    ///
114    /// SystemAbilityManager::remove_system_ability(DOWNLOAD_SERVICE_IDD);
115    /// ```
116    pub fn remove_system_ability(said: i32) -> i32 {
117        info!("remove system ability {}", said);
118        RemoveSystemAbility(said)
119    }
120
121    /// Adds a new system ability
122    pub fn add_systemability<A: RemoteStub + 'static>(said: i32, ability: A) -> i32 {
123        info!("add system ability {}", said);
124        let is_distributed = false;
125        let dump_flags = DumpFlagPriority::Default;
126        let capability = "";
127        let permission = "";
128        let stub = AbilityStub::new(ability);
129        AddSystemAbility(
130            said,
131            Box::new(stub),
132            AddSystemAbilityConfig {
133                is_distributed,
134                dump_flags: dump_flags as u32,
135                capability: capability.to_string(),
136                permission: permission.to_string(),
137            },
138        )
139    }
140
141    pub fn add_systemability_with_extra<A: RemoteStub + 'static>(
142        said: i32,
143        ability: A,
144        is_distributed: bool,
145        dump_flags: DumpFlagPriority,
146        capability: &str,
147        permission: &str,
148    ) -> i32 {
149        info!("add system ability {}", said);
150        let stub = AbilityStub::new(ability);
151        AddSystemAbility(
152            said,
153            Box::new(stub),
154            AddSystemAbilityConfig {
155                is_distributed,
156                dump_flags: dump_flags as u32,
157                capability: capability.to_string(),
158                permission: permission.to_string(),
159            },
160        )
161    }
162
163    pub fn load_system_ability(said: i32, timeout: i32) -> Option<RemoteObj> {
164        info!("load system ability {}", said);
165        RemoteObj::from_sptr(LoadSystemAbility(said, timeout))
166    }
167
168    pub fn load_system_ability_with_callback(said: i32, on_success: fn(), on_fail: fn()) -> i32 {
169        info!("load system ability {}", said);
170        LoadSystemAbilityWithCallback(said, on_success, on_fail)
171    }
172
173    pub fn subscribe_system_ability(
174        said: i32,
175        on_add: fn(i32, &str),
176        on_remove: fn(i32, &str),
177    ) -> UnsubscribeHandler {
178        info!("subscribe system ability {}", said);
179        UnsubscribeHandler::new(Unsubscribe::Ability(SubscribeSystemAbility(
180            said, on_add, on_remove,
181        )))
182    }
183
184    /// # Example
185    /// ```rust
186    /// use samgr::definition::DOWNLOAD_SERVICE_ID;
187    /// use samgr::manage::SystemAbilityManager;
188    ///
189    /// SystemAbilityManager::remove_system_ability(DOWNLOAD_SERVICE_IDD);
190    /// ```
191    pub fn add_ondemand_system_ability_info(said: i32, local_ability_manager_name: &str) -> i32 {
192        info!("add ondemand system ability {} info", said);
193
194        AddOnDemandSystemAbilityInfo(said, local_ability_manager_name)
195    }
196
197    pub fn unload_system_ability(said: i32) -> i32 {
198        info!("unload system ability {}", said);
199        UnloadSystemAbility(said)
200    }
201
202    pub fn cancel_unload_system_ability(said: i32) -> i32 {
203        info!("cancel unload system ability {}", said);
204        CancelUnloadSystemAbility(said)
205    }
206
207    /// # Example
208    /// ```rust
209    /// use samgr::definition::DOWNLOAD_SERVICE_ID;
210    ///
211    /// SystemAbilityManager::unload_all_idle_system_ability();
212    /// ```
213    pub fn unload_all_idle_system_ability(&self) -> i32 {
214        info!("unload all idle system ability");
215        UnloadAllIdleSystemAbility()
216    }
217
218    pub fn get_system_process_info(said: i32) -> SystemProcessInfo {
219        info!("get system ability {} process info", said);
220        GetSystemProcessInfo(said)
221    }
222
223    pub fn get_running_system_process() -> Vec<SystemProcessInfo> {
224        info!("get running system ability process info");
225        GetRunningSystemProcess()
226    }
227
228    ///
229    pub fn send_strategy(s_type: i32, saids: Vec<i32>, level: i32, action: &str) -> i32 {
230        let_cxx_string!(action = action);
231        SendStrategy(s_type, saids, level, action)
232    }
233
234    pub fn get_common_event_extra_data_id_list(said: i32, extraids: &mut Vec<i64>, event_name: &str) -> i32 {
235        let_cxx_string!(event_name = event_name);
236        GetCommonEventExtraDataIdlist(said, extraids, &event_name)
237    }
238
239    pub fn subscribe_system_process(
240        on_start: fn(&SystemProcessInfo),
241        on_stop: fn(&SystemProcessInfo),
242    ) -> UnsubscribeHandler {
243        UnsubscribeHandler::new(Unsubscribe::Process(SubscribeSystemProcess(
244            on_start, on_stop,
245        )))
246    }
247
248    pub fn get_on_demand_reason_extra_date(extra_data_id: i64, parcel: &mut MsgParcel) -> i32 {
249        GetOnDemandReasonExtraData(extra_data_id, parcel.pin_mut().unwrap())
250    }
251}
252
253enum Unsubscribe {
254    Ability(UniquePtr<UnSubscribeSystemAbilityHandler>),
255    Process(UniquePtr<UnSubscribeSystemProcessHandler>),
256}
257
258pub struct UnsubscribeHandler {
259    inner: Unsubscribe,
260}
261
262impl UnsubscribeHandler {
263    fn new(inner: Unsubscribe) -> Self {
264        Self { inner }
265    }
266
267    pub fn unsubscribe(self) {
268        match self.inner {
269            Unsubscribe::Ability(mut p) => p.pin_mut().UnSubscribe(),
270            Unsubscribe::Process(mut p) => p.pin_mut().UnSubscribe(),
271        }
272    }
273}
274