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 "accessibility_interaction_bridge.h"
17
18 #include <algorithm>
19 #include <new>
20 #include "accessibility_ability_info.h"
21 #include "accessibility_account_data.h"
22 #include "accessibility_display_manager.h"
23 #include "accessibility_window_manager.h"
24 #include "accessible_ability_connection.h"
25
26 namespace OHOS {
27 namespace Accessibility {
28 const int INTERACTION_BRIDGE_CHANNEL_ID = 0;
29 const int NONE_ID = -1;
30
GetInstance()31 AccessibilityInteractionBridge& AccessibilityInteractionBridge::GetInstance()
32 {
33 HILOG_DEBUG("start");
34 static AccessibilityInteractionBridge instance_;
35
36 return instance_;
37 }
38
AccessibilityInteractionBridge()39 AccessibilityInteractionBridge::AccessibilityInteractionBridge()
40 {
41 HILOG_DEBUG("start");
42 AppExecFwk::ExtensionAbilityInfo info;
43 sptr<AccessibilityAbilityInfo> abilityInfo = new(std::nothrow) AccessibilityAbilityInfo(info);
44 if (!abilityInfo) {
45 HILOG_ERROR("abilityInfo is not matched");
46 return;
47 }
48 abilityInfo->SetCapabilityValues(Capability::CAPABILITY_RETRIEVE);
49 accountData_ = DelayedSingleton<AccessibleAbilityManagerService>::GetInstance()->GetCurrentAccountData();
50 connection_ = new(std::nothrow) AccessibleAbilityConnection(accountData_,
51 INTERACTION_BRIDGE_CHANNEL_ID, *abilityInfo);
52 if (!connection_) {
53 HILOG_ERROR("connection_ is null");
54 return;
55 }
56 channel_ = new(std::nothrow) AccessibleAbilityChannelStubImpl(*connection_);
57 if (!channel_) {
58 HILOG_ERROR("channel_ is null");
59 return;
60 }
61 if (!channel_) {
62 HILOG_DEBUG("channel is nullptr.");
63 AccessibilityOperator::GetInstance().RemoveChannel(INTERACTION_BRIDGE_CHANNEL_ID);
64 } else {
65 HILOG_DEBUG("AddChannel start.");
66 AccessibilityOperator::GetInstance().AddChannel(INTERACTION_BRIDGE_CHANNEL_ID, channel_);
67 }
68 HILOG_INFO("AccessibleAbilityManagerService::AccessibilityInteractionBridge successfully");
69 }
70
FindFocusedElementInfo()71 AccessibilityElementInfo AccessibilityInteractionBridge::FindFocusedElementInfo()
72 {
73 HILOG_DEBUG("[without window]");
74
75 return FindFocusedElementInfo(ANY_WINDOW_ID);
76 }
77
ExecuteActionOnAccessibilityFocused(const ActionType & action)78 bool AccessibilityInteractionBridge::ExecuteActionOnAccessibilityFocused(const ActionType& action)
79 {
80 HILOG_DEBUG("start");
81 auto focus = FindFocusedElementInfo();
82 std::map<std::string, std::string> actionArguments {};
83 HILOG_DEBUG("[ExecuteAction]");
84 return focus.ExecuteAction(action, actionArguments);
85 }
86
Intersect(Rect & focus,Rect source)87 bool Intersect(Rect& focus, Rect source)
88 {
89 HILOG_DEBUG("start");
90 int minx = std::max(focus.GetLeftTopXScreenPostion(), source.GetLeftTopXScreenPostion());
91 int miny = std::max(focus.GetLeftTopYScreenPostion(), source.GetLeftTopYScreenPostion());
92 int maxx = std::min(focus.GetRightBottomXScreenPostion(), source.GetRightBottomXScreenPostion());
93 int maxy = std::min(focus.GetRightBottomYScreenPostion(), source.GetRightBottomYScreenPostion());
94 if ((minx > maxx) || (miny > maxy)) {
95 HILOG_DEBUG("The two Rects do not intersect");
96 return false;
97 }
98 focus.SetLeftTopScreenPostion(minx, miny);
99 focus.SetRightBottomScreenPostion(maxx, maxy);
100 return true;
101 }
102
Intersect(Rect & rect,AccessibilityWindowInfo window)103 bool Intersect(Rect& rect, AccessibilityWindowInfo window)
104 {
105 HILOG_DEBUG("start");
106 if (!Intersect(rect, window.GetRectInScreen())) {
107 return false;
108 }
109 return true;
110 }
111
Intersect(Rect & rect,Rosen::Display & display)112 bool Intersect(Rect& rect, Rosen::Display& display)
113 {
114 HILOG_DEBUG("start");
115 Rect source(0, 0, display.GetWidth(), display.GetHeight());
116 if (!Intersect(rect, source)) {
117 return false;
118 }
119 return true;
120 }
121
GetPointerItermOfAccessibilityFocusClick(MMI::PointerEvent::PointerItem & point)122 bool AccessibilityInteractionBridge::GetPointerItermOfAccessibilityFocusClick(MMI::PointerEvent::PointerItem &point)
123 {
124 HILOG_DEBUG("start");
125 auto focus = FindFocusedElementInfo();
126 auto focusRect = focus.GetRectInScreen();
127 float denominator = 2.0;
128 /* Apply magnification if needed. */
129
130 // Intersect with window
131 auto& windowManager = AccessibilityWindowInfoManager::GetInstance();
132 AccessibilityWindowInfo window;
133 auto result = windowManager.GetAccessibilityWindow(windowManager.activeWindowId_, window);
134 if (!result) {
135 return false;
136 }
137 if (!Intersect(focusRect, window)) {
138 return false;
139 }
140 // Intersect with display dummy
141 auto display = AccessibilityDisplayManager::GetInstance().GetDefaultDisplay();
142 if (!Intersect(focusRect, *display)) {
143 return false;
144 }
145
146 float px = (focusRect.GetLeftTopXScreenPostion() + focusRect.GetRightBottomXScreenPostion()) / denominator;
147 float py = (focusRect.GetLeftTopYScreenPostion() + focusRect.GetRightBottomYScreenPostion()) / denominator;
148 point.SetGlobalX(px);
149 point.SetGlobalY(py);
150 return true;
151 }
152
FindFocusedElementInfo(const int & windowId)153 AccessibilityElementInfo AccessibilityInteractionBridge::FindFocusedElementInfo(const int &windowId)
154 {
155 HILOG_DEBUG("[windowId %{public}d]", windowId);
156 AccessibilityElementInfo info {};
157 AccessibilityOperator::GetInstance().FindFocusedElementInfo(INTERACTION_BRIDGE_CHANNEL_ID,
158 windowId, NONE_ID, FOCUS_TYPE_ACCESSIBILITY, info);
159 return info;
160 }
161 } // namespace Accessibility
162 } // namespace OHOS
163