• 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 #ifdef OHOS_BUILD_ENABLE_HITRACE
19 #include <hitrace_meter.h>
20 #endif // OHOS_BUILD_ENABLE_HITRACE
21 
22 #include "ability_manager_client.h"
23 #include "accessible_ability_manager_service.h"
24 #ifdef OHOS_BUILD_ENABLE_POWER_MANAGER
25 #include "accessibility_power_manager.h"
26 #endif
27 #include "hilog_wrapper.h"
28 #include "utils.h"
29 
30 namespace OHOS {
31 namespace Accessibility {
AccessibleAbilityConnection(int32_t accountId,int32_t connectionId,AccessibilityAbilityInfo & abilityInfo)32 AccessibleAbilityConnection::AccessibleAbilityConnection(int32_t accountId, int32_t connectionId,
33     AccessibilityAbilityInfo &abilityInfo)
34     : accountId_(accountId), connectionId_(connectionId), abilityInfo_(abilityInfo)
35 {
36     eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(
37         Singleton<AccessibleAbilityManagerService>::GetInstance().GetMainRunner());
38 }
39 
~AccessibleAbilityConnection()40 AccessibleAbilityConnection::~AccessibleAbilityConnection()
41 {
42     HILOG_DEBUG();
43     if (abilityClient_ && abilityClient_->AsObject()) {
44         abilityClient_->AsObject()->RemoveDeathRecipient(deathRecipient_);
45         abilityClient_ = nullptr;
46     }
47 }
48 
HandleNoEventHandler(const AppExecFwk::ElementName & element)49 void AccessibleAbilityConnection::HandleNoEventHandler(const AppExecFwk::ElementName &element)
50 {
51     HILOG_ERROR("eventHandler_ is nullptr.");
52     auto accountData = Singleton<AccessibleAbilityManagerService>::GetInstance().GetAccountData(accountId_);
53     if (accountData != nullptr) {
54         accountData->RemoveConnectingA11yAbility(Utils::GetUri(element));
55     }
56 }
57 
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int32_t resultCode)58 void AccessibleAbilityConnection::OnAbilityConnectDone(const AppExecFwk::ElementName &element,
59     const sptr<IRemoteObject> &remoteObject, int32_t resultCode)
60 {
61     HILOG_INFO("ResultCode is %{public}d", resultCode);
62     if (!eventHandler_) {
63         HandleNoEventHandler(element);
64         return;
65     }
66 
67     int32_t accountId = accountId_;
68     eventHandler_->PostTask([accountId, element, remoteObject, resultCode]() {
69 #ifdef OHOS_BUILD_ENABLE_HITRACE
70         FinishAsyncTrace(HITRACE_TAG_ACCESSIBILITY_MANAGER, "AccessibleAbilityConnect",
71             static_cast<int32_t>(TraceTaskId::ACCESSIBLE_ABILITY_CONNECT));
72 #endif // OHOS_BUILD_ENABLE_HITRACE
73         std::string bundleName = element.GetBundleName();
74         std::string abilityName = element.GetAbilityName();
75         auto accountData = Singleton<AccessibleAbilityManagerService>::GetInstance().GetAccountData(accountId);
76         if (!accountData) {
77             Utils::RecordUnavailableEvent(A11yUnavailableEvent::CONNECT_EVENT,
78                 A11yError::ERROR_CONNECT_A11Y_APPLICATION_FAILED, bundleName, abilityName);
79             HILOG_ERROR("accountData is nullptr.");
80             return;
81         }
82 
83         if (resultCode != NO_ERROR) {
84             accountData->RemoveEnabledAbility(Utils::GetUri(element));
85             accountData->RemoveConnectingA11yAbility(Utils::GetUri(element));
86             accountData->UpdateAbilities();
87             Utils::RecordUnavailableEvent(A11yUnavailableEvent::CONNECT_EVENT,
88                 A11yError::ERROR_CONNECT_A11Y_APPLICATION_FAILED, bundleName, abilityName);
89             return;
90         }
91 
92         if (!remoteObject) {
93             Utils::RecordUnavailableEvent(A11yUnavailableEvent::CONNECT_EVENT,
94                 A11yError::ERROR_CONNECT_A11Y_APPLICATION_FAILED, bundleName, abilityName);
95             HILOG_ERROR("AccessibleAbilityConnection::OnAbilityConnectDone get remoteObject failed");
96             return;
97         }
98 
99         sptr<AccessibleAbilityConnection> connection = accountData->GetConnectingA11yAbility(Utils::GetUri(element));
100         if (!connection) {
101             HILOG_ERROR("connection is nullptr");
102             return;
103         }
104 
105         accountData->AddConnectedAbility(connection);
106         accountData->RemoveConnectingA11yAbility(Utils::GetUri(element));
107         Singleton<AccessibleAbilityManagerService>::GetInstance().UpdateAccessibilityManagerService();
108         connection->InitAbilityClient(remoteObject);
109         accountData->UpdateEnableAbilityListsState();
110         }, "OnAbilityConnectDone");
111 }
112 
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int32_t resultCode)113 void AccessibleAbilityConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int32_t resultCode)
114 {
115     HILOG_INFO("resultCode[%{public}d]", resultCode);
116     if (resultCode == NO_ERROR) {
117         return;
118     }
119     // when calling ConnectAbility function, OnAbilityDisconnectDone could be called when ability crashed
120     // and OnAbilityConnectDone won't be called. At this time, ConnectingA11yAbility should be cleaned up
121     if (!eventHandler_) {
122         HILOG_ERROR("eventHanlder_ is nullptr");
123         auto accountData = Singleton<AccessibleAbilityManagerService>::GetInstance().GetAccountData(accountId_);
124         if (accountData != nullptr) {
125             accountData->RemoveConnectingA11yAbility(Utils::GetUri(element));
126         }
127         return;
128     }
129 
130     int32_t accountId = accountId_;
131     eventHandler_->PostTask([accountId, element]() {
132         auto accountData = Singleton<AccessibleAbilityManagerService>::GetInstance().GetAccountData(accountId);
133         if (accountData != nullptr) {
134             accountData->RemoveConnectingA11yAbility(Utils::GetUri(element));
135         }
136         }, "OnAbilityDisconnectDone");
137 }
138 
OnAccessibilityEvent(AccessibilityEventInfo & eventInfo)139 void AccessibleAbilityConnection::OnAccessibilityEvent(AccessibilityEventInfo &eventInfo)
140 {
141     HILOG_DEBUG();
142     if (!abilityClient_) {
143         HILOG_ERROR("OnAccessibilityEvent​ failed");
144         return;
145     }
146 
147     std::vector<std::string> filterBundleNames = abilityInfo_.GetFilterBundleNames();
148     if (IsWantedEvent(eventInfo.GetEventType()) && (filterBundleNames.empty() || find(filterBundleNames.begin(),
149         filterBundleNames.end(), eventInfo.GetBundleName()) != filterBundleNames.end())) {
150         abilityClient_->OnAccessibilityEvent(eventInfo);
151         HILOG_DEBUG("windowId[%{public}d] evtType[%{public}d] windowChangeType[%{public}d] GestureId[%{public}d]",
152             eventInfo.GetWindowId(), eventInfo.GetEventType(), eventInfo.GetWindowChangeTypes(),
153             eventInfo.GetGestureType());
154     }
155 }
156 
OnKeyPressEvent(const MMI::KeyEvent & keyEvent,const int32_t sequence)157 bool AccessibleAbilityConnection::OnKeyPressEvent(const MMI::KeyEvent &keyEvent, const int32_t sequence)
158 {
159     if (!abilityClient_) {
160         HILOG_ERROR("OnKeyPressEvent failed");
161         return false;
162     }
163 
164     if (!(abilityInfo_.GetCapabilityValues() & Capability::CAPABILITY_KEY_EVENT_OBSERVER)) {
165         HILOG_ERROR("Capability failed");
166         return false;
167     }
168 
169     abilityClient_->OnKeyPressEvent(keyEvent, sequence);
170     return true;
171 }
172 
SetAbilityInfoTargetBundleName(const std::vector<std::string> & targetBundleNames)173 void AccessibleAbilityConnection::SetAbilityInfoTargetBundleName(const std::vector<std::string> &targetBundleNames)
174 {
175     HILOG_DEBUG();
176     abilityInfo_.SetFilterBundleNames(targetBundleNames);
177 }
178 
IsWantedEvent(int32_t eventType)179 bool AccessibleAbilityConnection::IsWantedEvent(int32_t eventType)
180 {
181     uint32_t type = static_cast<uint32_t>(eventType);
182     if ((type & abilityInfo_.GetEventTypes()) != type) {
183         HILOG_DEBUG("EventType(%{public}d) is not wanted", type);
184         return false;
185     }
186     return true;
187 }
188 
CreateWant(AppExecFwk::ElementName & element)189 AAFwk::Want CreateWant(AppExecFwk::ElementName& element)
190 {
191     AAFwk::Want want;
192     want.SetElement(element);
193 
194     return want;
195 }
196 
Disconnect()197 void AccessibleAbilityConnection::Disconnect()
198 {
199     HILOG_DEBUG();
200 
201     if (accountId_ == Singleton<AccessibleAbilityManagerService>::GetInstance().GetCurrentAccountId()) {
202         Singleton<AccessibleAbilityManagerService>::GetInstance().UpdateAccessibilityManagerService();
203     }
204 
205     if (!abilityClient_) {
206         HILOG_ERROR("abilityClient is nullptr");
207         return;
208     }
209     abilityClient_->Disconnect(connectionId_);
210 
211     if (isRegisterDisconnectCallback_) {
212         int32_t accountId = accountId_;
213         std::string clientName = Utils::GetUri(elementName_);
214         if (!eventHandler_) {
215             HILOG_ERROR("eventHanlder_ is nullptr");
216             auto accountData = Singleton<AccessibleAbilityManagerService>::GetInstance().GetAccountData(accountId_);
217             if (accountData != nullptr) {
218                 accountData->RemoveConnectingA11yAbility(clientName);
219             }
220             return;
221         }
222         eventHandler_->PostTask([this, accountId, clientName]() {
223             DisconnectAbility();
224             auto accountData = Singleton<AccessibleAbilityManagerService>::GetInstance().GetAccountData(accountId);
225             accountData->RemoveWaitDisconnectAbility(clientName);
226             }, "DISCONNECT_" + elementName_.GetBundleName(), WAIT_NOTIFY_DISCONNECT_TIMEOUT);
227     } else {
228         DisconnectAbility();
229     }
230 }
231 
DisconnectAbility()232 void AccessibleAbilityConnection::DisconnectAbility()
233 {
234     HILOG_INFO();
235     if (deathRecipient_ == nullptr || !abilityClient_->AsObject() ||
236         !abilityClient_->AsObject()->RemoveDeathRecipient(deathRecipient_)) {
237         HILOG_ERROR("Failed to add death recipient");
238     }
239 
240     auto abilityManagerClient = AAFwk::AbilityManagerClient::GetInstance();
241     if (!abilityManagerClient) {
242         HILOG_ERROR("abilityManagerClient is nullptr");
243         return;
244     }
245     if (abilityManagerClient->DisconnectAbility(this) != ERR_OK) {
246         HILOG_ERROR("Disconnect failed!");
247         return;
248     }
249 }
250 
NotifyDisconnect()251 void AccessibleAbilityConnection::NotifyDisconnect()
252 {
253     HILOG_INFO();
254     if (!eventHandler_) {
255         HILOG_ERROR("eventHanlder_ is nullptr");
256         auto accountData = Singleton<AccessibleAbilityManagerService>::GetInstance().GetAccountData(accountId_);
257         if (accountData != nullptr) {
258             accountData->RemoveConnectingA11yAbility(Utils::GetUri(elementName_));
259         }
260         return;
261     }
262     eventHandler_->RemoveTask("DISCONNECT_" + elementName_.GetBundleName());
263     DisconnectAbility();
264 }
265 
Connect(const AppExecFwk::ElementName & element)266 bool AccessibleAbilityConnection::Connect(const AppExecFwk::ElementName &element)
267 {
268     HILOG_DEBUG();
269 #ifdef OHOS_BUILD_ENABLE_HITRACE
270     StartAsyncTrace(HITRACE_TAG_ACCESSIBILITY_MANAGER, "AccessibleAbilityConnect",
271         static_cast<int32_t>(TraceTaskId::ACCESSIBLE_ABILITY_CONNECT));
272 #endif // OHOS_BUILD_ENABLE_HITRACE
273     std::string bundleName = element.GetBundleName();
274     std::string abilityName = element.GetAbilityName();
275 
276     elementName_ = element;
277     HILOG_DEBUG("bundleName[%{public}s], abilityName [%{public}s], accountId [%{public}d]",
278         bundleName.c_str(), abilityName.c_str(), accountId_);
279 
280     int uid = Singleton<AccessibilityResourceBundleManager>::GetInstance().GetUidByBundleName(
281         bundleName, abilityName, accountId_);
282     HILOG_DEBUG("uid is %{public}d ", uid);
283 
284     auto abilityManagerClient = AAFwk::AbilityManagerClient::GetInstance();
285     if (!abilityManagerClient) {
286         Utils::RecordUnavailableEvent(A11yUnavailableEvent::CONNECT_EVENT,
287             A11yError::ERROR_CONNECT_A11Y_APPLICATION_FAILED, bundleName, abilityName);
288         HILOG_ERROR("abilityManagerClient is nullptr");
289         return false;
290     }
291     AAFwk::Want want = CreateWant(elementName_);
292     if (abilityManagerClient->ConnectAbility(want, this, nullptr, uid / UID_MASK) != ERR_OK) {
293         Utils::RecordUnavailableEvent(A11yUnavailableEvent::CONNECT_EVENT,
294             A11yError::ERROR_CONNECT_A11Y_APPLICATION_FAILED, bundleName, abilityName);
295         HILOG_ERROR("ConnectAbility failed!");
296         return false;
297     }
298     return true;
299 }
300 
GetChannelId()301 int32_t AccessibleAbilityConnection::GetChannelId()
302 {
303     HILOG_DEBUG("connectionId_ is %{public}d", connectionId_);
304     return connectionId_;
305 }
306 
OnAbilityConnectDoneSync(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject)307 void AccessibleAbilityConnection::OnAbilityConnectDoneSync(const AppExecFwk::ElementName &element,
308     const sptr<IRemoteObject> &remoteObject)
309 {
310     HILOG_DEBUG();
311     auto accountData = Singleton<AccessibleAbilityManagerService>::GetInstance().GetAccountData(accountId_);
312     if (!accountData) {
313         HILOG_ERROR("accountData is nullptr.");
314         return;
315     }
316     if (!remoteObject) {
317         HILOG_ERROR("AccessibleAbilityConnection::OnAbilityConnectDone get remoteObject failed");
318         return;
319     }
320     elementName_ = element;
321 
322     sptr<AccessibleAbilityConnection> pointer = this;
323     accountData->AddConnectedAbility(pointer);
324     Singleton<AccessibleAbilityManagerService>::GetInstance().UpdateAccessibilityManagerService();
325     InitAbilityClient(remoteObject);
326 }
327 
OnAbilityDisconnectDoneSync(const AppExecFwk::ElementName & element)328 void AccessibleAbilityConnection::OnAbilityDisconnectDoneSync(const AppExecFwk::ElementName &element)
329 {
330     HILOG_DEBUG();
331 
332     if (accountId_ == Singleton<AccessibleAbilityManagerService>::GetInstance().GetCurrentAccountId()) {
333         Singleton<AccessibleAbilityManagerService>::GetInstance().UpdateAccessibilityManagerService();
334     }
335 
336     if (!abilityClient_) {
337         HILOG_ERROR("abilityClient_ is nullptr");
338         return;
339     }
340     abilityClient_->Disconnect(connectionId_);
341 }
342 
InitAbilityClient(const sptr<IRemoteObject> & remoteObject)343 void AccessibleAbilityConnection::InitAbilityClient(const sptr<IRemoteObject> &remoteObject)
344 {
345     std::string bundleName = elementName_.GetBundleName();
346     std::string abilityName = elementName_.GetAbilityName();
347     abilityClient_ = new(std::nothrow) AccessibleAbilityClientProxy(remoteObject);
348     if (!abilityClient_) {
349         Utils::RecordUnavailableEvent(A11yUnavailableEvent::CONNECT_EVENT,
350             A11yError::ERROR_CONNECT_A11Y_APPLICATION_FAILED, bundleName, abilityName);
351         HILOG_ERROR("abilityClient_ is null");
352         return;
353     }
354 
355     if (!deathRecipient_) {
356         deathRecipient_ = new(std::nothrow) AccessibleAbilityConnectionDeathRecipient(
357             accountId_, elementName_, eventHandler_);
358         if (!deathRecipient_) {
359             Utils::RecordUnavailableEvent(A11yUnavailableEvent::CONNECT_EVENT,
360                 A11yError::ERROR_CONNECT_A11Y_APPLICATION_FAILED, bundleName, abilityName);
361             HILOG_ERROR("deathRecipient_ is null");
362             return;
363         }
364     }
365 
366     if (!abilityClient_->AsObject() || !abilityClient_->AsObject()->AddDeathRecipient(deathRecipient_)) {
367         HILOG_ERROR("Failed to add death recipient");
368     }
369 
370     channel_ = new(std::nothrow) AccessibleAbilityChannel(accountId_, abilityInfo_.GetId());
371     if (!channel_) {
372         Utils::RecordUnavailableEvent(A11yUnavailableEvent::CONNECT_EVENT,
373             A11yError::ERROR_CONNECT_A11Y_APPLICATION_FAILED, bundleName, abilityName);
374         HILOG_ERROR("channel_ is null");
375         return;
376     }
377     abilityClient_->Init(channel_, connectionId_);
378 }
379 
OnRemoteDied(const wptr<IRemoteObject> & remote)380 void AccessibleAbilityConnection::AccessibleAbilityConnectionDeathRecipient::OnRemoteDied(
381     const wptr<IRemoteObject> &remote)
382 {
383     Utils::RecordUnavailableEvent(A11yUnavailableEvent::CONNECT_EVENT,
384         A11yError::ERROR_A11Y_APPLICATION_DISCONNECT_ABNORMALLY,
385         recipientElementName_.GetBundleName(), recipientElementName_.GetAbilityName());
386     if (!handler_) {
387         HILOG_ERROR("handler_ is nullptr");
388         return;
389     }
390     std::shared_ptr<AppExecFwk::ElementName> sharedElementName =
391         std::make_shared<AppExecFwk::ElementName>(recipientElementName_);
392 
393     if (sharedElementName == nullptr) {
394         HILOG_ERROR("sharedElementName is nullptr");
395         return;
396     }
397     int32_t accountId = accountId_;
398     handler_->PostTask([accountId, sharedElementName]() {
399         HILOG_DEBUG();
400 
401         auto &aams = Singleton<AccessibleAbilityManagerService>::GetInstance();
402         auto accountData = aams.GetAccountData(accountId);
403         if (!accountData) {
404             HILOG_ERROR("accountData is null.");
405             return;
406         }
407 
408         std::string uri = Utils::GetUri(*sharedElementName);
409         sptr<AccessibleAbilityConnection> connection = accountData->GetAccessibleAbilityConnection(uri);
410         if (!connection) {
411             HILOG_ERROR("There is no connection for %{public}s.", uri.c_str());
412             return;
413         }
414         accountData->RemoveConnectedAbility(*sharedElementName);
415         accountData->RemoveEnabledAbility(uri);
416 
417         // the extension ability connected to aams by inner api
418         if (sharedElementName->GetBundleName() == sharedElementName->GetAbilityName()) {
419             accountData->RemoveInstalledAbility(sharedElementName->GetBundleName());
420         }
421 
422 #ifdef OHOS_BUILD_ENABLE_POWER_MANAGER
423     std::string bundleName = sharedElementName->GetBundleName();
424     auto &powerManager = Singleton<AccessibilityPowerManager>::GetInstance();
425     if (!powerManager.UnholdRunningLock(bundleName)) {
426         HILOG_DEBUG("OnRemoteDied UnholdRunningLock failed.");
427     }
428 #endif
429         accountData->UpdateAbilities();
430         aams.UpdateAccessibilityManagerService();
431         }, "OnRemoteDied");
432 }
433 
GetIsRegisterDisconnectCallback() const434 bool AccessibleAbilityConnection::GetIsRegisterDisconnectCallback() const
435 {
436     return isRegisterDisconnectCallback_;
437 }
438 
SetIsRegisterDisconnectCallback(bool isRegister)439 void AccessibleAbilityConnection::SetIsRegisterDisconnectCallback(bool isRegister)
440 {
441     isRegisterDisconnectCallback_ = isRegister;
442 }
443 } // namespace Accessibility
444 } // namespace OHOS