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_client.h"
17
18 #include <cinttypes>
19 #include <hitrace_meter.h>
20
21 #include "accessibility_element_operator_callback_impl.h"
22 #include "hilog_wrapper.h"
23
24 namespace OHOS {
25 namespace Accessibility {
26 namespace {
27 constexpr uint32_t TIME_OUT_OPERATOR = 5000;
28 constexpr int32_t REQUEST_ID_MAX = 0x0000FFFF;
29 } // namespace
30
GenerateRequestId()31 int32_t AccessibleAbilityChannelClient::GenerateRequestId()
32 {
33 int32_t requestId = requestId_++;
34 requestId = requestId % REQUEST_ID_MAX;
35
36 return requestId;
37 }
38
GetRemote()39 sptr<IRemoteObject> AccessibleAbilityChannelClient::GetRemote()
40 {
41 return proxy_->AsObject();
42 }
43
SetOnKeyPressEventResult(const bool handled,const int32_t sequence)44 void AccessibleAbilityChannelClient::SetOnKeyPressEventResult(const bool handled, const int32_t sequence)
45 {
46 HILOG_INFO("[channelId:%{public}d]", channelId_);
47 if (proxy_) {
48 proxy_->SetOnKeyPressEventResult(handled, sequence);
49 } else {
50 HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId_);
51 }
52 }
53
FindFocusedElementInfo(int32_t accessibilityWindowId,int32_t elementId,int32_t focusType,AccessibilityElementInfo & elementInfo)54 RetError AccessibleAbilityChannelClient::FindFocusedElementInfo(int32_t accessibilityWindowId,
55 int32_t elementId, int32_t focusType, AccessibilityElementInfo &elementInfo)
56 {
57 HILOG_DEBUG("[channelId:%{public}d]", channelId_);
58 HITRACE_METER_NAME(HITRACE_TAG_ACCESSIBILITY_MANAGER, "FindFocusedElement");
59 if (!proxy_) {
60 HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId_);
61 return RET_ERR_SAMGR;
62 }
63
64 int32_t requestId = GenerateRequestId();
65 sptr<AccessibilityElementOperatorCallbackImpl> elementOperator =
66 new(std::nothrow) AccessibilityElementOperatorCallbackImpl();
67 if (!elementOperator) {
68 HILOG_ERROR("Failed to create elementOperator.");
69 return RET_ERR_NULLPTR;
70 }
71 std::future<void> promiseFuture = elementOperator->promise_.get_future();
72
73 int32_t windowId = accessibilityWindowId;
74 if (accessibilityWindowId == ANY_WINDOW_ID && focusType == FOCUS_TYPE_ACCESSIBILITY &&
75 accessibilityFocusedWindowId_ != INVALID_WINDOW_ID) {
76 windowId = accessibilityFocusedWindowId_;
77 HILOG_INFO("Convert into accessibility focused window id[%{public}d]", windowId);
78 }
79
80 RetError ret = proxy_->FindFocusedElementInfo(windowId,
81 elementId, focusType, requestId, elementOperator);
82 if (ret != RET_OK) {
83 HILOG_ERROR("FindFocusedElementInfo failed. ret[%{public}d]", ret);
84 return ret;
85 }
86 HILOG_DEBUG("channelId:%{public}d, windowId:%{public}d, elementId:%{public}d, focusType:%{public}d",
87 channelId_, windowId, elementId, focusType);
88
89 std::future_status wait = promiseFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
90 if (wait != std::future_status::ready) {
91 HILOG_ERROR("Failed to wait result");
92 return RET_ERR_TIME_OUT;
93 }
94
95 if (elementOperator->accessibilityInfoResult_.GetAccessibilityId() ==
96 AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID) {
97 HILOG_ERROR("The elementInfo from ace is wrong");
98 return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
99 }
100 HILOG_INFO("Get result successfully from ace.");
101
102 elementInfo = elementOperator->accessibilityInfoResult_;
103 return RET_OK;
104 }
105
SendSimulateGesture(const std::shared_ptr<AccessibilityGestureInjectPath> & gesturePath)106 RetError AccessibleAbilityChannelClient::SendSimulateGesture(
107 const std::shared_ptr<AccessibilityGestureInjectPath> &gesturePath)
108 {
109 HILOG_INFO("[channelId:%{public}d]", channelId_);
110 if (proxy_) {
111 return proxy_->SendSimulateGesture(gesturePath);
112 } else {
113 HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId_);
114 return RET_ERR_SAMGR;
115 }
116 }
117
ExecuteAction(int32_t accessibilityWindowId,int32_t elementId,int32_t action,const std::map<std::string,std::string> & actionArguments)118 RetError AccessibleAbilityChannelClient::ExecuteAction(int32_t accessibilityWindowId,
119 int32_t elementId, int32_t action, const std::map<std::string, std::string> &actionArguments)
120 {
121 HILOG_DEBUG("[channelId:%{public}d]", channelId_);
122 HITRACE_METER_NAME(HITRACE_TAG_ACCESSIBILITY_MANAGER, "ExecuteAction");
123 if (!proxy_) {
124 HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId_);
125 return RET_ERR_SAMGR;
126 }
127
128 int32_t requestId = GenerateRequestId();
129 sptr<AccessibilityElementOperatorCallbackImpl> elementOperator =
130 new(std::nothrow) AccessibilityElementOperatorCallbackImpl();
131 if (!elementOperator) {
132 HILOG_ERROR("Failed to create elementOperator.");
133 return RET_ERR_NULLPTR;
134 }
135 std::future<void> promiseFuture = elementOperator->promise_.get_future();
136
137 RetError ret = proxy_->ExecuteAction(accessibilityWindowId,
138 elementId, action, actionArguments, requestId, elementOperator);
139 if (ret != RET_OK) {
140 HILOG_ERROR("ExecuteAction failed. ret[%{public}d]", ret);
141 return ret;
142 }
143
144 std::future_status wait = promiseFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
145 if (wait != std::future_status::ready) {
146 HILOG_ERROR("Failed to wait result");
147 return RET_ERR_TIME_OUT;
148 }
149 HILOG_INFO("Get result successfully from ace. executeActionResult_[%{public}d]",
150 elementOperator->executeActionResult_);
151
152 if (elementOperator->executeActionResult_) {
153 switch (action) {
154 case ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS:
155 accessibilityFocusedWindowId_ = accessibilityWindowId;
156 HILOG_INFO("Set accessibility focused window id[%{public}d]", accessibilityFocusedWindowId_);
157 break;
158 case ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS:
159 accessibilityFocusedWindowId_ = INVALID_WINDOW_ID;
160 HILOG_INFO("Clear accessibility focused window id");
161 break;
162 default:
163 break;
164 }
165 }
166 return elementOperator->executeActionResult_ ? RET_OK : RET_ERR_PERFORM_ACTION_FAILED_BY_ACE;
167 }
168
SearchElementInfosByAccessibilityId(int32_t accessibilityWindowId,int32_t elementId,int32_t mode,std::vector<AccessibilityElementInfo> & elementInfos)169 RetError AccessibleAbilityChannelClient::SearchElementInfosByAccessibilityId(int32_t accessibilityWindowId,
170 int32_t elementId, int32_t mode, std::vector<AccessibilityElementInfo> &elementInfos)
171 {
172 HILOG_DEBUG("[channelId:%{public}d] [windowId:%{public}d]", channelId_, accessibilityWindowId);
173 HITRACE_METER_NAME(HITRACE_TAG_ACCESSIBILITY_MANAGER, "SearchElementById");
174 if (!proxy_) {
175 HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId_);
176 return RET_ERR_SAMGR;
177 }
178
179 int32_t requestId = GenerateRequestId();
180 sptr<AccessibilityElementOperatorCallbackImpl> elementOperator =
181 new(std::nothrow) AccessibilityElementOperatorCallbackImpl();
182 if (!elementOperator) {
183 HILOG_ERROR("Failed to create elementOperator.");
184 return RET_ERR_NULLPTR;
185 }
186 std::future<void> promiseFuture = elementOperator->promise_.get_future();
187
188 RetError ret = proxy_->SearchElementInfoByAccessibilityId(accessibilityWindowId, elementId, requestId,
189 elementOperator, mode);
190 if (ret != RET_OK) {
191 HILOG_ERROR("SearchElementInfosByAccessibilityId failed. ret[%{public}d]", ret);
192 return ret;
193 }
194
195 std::future_status wait = promiseFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
196 if (wait != std::future_status::ready) {
197 HILOG_ERROR("Failed to wait result");
198 return RET_ERR_TIME_OUT;
199 }
200
201 for (auto &info : elementOperator->elementInfosResult_) {
202 if (info.GetAccessibilityId() == AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID) {
203 HILOG_ERROR("The elementInfo from ace is wrong");
204 return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
205 }
206 }
207 HILOG_INFO("Get result successfully from ace. size[%{public}zu]", elementOperator->elementInfosResult_.size());
208 elementInfos = elementOperator->elementInfosResult_;
209 return RET_OK;
210 }
211
GetWindow(const int32_t windowId,AccessibilityWindowInfo & windowInfo)212 RetError AccessibleAbilityChannelClient::GetWindow(const int32_t windowId, AccessibilityWindowInfo &windowInfo)
213 {
214 HILOG_DEBUG("[channelId:%{public}d] [windowId:%{public}d]", channelId_, windowId);
215 HITRACE_METER(HITRACE_TAG_ACCESSIBILITY_MANAGER);
216 if (!proxy_) {
217 HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId_);
218 return RET_ERR_SAMGR;
219 }
220 return proxy_->GetWindow(windowId, windowInfo);
221 }
222
GetWindows(std::vector<AccessibilityWindowInfo> & windows)223 RetError AccessibleAbilityChannelClient::GetWindows(std::vector<AccessibilityWindowInfo> &windows)
224 {
225 HILOG_DEBUG("[channelId:%{public}d]", channelId_);
226 HITRACE_METER(HITRACE_TAG_ACCESSIBILITY_MANAGER);
227 if (proxy_) {
228 return proxy_->GetWindows(windows);
229 } else {
230 HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId_);
231 return RET_ERR_SAMGR;
232 }
233 }
234
GetWindows(const uint64_t displayId,std::vector<AccessibilityWindowInfo> & windows) const235 RetError AccessibleAbilityChannelClient::GetWindows(const uint64_t displayId,
236 std::vector<AccessibilityWindowInfo> &windows) const
237 {
238 HILOG_DEBUG("[channelId:%{public}d] [displayId:%{public}" PRIu64 "]", channelId_, displayId);
239 HITRACE_METER_NAME(HITRACE_TAG_ACCESSIBILITY_MANAGER, "GetWindowsByDisplayId");
240 if (proxy_) {
241 return proxy_->GetWindowsByDisplayId(displayId, windows);
242 } else {
243 HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId_);
244 return RET_ERR_SAMGR;
245 }
246 }
247
SearchElementInfosByText(int32_t accessibilityWindowId,int32_t elementId,const std::string & text,std::vector<AccessibilityElementInfo> & elementInfos)248 RetError AccessibleAbilityChannelClient::SearchElementInfosByText(int32_t accessibilityWindowId,
249 int32_t elementId, const std::string &text, std::vector<AccessibilityElementInfo> &elementInfos)
250 {
251 HILOG_DEBUG("[channelId:%{public}d]", channelId_);
252 HITRACE_METER_NAME(HITRACE_TAG_ACCESSIBILITY_MANAGER, "SearchElementByText");
253 if (!proxy_) {
254 HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId_);
255 return RET_ERR_SAMGR;
256 }
257
258 int32_t requestId = GenerateRequestId();
259 sptr<AccessibilityElementOperatorCallbackImpl> elementOperator =
260 new(std::nothrow) AccessibilityElementOperatorCallbackImpl();
261 if (!elementOperator) {
262 HILOG_ERROR("Failed to create elementOperator.");
263 return RET_ERR_NULLPTR;
264 }
265 std::future<void> promiseFuture = elementOperator->promise_.get_future();
266
267 RetError ret = proxy_->SearchElementInfosByText(accessibilityWindowId,
268 elementId, text, requestId, elementOperator);
269 if (ret != RET_OK) {
270 HILOG_ERROR("SearchElementInfosByText failed. ret[%{public}d]", ret);
271 return ret;
272 }
273
274 std::future_status wait = promiseFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
275 if (wait != std::future_status::ready) {
276 HILOG_ERROR("Failed to wait result");
277 return RET_ERR_TIME_OUT;
278 }
279
280 for (auto &info : elementOperator->elementInfosResult_) {
281 if (info.GetAccessibilityId() == AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID) {
282 HILOG_ERROR("The elementInfo from ace is wrong");
283 return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
284 }
285 }
286 HILOG_INFO("Get result successfully from ace. size[%{public}zu]", elementOperator->elementInfosResult_.size());
287 elementInfos = elementOperator->elementInfosResult_;
288 return RET_OK;
289 }
290
FocusMoveSearch(int32_t accessibilityWindowId,int32_t elementId,int32_t direction,AccessibilityElementInfo & elementInfo)291 RetError AccessibleAbilityChannelClient::FocusMoveSearch(int32_t accessibilityWindowId,
292 int32_t elementId, int32_t direction, AccessibilityElementInfo &elementInfo)
293 {
294 HILOG_DEBUG("[channelId:%{public}d]", channelId_);
295 if (!proxy_) {
296 HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId_);
297 return RET_ERR_SAMGR;
298 }
299
300 int32_t requestId = GenerateRequestId();
301 sptr<AccessibilityElementOperatorCallbackImpl> elementOperator =
302 new(std::nothrow) AccessibilityElementOperatorCallbackImpl();
303 if (!elementOperator) {
304 HILOG_ERROR("Failed to create elementOperator.");
305 return RET_ERR_NULLPTR;
306 }
307 std::future<void> promiseFuture = elementOperator->promise_.get_future();
308
309 RetError ret = proxy_->FocusMoveSearch(accessibilityWindowId, elementId, direction, requestId, elementOperator);
310 if (ret != RET_OK) {
311 HILOG_ERROR("FocusMoveSearch failed. ret[%{public}d]", ret);
312 return ret;
313 }
314
315 std::future_status wait = promiseFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
316 if (wait != std::future_status::ready) {
317 HILOG_ERROR("Failed to wait result");
318 return RET_ERR_TIME_OUT;
319 }
320
321 if (elementOperator->accessibilityInfoResult_.GetAccessibilityId() ==
322 AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID) {
323 HILOG_ERROR("The elementInfo from ace is wrong");
324 return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
325 }
326
327 HILOG_INFO("Get result successfully from ace");
328 elementInfo = elementOperator->accessibilityInfoResult_;
329 return RET_OK;
330 }
331
SetTargetBundleName(const std::vector<std::string> & targetBundleNames)332 RetError AccessibleAbilityChannelClient::SetTargetBundleName(const std::vector<std::string> &targetBundleNames)
333 {
334 HILOG_INFO("[channelId:%{public}d]", channelId_);
335 if (proxy_) {
336 return proxy_->SetTargetBundleName(targetBundleNames);
337 } else {
338 HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId_);
339 return RET_ERR_SAMGR;
340 }
341 }
342 } // namespace Accessibility
343 } // namespace OHOS