Merge "[AT-SPI] Split accessibility-impl.h" into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / accessibility / bridge / accessible.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
20 //INTERNAL INCLUDES
21 #include <dali/devel-api/atspi-interfaces/accessible.h>
22 #include <dali/devel-api/atspi-interfaces/action.h>
23 #include <dali/devel-api/atspi-interfaces/application.h>
24 #include <dali/devel-api/atspi-interfaces/collection.h>
25 #include <dali/devel-api/atspi-interfaces/component.h>
26 #include <dali/devel-api/atspi-interfaces/editable-text.h>
27 #include <dali/devel-api/atspi-interfaces/hyperlink.h>
28 #include <dali/devel-api/atspi-interfaces/hypertext.h>
29 #include <dali/devel-api/atspi-interfaces/selection.h>
30 #include <dali/devel-api/atspi-interfaces/text.h>
31 #include <dali/devel-api/atspi-interfaces/value.h>
32 #include <dali/devel-api/adaptor-framework/accessibility-bridge.h>
33 #include <dali/internal/accessibility/bridge/accessibility-common.h>
34 #include <third-party/libunibreak/linebreak.h>
35 #include <third-party/libunibreak/wordbreak.h>
36
37 using namespace Dali::Accessibility;
38
39 std::vector<std::string> Accessible::GetInterfaces()
40 {
41   std::vector<std::string> tmp;
42   tmp.push_back(AtspiDbusInterfaceAccessible);
43   if(dynamic_cast<Collection*>(this))
44   {
45     tmp.push_back(AtspiDbusInterfaceCollection);
46   }
47   if(dynamic_cast<Text*>(this))
48   {
49     tmp.push_back(AtspiDbusInterfaceText);
50   }
51   if(dynamic_cast<EditableText*>(this))
52   {
53     tmp.push_back(AtspiDbusInterfaceEditableText);
54   }
55   if(dynamic_cast<Value*>(this))
56   {
57     tmp.push_back(AtspiDbusInterfaceValue);
58   }
59   if(dynamic_cast<Component*>(this))
60   {
61     tmp.push_back(AtspiDbusInterfaceComponent);
62   }
63   if(auto action = dynamic_cast<Action*>(this))
64   {
65     if(action->GetActionCount() > 0)
66     {
67       tmp.push_back(AtspiDbusInterfaceAction);
68     }
69   }
70   if(dynamic_cast<Selection*>(this))
71   {
72     tmp.push_back(AtspiDbusInterfaceSelection);
73   }
74   if(dynamic_cast<Hypertext*>(this))
75   {
76     tmp.push_back(AtspiDbusInterfaceHypertext);
77   }
78   if(dynamic_cast<Hyperlink*>(this))
79   {
80     tmp.push_back(AtspiDbusInterfaceHyperlink);
81   }
82   return tmp;
83 }
84
85 Accessible::Accessible()
86 {
87 }
88
89 Accessible::~Accessible()
90 {
91   auto handle = mBridgeData.lock();
92   if(handle)
93   {
94     handle->mKnownObjects.erase(this);
95   }
96 }
97
98 void Accessible::EmitActiveDescendantChanged(Accessible* obj, Accessible* child)
99 {
100   if(auto bridgeData = GetBridgeData())
101   {
102     bridgeData->mBridge->EmitActiveDescendantChanged(obj, child);
103   }
104 }
105
106 void Accessible::EmitStateChanged(State state, int newValue, int reserved)
107 {
108   if(auto bridgeData = GetBridgeData())
109   {
110     bridgeData->mBridge->EmitStateChanged(this, state, newValue, reserved);
111   }
112 }
113
114 void Accessible::EmitShowing(bool isShowing)
115 {
116   if(auto bridgeData = GetBridgeData())
117   {
118     bridgeData->mBridge->EmitStateChanged(this, State::SHOWING, isShowing ? 1 : 0, 0);
119   }
120 }
121
122 void Accessible::EmitVisible(bool isVisible)
123 {
124   if(auto bridgeData = GetBridgeData())
125   {
126     bridgeData->mBridge->EmitStateChanged(this, State::VISIBLE, isVisible ? 1 : 0, 0);
127   }
128 }
129
130 void Accessible::EmitHighlighted(bool isHighlighted)
131 {
132   if(auto bridgeData = GetBridgeData())
133   {
134     bridgeData->mBridge->EmitStateChanged(this, State::HIGHLIGHTED, isHighlighted ? 1 : 0, 0);
135   }
136 }
137
138 void Accessible::EmitFocused(bool isFocused)
139 {
140   if(auto bridgeData = GetBridgeData())
141   {
142     bridgeData->mBridge->EmitStateChanged(this, State::FOCUSED, isFocused ? 1 : 0, 0);
143   }
144 }
145 void Accessible::EmitTextInserted(unsigned int position, unsigned int length, const std::string& content)
146 {
147   if(auto bridgeData = GetBridgeData())
148   {
149     bridgeData->mBridge->EmitTextChanged(this, TextChangedState::INSERTED, position, length, content);
150   }
151 }
152 void Accessible::EmitTextDeleted(unsigned int position, unsigned int length, const std::string& content)
153 {
154   if(auto bridgeData = GetBridgeData())
155   {
156     bridgeData->mBridge->EmitTextChanged(this, TextChangedState::DELETED, position, length, content);
157   }
158 }
159 void Accessible::EmitTextCursorMoved(unsigned int cursorPosition)
160 {
161   if(auto bridgeData = GetBridgeData())
162   {
163     bridgeData->mBridge->EmitCursorMoved(this, cursorPosition);
164   }
165 }
166
167 void Accessible::EmitMovedOutOfScreen(ScreenRelativeMoveType type)
168 {
169   if(auto bridgeData = GetBridgeData())
170   {
171     bridgeData->mBridge->EmitMovedOutOfScreen(this, type);
172   }
173 }
174
175 void Accessible::Emit(WindowEvent event, unsigned int detail)
176 {
177   if(auto bridgeData = GetBridgeData())
178   {
179     bridgeData->mBridge->Emit(this, event, detail);
180   }
181 }
182 void Accessible::Emit(ObjectPropertyChangeEvent event)
183 {
184   if(auto bridgeData = GetBridgeData())
185   {
186     bridgeData->mBridge->Emit(this, event);
187   }
188 }
189
190 void Accessible::EmitBoundsChanged(Rect<> rect)
191 {
192   if(auto bridgeData = GetBridgeData())
193   {
194     bridgeData->mBridge->EmitBoundsChanged(this, rect);
195   }
196 }
197
198 std::vector<Accessible*> Accessible::GetChildren()
199 {
200   std::vector<Accessible*> tmp(GetChildCount());
201   for(auto i = 0u; i < tmp.size(); ++i)
202   {
203     tmp[i] = GetChildAtIndex(i);
204   }
205   return tmp;
206 }
207
208 std::shared_ptr<Bridge::Data> Accessible::GetBridgeData()
209 {
210   auto handle = mBridgeData.lock();
211   if(!handle)
212   {
213     auto bridge = Bridge::GetCurrentBridge();
214     handle      = bridge->mData;
215   }
216   return handle;
217 }
218
219 Address Accessible::GetAddress()
220 {
221   auto handle = mBridgeData.lock();
222   if(!handle)
223   {
224     handle = GetBridgeData();
225     if(handle)
226     {
227       handle->mBridge->RegisterOnBridge(this);
228     }
229   }
230   std::ostringstream tmp;
231   tmp << this;
232   return {handle ? handle->mBusName : "", tmp.str()};
233 }
234
235 void Bridge::RegisterOnBridge(Accessible* object)
236 {
237   assert(!object->mBridgeData.lock() || object->mBridgeData.lock() == mData);
238   if(!object->mBridgeData.lock())
239   {
240     assert(mData);
241     mData->mKnownObjects.insert(object);
242     object->mBridgeData = mData;
243   }
244 }
245
246 bool Accessible::IsProxy()
247 {
248   return false;
249 }
250
251 void Accessible::NotifyAccessibilityStateChange(Dali::Accessibility::States states, bool isRecursive)
252 {
253   if(auto data = GetBridgeData())
254   {
255     for(auto i = 0u; i < static_cast<unsigned int>(Dali::Accessibility::State::MAX_COUNT); i++)
256     {
257       auto index = static_cast<Dali::Accessibility::State>(i);
258       if(states[index])
259       {
260         data->mBridge->EmitStateChanged(this, index, GetStates()[index], 0);
261       }
262     }
263
264     if(isRecursive)
265     {
266       auto children = GetChildren();
267       for(auto iter : children)
268       {
269         iter->NotifyAccessibilityStateChange(states, isRecursive);
270       }
271     }
272   }
273 }
274
275 void Accessible::FindWordSeparationsUtf8(const utf8_t* string, size_t length, const char* language, char* breaks)
276 {
277   set_wordbreaks_utf8(string, length, language, breaks);
278 }
279
280 void Accessible::FindLineSeparationsUtf8(const utf8_t* string, size_t length, const char* language, char* breaks)
281 {
282   set_linebreaks_utf8(string, length, language, breaks);
283 }