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