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_channel.h"
17 #include "accessible_ability_manager_service.h"
18 #include "accessibility_window_connection.h"
19 #include "accessibility_window_manager.h"
20 #include "accessible_ability_connection.h"
21 #include "hilog_wrapper.h"
22
23 namespace OHOS {
24 namespace Accessibility {
AccessibleAbilityChannel(const int32_t accountId,const std::string & clientName)25 AccessibleAbilityChannel::AccessibleAbilityChannel(const int32_t accountId, const std::string &clientName)
26 : clientName_(clientName), accountId_(accountId)
27 {
28 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(
29 Singleton<AccessibleAbilityManagerService>::GetInstance().GetMainRunner());
30 }
31
SearchElementInfoByAccessibilityId(const int32_t accessibilityWindowId,const int32_t elementId,const int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback,const int32_t mode)32 RetError AccessibleAbilityChannel::SearchElementInfoByAccessibilityId(const int32_t accessibilityWindowId,
33 const int32_t elementId, const int32_t requestId, const sptr<IAccessibilityElementOperatorCallback> &callback,
34 const int32_t mode)
35 {
36 HILOG_DEBUG();
37
38 if (!eventHandler_) {
39 HILOG_ERROR("eventHandler_ is nullptr.");
40 return RET_ERR_NULLPTR;
41 }
42
43 std::promise<RetError> syncPromise;
44 std::future syncFuture = syncPromise.get_future();
45 eventHandler_->PostTask(std::bind([&syncPromise, accessibilityWindowId, elementId, requestId, callback, mode](
46 int32_t accountId, const std::string &name) -> void {
47 HILOG_DEBUG("accountId[%{public}d], name[%{public}s]", accountId, name.c_str());
48 sptr<IAccessibilityElementOperator> elementOperator = nullptr;
49 RetError ret = GetElementOperator(accountId, accessibilityWindowId, FOCUS_TYPE_INVALID, name, elementOperator);
50 if (ret != RET_OK) {
51 HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", accessibilityWindowId);
52 syncPromise.set_value(ret);
53 return;
54 }
55 elementOperator->SearchElementInfoByAccessibilityId(elementId, requestId, callback, mode);
56 HILOG_DEBUG("AccessibleAbilityChannel::SearchElementInfoByAccessibilityId successfully");
57 syncPromise.set_value(RET_OK);
58 }, accountId_, clientName_), "SearchElementInfoByAccessibilityId");
59 return syncFuture.get();
60 }
61
SearchElementInfosByText(const int32_t accessibilityWindowId,const int32_t elementId,const std::string & text,const int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback)62 RetError AccessibleAbilityChannel::SearchElementInfosByText(const int32_t accessibilityWindowId,
63 const int32_t elementId, const std::string &text, const int32_t requestId,
64 const sptr<IAccessibilityElementOperatorCallback> &callback)
65 {
66 HILOG_DEBUG();
67
68 if (!eventHandler_) {
69 HILOG_ERROR("eventHandler_ is nullptr.");
70 return RET_ERR_NULLPTR;
71 }
72
73 std::promise<RetError> syncPromise;
74 std::future syncFuture = syncPromise.get_future();
75 eventHandler_->PostTask(std::bind([&syncPromise, accessibilityWindowId, elementId, text, requestId, callback](
76 int32_t accountId, const std::string &name) -> void {
77 HILOG_DEBUG("accountId[%{public}d], name[%{public}s]", accountId, name.c_str());
78 sptr<IAccessibilityElementOperator> elementOperator = nullptr;
79 RetError ret = GetElementOperator(accountId, accessibilityWindowId, FOCUS_TYPE_INVALID, name, elementOperator);
80 if (ret != RET_OK) {
81 HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", accessibilityWindowId);
82 syncPromise.set_value(ret);
83 return;
84 }
85 elementOperator->SearchElementInfosByText(elementId, text, requestId, callback);
86 syncPromise.set_value(RET_OK);
87 }, accountId_, clientName_), "SearchElementInfosByText");
88 return syncFuture.get();
89 }
90
FindFocusedElementInfo(const int32_t accessibilityWindowId,const int32_t elementId,const int32_t focusType,const int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback)91 RetError AccessibleAbilityChannel::FindFocusedElementInfo(const int32_t accessibilityWindowId,
92 const int32_t elementId, const int32_t focusType, const int32_t requestId,
93 const sptr<IAccessibilityElementOperatorCallback> &callback)
94 {
95 HILOG_DEBUG();
96
97 if (!eventHandler_) {
98 HILOG_ERROR("eventHandler_ is nullptr.");
99 return RET_ERR_NULLPTR;
100 }
101
102 std::promise<RetError> syncPromise;
103 std::future syncFuture = syncPromise.get_future();
104 eventHandler_->PostTask(std::bind([&syncPromise, accessibilityWindowId, elementId,
105 focusType, requestId, callback](int32_t accountId, const std::string &name) -> void {
106 HILOG_DEBUG("accountId[%{public}d], name[%{public}s]", accountId, name.c_str());
107 sptr<IAccessibilityElementOperator> elementOperator = nullptr;
108 RetError ret = GetElementOperator(accountId, accessibilityWindowId, focusType, name, elementOperator);
109 if (ret != RET_OK) {
110 HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", accessibilityWindowId);
111 syncPromise.set_value(ret);
112 return;
113 }
114 elementOperator->FindFocusedElementInfo(elementId, focusType, requestId, callback);
115 syncPromise.set_value(RET_OK);
116 }, accountId_, clientName_), "FindFocusedElementInfo");
117 return syncFuture.get();
118 }
119
FocusMoveSearch(const int32_t accessibilityWindowId,const int32_t elementId,const int32_t direction,const int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback)120 RetError AccessibleAbilityChannel::FocusMoveSearch(const int32_t accessibilityWindowId, const int32_t elementId,
121 const int32_t direction, const int32_t requestId, const sptr<IAccessibilityElementOperatorCallback> &callback)
122 {
123 HILOG_DEBUG();
124
125 if (!eventHandler_) {
126 HILOG_ERROR("eventHandler_ is nullptr.");
127 return RET_ERR_NULLPTR;
128 }
129
130 std::promise<RetError> syncPromise;
131 std::future syncFuture = syncPromise.get_future();
132 eventHandler_->PostTask(std::bind([&syncPromise, accessibilityWindowId,
133 elementId, direction, requestId, callback](int32_t accountId, const std::string &name) -> void {
134 HILOG_DEBUG("accountId[%{public}d], name[%{public}s]", accountId, name.c_str());
135 sptr<IAccessibilityElementOperator> elementOperator = nullptr;
136 RetError ret = GetElementOperator(accountId, accessibilityWindowId, FOCUS_TYPE_INVALID, name, elementOperator);
137 if (ret != RET_OK) {
138 HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", accessibilityWindowId);
139 syncPromise.set_value(ret);
140 return;
141 }
142 elementOperator->FocusMoveSearch(elementId, direction, requestId, callback);
143 syncPromise.set_value(RET_OK);
144 }, accountId_, clientName_), "FocusMoveSearch");
145 return syncFuture.get();
146 }
147
ExecuteAction(const int32_t accessibilityWindowId,const int32_t elementId,const int32_t action,const std::map<std::string,std::string> & actionArguments,const int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback)148 RetError AccessibleAbilityChannel::ExecuteAction(const int32_t accessibilityWindowId, const int32_t elementId,
149 const int32_t action, const std::map<std::string, std::string> &actionArguments, const int32_t requestId,
150 const sptr<IAccessibilityElementOperatorCallback> &callback)
151 {
152 HILOG_DEBUG();
153
154 if (!eventHandler_) {
155 HILOG_ERROR("eventHandler_ is nullptr.");
156 return RET_ERR_NULLPTR;
157 }
158
159 std::promise<RetError> syncPromise;
160 std::future syncFuture = syncPromise.get_future();
161 eventHandler_->PostTask(std::bind([&syncPromise, accessibilityWindowId, elementId, action,
162 actionArguments, requestId, callback](int32_t accountId, const std::string &name) -> void {
163 HILOG_DEBUG("accountId[%{public}d], name[%{public}s]", accountId, name.c_str());
164 sptr<IAccessibilityElementOperator> elementOperator = nullptr;
165 RetError ret = GetElementOperator(accountId, accessibilityWindowId, FOCUS_TYPE_INVALID, name, elementOperator);
166 if (ret != RET_OK) {
167 HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", accessibilityWindowId);
168 syncPromise.set_value(ret);
169 return;
170 }
171 elementOperator->ExecuteAction(elementId, action, actionArguments, requestId, callback);
172 syncPromise.set_value(RET_OK);
173 }, accountId_, clientName_), "ExecuteAction");
174 return syncFuture.get();
175 }
176
GetWindow(const int32_t windowId,AccessibilityWindowInfo & windowInfo)177 RetError AccessibleAbilityChannel::GetWindow(const int32_t windowId, AccessibilityWindowInfo &windowInfo)
178 {
179 HILOG_DEBUG("windowId:%{public}d", windowId);
180
181 if (!eventHandler_) {
182 HILOG_ERROR("eventHandler_ is nullptr.");
183 return RET_ERR_NULLPTR;
184 }
185
186 std::promise<RetError> syncPromise;
187 std::future syncFuture = syncPromise.get_future();
188 eventHandler_->PostTask(std::bind([windowId, &windowInfo, &syncPromise](
189 int32_t accountId, const std::string &name) -> void {
190 HILOG_DEBUG("windowId:%{public}d", windowId);
191 sptr<AccessibleAbilityConnection> clientConnection = GetConnection(accountId, name);
192 if (!clientConnection) {
193 HILOG_ERROR("There is no client connection");
194 syncPromise.set_value(RET_ERR_NO_CONNECTION);
195 return;
196 }
197 if (!(clientConnection->GetAbilityInfo().GetCapabilityValues() & Capability::CAPABILITY_RETRIEVE)) {
198 HILOG_ERROR("AccessibleAbilityChannel::GetWindow failed: no capability");
199 syncPromise.set_value(RET_ERR_NO_CAPABILITY);
200 return;
201 }
202
203 if (Singleton<AccessibilityWindowManager>::GetInstance().GetAccessibilityWindow(windowId, windowInfo)) {
204 syncPromise.set_value(RET_OK);
205 } else {
206 syncPromise.set_value(RET_ERR_NO_WINDOW_CONNECTION);
207 }
208 }, accountId_, clientName_), "GetWindow");
209 return syncFuture.get();
210 }
211
GetWindows(std::vector<AccessibilityWindowInfo> & windows)212 RetError AccessibleAbilityChannel::GetWindows(std::vector<AccessibilityWindowInfo> &windows)
213 {
214 HILOG_DEBUG();
215 uint64_t displayId = Singleton<AccessibilityDisplayManager>::GetInstance().GetDefaultDisplayId();
216 HILOG_DEBUG("default display id is %{public}" PRIu64 "", displayId);
217 return GetWindows(displayId, windows);
218 }
219
GetWindowsByDisplayId(const uint64_t displayId,std::vector<AccessibilityWindowInfo> & windows)220 RetError AccessibleAbilityChannel::GetWindowsByDisplayId(const uint64_t displayId,
221 std::vector<AccessibilityWindowInfo> &windows)
222 {
223 HILOG_DEBUG();
224 return GetWindows(displayId, windows);
225 }
226
GetWindows(uint64_t displayId,std::vector<AccessibilityWindowInfo> & windows) const227 RetError AccessibleAbilityChannel::GetWindows(uint64_t displayId, std::vector<AccessibilityWindowInfo> &windows) const
228 {
229 if (!eventHandler_) {
230 HILOG_ERROR("eventHandler_ is nullptr.");
231 return RET_ERR_NULLPTR;
232 }
233
234 std::promise<RetError> syncPromise;
235 std::future syncFuture = syncPromise.get_future();
236 eventHandler_->PostTask(std::bind([displayId, &windows, &syncPromise](
237 int32_t accountId, const std::string &name) -> void {
238 HILOG_DEBUG();
239 sptr<AccessibleAbilityConnection> clientConnection = GetConnection(accountId, name);
240 if (!clientConnection) {
241 HILOG_ERROR("There is no client connection");
242 syncPromise.set_value(RET_ERR_NO_CONNECTION);
243 return;
244 }
245
246 if (!(clientConnection->GetAbilityInfo().GetCapabilityValues() & Capability::CAPABILITY_RETRIEVE)) {
247 HILOG_ERROR("GetWindows failed: no capability");
248 syncPromise.set_value(RET_ERR_NO_CAPABILITY);
249 return;
250 }
251
252 std::vector<AccessibilityWindowInfo> windowInfos =
253 Singleton<AccessibilityWindowManager>::GetInstance().GetAccessibilityWindows();
254 for (auto &window : windowInfos) {
255 if (window.GetDisplayId() == displayId) {
256 windows.emplace_back(window);
257 }
258 }
259 syncPromise.set_value(RET_OK);
260 }, accountId_, clientName_), "GetWindows");
261 return syncFuture.get();
262 }
263
SetOnKeyPressEventResult(const bool handled,const int32_t sequence)264 void AccessibleAbilityChannel::SetOnKeyPressEventResult(const bool handled, const int32_t sequence)
265 {
266 HILOG_DEBUG();
267
268 if (!eventHandler_) {
269 HILOG_ERROR("eventHandler_ is nullptr.");
270 return;
271 }
272
273 eventHandler_->PostTask(std::bind([=](int32_t accountId, const std::string &name) -> void {
274 sptr<KeyEventFilter> keyEventFilter =
275 Singleton<AccessibleAbilityManagerService>::GetInstance().GetKeyEventFilter();
276 if (!keyEventFilter) {
277 return;
278 }
279
280 sptr<AccessibleAbilityConnection> clientConnection = GetConnection(accountId, name);
281 if (!clientConnection) {
282 HILOG_ERROR("There is no client connection");
283 return;
284 }
285 keyEventFilter->SetServiceOnKeyEventResult(*clientConnection, handled, sequence);
286 }, accountId_, clientName_), "SetOnKeyPressEventResult");
287 }
288
SendSimulateGesture(const std::shared_ptr<AccessibilityGestureInjectPath> & gesturePath)289 RetError AccessibleAbilityChannel::SendSimulateGesture(
290 const std::shared_ptr<AccessibilityGestureInjectPath>& gesturePath)
291 {
292 HILOG_INFO();
293 if (!eventHandler_) {
294 HILOG_ERROR("eventHandler_ is nullptr");
295 return RET_ERR_NULLPTR;
296 }
297 std::promise<RetError> syncPromise;
298 std::future syncFuture = syncPromise.get_future();
299
300 eventHandler_->PostTask(std::bind([gesturePath, &syncPromise](int32_t accountId, const std::string &name) -> void {
301 HILOG_DEBUG();
302 sptr<AccessibleAbilityConnection> clientConnection = GetConnection(accountId, name);
303 if (!clientConnection) {
304 HILOG_ERROR("There is no client connection");
305 syncPromise.set_value(RET_ERR_NO_CONNECTION);
306 return;
307 }
308
309 if (!(clientConnection->GetAbilityInfo().GetCapabilityValues() & Capability::CAPABILITY_GESTURE)) {
310 HILOG_ERROR("AccessibleAbilityChannel::SendSimulateGesture failed: no capability");
311 syncPromise.set_value(RET_ERR_NO_CAPABILITY);
312 return;
313 }
314
315 sptr<TouchEventInjector> touchEventInjector =
316 Singleton<AccessibleAbilityManagerService>::GetInstance().GetTouchEventInjector();
317 if (!touchEventInjector) {
318 HILOG_ERROR("touchEventInjector is null");
319 syncPromise.set_value(RET_ERR_NO_INJECTOR);
320 return;
321 }
322 touchEventInjector->InjectEvents(gesturePath);
323 syncPromise.set_value(RET_OK);
324 }, accountId_, clientName_), "SendSimulateGesture");
325 return syncFuture.get();
326 }
327
SetTargetBundleName(const std::vector<std::string> & targetBundleNames)328 RetError AccessibleAbilityChannel::SetTargetBundleName(const std::vector<std::string> &targetBundleNames)
329 {
330 HILOG_DEBUG();
331 if (!eventHandler_) {
332 HILOG_ERROR("eventHandler_ is nullptr");
333 return RET_ERR_NULLPTR;
334 }
335 std::promise<RetError> syncPromise;
336 std::future syncFuture = syncPromise.get_future();
337
338 eventHandler_->PostTask(std::bind([targetBundleNames, &syncPromise](
339 int32_t accountId, const std::string &name) -> void {
340 HILOG_DEBUG();
341 sptr<AccessibleAbilityConnection> clientConnection = GetConnection(accountId, name);
342 if (!clientConnection) {
343 HILOG_ERROR("There is no client connection");
344 syncPromise.set_value(RET_ERR_NO_CONNECTION);
345 return;
346 }
347
348 clientConnection->SetAbilityInfoTargetBundleName(targetBundleNames);
349 syncPromise.set_value(RET_OK);
350 }, accountId_, clientName_), "SetTargetBundleName");
351 return syncFuture.get();
352 }
353
GetConnection(int32_t accountId,const std::string & clientName)354 sptr<AccessibleAbilityConnection> AccessibleAbilityChannel::GetConnection(
355 int32_t accountId, const std::string &clientName)
356 {
357 HILOG_DEBUG();
358 sptr<AccessibilityAccountData> accountData =
359 Singleton<AccessibleAbilityManagerService>::GetInstance().GetAccountData(accountId);
360 if (!accountData) {
361 HILOG_ERROR("accountData is nullptr");
362 return nullptr;
363 }
364
365 HILOG_DEBUG("accountId[%{public}d] clientName[%{public}s]", accountId, clientName.c_str());
366 return accountData->GetAccessibleAbilityConnection(clientName);
367 }
368
GetElementOperator(int32_t accountId,int32_t windowId,int32_t focusType,const std::string & clientName,sptr<IAccessibilityElementOperator> & elementOperator)369 RetError AccessibleAbilityChannel::GetElementOperator(
370 int32_t accountId, int32_t windowId, int32_t focusType, const std::string &clientName,
371 sptr<IAccessibilityElementOperator> &elementOperator)
372 {
373 HILOG_DEBUG();
374 elementOperator = nullptr;
375 sptr<AccessibleAbilityConnection> clientConnection = GetConnection(accountId, clientName);
376 if (!clientConnection) {
377 HILOG_ERROR("There is no client connection");
378 return RET_ERR_NO_CONNECTION;
379 }
380 if (!(clientConnection->GetAbilityInfo().GetCapabilityValues() & Capability::CAPABILITY_RETRIEVE)) {
381 HILOG_ERROR("the client has no retieve capability");
382 return RET_ERR_NO_CAPABILITY;
383 }
384
385 sptr<AccessibilityAccountData> accountData =
386 Singleton<AccessibleAbilityManagerService>::GetInstance().GetAccountData(accountId);
387 if (!accountData) {
388 HILOG_ERROR("accountData is nullptr");
389 return RET_ERR_NULLPTR;
390 }
391 int32_t realId = Singleton<AccessibilityWindowManager>::GetInstance().ConvertToRealWindowId(windowId, focusType);
392 sptr<AccessibilityWindowConnection> connection = accountData->GetAccessibilityWindowConnection(realId);
393 if (!connection) {
394 HILOG_ERROR("windowId[%{public}d] has no connection", realId);
395 return RET_ERR_NO_WINDOW_CONNECTION;
396 }
397 elementOperator = connection->GetProxy();
398 if (!elementOperator) {
399 HILOG_ERROR("The proxy of window connection is nullptr");
400 return RET_ERR_NULLPTR;
401 }
402 return RET_OK;
403 }
404 } // namespace Accessibility
405 } // namespace OHOS