Fix coverity issue : Adaptor available check in async task manager
[platform/core/uifw/dali-adaptor.git] / dali / internal / accessibility / bridge / bridge-object.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/accessibility/bridge/bridge-object.h>
20
21 // EXTERNAL INCLUDES
22 #include <iostream>
23 #include <string>
24 #include <string_view>
25 #include <unordered_map>
26
27 using namespace Dali::Accessibility;
28
29 namespace
30 {
31 inline std::string GetAccessiblePath(Accessible* accessible)
32 {
33   auto address = accessible->GetAddress();
34   return address ? ATSPI_PREFIX_PATH + address.GetPath() : ATSPI_NULL_PATH;
35 }
36 } // namespace
37
38 BridgeObject::BridgeObject()
39 {
40 }
41
42 void BridgeObject::RegisterInterfaces()
43 {
44   // DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT)};
45   // mStateChanged = addSignal<std::string, int, int, DBus::EldbusVariant<int>, Accessible*>(desc, "StateChanged");
46   // mDbusServer.addInterface("/", desc, true);
47 }
48
49 void BridgeObject::EmitActiveDescendantChanged(Accessible* obj, Accessible* child)
50 {
51   if(!IsUp() || obj->IsHidden() || obj->GetSuppressedEvents()[AtspiEvent::ACTIVE_DESCENDANT_CHANGED] || child->IsHidden())
52   {
53     return;
54   }
55
56   auto index = child->GetIndexInParent();
57
58   mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<Address>, Address>(
59     GetAccessiblePath(obj),
60     Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
61     "ActiveDescendantChanged",
62     "",
63     index,
64     0,
65     {child->GetAddress()},
66     {"", "root"});
67 }
68
69 void BridgeObject::Emit(Accessible* obj, ObjectPropertyChangeEvent event)
70 {
71   static const std::unordered_map<ObjectPropertyChangeEvent, std::string_view> eventMap{
72     {ObjectPropertyChangeEvent::NAME, "accessible-name"},
73     {ObjectPropertyChangeEvent::DESCRIPTION, "accessible-description"},
74     {ObjectPropertyChangeEvent::VALUE, "accessible-value"},
75     {ObjectPropertyChangeEvent::PARENT, "accessible-parent"},
76     {ObjectPropertyChangeEvent::ROLE, "accessible-role"},
77   };
78
79   if(!IsUp() || obj->IsHidden() || obj->GetSuppressedEvents()[AtspiEvent::PROPERTY_CHANGED])
80   {
81     return;
82   }
83
84   auto eventName = eventMap.find(event);
85
86   if(eventName != eventMap.end())
87   {
88     mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
89       GetAccessiblePath(obj),
90       Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
91       "PropertyChange",
92       std::string{eventName->second},
93       0,
94       0,
95       {0},
96       {"", "root"});
97   }
98 }
99
100 void BridgeObject::Emit(Accessible* obj, WindowEvent event, unsigned int detail)
101 {
102   static const std::unordered_map<WindowEvent, std::string_view> eventMap{
103     {WindowEvent::PROPERTY_CHANGE, "PropertyChange"},
104     {WindowEvent::MINIMIZE, "Minimize"},
105     {WindowEvent::MAXIMIZE, "Maximize"},
106     {WindowEvent::RESTORE, "Restore"},
107     {WindowEvent::CLOSE, "Close"},
108     {WindowEvent::CREATE, "Create"},
109     {WindowEvent::REPARENT, "Reparent"},
110     {WindowEvent::DESKTOP_CREATE, "DesktopCreate"},
111     {WindowEvent::DESKTOP_DESTROY, "DesktopDestroy"},
112     {WindowEvent::DESTROY, "Destroy"},
113     {WindowEvent::ACTIVATE, "Activate"},
114     {WindowEvent::DEACTIVATE, "Deactivate"},
115     {WindowEvent::RAISE, "Raise"},
116     {WindowEvent::LOWER, "Lower"},
117     {WindowEvent::MOVE, "Move"},
118     {WindowEvent::RESIZE, "Resize"},
119     {WindowEvent::SHADE, "Shade"},
120     {WindowEvent::UU_SHADE, "uUshade"},
121     {WindowEvent::RESTYLE, "Restyle"},
122   };
123
124   if(!IsUp() || obj->IsHidden() || obj->GetSuppressedEvents()[AtspiEvent::WINDOW_CHANGED])
125   {
126     return;
127   }
128
129   auto eventName = eventMap.find(event);
130
131   if(eventName != eventMap.end())
132   {
133     mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
134       GetAccessiblePath(obj),
135       Accessible::GetInterfaceName(AtspiInterface::EVENT_WINDOW),
136       std::string{eventName->second},
137       "",
138       detail,
139       0,
140       {0},
141       {"", "root"});
142   }
143 }
144
145 void BridgeObject::EmitStateChanged(Accessible* obj, State state, int newValue, int reserved)
146 {
147   static const std::unordered_map<State, std::string_view> stateMap{
148     {State::INVALID, "invalid"},
149     {State::ACTIVE, "active"},
150     {State::ARMED, "armed"},
151     {State::BUSY, "busy"},
152     {State::CHECKED, "checked"},
153     {State::COLLAPSED, "collapsed"},
154     {State::DEFUNCT, "defunct"},
155     {State::EDITABLE, "editable"},
156     {State::ENABLED, "enabled"},
157     {State::EXPANDABLE, "expandable"},
158     {State::EXPANDED, "expanded"},
159     {State::FOCUSABLE, "focusable"},
160     {State::FOCUSED, "focused"},
161     {State::HAS_TOOLTIP, "has-tooltip"},
162     {State::HORIZONTAL, "horizontal"},
163     {State::ICONIFIED, "iconified"},
164     {State::MODAL, "modal"},
165     {State::MULTI_LINE, "multi-line"},
166     {State::MULTI_SELECTABLE, "multiselectable"},
167     {State::OPAQUE, "opaque"},
168     {State::PRESSED, "pressed"},
169     {State::RESIZEABLE, "resizable"},
170     {State::SELECTABLE, "selectable"},
171     {State::SELECTED, "selected"},
172     {State::SENSITIVE, "sensitive"},
173     {State::SHOWING, "showing"},
174     {State::SINGLE_LINE, "single-line"},
175     {State::STALE, "stale"},
176     {State::TRANSIENT, "transient"},
177     {State::VERTICAL, "vertical"},
178     {State::VISIBLE, "visible"},
179     {State::MANAGES_DESCENDANTS, "manages-descendants"},
180     {State::INDETERMINATE, "indeterminate"},
181     {State::REQUIRED, "required"},
182     {State::TRUNCATED, "truncated"},
183     {State::ANIMATED, "animated"},
184     {State::INVALID_ENTRY, "invalid-entry"},
185     {State::SUPPORTS_AUTOCOMPLETION, "supports-autocompletion"},
186     {State::SELECTABLE_TEXT, "selectable-text"},
187     {State::IS_DEFAULT, "is-default"},
188     {State::VISITED, "visited"},
189     {State::CHECKABLE, "checkable"},
190     {State::HAS_POPUP, "has-popup"},
191     {State::READ_ONLY, "read-only"},
192     {State::HIGHLIGHTED, "highlighted"},
193     {State::HIGHLIGHTABLE, "highlightable"},
194   };
195
196   if(!IsUp() || obj->IsHidden() || obj->GetSuppressedEvents()[AtspiEvent::STATE_CHANGED]) // separate ?
197   {
198     return;
199   }
200
201   auto stateName = stateMap.find(state);
202
203   if(stateName != stateMap.end())
204   {
205     mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
206       GetAccessiblePath(obj),
207       Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
208       "StateChanged",
209       std::string{stateName->second},
210       newValue,
211       reserved,
212       {0},
213       {"", "root"});
214   }
215 }
216
217 void BridgeObject::EmitBoundsChanged(Accessible* obj, Dali::Rect<> rect)
218 {
219   if(!IsUp() || !IsBoundsChangedEventAllowed || obj->IsHidden() || obj->GetSuppressedEvents()[AtspiEvent::BOUNDS_CHANGED])
220   {
221     return;
222   }
223
224   DBus::EldbusVariant<std::tuple<int32_t, int32_t, int32_t, int32_t> > tmp{
225     std::tuple<int32_t, int32_t, int32_t, int32_t>{rect.x, rect.y, rect.width, rect.height}};
226
227   AddCoalescableMessage(CoalescableMessages::BOUNDS_CHANGED, obj, 1.0f, [=]() {
228     mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<std::tuple<int32_t, int32_t, int32_t, int32_t> >, Address>(
229       GetAccessiblePath(obj),
230       Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
231       "BoundsChanged",
232       "",
233       0,
234       0,
235       tmp,
236       {"", "root"});
237   });
238 }
239
240 void BridgeObject::EmitCursorMoved(Accessible* obj, unsigned int cursorPosition)
241 {
242   if(!IsUp() || obj->IsHidden() || obj->GetSuppressedEvents()[AtspiEvent::TEXT_CARET_MOVED])
243   {
244     return;
245   }
246
247   mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
248     GetAccessiblePath(obj),
249     Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
250     "TextCaretMoved",
251     "",
252     cursorPosition,
253     0,
254     {0},
255     {"", "root"});
256 }
257
258 void BridgeObject::EmitTextChanged(Accessible* obj, TextChangedState state, unsigned int position, unsigned int length, const std::string& content)
259 {
260   static const std::unordered_map<TextChangedState, std::string_view> stateMap{
261     {TextChangedState::INSERTED, "insert"},
262     {TextChangedState::DELETED, "delete"},
263   };
264
265   if(!IsUp() || obj->IsHidden() || obj->GetSuppressedEvents()[AtspiEvent::TEXT_CHANGED])
266   {
267     return;
268   }
269
270   auto stateName = stateMap.find(state);
271
272   if(stateName != stateMap.end())
273   {
274     mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<std::string>, Address>(
275       GetAccessiblePath(obj),
276       Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
277       "TextChanged",
278       std::string{stateName->second},
279       position,
280       length,
281       {content},
282       {"", "root"});
283   }
284 }
285
286 void BridgeObject::EmitMovedOutOfScreen(Accessible* obj, ScreenRelativeMoveType type)
287 {
288   if(!IsUp() || obj->IsHidden() || obj->GetSuppressedEvents()[AtspiEvent::MOVED_OUT])
289   {
290     return;
291   }
292
293   mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
294     GetAccessiblePath(obj),
295     Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
296     "MoveOuted",
297     "",
298     static_cast<int>(type),
299     0,
300     {0},
301     {"", "root"});
302 }
303
304 void BridgeObject::EmitSocketAvailable(Accessible* obj)
305 {
306   if(!IsUp() || obj->IsHidden()) //TODO Suppress SocketAvailable event
307   {
308     return;
309   }
310
311   mDbusServer.emit2<Address, Address>(
312     GetAccessiblePath(obj),
313     Accessible::GetInterfaceName(AtspiInterface::SOCKET),
314     "Available",
315     obj->GetAddress(),
316     {"", "root"});
317 }