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 #include "dm_publish_common_event.h"
17 
18 #include <pthread.h>
19 #include <thread>
20 #ifdef SUPPORT_BLUETOOTH
21 #include "bluetooth_def.h"
22 #endif // SUPPORT_BLUETOOTH
23 #include "common_event_support.h"
24 #include "iservice_registry.h"
25 #include "system_ability_definition.h"
26 #ifdef SUPPORT_WIFI
27 #include "wifi_msg.h"
28 #endif // SUPPORT_WIFI
29 #include "dm_log.h"
30 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
31 #include "ffrt.h"
32 #endif
33 
34 namespace OHOS {
35 namespace DistributedHardware {
36 using OHOS::EventFwk::MatchingSkills;
37 using OHOS::EventFwk::CommonEventManager;
38 
39 #if (defined(__LITEOS_M__) || defined(LITE_DEVICE))
40 constexpr const char* DEAL_THREAD = "publish_common_event";
41 #endif
42 constexpr int32_t MAX_TRY_TIMES = 3;
43 
GetSubscriberEventNameVec() const44 std::vector<std::string> DmPublishEventSubscriber::GetSubscriberEventNameVec() const
45 {
46     return eventNameVec_;
47 }
48 
~DmPublishCommonEventManager()49 DmPublishCommonEventManager::~DmPublishCommonEventManager()
50 {
51     DmPublishCommonEventManager::UnsubscribePublishCommonEvent();
52 }
53 
SubscribePublishCommonEvent(const std::vector<std::string> & eventNameVec,const PublishEventCallback & callback)54 bool DmPublishCommonEventManager::SubscribePublishCommonEvent(const std::vector<std::string> &eventNameVec,
55     const PublishEventCallback &callback)
56 {
57     if (eventNameVec.empty() || callback == nullptr) {
58         LOGE("eventNameVec is empty or callback is nullptr.");
59         return false;
60     }
61     std::lock_guard<std::mutex> locker(evenSubscriberMutex_);
62     if (eventValidFlag_) {
63         LOGE("failed to subscribe ble/wifi/screen commom eventName size: %{public}zu", eventNameVec.size());
64         return false;
65     }
66 
67     MatchingSkills matchingSkills;
68     for (auto &item : eventNameVec) {
69         matchingSkills.AddEvent(item);
70     }
71     CommonEventSubscribeInfo subscriberInfo(matchingSkills);
72     subscriber_ = std::make_shared<DmPublishEventSubscriber>(subscriberInfo, callback, eventNameVec);
73     auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
74     if (samgrProxy == nullptr) {
75         LOGE("samgrProxy is nullptr");
76         subscriber_ = nullptr;
77         return false;
78     }
79     statusChangeListener_ = new (std::nothrow) SystemAbilityStatusChangeListener(subscriber_);
80     if (statusChangeListener_ == nullptr) {
81         LOGE("statusChangeListener_ is nullptr");
82         subscriber_ = nullptr;
83         return false;
84     }
85     while (counter_ != MAX_TRY_TIMES) {
86         if (samgrProxy->SubscribeSystemAbility(COMMON_EVENT_SERVICE_ID, statusChangeListener_) == ERR_OK) {
87             LOGI("SubscribeServiceEvent success.");
88             counter_ = 0;
89             break;
90         }
91         if (++counter_ == MAX_TRY_TIMES) {
92             LOGI("SubscribeServiceEvent failed.");
93         }
94         sleep(1);
95     }
96     eventNameVec_ = eventNameVec;
97     eventValidFlag_ = true;
98     SetSubscriber(subscriber_);
99     LOGI("success to subscribe ble/wifi/screen commom event name size: %{public}zu", eventNameVec.size());
100     return true;
101 }
102 
UnsubscribePublishCommonEvent()103 bool DmPublishCommonEventManager::UnsubscribePublishCommonEvent()
104 {
105     std::lock_guard<std::mutex> locker(evenSubscriberMutex_);
106     if (!eventValidFlag_) {
107         LOGE("failed to unsubscribe ble/wifi/screen commom event name size: %{public}zu because event is invalid.",
108             eventNameVec_.size());
109         return false;
110     }
111     if (subscriber_ != nullptr) {
112         LOGI("start to unsubscribe commom event name size: %{public}zu", eventNameVec_.size());
113         if (!CommonEventManager::UnSubscribeCommonEvent(subscriber_)) {
114             LOGE("failed to unsubscribe ble/wifi/screen commom event name size: %{public}zu", eventNameVec_.size());
115             return false;
116         }
117         LOGI("success to unsubscribe ble/wifi/screen commom event name size: %{public}zu", eventNameVec_.size());
118         subscriber_ = nullptr;
119     }
120     if (statusChangeListener_ != nullptr) {
121         auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
122         if (samgrProxy == nullptr) {
123             LOGE("samgrProxy is nullptr");
124             return false;
125         }
126         int32_t ret = samgrProxy->UnSubscribeSystemAbility(COMMON_EVENT_SERVICE_ID, statusChangeListener_);
127         if (ret != ERR_OK) {
128             LOGE("failed to unsubscribe system ability COMMON_EVENT_SERVICE_ID ret:%{public}d", ret);
129             return false;
130         }
131         statusChangeListener_ = nullptr;
132     }
133 
134     LOGI("success to unsubscribe ble/wifi/screen commom event name size: %{public}zu", eventNameVec_.size());
135     eventValidFlag_ = false;
136     return true;
137 }
138 
SetSubscriber(std::shared_ptr<DmPublishEventSubscriber> subscriber)139 void DmPublishCommonEventManager::SetSubscriber(std::shared_ptr<DmPublishEventSubscriber> subscriber)
140 {
141     std::lock_guard<std::mutex> lock(subscriberMutex_);
142     subscriber_ = subscriber;
143 }
144 
GetSubscriber()145 std::shared_ptr<DmPublishEventSubscriber> DmPublishCommonEventManager::GetSubscriber()
146 {
147     std::lock_guard<std::mutex> lock(subscriberMutex_);
148     return subscriber_;
149 }
150 
SetWifiState(const int32_t wifiState)151 void DmPublishEventSubscriber::SetWifiState(const int32_t wifiState)
152 {
153     std::lock_guard<std::mutex> lock(wifiStateMutex_);
154     wifiState_ = wifiState;
155 }
156 
GetWifiState()157 int32_t DmPublishEventSubscriber::GetWifiState()
158 {
159     std::lock_guard<std::mutex> lock(wifiStateMutex_);
160     return wifiState_;
161 }
162 
SetBluetoothState(const int32_t bluetoothState)163 void DmPublishEventSubscriber::SetBluetoothState(const int32_t bluetoothState)
164 {
165     std::lock_guard<std::mutex> lock(bluetoothStateMutex_);
166     bluetoothState_ = bluetoothState;
167 }
168 
GetBluetoothState()169 int32_t DmPublishEventSubscriber::GetBluetoothState()
170 {
171     std::lock_guard<std::mutex> lock(bluetoothStateMutex_);
172     return bluetoothState_;
173 }
174 
SetScreenState(const int32_t screenState)175 void DmPublishEventSubscriber::SetScreenState(const int32_t screenState)
176 {
177     std::lock_guard<std::mutex> lock(screenStateMutex_);
178     screenState_ = screenState;
179 }
180 
GetScreenState()181 int32_t DmPublishEventSubscriber::GetScreenState()
182 {
183     std::lock_guard<std::mutex> lock(screenStateMutex_);
184     return screenState_;
185 }
186 
SetScreenEventState(const std::string & receiveEvent)187 void DmPublishEventSubscriber::SetScreenEventState(const std::string &receiveEvent)
188 {
189     std::lock_guard<std::mutex> lock(screenStateMutex_);
190 #ifdef SUPPORT_POWER_MANAGER
191     if (receiveEvent == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON) {
192         screenState_ = DM_SCREEN_ON;
193     } else if (receiveEvent == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF) {
194         screenState_ = DM_SCREEN_OFF;
195     }
196 #else
197     screenState_ = DM_SCREEN_ON;
198 #endif // SUPPORT_POWER_MANAGER
199 }
200 
OnReceiveEvent(const CommonEventData & data)201 void DmPublishEventSubscriber::OnReceiveEvent(const CommonEventData &data)
202 {
203     std::string receiveEvent = data.GetWant().GetAction();
204     int32_t eventState = data.GetCode();
205     LOGI("On Received receiveEvent: %{public}s, eventState: %{public}d", receiveEvent.c_str(), eventState);
206     SetScreenEventState(receiveEvent);
207 
208 #ifdef SUPPORT_BLUETOOTH
209     {
210         std::lock_guard<std::mutex> lock(bluetoothStateMutex_);
211         if (receiveEvent == EventFwk::CommonEventSupport::COMMON_EVENT_BLUETOOTH_HOST_STATE_UPDATE &&
212             eventState == static_cast<int32_t>(Bluetooth::BTStateID::STATE_TURN_ON)) {
213             bluetoothState_ = static_cast<int32_t>(Bluetooth::BTStateID::STATE_TURN_ON);
214         } else if (receiveEvent == EventFwk::CommonEventSupport::COMMON_EVENT_BLUETOOTH_HOST_STATE_UPDATE &&
215             eventState == static_cast<int32_t>(Bluetooth::BTStateID::STATE_TURN_OFF)) {
216             bluetoothState_ = static_cast<int32_t>(Bluetooth::BTStateID::STATE_TURN_OFF);
217         } else if (receiveEvent == EventFwk::CommonEventSupport::COMMON_EVENT_BLUETOOTH_HOST_STATE_UPDATE) {
218             LOGI("bluetooth eventState: %{public}d", eventState);
219             return;
220         }
221     }
222 #endif // SUPPORT_BLUETOOTH
223 
224 #ifdef SUPPORT_WIFI
225     {
226         std::lock_guard<std::mutex> lock(wifiStateMutex_);
227         if (receiveEvent == EventFwk::CommonEventSupport::COMMON_EVENT_WIFI_POWER_STATE &&
228             eventState == static_cast<int32_t>(OHOS::Wifi::WifiState::ENABLED)) {
229             wifiState_ = static_cast<int32_t>(OHOS::Wifi::WifiState::ENABLED);
230         } else if (receiveEvent == EventFwk::CommonEventSupport::COMMON_EVENT_WIFI_POWER_STATE &&
231             eventState == static_cast<int32_t>(OHOS::Wifi::WifiState::DISABLED)) {
232             wifiState_ = static_cast<int32_t>(OHOS::Wifi::WifiState::DISABLED);
233         } else if (receiveEvent == EventFwk::CommonEventSupport::COMMON_EVENT_WIFI_POWER_STATE) {
234             LOGI("wifi eventState: %{public}d", eventState);
235             return;
236         }
237     }
238 #endif // SUPPORT_WIFI
239 
240 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
241     ffrt::submit([=]() { callback_(bluetoothState_, wifiState_, screenState_); });
242 #else
243     std::thread dealThread([=]() { callback_(bluetoothState_, wifiState_, screenState_); });
244     int32_t ret = pthread_setname_np(dealThread.native_handle(), DEAL_THREAD);
245     if (ret != DM_OK) {
246         LOGE("dealThread setname failed.");
247     }
248     dealThread.detach();
249 #endif
250 }
251 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)252 void DmPublishCommonEventManager::SystemAbilityStatusChangeListener::OnAddSystemAbility(
253     int32_t systemAbilityId, const std::string& deviceId)
254 {
255     LOGI("systemAbility is added with said: %{public}d.", systemAbilityId);
256     if (systemAbilityId != COMMON_EVENT_SERVICE_ID) {
257         return;
258     }
259     if (changeSubscriber_ == nullptr) {
260         LOGE("failed to subscribe ble/wifi/screen commom event because changeSubscriber_ is nullptr.");
261         return;
262     }
263     std::vector<std::string> eventNameVec = changeSubscriber_->GetSubscriberEventNameVec();
264     LOGI("start to subscribe ble/wifi/screen commom eventName: %{public}zu", eventNameVec.size());
265     if (!CommonEventManager::SubscribeCommonEvent(changeSubscriber_)) {
266         LOGE("failed to subscribe ble/wifi/screen commom event: %{public}zu", eventNameVec.size());
267         return;
268     }
269 }
270 
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)271 void DmPublishCommonEventManager::SystemAbilityStatusChangeListener::OnRemoveSystemAbility(
272     int32_t systemAbilityId, const std::string& deviceId)
273 {
274     LOGI("systemAbility is removed with said: %{public}d.", systemAbilityId);
275 }
276 } // namespace DistributedHardware
277 } // namespace OHOS
278