• 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_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