1 /*
2  * Copyright (C) 2022 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 "accessibility_common_event.h"
17 #include <unistd.h>
18 #include "accessible_ability_manager_service.h"
19 #include "common_event_manager.h"
20 #include "common_event_support.h"
21 #include "hilog_wrapper.h"
22 
23 namespace OHOS {
24 namespace Accessibility {
25 namespace {
26     constexpr int32_t RETRY_SUBSCRIBER = 3;
27     const std::string KEY_USER_ID = "userId";
28 } // namespace
29 
AccessibilityCommonEvent()30 AccessibilityCommonEvent::AccessibilityCommonEvent()
31 {
32     HILOG_DEBUG();
33     handleEventFunc_[EventFwk::CommonEventSupport::COMMON_EVENT_USER_ADDED] =
34         &AccessibilityCommonEvent::HandleUserAdded;
35     handleEventFunc_[EventFwk::CommonEventSupport::COMMON_EVENT_USER_REMOVED] =
36         &AccessibilityCommonEvent::HandleUserRemoved;
37     handleEventFunc_[EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED] =
38         &AccessibilityCommonEvent::HandleUserSwitched;
39     handleEventFunc_[EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED] =
40         &AccessibilityCommonEvent::HandlePackageAdd;
41     handleEventFunc_[EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED] =
42         &AccessibilityCommonEvent::HandlePackageRemoved;
43     handleEventFunc_[EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED] =
44         &AccessibilityCommonEvent::HandlePackageChanged;
45 
46     for (auto it = handleEventFunc_.begin(); it != handleEventFunc_.end(); ++it) {
47         HILOG_DEBUG("Add event: %{public}s", it->first.c_str());
48         eventHandles_.emplace(it->first, [this, it](const OHOS::EventFwk::CommonEventData &eventId) {
49             auto requestFunc = it->second;
50             if (requestFunc != nullptr) {
51                 (this->*requestFunc)(eventId);
52             }
53         });
54     }
55 }
56 
~AccessibilityCommonEvent()57 AccessibilityCommonEvent::~AccessibilityCommonEvent()
58 {
59     UnSubscriberEvent();
60 }
61 
SubscriberEvent(const std::shared_ptr<AppExecFwk::EventHandler> & handler)62 void AccessibilityCommonEvent::SubscriberEvent(const std::shared_ptr<AppExecFwk::EventHandler> &handler)
63 {
64     HILOG_DEBUG();
65 
66     if (subscriber_) {
67         HILOG_DEBUG("Common Event is already subscribered!");
68         return;
69     }
70 
71     EventFwk::MatchingSkills matchingSkills;
72     for (auto &event : handleEventFunc_) {
73         HILOG_DEBUG("Add event: %{public}s", event.first.c_str());
74         matchingSkills.AddEvent(event.first);
75     }
76 
77     EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
78     subscriber_ = std::make_shared<AccessibilityCommonEventSubscriber>(subscribeInfo, *this);
79     eventHandler_ = handler;
80 
81     int32_t retry = RETRY_SUBSCRIBER;
82     do {
83         bool subscribeResult = EventFwk::CommonEventManager::SubscribeCommonEvent(subscriber_);
84         if (subscribeResult) {
85             HILOG_INFO("SubscriberEvent success.");
86             return;
87         } else {
88             HILOG_DEBUG("SubscriberEvent failed, retry %{public}d", retry);
89             retry--;
90             sleep(1);
91         }
92     } while (retry);
93 
94     HILOG_ERROR("SubscriberEvent failed.");
95 }
96 
UnSubscriberEvent()97 void AccessibilityCommonEvent::UnSubscriberEvent()
98 {
99     HILOG_INFO();
100     eventHandles_.clear();
101     if (subscriber_) {
102         bool unSubscribeResult = EventFwk::CommonEventManager::UnSubscribeCommonEvent(subscriber_);
103         HILOG_INFO("unSubscribeResult = %{public}d", unSubscribeResult);
104         subscriber_ = nullptr;
105         eventHandler_ = nullptr;
106     }
107 }
108 
OnReceiveEvent(const EventFwk::CommonEventData & data)109 void AccessibilityCommonEvent::OnReceiveEvent(const EventFwk::CommonEventData &data)
110 {
111     HILOG_DEBUG();
112     if (!eventHandler_) {
113         HILOG_ERROR("eventHandler_ is nullptr.");
114         return;
115     }
116     eventHandler_->PostTask([this, data]() {
117         HILOG_DEBUG();
118         std::string action = data.GetWant().GetAction();
119         HILOG_INFO("Handle event:[%{public}s] eventHandles size[%{public}zu]", action.c_str(), eventHandles_.size());
120         auto it = eventHandles_.find(action);
121         if (it == eventHandles_.end()) {
122             HILOG_ERROR("Ignore event: %{public}s", action.c_str());
123             return;
124         }
125         it->second(data);
126         }, "TASK_ON_RECEIVE_EVENT");
127 }
128 
HandleUserAdded(const EventFwk::CommonEventData & data) const129 void AccessibilityCommonEvent::HandleUserAdded(const EventFwk::CommonEventData &data) const
130 {
131     int32_t accountId = data.GetCode();
132     HILOG_INFO();
133     if (accountId == -1) {
134         HILOG_ERROR("account id is wrong");
135         return;
136     }
137     Singleton<AccessibleAbilityManagerService>::GetInstance().AddedUser(accountId);
138 }
139 
HandleUserRemoved(const EventFwk::CommonEventData & data) const140 void AccessibilityCommonEvent::HandleUserRemoved(const EventFwk::CommonEventData &data) const
141 {
142     int32_t accountId = data.GetCode();
143     HILOG_INFO();
144     if (accountId == -1) {
145         HILOG_ERROR("account id is wrong");
146         return;
147     }
148     Singleton<AccessibleAbilityManagerService>::GetInstance().RemovedUser(accountId);
149 }
150 
HandleUserSwitched(const EventFwk::CommonEventData & data) const151 void AccessibilityCommonEvent::HandleUserSwitched(const EventFwk::CommonEventData &data) const
152 {
153     int32_t accountId = data.GetCode();
154     HILOG_INFO();
155     if (accountId == -1) {
156         HILOG_ERROR("account id is wrong");
157         return;
158     }
159     Singleton<AccessibleAbilityManagerService>::GetInstance().SwitchedUser(accountId);
160 }
161 
HandlePackageRemoved(const EventFwk::CommonEventData & data) const162 void AccessibilityCommonEvent::HandlePackageRemoved(const EventFwk::CommonEventData &data) const
163 {
164     std::string bundleName = data.GetWant().GetBundle();
165     int userId = data.GetWant().GetIntParam(KEY_USER_ID, 0);
166     int32_t accountId = Singleton<AccessibleAbilityManagerService>::GetInstance().GetCurrentAccountId();
167     HILOG_INFO("bundleName is %{public}s", bundleName.c_str());
168     if (userId != accountId) {
169         HILOG_ERROR("not same user.");
170         return;
171     }
172     Singleton<AccessibleAbilityManagerService>::GetInstance().PackageRemoved(bundleName);
173 }
174 
HandlePackageAdd(const EventFwk::CommonEventData & data) const175 void AccessibilityCommonEvent::HandlePackageAdd(const EventFwk::CommonEventData &data) const
176 {
177     std::string bundleName = data.GetWant().GetBundle();
178     int userId = data.GetWant().GetIntParam(KEY_USER_ID, 0);
179     int32_t accountId = Singleton<AccessibleAbilityManagerService>::GetInstance().GetCurrentAccountId();
180     HILOG_INFO("bundleName is %{public}s", bundleName.c_str());
181     if (userId != accountId) {
182         HILOG_ERROR("not same user.");
183         return;
184     }
185     Singleton<AccessibleAbilityManagerService>::GetInstance().PackageAdd(bundleName);
186 }
187 
HandlePackageChanged(const EventFwk::CommonEventData & data) const188 void AccessibilityCommonEvent::HandlePackageChanged(const EventFwk::CommonEventData &data) const
189 {
190     std::string bundleName = data.GetWant().GetBundle();
191     int userId = data.GetWant().GetIntParam(KEY_USER_ID, 0);
192     int32_t accountId = Singleton<AccessibleAbilityManagerService>::GetInstance().GetCurrentAccountId();
193     HILOG_INFO("bundleName is %{public}s", bundleName.c_str());
194     if (userId != accountId) {
195         HILOG_ERROR("not same user.");
196         return;
197     }
198     Singleton<AccessibleAbilityManagerService>::GetInstance().PackageChanged(bundleName);
199 }
200 } // namespace Accessibility
201 } // namespace OHOS