• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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 "accessibility_property.h"
17 
18 #include "core/accessibility/accessibility_constants.h"
19 #include "core/components_ng/base/frame_node.h"
20 #include "core/pipeline_ng/pipeline_context.h"
21 
22 namespace OHOS::Ace::NG {
23 constexpr uint64_t ACTIONS = std::numeric_limits<uint64_t>::max();
GetSupportAction() const24 std::unordered_set<AceAction> AccessibilityProperty::GetSupportAction() const
25 {
26     static const AceAction allActions[] = {
27         AceAction::ACTION_NONE,
28         AceAction::GLOBAL_ACTION_BACK,
29         AceAction::CUSTOM_ACTION,
30         AceAction::ACTION_CLICK,
31         AceAction::ACTION_LONG_CLICK,
32         AceAction::ACTION_SCROLL_FORWARD,
33         AceAction::ACTION_SCROLL_BACKWARD,
34         AceAction::ACTION_FOCUS,
35         AceAction::ACTION_CLEAR_FOCUS,
36         AceAction::ACTION_ACCESSIBILITY_FOCUS,
37         AceAction::ACTION_CLEAR_ACCESSIBILITY_FOCUS,
38         AceAction::ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
39         AceAction::ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
40         AceAction::ACTION_SET_TEXT,
41         AceAction::ACTION_COPY,
42         AceAction::ACTION_PASTE,
43         AceAction::ACTION_CUT,
44         AceAction::ACTION_SELECT,
45         AceAction::ACTION_SET_SELECTION,
46         AceAction::ACTION_CLEAR_SELECTION,
47         AceAction::ACTION_SET_CURSOR_POSITION,
48         AceAction::ACTION_EXEC_SUB_COMPONENT,
49     };
50 
51     std::unordered_set<AceAction> supportActions;
52     if (supportActions_ == 0) {
53         return supportActions;
54     }
55 
56     auto finalSupportActions = supportActions_ & ACTIONS;
57     for (auto action : allActions) {
58         if ((finalSupportActions & (1UL << static_cast<uint32_t>(action))) != 0) {
59             supportActions.emplace(action);
60         }
61     }
62     return supportActions;
63 }
64 
NotifyComponentChangeEvent(AccessibilityEventType eventType)65 void AccessibilityProperty::NotifyComponentChangeEvent(AccessibilityEventType eventType)
66 {
67     auto frameNode = host_.Upgrade();
68     CHECK_NULL_VOID(frameNode);
69     auto pipeline = frameNode->GetContext();
70     CHECK_NULL_VOID(pipeline);
71     pipeline->AddAccessibilityCallbackEvent(AccessibilityCallbackEventId::ON_SEND_ELEMENT_INFO_CHANGE,
72         frameNode->GetAccessibilityId());
73 }
74 
GetText() const75 std::string AccessibilityProperty::GetText() const
76 {
77     return propText_.value_or("");
78 }
79 
GetGroupText(bool forceGetChildren) const80 std::string AccessibilityProperty::GetGroupText(bool forceGetChildren) const
81 {
82     std::string text;
83     GetGroupTextRecursive(forceGetChildren, text);
84     return text;
85 }
86 
GetGroupTextRecursive(bool forceGetChildren,std::string & text) const87 void AccessibilityProperty::GetGroupTextRecursive(bool forceGetChildren, std::string& text) const
88 {
89     auto node = host_.Upgrade();
90     CHECK_NULL_VOID(node);
91     if (node->IsInternal()) {
92         return;
93     }
94     auto level = GetAccessibilityLevel();
95     if (level == Level::AUTO || level == Level::YES_STR) {
96         auto nodeText = GetText();
97         if (!text.empty() && !nodeText.empty()) {
98             text += ", ";
99         }
100         text += nodeText;
101     } else if (level == Level::NO_HIDE_DESCENDANTS) {
102         return;
103     }
104     // Do not change text if level is no
105 
106     if (!(forceGetChildren || IsAccessibilityGroup())) {
107         return;
108     }
109     auto& children = node->GetFrameChildren();
110     for (auto& childWeak : children) {
111         auto child = childWeak.Upgrade();
112         if (child == nullptr) {
113             continue;
114         }
115         child->GetAccessibilityProperty<AccessibilityProperty>()->GetGroupTextRecursive(true, text);
116     }
117 }
118 
GetScrollOffSet() const119 float AccessibilityProperty::GetScrollOffSet() const
120 {
121     return DEFAULT_ACCESSIBILITY_SCROLL_OFFSET;
122 }
123 
HoverTest(const PointF & point,const RefPtr<FrameNode> & root,std::unique_ptr<HoverTestDebugTraceInfo> & debugInfo)124 AccessibilityHoverTestPath AccessibilityProperty::HoverTest(
125     const PointF& point,
126     const RefPtr<FrameNode>& root,
127     std::unique_ptr<HoverTestDebugTraceInfo>& debugInfo)
128 {
129     AccessibilityHoverTestPath path;
130     CHECK_NULL_RETURN(root, path);
131     ACE_SCOPED_TRACE("AccessibilityHoverTest");
132     bool ancestorGroupFlag = false;
133     auto accessibilityProperty = root->GetAccessibilityProperty<NG::AccessibilityProperty>();
134     if (accessibilityProperty != nullptr) {
135         ancestorGroupFlag = accessibilityProperty->IsAccessibilityGroup();
136     }
137     AccessibilityProperty::HoverTestRecursive(point, root, path, debugInfo, ancestorGroupFlag);
138     return path;
139 }
140 
GetHitTestModeStr(HitTestMode hitTestMode,std::string & testModeStr)141 void GetHitTestModeStr(HitTestMode hitTestMode, std::string& testModeStr)
142 {
143     switch (hitTestMode) {
144         case HitTestMode::HTMDEFAULT:
145             testModeStr = "Default";
146             break;
147         case HitTestMode::HTMBLOCK:
148             testModeStr = "Block";
149             break;
150         case HitTestMode::HTMTRANSPARENT:
151             testModeStr = "Transparent";
152             break;
153         case HitTestMode::HTMNONE:
154             testModeStr = "None";
155             break;
156         default:
157             testModeStr = "Unsupported";
158     }
159 }
160 
CreateNodeSearchInfo(const RefPtr<FrameNode> & node,const PointF & parentPoint,bool & ancestorGroupFlag)161 std::unique_ptr<JsonValue> AccessibilityProperty::CreateNodeSearchInfo(const RefPtr<FrameNode>& node,
162     const PointF& parentPoint, bool& ancestorGroupFlag)
163 {
164     auto nodeInfo = JsonUtil::Create();
165     nodeInfo->Put("id", node->GetAccessibilityId());
166     nodeInfo->Put("tag", node->GetTag().c_str());
167     if (!node->IsRootNode()) {
168         if (node->GetParent()) {
169             nodeInfo->Put("parent", node->GetParent()->GetAccessibilityId());
170         } else {
171             nodeInfo->Put("parent", -1);
172         }
173     }
174     nodeInfo->Put("visible", node->IsVisible());
175     auto [shouldSearchSelf, shouldSearchChildren, groupFlag]
176         = AccessibilityProperty::GetSearchStrategy(node, ancestorGroupFlag);
177     nodeInfo->Put("shouldSearchSelf", shouldSearchSelf);
178     nodeInfo->Put("shouldSearchChildren", shouldSearchChildren);
179     nodeInfo->Put("currentGroup", groupFlag);
180 
181     auto renderContext = node->GetRenderContext();
182     auto rect = renderContext->GetPaintRectWithoutTransform();
183     PointF selfPoint = parentPoint;
184     renderContext->GetPointWithRevert(selfPoint);
185     bool hitSelf = rect.IsInnerRegion(selfPoint);
186     nodeInfo->Put("hitNode", hitSelf);
187     nodeInfo->Put("rect", rect.ToString().c_str());
188     nodeInfo->Put("hoverPoint", selfPoint.ToString().c_str());
189     nodeInfo->Put("clip", renderContext->GetClipEdge().value_or(false));
190 
191     auto eventHub = node->GetEventHub<EventHub>();
192     nodeInfo->Put("enabled", eventHub->IsEnabled());
193 
194     auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
195     if (accessibilityProperty != nullptr) {
196         nodeInfo->Put("accessibilityLevel", accessibilityProperty->GetAccessibilityLevel().c_str());
197         nodeInfo->Put("accessibilityGroup", accessibilityProperty->IsAccessibilityGroup());
198         nodeInfo->Put("hasVirtualNode", accessibilityProperty->HasAccessibilityVirtualNode());
199         nodeInfo->Put("accessibilityText", accessibilityProperty->GetAccessibilityText().c_str());
200         nodeInfo->Put("accessibilityDescription", accessibilityProperty->GetAccessibilityDescription().c_str());
201     }
202 
203     std::string testModeStr = "";
204     GetHitTestModeStr(node->GetHitTestMode(), testModeStr);
205     nodeInfo->Put("hitTestMode", testModeStr.c_str());
206     return nodeInfo;
207 }
208 
ProcessHoverTestRecursive(const PointF & noOffsetPoint,const RefPtr<FrameNode> & node,AccessibilityHoverTestPath & path,std::unique_ptr<HoverTestDebugTraceInfo> & debugInfo,RecursiveParam recursiveParam)209 bool AccessibilityProperty::ProcessHoverTestRecursive(const PointF& noOffsetPoint, const RefPtr<FrameNode>& node,
210     AccessibilityHoverTestPath& path, std::unique_ptr<HoverTestDebugTraceInfo>& debugInfo,
211     RecursiveParam recursiveParam)
212 {
213     auto property = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
214     auto virtualNode = property->GetAccessibilityVirtualNode();
215     if (virtualNode != nullptr) {
216         auto frameNode = AceType::DynamicCast<FrameNode>(virtualNode);
217         CHECK_NULL_RETURN(frameNode, false);
218 
219         if (AccessibilityProperty::HoverTestRecursive(noOffsetPoint, frameNode, path, debugInfo,
220             recursiveParam.ancestorGroupFlag)) {
221             return true;
222         }
223     } else {
224         auto children = node->GetFrameChildren();
225         for (auto childWeak = children.rbegin(); childWeak != children.rend(); ++childWeak) {
226             auto child = childWeak->Upgrade();
227             if (child == nullptr) {
228                 continue;
229             }
230             if (AccessibilityProperty::HoverTestRecursive(noOffsetPoint, child, path, debugInfo,
231                 recursiveParam.ancestorGroupFlag)) {
232                 return true;
233             }
234         }
235     }
236     return recursiveParam.hitTarget;
237 }
238 
HoverTestRecursive(const PointF & parentPoint,const RefPtr<FrameNode> & node,AccessibilityHoverTestPath & path,std::unique_ptr<HoverTestDebugTraceInfo> & debugInfo,bool & ancestorGroupFlag)239 bool AccessibilityProperty::HoverTestRecursive(
240     const PointF& parentPoint,
241     const RefPtr<FrameNode>& node,
242     AccessibilityHoverTestPath& path,
243     std::unique_ptr<HoverTestDebugTraceInfo>& debugInfo,
244     bool& ancestorGroupFlag)
245 {
246     if (!node->IsAccessibilityVirtualNode()) {
247         if (!node->IsActive() || node->IsInternal()) {
248             return false;
249         }
250     }
251     if (debugInfo != nullptr) {
252         auto nodeInfo = CreateNodeSearchInfo(node, parentPoint, ancestorGroupFlag);
253         debugInfo->trace.push_back(std::move(nodeInfo));
254     }
255     bool hitTarget = false;
256     if (!node->IsVisible()) {
257         return false;
258     }
259 
260     auto [shouldSearchSelf, shouldSearchChildren, currentGroupFlag]
261         = AccessibilityProperty::GetSearchStrategy(node, ancestorGroupFlag);
262 
263     auto renderContext = node->GetRenderContext();
264     auto rect = renderContext->GetPaintRectWithoutTransform();
265     PointF selfPoint = parentPoint;
266     renderContext->GetPointWithRevert(selfPoint);
267     bool hitSelf = rect.IsInnerRegion(selfPoint);
268     if (hitSelf && shouldSearchSelf && (IsAccessibilityFocusable(node) || IsTagInModalDialog(node))) {
269         hitTarget = true;
270         path.push_back(node);
271     }
272     bool hasClip = renderContext->GetClipEdge().value_or(false);
273     if (hasClip && !hitSelf) {
274         return false;
275     }
276 
277     if (shouldSearchChildren) {
278         PointF noOffsetPoint = selfPoint - rect.GetOffset();
279         RecursiveParam recursiveParam;
280         recursiveParam.hitTarget = hitTarget;
281         recursiveParam.ancestorGroupFlag = currentGroupFlag;
282         return ProcessHoverTestRecursive(noOffsetPoint, node, path, debugInfo, recursiveParam);
283     }
284     return hitTarget;
285 }
286 
UpdateSearchStrategyByHitTestMode(HitTestMode hitTestMode,bool & shouldSearchSelf,bool & shouldSearchChildren)287 void UpdateSearchStrategyByHitTestMode(HitTestMode hitTestMode, bool& shouldSearchSelf, bool& shouldSearchChildren)
288 {
289     switch (hitTestMode) {
290         case HitTestMode::HTMBLOCK:
291             shouldSearchChildren = false;
292             break;
293         case HitTestMode::HTMTRANSPARENT:
294             break;
295         case HitTestMode::HTMNONE:
296             shouldSearchSelf = false;
297             break;
298         default:
299             break;
300     }
301 }
302 
303 static const std::set<std::string> TAGS_CROSS_PROCESS_COMPONENT = {
304     V2::XCOMPONENT_ETS_TAG,
305     V2::UI_EXTENSION_COMPONENT_ETS_TAG,
306     V2::EMBEDDED_COMPONENT_ETS_TAG,
307     V2::FORM_ETS_TAG,
308     V2::ISOLATED_COMPONENT_ETS_TAG
309 };
310 
311 static const std::set<std::string> TAGS_MODAL_DIALOG_COMPONENT = {
312     V2::MENU_WRAPPER_ETS_TAG,
313     V2::POPUP_ETS_TAG,
314     V2::SELECT_ETS_TAG,
315     V2::DIALOG_ETS_TAG,
316     V2::SHEET_PAGE_TAG,
317     V2::SHEET_WRAPPER_TAG,
318 };
319 
IsTagInCrossProcessComponent(const std::string & tag)320 bool AccessibilityProperty::IsTagInCrossProcessComponent(const std::string& tag)
321 {
322     if (TAGS_CROSS_PROCESS_COMPONENT.find(tag) != TAGS_CROSS_PROCESS_COMPONENT.end()) {
323         return true;
324     }
325     return false;
326 }
327 
IsTagInModalDialog(const RefPtr<FrameNode> & node)328 bool AccessibilityProperty::IsTagInModalDialog(const RefPtr<FrameNode>& node)
329 {
330     CHECK_NULL_RETURN(node, false);
331     return TAGS_MODAL_DIALOG_COMPONENT.find(node->GetTag()) != TAGS_MODAL_DIALOG_COMPONENT.end();
332 }
333 
GetSearchStrategy(const RefPtr<FrameNode> & node,bool & ancestorGroupFlag)334 std::tuple<bool, bool, bool> AccessibilityProperty::GetSearchStrategy(const RefPtr<FrameNode>& node,
335     bool& ancestorGroupFlag)
336 {
337     bool shouldSearchSelf = true;
338     bool shouldSearchChildren = true;
339     bool currentGroupFlag = false;
340     auto level = AccessibilityProperty::Level::AUTO;
341     do {
342         auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
343         if (accessibilityProperty != nullptr) {
344             level = accessibilityProperty->GetAccessibilityLevel();
345             currentGroupFlag = accessibilityProperty->IsAccessibilityGroup();
346             bool hasAccessibilityText = accessibilityProperty->HasAccessibilityTextOrDescription();
347             if (level == AccessibilityProperty::Level::YES_STR) {
348                 break;
349             } else if (level == AccessibilityProperty::Level::NO_HIDE_DESCENDANTS) {
350                 shouldSearchSelf = false;
351                 shouldSearchChildren = false;
352                 break;
353             } else {
354                 if (level == AccessibilityProperty::Level::NO_STR) {
355                     shouldSearchSelf = false;
356                 } else {
357                     // shouldSearchSelf is true here
358                     if (hasAccessibilityText) {
359                         break;
360                     }
361                 }
362             }
363         }
364         auto eventHub = node->GetEventHub<EventHub>();
365         if (!eventHub->IsEnabled()) {
366             shouldSearchChildren = false;
367             // Fall through to update `shouldSearchSelf`
368         }
369         HitTestMode hitTestMode = node->GetHitTestMode();
370         UpdateSearchStrategyByHitTestMode(hitTestMode, shouldSearchSelf, shouldSearchChildren);
371         if (accessibilityProperty != nullptr && accessibilityProperty->HasAccessibilityVirtualNode() &&
372             accessibilityProperty->GetAccessibilityLevel() != AccessibilityProperty::Level::NO_HIDE_DESCENDANTS) {
373             shouldSearchChildren = true;
374         }
375     } while (0);
376     shouldSearchSelf = IsTagInCrossProcessComponent(node->GetTag()) ? true : shouldSearchSelf;
377     if (ancestorGroupFlag == true) {
378         if (level != AccessibilityProperty::Level::YES_STR) {
379             shouldSearchSelf = false;
380         }
381         currentGroupFlag = true;
382     }
383 
384     return std::make_tuple(shouldSearchSelf, shouldSearchChildren, currentGroupFlag);
385 }
386 
387 static const std::set<std::string> TAGS_FOCUSABLE = {
388     V2::CHECKBOX_ETS_TAG,
389     V2::CHECKBOXGROUP_ETS_TAG,
390     V2::GAUGE_ETS_TAG,
391     V2::MARQUEE_ETS_TAG,
392     V2::MENU_ETS_TAG,
393     V2::MENU_ITEM_ETS_TAG,
394     V2::MENU_ITEM_GROUP_ETS_TAG,
395     V2::NAVIGATION_VIEW_ETS_TAG,
396     V2::DATE_PICKER_ETS_TAG,
397     V2::PROGRESS_ETS_TAG,
398     V2::RADIO_ETS_TAG,
399     V2::RATING_ETS_TAG,
400     V2::SCROLL_BAR_ETS_TAG,
401     V2::SELECT_ETS_TAG,
402     V2::SLIDER_ETS_TAG,
403     V2::STEPPER_ETS_TAG,
404     V2::TEXT_ETS_TAG,
405     V2::TEXTCLOCK_ETS_TAG,
406     V2::TEXT_PICKER_ETS_TAG,
407     V2::TEXTTIMER_ETS_TAG,
408     V2::TIME_PICKER_ETS_TAG,
409     V2::TOGGLE_ETS_TAG,
410     V2::WEB_ETS_TAG,
411     V2::XCOMPONENT_ETS_TAG,
412     V2::UI_EXTENSION_COMPONENT_ETS_TAG,
413     V2::EMBEDDED_COMPONENT_ETS_TAG,
414     V2::FORM_ETS_TAG
415 };
416 
IsAccessibilityFocusableTag(const std::string & tag)417 bool AccessibilityProperty::IsAccessibilityFocusableTag(const std::string &tag)
418 {
419     if (TAGS_FOCUSABLE.find(tag) != TAGS_FOCUSABLE.end()) {
420         return true;
421     }
422     return false;
423 }
424 
IsAccessibilityFocusableDebug(const RefPtr<FrameNode> & node,std::unique_ptr<JsonValue> & info)425 bool AccessibilityProperty::IsAccessibilityFocusableDebug(const RefPtr<FrameNode>& node,
426     std::unique_ptr<JsonValue>& info)
427 {
428     bool focusable = IsAccessibilityFocusable(node);
429     info->Put("id", node->GetAccessibilityId());
430     info->Put("tag", node->GetTag().c_str());
431     if (!node->IsRootNode()) {
432         info->Put("parent", node->GetParent()->GetAccessibilityId());
433     }
434     info->Put("selected", focusable);
435 
436     auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
437     if (accessibilityProperty != nullptr) {
438         info->Put("accessibilityLevel", accessibilityProperty->GetAccessibilityLevel().c_str());
439         info->Put("accessibilityGroup", accessibilityProperty->IsAccessibilityGroup());
440         info->Put("hasVirtualNode", accessibilityProperty->HasAccessibilityVirtualNode());
441         info->Put("accessibilityText", accessibilityProperty->GetAccessibilityText().c_str());
442         info->Put("accessibilityDescription", accessibilityProperty->GetAccessibilityDescription().c_str());
443         info->Put("text", accessibilityProperty->GetText().c_str());
444         info->Put("hasAction", accessibilityProperty->HasAction());
445     }
446 
447     auto eventHub = node->GetEventHub<EventHub>();
448     info->Put("enabled", eventHub->IsEnabled());
449     auto gestureEventHub = eventHub->GetGestureEventHub();
450     if (gestureEventHub != nullptr) {
451         info->Put("clickable", gestureEventHub->IsAccessibilityClickable());
452         info->Put("longClickable", gestureEventHub->IsAccessibilityLongClickable());
453     }
454     return focusable;
455 }
456 
457 
IsAccessibilityFocusable(const RefPtr<FrameNode> & node)458 bool AccessibilityProperty::IsAccessibilityFocusable(const RefPtr<FrameNode>& node)
459 {
460     if (node->IsRootNode()) {
461         return false;
462     }
463     bool focusable = false;
464     do {
465         auto accessibilityProperty = node->GetAccessibilityProperty<NG::AccessibilityProperty>();
466         if (accessibilityProperty != nullptr) {
467             auto level = accessibilityProperty->GetAccessibilityLevel();
468             if (level == AccessibilityProperty::Level::YES_STR) {
469                 focusable = true;
470                 break;
471             }
472             if (level == AccessibilityProperty::Level::NO_STR) {
473                 break;
474             }
475             if (accessibilityProperty->IsAccessibilityGroup() ||
476                 accessibilityProperty->HasAccessibilityVirtualNode() ||
477                 accessibilityProperty->HasAction() ||
478                 accessibilityProperty->HasAccessibilityTextOrDescription() ||
479                 !accessibilityProperty->GetText().empty()) {
480                 focusable = true;
481                 break;
482             }
483         }
484 
485         auto eventHub = node->GetEventHub<EventHub>();
486         if (!eventHub->IsEnabled()) {
487             focusable = true;
488             break;
489         }
490         auto gestureEventHub = eventHub->GetGestureEventHub();
491         if (gestureEventHub != nullptr) {
492             if (gestureEventHub->IsAccessibilityClickable() ||
493                 gestureEventHub->IsAccessibilityLongClickable()) {
494                 focusable = true;
495                 break;
496             }
497         }
498 
499         if (TAGS_FOCUSABLE.find(node->GetTag()) != TAGS_FOCUSABLE.end()) {
500             focusable = true;
501             break;
502         }
503     } while (0);
504     if (IsTagInCrossProcessComponent(node->GetTag())) {
505         focusable = true;
506     }
507     return focusable;
508 }
509 
HasAccessibilityTextOrDescription() const510 bool AccessibilityProperty::HasAccessibilityTextOrDescription() const
511 {
512     return !accessibilityText_.value_or("").empty() ||
513         !accessibilityDescription_.value_or("").empty();
514 }
515 
HasAction() const516 bool AccessibilityProperty::HasAction() const
517 {
518     return (supportActions_ & ACTIONS) != 0 ||
519         IsCheckable() ||
520         IsScrollable() ||
521         IsEditable() ||
522         IsDeletable();
523 }
524 
SetAccessibilityActions(uint32_t actions)525 void AccessibilityProperty::SetAccessibilityActions(uint32_t actions)
526 {
527     accessibilityActions_ = actions;
528 }
529 
ResetAccessibilityActions()530 void AccessibilityProperty::ResetAccessibilityActions()
531 {
532     accessibilityActions_ = std::nullopt;
533 }
534 
HasAccessibilityActions()535 bool AccessibilityProperty::HasAccessibilityActions()
536 {
537     return accessibilityActions_.has_value();
538 }
539 
GetAccessibilityActions() const540 uint32_t AccessibilityProperty::GetAccessibilityActions() const
541 {
542     return accessibilityActions_.value_or(0);
543 }
544 
SetAccessibilityRole(const std::string & role)545 void AccessibilityProperty::SetAccessibilityRole(const std::string& role)
546 {
547     accessibilityRole_ = role;
548 }
549 
ResetAccessibilityRole()550 void AccessibilityProperty::ResetAccessibilityRole()
551 {
552     accessibilityRole_ = std::nullopt;
553 }
554 
HasAccessibilityRole()555 bool AccessibilityProperty::HasAccessibilityRole()
556 {
557     return accessibilityRole_.has_value();
558 }
559 
GetAccessibilityRole() const560 std::string AccessibilityProperty::GetAccessibilityRole() const
561 {
562     return accessibilityRole_.value_or("");
563 }
564 
SetActions(const ActionsImpl & actionsImpl)565 void AccessibilityProperty::SetActions(const ActionsImpl& actionsImpl)
566 {
567     actionsImpl_ = actionsImpl;
568 }
569 
ActionsDefined(uint32_t action)570 bool AccessibilityProperty::ActionsDefined(uint32_t action)
571 {
572     if (!HasAccessibilityActions()) {
573         return false;
574     }
575     if (!actionsImpl_) {
576         return false;
577     }
578     int result = GetAccessibilityActions() & action;
579     return result != 0;
580 }
581 
SetUserDisabled(const bool & isDisabled)582 void AccessibilityProperty::SetUserDisabled(const bool& isDisabled)
583 {
584     isDisabled_ = isDisabled;
585 }
586 
HasUserDisabled()587 bool AccessibilityProperty::HasUserDisabled()
588 {
589     return isDisabled_.has_value();
590 }
591 
IsUserDisabled()592 bool AccessibilityProperty::IsUserDisabled()
593 {
594     return isDisabled_.value_or(false);
595 }
596 
SetUserSelected(const bool & isSelected)597 void AccessibilityProperty::SetUserSelected(const bool& isSelected)
598 {
599     isSelected_ = isSelected;
600 }
601 
HasUserSelected()602 bool AccessibilityProperty::HasUserSelected()
603 {
604     return isSelected_.has_value();
605 }
606 
IsUserSelected()607 bool AccessibilityProperty::IsUserSelected()
608 {
609     return isSelected_.value_or(false);
610 }
611 
ResetUserSelected()612 void AccessibilityProperty::ResetUserSelected()
613 {
614     isSelected_.reset();
615 }
616 
SetUserCheckedType(const int32_t & checkedType)617 void AccessibilityProperty::SetUserCheckedType(const int32_t& checkedType)
618 {
619     checkedType_ = checkedType;
620 }
621 
HasUserCheckedType()622 bool AccessibilityProperty::HasUserCheckedType()
623 {
624     return checkedType_.has_value();
625 }
626 
GetUserCheckedType()627 int32_t AccessibilityProperty::GetUserCheckedType()
628 {
629     return checkedType_.value_or(0);
630 }
631 
ResetUserCheckedType()632 void AccessibilityProperty::ResetUserCheckedType()
633 {
634     checkedType_.reset();
635 }
636 
SetUserCheckable(const bool & checkable)637 void AccessibilityProperty::SetUserCheckable(const bool& checkable)
638 {
639     isUserCheckable_ = checkable;
640 }
641 
HasUserCheckable()642 bool AccessibilityProperty::HasUserCheckable()
643 {
644     return isUserCheckable_.has_value();
645 }
646 
IsUserCheckable()647 bool AccessibilityProperty::IsUserCheckable()
648 {
649     return isUserCheckable_.value_or(false);
650 }
651 
ResetUserCheckable()652 void AccessibilityProperty::ResetUserCheckable()
653 {
654     isUserCheckable_.reset();
655 }
656 
SetUserMinValue(const int32_t & minValue)657 void AccessibilityProperty::SetUserMinValue(const int32_t& minValue)
658 {
659     minValue_ = minValue;
660 }
661 
HasUserMinValue()662 bool AccessibilityProperty::HasUserMinValue()
663 {
664     return minValue_.has_value();
665 }
666 
GetUserMinValue()667 int32_t AccessibilityProperty::GetUserMinValue()
668 {
669     return minValue_.value_or(-1);
670 }
671 
SetUserMaxValue(const int32_t & maxValue)672 void AccessibilityProperty::SetUserMaxValue(const int32_t& maxValue)
673 {
674     maxValue_ = maxValue;
675 }
676 
HasUserMaxValue()677 bool AccessibilityProperty::HasUserMaxValue()
678 {
679     return maxValue_.has_value();
680 }
681 
GetUserMaxValue()682 int32_t AccessibilityProperty::GetUserMaxValue()
683 {
684     return maxValue_.value_or(-1);
685 }
686 
SetUserCurrentValue(const int32_t & currentValue)687 void AccessibilityProperty::SetUserCurrentValue(const int32_t& currentValue)
688 {
689     currentValue_ = currentValue;
690 }
691 
HasUserCurrentValue()692 bool AccessibilityProperty::HasUserCurrentValue()
693 {
694     return currentValue_.has_value();
695 }
696 
GetUserCurrentValue()697 int32_t AccessibilityProperty::GetUserCurrentValue()
698 {
699     return currentValue_.value_or(-1);
700 }
701 
SetUserTextValue(const std::string & textValue)702 void AccessibilityProperty::SetUserTextValue(const std::string& textValue)
703 {
704     textValue_ = textValue;
705 }
706 
HasUserTextValue()707 bool AccessibilityProperty::HasUserTextValue()
708 {
709     return textValue_.has_value();
710 }
711 
GetUserTextValue()712 std::string AccessibilityProperty::GetUserTextValue()
713 {
714     return textValue_.value_or("");
715 }
716 
SetAccessibilityGroup(bool accessibilityGroup)717 void AccessibilityProperty::SetAccessibilityGroup(bool accessibilityGroup)
718 {
719     if (accessibilityGroup == accessibilityGroup_) {
720         return;
721     }
722     accessibilityGroup_ = accessibilityGroup;
723     NotifyComponentChangeEvent(AccessibilityEventType::ELEMENT_INFO_CHANGE);
724 }
725 
SetAccessibilityText(const std::string & text)726 void AccessibilityProperty::SetAccessibilityText(const std::string& text)
727 {
728     if (text == accessibilityText_.value_or("")) {
729         return;
730     }
731     accessibilityText_ = text;
732     NotifyComponentChangeEvent(AccessibilityEventType::TEXT_CHANGE);
733 }
734 
SetAccessibilityTextWithEvent(const std::string & text)735 void AccessibilityProperty::SetAccessibilityTextWithEvent(const std::string& text)
736 {
737     if (text == accessibilityText_.value_or("")) {
738         return;
739     }
740     accessibilityText_ = text;
741     NotifyComponentChangeEvent(AccessibilityEventType::TEXT_CHANGE);
742 }
743 
SetAccessibilityDescription(const std::string & accessibilityDescription)744 void AccessibilityProperty::SetAccessibilityDescription(const std::string& accessibilityDescription)
745 {
746     if (accessibilityDescription == accessibilityDescription_.value_or("")) {
747         return;
748     }
749     accessibilityDescription_ = accessibilityDescription;
750     NotifyComponentChangeEvent(AccessibilityEventType::TEXT_CHANGE);
751 }
752 
SetAccessibilityDescriptionWithEvent(const std::string & accessibilityDescription)753 void AccessibilityProperty::SetAccessibilityDescriptionWithEvent(const std::string& accessibilityDescription)
754 {
755     if (accessibilityDescription == accessibilityDescription_.value_or("")) {
756         return;
757     }
758     accessibilityDescription_ = accessibilityDescription;
759     NotifyComponentChangeEvent(AccessibilityEventType::TEXT_CHANGE);
760 }
761 
SetAccessibilityLevel(const std::string & accessibilityLevel)762 void AccessibilityProperty::SetAccessibilityLevel(const std::string& accessibilityLevel)
763 {
764     if (accessibilityLevel == accessibilityLevel_.value_or("")) {
765         return;
766     }
767     if (accessibilityLevel == Level::YES_STR ||
768         accessibilityLevel == Level::NO_STR ||
769         accessibilityLevel == Level::NO_HIDE_DESCENDANTS) {
770         accessibilityLevel_ = accessibilityLevel;
771     } else {
772         accessibilityLevel_ = Level::AUTO;
773     }
774     NotifyComponentChangeEvent(AccessibilityEventType::ELEMENT_INFO_CHANGE);
775 }
776 } // namespace OHOS::Ace::NG
777