• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "core/accessibility/native_interface_accessibility_provider.h"
17 
18 using namespace OHOS::Ace;
19 namespace {
20 constexpr int32_t SEND_EVENT_FAILED = -1;
21 constexpr int32_t SEND_EVENT_SUCCESS = 0;
22 
CheckProviderCallback(ArkUI_AccessibilityProviderCallbacks * callbacks)23 bool CheckProviderCallback(ArkUI_AccessibilityProviderCallbacks* callbacks)
24 {
25     if (callbacks == nullptr) {
26         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "callbacks is null");
27         return false;
28     }
29 
30     bool result = true;
31     if (callbacks->findAccessibilityNodeInfosById == nullptr) {
32         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findAccessibilityNodeInfosById is null");
33         result = false;
34     }
35 
36     if (callbacks->findAccessibilityNodeInfosByText == nullptr) {
37         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findAccessibilityNodeInfosByText is null");
38         result = false;
39     }
40 
41     if (callbacks->findFocusedAccessibilityNode == nullptr) {
42         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findFocusedAccessibilityNode is null");
43         result = false;
44     }
45 
46     if (callbacks->findNextFocusAccessibilityNode == nullptr) {
47         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findNextFocusAccessibilityNode is null");
48         result = false;
49     }
50 
51     if (callbacks->executeAccessibilityAction == nullptr) {
52         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "executeAccessibilityAction is null");
53         result = false;
54     }
55 
56     if (callbacks->clearFocusedFocusAccessibilityNode == nullptr) {
57         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "clearFocusedFocusAccessibilityNode is null");
58         result = false;
59     }
60 
61     if (callbacks->getAccessibilityNodeCursorPosition == nullptr) {
62         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "getAccessibilityNodeCursorPosition is null");
63         result = false;
64     }
65 
66     return result;
67 }
68 
CheckProviderCallbackWithInstance(ArkUI_AccessibilityProviderCallbacksWithInstance * callbacks)69 bool CheckProviderCallbackWithInstance(ArkUI_AccessibilityProviderCallbacksWithInstance* callbacks)
70 {
71     if (callbacks == nullptr) {
72         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "callbacks is null");
73         return false;
74     }
75 
76     if (callbacks->findAccessibilityNodeInfosById == nullptr) {
77         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findAccessibilityNodeInfosById is null");
78         return false;
79     }
80 
81     if (callbacks->findAccessibilityNodeInfosByText == nullptr) {
82         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findAccessibilityNodeInfosByText is null");
83         return false;
84     }
85 
86     if (callbacks->findFocusedAccessibilityNode == nullptr) {
87         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findFocusedAccessibilityNode is null");
88         return false;
89     }
90 
91     if (callbacks->findNextFocusAccessibilityNode == nullptr) {
92         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findNextFocusAccessibilityNode is null");
93         return false;
94     }
95 
96     if (callbacks->executeAccessibilityAction == nullptr) {
97         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "executeAccessibilityAction is null");
98         return false;
99     }
100 
101     if (callbacks->clearFocusedFocusAccessibilityNode == nullptr) {
102         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "clearFocusedFocusAccessibilityNode is null");
103         return false;
104     }
105 
106     if (callbacks->getAccessibilityNodeCursorPosition == nullptr) {
107         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "getAccessibilityNodeCursorPosition is null");
108         return false;
109     }
110 
111     return true;
112 }
113 }
AccessibilityProviderRegisterCallback(ArkUI_AccessibilityProviderCallbacks * callbacks)114 int32_t ArkUI_AccessibilityProvider::AccessibilityProviderRegisterCallback(
115     ArkUI_AccessibilityProviderCallbacks* callbacks)
116 {
117     if (!CheckProviderCallback(callbacks)) {
118         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "CheckProviderCallback failed.");
119         if (registerCallback_) {
120             registerCallback_(false);
121         }
122         return ARKUI_ACCESSIBILITY_NATIVE_RESULT_BAD_PARAMETER;
123     }
124 
125     accessibilityProviderCallbacks_ = *callbacks;
126     if (registerCallback_) {
127         registerCallback_(true);
128     }
129     TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "AccessibilityProviderRegisterCallback success");
130     return ARKUI_ACCESSIBILITY_NATIVE_RESULT_SUCCESSFUL;
131 }
132 
AccessibilityProviderRegisterCallbackWithInstance(const char * instanceId,ArkUI_AccessibilityProviderCallbacksWithInstance * callbacks)133 int32_t ArkUI_AccessibilityProvider::AccessibilityProviderRegisterCallbackWithInstance(const char* instanceId,
134     ArkUI_AccessibilityProviderCallbacksWithInstance* callbacks)
135 {
136     if (!CheckProviderCallbackWithInstance(callbacks)) {
137         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "CheckProviderCallbackWithInstance failed.");
138         if (registerCallback_) {
139             registerCallback_(false);
140         }
141         return ARKUI_ACCESSIBILITY_NATIVE_RESULT_BAD_PARAMETER;
142     }
143     accessibilityProviderCallbacksWithInstance_ = *callbacks;
144     if (registerCallback_) {
145         registerCallback_(true);
146     }
147     instanceId_ = instanceId;
148     TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "AccessibilityProviderRegisterCallbackWithInstance success");
149     return ARKUI_ACCESSIBILITY_NATIVE_RESULT_SUCCESSFUL;
150 }
151 
FindAccessibilityNodeInfosById(const int64_t elementId,const int32_t mode,const int32_t requestId,std::vector<ArkUI_AccessibilityElementInfo> & infos)152 int32_t ArkUI_AccessibilityProvider::FindAccessibilityNodeInfosById(
153     const int64_t elementId, const int32_t mode, const int32_t requestId,
154     std::vector<ArkUI_AccessibilityElementInfo>& infos)
155 {
156     auto accessibilityElementInfoList = std::make_unique<ArkUI_AccessibilityElementInfoList>();
157     int32_t ret = 0;
158     if (accessibilityProviderCallbacksWithInstance_.findAccessibilityNodeInfosById) {
159         ret = accessibilityProviderCallbacksWithInstance_.findAccessibilityNodeInfosById(instanceId_.c_str(),
160             elementId, static_cast<ArkUI_AccessibilitySearchMode>(mode),
161             requestId, accessibilityElementInfoList.get());
162     } else if (accessibilityProviderCallbacks_.findAccessibilityNodeInfosById) {
163         ret = accessibilityProviderCallbacks_.findAccessibilityNodeInfosById(
164             elementId, static_cast<ArkUI_AccessibilitySearchMode>(mode),
165             requestId, accessibilityElementInfoList.get());
166     } else {
167         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findAccessibilityNodeInfosById is null");
168         return AccessibilityProviderOperatorErrorCode::NOT_REGISTERED;
169     }
170 
171     if (!accessibilityElementInfoList->CopyAccessibilityElementInfo(infos)) {
172         ret = AccessibilityProviderOperatorErrorCode::COPY_FAILED;
173     }
174 
175     return ret;
176 }
177 
FindAccessibilityNodeInfosByText(const int64_t elementId,std::string text,const int32_t requestId,std::vector<ArkUI_AccessibilityElementInfo> & infos)178 int32_t ArkUI_AccessibilityProvider::FindAccessibilityNodeInfosByText(
179     const int64_t elementId, std::string text, const int32_t requestId,
180     std::vector<ArkUI_AccessibilityElementInfo>& infos)
181 {
182     auto accessibilityElementInfoList = std::make_unique<ArkUI_AccessibilityElementInfoList>();
183     int32_t ret = 0;
184     if (accessibilityProviderCallbacksWithInstance_.findAccessibilityNodeInfosByText) {
185         ret = accessibilityProviderCallbacksWithInstance_.findAccessibilityNodeInfosByText(instanceId_.c_str(),
186             elementId, text.c_str(), requestId, accessibilityElementInfoList.get());
187     } else if (accessibilityProviderCallbacks_.findAccessibilityNodeInfosByText) {
188         ret = accessibilityProviderCallbacks_.findAccessibilityNodeInfosByText(
189             elementId, text.c_str(), requestId, accessibilityElementInfoList.get());
190     } else {
191         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findAccessibilityNodeInfosByText is null");
192         return AccessibilityProviderOperatorErrorCode::NOT_REGISTERED;
193     }
194 
195     if (!accessibilityElementInfoList->CopyAccessibilityElementInfo(infos)) {
196         ret = AccessibilityProviderOperatorErrorCode::COPY_FAILED;
197     }
198 
199     return ret;
200 }
201 
FindFocusedAccessibilityNode(const int64_t elementId,int32_t focusType,const int32_t requestId,ArkUI_AccessibilityElementInfo & elementInfo)202 int32_t ArkUI_AccessibilityProvider::FindFocusedAccessibilityNode(
203     const int64_t elementId, int32_t focusType, const int32_t requestId,
204     ArkUI_AccessibilityElementInfo& elementInfo)
205 {
206     if (accessibilityProviderCallbacksWithInstance_.findFocusedAccessibilityNode) {
207         return accessibilityProviderCallbacksWithInstance_.findFocusedAccessibilityNode(instanceId_.c_str(),
208             elementId, static_cast<ArkUI_AccessibilityFocusType>(focusType), requestId, &elementInfo);
209     } else if (accessibilityProviderCallbacks_.findFocusedAccessibilityNode) {
210         return accessibilityProviderCallbacks_.findFocusedAccessibilityNode(elementId,
211             static_cast<ArkUI_AccessibilityFocusType>(focusType), requestId, &elementInfo);
212     } else {
213         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findFocusedAccessibilityNode is null");
214         return AccessibilityProviderOperatorErrorCode::NOT_REGISTERED;
215     }
216 }
217 
FindNextFocusAccessibilityNode(const int64_t elementId,int32_t direction,const int32_t requestId,ArkUI_AccessibilityElementInfo & elementInfo)218 int32_t ArkUI_AccessibilityProvider::FindNextFocusAccessibilityNode(
219     const int64_t elementId, int32_t direction, const int32_t requestId,
220     ArkUI_AccessibilityElementInfo& elementInfo)
221 {
222     if (accessibilityProviderCallbacksWithInstance_.findNextFocusAccessibilityNode) {
223         return accessibilityProviderCallbacksWithInstance_.findNextFocusAccessibilityNode(instanceId_.c_str(),
224             elementId, static_cast<ArkUI_AccessibilityFocusMoveDirection>(direction), requestId, &elementInfo);
225     } else if (accessibilityProviderCallbacks_.findNextFocusAccessibilityNode) {
226         return accessibilityProviderCallbacks_.findNextFocusAccessibilityNode(elementId,
227             static_cast<ArkUI_AccessibilityFocusMoveDirection>(direction), requestId, &elementInfo);
228     } else {
229         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findNextFocusAccessibilityNode is null");
230         return AccessibilityProviderOperatorErrorCode::NOT_REGISTERED;
231     }
232 }
233 
ExecuteAccessibilityAction(const int64_t elementId,int32_t action,const int32_t requestId,const std::map<std::string,std::string> & actionArguments)234 int32_t ArkUI_AccessibilityProvider::ExecuteAccessibilityAction(
235     const int64_t elementId, int32_t action, const int32_t requestId,
236     const std::map<std::string, std::string>& actionArguments)
237 {
238     auto actionArgumentsUnique = std::make_unique<ArkUI_AccessibilityActionArguments>(actionArguments);
239     if (accessibilityProviderCallbacksWithInstance_.executeAccessibilityAction) {
240         return accessibilityProviderCallbacksWithInstance_.executeAccessibilityAction(instanceId_.c_str(), elementId,
241             static_cast<ArkUI_Accessibility_ActionType>(action),
242             actionArgumentsUnique.get(),
243             requestId);
244     } else if (accessibilityProviderCallbacks_.executeAccessibilityAction) {
245         return accessibilityProviderCallbacks_.executeAccessibilityAction(
246             elementId, static_cast<ArkUI_Accessibility_ActionType>(action),
247             actionArgumentsUnique.get(), requestId);
248     } else {
249         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "executeAccessibilityAction is null");
250         return AccessibilityProviderOperatorErrorCode::NOT_REGISTERED;
251     }
252 }
253 
ClearFocusedAccessibilityNode()254 int32_t ArkUI_AccessibilityProvider::ClearFocusedAccessibilityNode()
255 {
256     if (accessibilityProviderCallbacksWithInstance_.clearFocusedFocusAccessibilityNode) {
257         return accessibilityProviderCallbacksWithInstance_.clearFocusedFocusAccessibilityNode(instanceId_.c_str());
258     } else if (accessibilityProviderCallbacks_.clearFocusedFocusAccessibilityNode) {
259         return accessibilityProviderCallbacks_.clearFocusedFocusAccessibilityNode();
260     } else {
261         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "clearFocusedFocusAccessibilityNode is null");
262         return AccessibilityProviderOperatorErrorCode::NOT_REGISTERED;
263     }
264 }
265 
GetAccessibilityNodeCursorPosition(const int64_t elementId,const int32_t requestId,int32_t & cursorPosition)266 int32_t ArkUI_AccessibilityProvider::GetAccessibilityNodeCursorPosition(
267     const int64_t elementId, const int32_t requestId, int32_t &cursorPosition)
268 {
269     if (accessibilityProviderCallbacksWithInstance_.getAccessibilityNodeCursorPosition) {
270         return accessibilityProviderCallbacksWithInstance_.getAccessibilityNodeCursorPosition(instanceId_.c_str(),
271             elementId, requestId, &cursorPosition);
272     } else if (accessibilityProviderCallbacks_.getAccessibilityNodeCursorPosition) {
273         return accessibilityProviderCallbacks_.getAccessibilityNodeCursorPosition(
274             elementId, requestId, &cursorPosition);
275     } else {
276         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "getAccessibilityNodeCursorPosition is null");
277         return AccessibilityProviderOperatorErrorCode::NOT_REGISTERED;
278     }
279 }
280 
SendAccessibilityAsyncEvent(ArkUI_AccessibilityEventInfo * accessibilityEvent,void (* callback)(int32_t errorCode))281 int32_t ArkUI_AccessibilityProvider::SendAccessibilityAsyncEvent(
282     ArkUI_AccessibilityEventInfo* accessibilityEvent,
283     void (*callback)(int32_t errorCode))
284 {
285     if (accessibilityEvent == nullptr) {
286         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "accessibilityEvent is null");
287         if (callback) {
288             callback(SEND_EVENT_FAILED);
289         }
290         return SEND_EVENT_FAILED;
291     }
292 
293     auto accessibilityProvider = accessibilityProvider_.Upgrade();
294     if (accessibilityProvider == nullptr) {
295         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "accessibilityProvider is null");
296         if (callback) {
297             callback(SEND_EVENT_FAILED);
298         }
299         return SEND_EVENT_FAILED;
300     }
301 
302     accessibilityProvider->SendAccessibilityAsyncEvent(*accessibilityEvent, callback);
303     return SEND_EVENT_SUCCESS;
304 }
305 
SetInnerAccessibilityProvider(const OHOS::Ace::WeakPtr<OHOS::Ace::AccessibilityProvider> & accessibilityProvider)306 void ArkUI_AccessibilityProvider::SetInnerAccessibilityProvider(
307     const OHOS::Ace::WeakPtr<OHOS::Ace::AccessibilityProvider>& accessibilityProvider)
308 {
309     accessibilityProvider_ = accessibilityProvider;
310 }
311 
IsRegister()312 bool ArkUI_AccessibilityProvider::IsRegister()
313 {
314     return accessibilityProviderCallbacks_.findAccessibilityNodeInfosById != nullptr ||
315         accessibilityProviderCallbacksWithInstance_.findAccessibilityNodeInfosById != nullptr;
316 }
317 
SetRegisterCallback(RegisterCallback callback)318 void ArkUI_AccessibilityProvider::SetRegisterCallback(RegisterCallback callback)
319 {
320     registerCallback_ = callback;
321 }
322