1 /*
2  * Copyright (c) 2023 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 #include "system_ability_wrapper.h"
17 
18 #include <unistd.h>
19 
20 #include "if_system_ability_manager.h"
21 #include "iservice_registry.h"
22 #include "system_ability_definition.h"
23 #include "system_ability_status_change_stub.h"
24 
25 #include "asset_log.h"
26 #include "system_event_wrapper.h"
27 
28 namespace {
29 const int32_t RETRY_TIMES_FOR_SAMGR = 50;
30 const int32_t RETRY_DURATION_US = 200 * 1000;
31 
32 class SystemAbilityHandler : public OHOS::SystemAbilityStatusChangeStub {
33 public:
SystemAbilityHandler(const EventCallBack eventCallBack)34     explicit SystemAbilityHandler(const EventCallBack eventCallBack) : eventCallBack(eventCallBack) {};
35     ~SystemAbilityHandler() = default;
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)36     void OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override
37     {
38         if (systemAbilityId != OHOS::COMMON_EVENT_SERVICE_ID) {
39             return;
40         }
41 
42         if (SubscribeSystemEvent(eventCallBack)) {
43             LOGI("Subscribe system event success.");
44         } else {
45             LOGE("Subscribe system event failed.");
46         }
47     }
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)48     void OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId) override
49     {
50         if (systemAbilityId != OHOS::COMMON_EVENT_SERVICE_ID) {
51             return;
52         }
53         if (UnSubscribeSystemEvent()) {
54             LOGI("UnSubscribe system event success.");
55         } else {
56             LOGE("UnSubscribe system event failed.");
57         }
58     }
59 private:
60     const EventCallBack eventCallBack;
61 };
62 
GetSystemAbility(void)63 OHOS::sptr<OHOS::ISystemAbilityManager> GetSystemAbility(void)
64 {
65     int32_t retryCount = RETRY_TIMES_FOR_SAMGR;
66     OHOS::sptr<OHOS::ISystemAbilityManager> samgrProxy =
67         OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
68     while (samgrProxy == nullptr && retryCount > 0) {
69         usleep(RETRY_DURATION_US);
70         samgrProxy = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
71         retryCount--;
72     }
73     return samgrProxy;
74 }
75 
76 OHOS::sptr<SystemAbilityHandler> abilityHandler;
77 } // namespace
78 
SubscribeSystemAbility(const EventCallBack eventCallBack)79 bool SubscribeSystemAbility(const EventCallBack eventCallBack)
80 {
81     OHOS::sptr<OHOS::ISystemAbilityManager> samgrProxy = GetSystemAbility();
82     if (samgrProxy == nullptr) {
83         LOGE("Get system ability failed");
84         return false;
85     }
86 
87     abilityHandler = new (std::nothrow) SystemAbilityHandler(eventCallBack);
88     if (abilityHandler == nullptr) {
89         LOGE("Create system ability handler failed.");
90         return false;
91     }
92 
93     int32_t ret = samgrProxy->SubscribeSystemAbility(OHOS::COMMON_EVENT_SERVICE_ID, abilityHandler);
94     if (ret != OHOS::ERR_OK) {
95         LOGE("Subscribe system ability failed.");
96         return false;
97     }
98     return true;
99 }
100 
UnSubscribeSystemAbility()101 bool UnSubscribeSystemAbility()
102 {
103     OHOS::sptr<OHOS::ISystemAbilityManager> samgrProxy = GetSystemAbility();
104     if (samgrProxy == nullptr || abilityHandler == nullptr) {
105         return false;
106     }
107 
108     if (samgrProxy->UnSubscribeSystemAbility(OHOS::COMMON_EVENT_SERVICE_ID, abilityHandler) != OHOS::ERR_OK ||
109         !UnSubscribeSystemEvent()) {
110         LOGE("UnSubscribe system ability or system event failed.");
111         return false;
112     }
113 
114     return true;
115 }