• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "accessible_ability_connection.h"
17 
18 #include <hitrace_meter.h>
19 
20 #include "ability_manager_client.h"
21 #include "accessible_ability_manager_service.h"
22 #include "hilog_wrapper.h"
23 #include "utils.h"
24 
25 namespace OHOS {
26 namespace Accessibility {
AccessibleAbilityConnection(int32_t accountId,int32_t connectionId,AccessibilityAbilityInfo & abilityInfo)27 AccessibleAbilityConnection::AccessibleAbilityConnection(int32_t accountId, int32_t connectionId,
28     AccessibilityAbilityInfo &abilityInfo)
29     : accountId_(accountId), connectionId_(connectionId), abilityInfo_(abilityInfo)
30 {
31     eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(
32         Singleton<AccessibleAbilityManagerService>::GetInstance().GetMainRunner());
33 }
34 
~AccessibleAbilityConnection()35 AccessibleAbilityConnection::~AccessibleAbilityConnection()
36 {
37     HILOG_DEBUG();
38     if (abilityClient_ && abilityClient_->AsObject()) {
39         abilityClient_->AsObject()->RemoveDeathRecipient(deathRecipient_);
40         abilityClient_ = nullptr;
41     }
42 }
43 
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int32_t resultCode)44 void AccessibleAbilityConnection::OnAbilityConnectDone(const AppExecFwk::ElementName &element,
45     const sptr<IRemoteObject> &remoteObject, int32_t resultCode)
46 {
47     HILOG_INFO();
48     if (!eventHandler_) {
49         HILOG_ERROR("eventHandler_ is nullptr.");
50         return;
51     }
52 
53     eventHandler_->PostTask(std::bind([element, remoteObject, resultCode](int32_t accountId) -> void {
54         HILOG_DEBUG("ResultCode is %{public}d", resultCode);
55         FinishAsyncTrace(HITRACE_TAG_ACCESSIBILITY_MANAGER, "AccessibleAbilityConnect",
56             static_cast<int32_t>(TraceTaskId::ACCESSIBLE_ABILITY_CONNECT));
57         std::string bundleName = element.GetBundleName();
58         std::string abilityName = element.GetAbilityName();
59         auto accountData = Singleton<AccessibleAbilityManagerService>::GetInstance().GetAccountData(accountId);
60         if (!accountData) {
61             Utils::RecordUnavailableEvent(A11yUnavailableEvent::CONNECT_EVENT,
62                 A11yError::ERROR_CONNECT_A11Y_APPLICATION_FAILED, bundleName, abilityName);
63             HILOG_ERROR("accountData is nullptr.");
64             return;
65         }
66 
67         if (resultCode != NO_ERROR) {
68             accountData->RemoveEnabledAbility(Utils::GetUri(element));
69             accountData->RemoveConnectingA11yAbility(Utils::GetUri(element));
70             accountData->UpdateAbilities();
71             Utils::RecordUnavailableEvent(A11yUnavailableEvent::CONNECT_EVENT,
72                 A11yError::ERROR_CONNECT_A11Y_APPLICATION_FAILED, bundleName, abilityName);
73             return;
74         }
75 
76         if (!remoteObject) {
77             Utils::RecordUnavailableEvent(A11yUnavailableEvent::CONNECT_EVENT,
78                 A11yError::ERROR_CONNECT_A11Y_APPLICATION_FAILED, bundleName, abilityName);
79             HILOG_ERROR("AccessibleAbilityConnection::OnAbilityConnectDone get remoteObject failed");
80             return;
81         }
82 
83         sptr<AccessibleAbilityConnection> connection = accountData->GetConnectingA11yAbility(Utils::GetUri(element));
84         if (!connection) {
85             HILOG_ERROR("connection is nullptr");
86             return;
87         }
88 
89         accountData->AddConnectedAbility(connection);
90         accountData->RemoveConnectingA11yAbility(Utils::GetUri(element));
91         Singleton<AccessibleAbilityManagerService>::GetInstance().UpdateAccessibilityManagerService();
92         connection->InitAbilityClient(remoteObject);
93         accountData->UpdateEnableAbilityListsState();
94         }, accountId_), "OnAbilityConnectDone");
95 }
96 
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int32_t resultCode)97 void AccessibleAbilityConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int32_t resultCode)
98 {
99     HILOG_INFO("resultCode[%{public}d]", resultCode);
100 }
101 
OnAccessibilityEvent(AccessibilityEventInfo & eventInfo)102 void AccessibleAbilityConnection::OnAccessibilityEvent(AccessibilityEventInfo &eventInfo)
103 {
104     HILOG_DEBUG();
105     if (!abilityClient_) {
106         HILOG_ERROR("OnAccessibilityEvent​ failed");
107         return;
108     }
109 
110     std::vector<std::string> filterBundleNames = abilityInfo_.GetFilterBundleNames();
111     if (IsWantedEvent(eventInfo.GetEventType()) && (filterBundleNames.empty() || find(filterBundleNames.begin(),
112         filterBundleNames.end(), eventInfo.GetBundleName()) != filterBundleNames.end())) {
113         abilityClient_->OnAccessibilityEvent(eventInfo);
114         HILOG_DEBUG("windowId[%{public}d] evtType[%{public}d] windowChangeType[%{public}d] GestureId[%{public}d]",
115             eventInfo.GetWindowId(), eventInfo.GetEventType(), eventInfo.GetWindowChangeTypes(),
116             eventInfo.GetGestureType());
117     }
118 }
119 
OnKeyPressEvent(const MMI::KeyEvent & keyEvent,const int32_t sequence)120 bool AccessibleAbilityConnection::OnKeyPressEvent(const MMI::KeyEvent &keyEvent, const int32_t sequence)
121 {
122     if (!abilityClient_) {
123         HILOG_ERROR("OnKeyPressEvent failed");
124         return false;
125     }
126 
127     if (!(abilityInfo_.GetCapabilityValues() & Capability::CAPABILITY_KEY_EVENT_OBSERVER)) {
128         HILOG_ERROR("Capability failed");
129         return false;
130     }
131 
132     abilityClient_->OnKeyPressEvent(keyEvent, sequence);
133     return true;
134 }
135 
SetAbilityInfoTargetBundleName(const std::vector<std::string> & targetBundleNames)136 void AccessibleAbilityConnection::SetAbilityInfoTargetBundleName(const std::vector<std::string> &targetBundleNames)
137 {
138     HILOG_DEBUG();
139     abilityInfo_.SetFilterBundleNames(targetBundleNames);
140 }
141 
IsWantedEvent(int32_t eventType)142 bool AccessibleAbilityConnection::IsWantedEvent(int32_t eventType)
143 {
144     uint32_t type = static_cast<uint32_t>(eventType);
145     if ((type & abilityInfo_.GetEventTypes()) != type) {
146         HILOG_DEBUG("EventType(%{public}d) is not wanted", type);
147         return false;
148     }
149     return true;
150 }
151 
CreateWant(AppExecFwk::ElementName & element)152 AAFwk::Want CreateWant(AppExecFwk::ElementName& element)
153 {
154     AAFwk::Want want;
155     want.SetElement(element);
156 
157     return want;
158 }
159 
Disconnect()160 void AccessibleAbilityConnection::Disconnect()
161 {
162     HILOG_DEBUG();
163 
164     if (accountId_ == Singleton<AccessibleAbilityManagerService>::GetInstance().GetCurrentAccountId()) {
165         Singleton<AccessibleAbilityManagerService>::GetInstance().UpdateAccessibilityManagerService();
166     }
167 
168     if (!abilityClient_) {
169         HILOG_ERROR("abilityClient is nullptr");
170         return;
171     }
172     abilityClient_->Disconnect(connectionId_);
173 
174     auto abilityManagerClient = AAFwk::AbilityManagerClient::GetInstance();
175     if (!abilityManagerClient) {
176         HILOG_ERROR("abilityManagerClient is nullptr");
177         return;
178     }
179     if (abilityManagerClient->DisconnectAbility(this) != ERR_OK) {
180         HILOG_ERROR("Disconnect failed!");
181         return;
182     }
183 }
184 
Connect(const AppExecFwk::ElementName & element)185 void AccessibleAbilityConnection::Connect(const AppExecFwk::ElementName &element)
186 {
187     HILOG_DEBUG();
188     StartAsyncTrace(HITRACE_TAG_ACCESSIBILITY_MANAGER, "AccessibleAbilityConnect",
189         static_cast<int32_t>(TraceTaskId::ACCESSIBLE_ABILITY_CONNECT));
190     std::string bundleName = element.GetBundleName();
191     std::string abilityName = element.GetAbilityName();
192 
193     elementName_ = element;
194     HILOG_DEBUG("bundleName[%{public}s], abilityName [%{public}s], accountId [%{public}d]",
195         bundleName.c_str(), abilityName.c_str(), accountId_);
196 
197     auto bundleMgr = Singleton<AccessibleAbilityManagerService>::GetInstance().GetBundleMgrProxy();
198     if (!bundleMgr) {
199         Utils::RecordUnavailableEvent(A11yUnavailableEvent::CONNECT_EVENT,
200             A11yError::ERROR_CONNECT_A11Y_APPLICATION_FAILED, bundleName, abilityName);
201         HILOG_ERROR("get bundleMgr failed");
202         return;
203     }
204     int uid = bundleMgr->GetUidByBundleName(bundleName, accountId_);
205     HILOG_DEBUG("uid is %{public}d ", uid);
206 
207     auto abilityManagerClient = AAFwk::AbilityManagerClient::GetInstance();
208     if (!abilityManagerClient) {
209         Utils::RecordUnavailableEvent(A11yUnavailableEvent::CONNECT_EVENT,
210             A11yError::ERROR_CONNECT_A11Y_APPLICATION_FAILED, bundleName, abilityName);
211         HILOG_ERROR("abilityManagerClient is nullptr");
212         return;
213     }
214     AAFwk::Want want = CreateWant(elementName_);
215     if (abilityManagerClient->ConnectAbility(want, this, nullptr, uid / UID_MASK) != ERR_OK) {
216         Utils::RecordUnavailableEvent(A11yUnavailableEvent::CONNECT_EVENT,
217             A11yError::ERROR_CONNECT_A11Y_APPLICATION_FAILED, bundleName, abilityName);
218         HILOG_ERROR("ConnectAbility failed!");
219         return;
220     }
221 }
222 
GetChannelId()223 int32_t AccessibleAbilityConnection::GetChannelId()
224 {
225     HILOG_DEBUG("connectionId_ is %{public}d", connectionId_);
226     return connectionId_;
227 }
228 
OnAbilityConnectDoneSync(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject)229 void AccessibleAbilityConnection::OnAbilityConnectDoneSync(const AppExecFwk::ElementName &element,
230     const sptr<IRemoteObject> &remoteObject)
231 {
232     HILOG_DEBUG();
233     auto accountData = Singleton<AccessibleAbilityManagerService>::GetInstance().GetAccountData(accountId_);
234     if (!accountData) {
235         HILOG_ERROR("accountData is nullptr.");
236         return;
237     }
238     if (!remoteObject) {
239         HILOG_ERROR("AccessibleAbilityConnection::OnAbilityConnectDone get remoteObject failed");
240         return;
241     }
242     elementName_ = element;
243 
244     sptr<AccessibleAbilityConnection> pointer = this;
245     accountData->AddConnectedAbility(pointer);
246     Singleton<AccessibleAbilityManagerService>::GetInstance().UpdateAccessibilityManagerService();
247     InitAbilityClient(remoteObject);
248 }
249 
OnAbilityDisconnectDoneSync(const AppExecFwk::ElementName & element)250 void AccessibleAbilityConnection::OnAbilityDisconnectDoneSync(const AppExecFwk::ElementName &element)
251 {
252     HILOG_DEBUG();
253 
254     if (accountId_ == Singleton<AccessibleAbilityManagerService>::GetInstance().GetCurrentAccountId()) {
255         Singleton<AccessibleAbilityManagerService>::GetInstance().UpdateAccessibilityManagerService();
256     }
257 
258     if (!abilityClient_) {
259         HILOG_ERROR("abilityClient_ is nullptr");
260         return;
261     }
262     abilityClient_->Disconnect(connectionId_);
263 }
264 
InitAbilityClient(const sptr<IRemoteObject> & remoteObject)265 void AccessibleAbilityConnection::InitAbilityClient(const sptr<IRemoteObject> &remoteObject)
266 {
267     std::string bundleName = elementName_.GetBundleName();
268     std::string abilityName = elementName_.GetAbilityName();
269     abilityClient_ = new(std::nothrow) AccessibleAbilityClientProxy(remoteObject);
270     if (!abilityClient_) {
271         Utils::RecordUnavailableEvent(A11yUnavailableEvent::CONNECT_EVENT,
272             A11yError::ERROR_CONNECT_A11Y_APPLICATION_FAILED, bundleName, abilityName);
273         HILOG_ERROR("abilityClient_ is null");
274         return;
275     }
276 
277     if (!deathRecipient_) {
278         deathRecipient_ = new(std::nothrow) AccessibleAbilityConnectionDeathRecipient(
279             accountId_, elementName_, eventHandler_);
280         if (!deathRecipient_) {
281             Utils::RecordUnavailableEvent(A11yUnavailableEvent::CONNECT_EVENT,
282                 A11yError::ERROR_CONNECT_A11Y_APPLICATION_FAILED, bundleName, abilityName);
283             HILOG_ERROR("deathRecipient_ is null");
284             return;
285         }
286     }
287 
288     if (!abilityClient_->AsObject() || !abilityClient_->AsObject()->AddDeathRecipient(deathRecipient_)) {
289         HILOG_ERROR("Failed to add death recipient");
290     }
291 
292     channel_ = new(std::nothrow) AccessibleAbilityChannel(accountId_, abilityInfo_.GetId());
293     if (!channel_) {
294         Utils::RecordUnavailableEvent(A11yUnavailableEvent::CONNECT_EVENT,
295             A11yError::ERROR_CONNECT_A11Y_APPLICATION_FAILED, bundleName, abilityName);
296         HILOG_ERROR("channel_ is null");
297         return;
298     }
299     abilityClient_->Init(channel_, connectionId_);
300 }
301 
OnRemoteDied(const wptr<IRemoteObject> & remote)302 void AccessibleAbilityConnection::AccessibleAbilityConnectionDeathRecipient::OnRemoteDied(
303     const wptr<IRemoteObject> &remote)
304 {
305     Utils::RecordUnavailableEvent(A11yUnavailableEvent::CONNECT_EVENT,
306         A11yError::ERROR_A11Y_APPLICATION_DISCONNECT_ABNORMALLY,
307         recipientElementName_.GetBundleName(), recipientElementName_.GetAbilityName());
308     if (!handler_) {
309         HILOG_ERROR("handler_ is nullptr");
310         return;
311     }
312     std::shared_ptr<AppExecFwk::ElementName> sharedElementName =
313         std::make_shared<AppExecFwk::ElementName>(recipientElementName_);
314     handler_->PostTask(std::bind([](int32_t accountId, std::shared_ptr<AppExecFwk::ElementName> elementName) -> void {
315         HILOG_DEBUG();
316 
317         auto &aams = Singleton<AccessibleAbilityManagerService>::GetInstance();
318         auto accountData = aams.GetAccountData(accountId);
319         if (!accountData) {
320             HILOG_ERROR("accountData is null.");
321             return;
322         }
323 
324         std::string uri = Utils::GetUri(*elementName);
325         sptr<AccessibleAbilityConnection> connection = accountData->GetAccessibleAbilityConnection(uri);
326         if (!connection) {
327             HILOG_ERROR("There is no connection for %{public}s.", uri.c_str());
328             return;
329         }
330         accountData->RemoveConnectedAbility(*elementName);
331         accountData->RemoveEnabledAbility(uri);
332 
333         std::string uiTestUri = Utils::GetUri("ohos.uitest", "uitestability");
334         if (uri == uiTestUri) {
335             accountData->RemoveInstalledAbility("ohos.uitest");
336         }
337 
338         accountData->UpdateAbilities();
339         aams.UpdateAccessibilityManagerService();
340         }, accountId_, sharedElementName), "OnRemoteDied");
341 }
342 } // namespace Accessibility
343 } // namespace OHOS