Fix a build error in MOBILE profile from accessibility impl code
[platform/core/uifw/dali-adaptor.git] / adaptors / mobile / accessibility-adaptor-impl-mobile.cpp
1 /*
2  * Copyright (c) 2015 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 "accessibility-adaptor-impl-mobile.h"
20
21 // EXTERNAL INCLUDES
22 #include <vconf.h>
23
24 #ifndef WAYLAND
25 #include <Ecore_X.h>
26 #endif
27
28 #include <Elementary.h>
29 #include <vconf.h>
30
31 #include <dali/public-api/object/type-registry.h>
32 #include <dali/integration-api/debug.h>
33 #include <dali/integration-api/debug.h>
34 #include <dali/integration-api/events/gesture-requests.h>
35
36 // INTERNAL INCLUDES
37 #include <singleton-service-impl.h>
38 #include "system-settings.h"
39
40 #ifndef WAYLAND
41 #define MSG_DOMAIN_CONTROL_ACCESS (int)ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL
42 #endif
43
44 namespace Dali
45 {
46
47 namespace Internal
48 {
49
50 namespace Adaptor
51 {
52
53 namespace // unnamed namespace
54 {
55
56 #if defined(DEBUG_ENABLED)
57 Debug::Filter* gAccessibilityAdaptorLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_ACCESSIBILITY_ADAPTOR");
58 #endif
59
60 const char * DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS = "db/setting/accessibility/atspi";
61
62 bool GetEnabledVConf()
63 {
64   int isEnabled = 0;
65   vconf_get_bool( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS, &isEnabled );
66
67   if( isEnabled == 0 )
68   {
69     vconf_get_bool( VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, &isEnabled );
70   }
71
72   return (bool)isEnabled;
73 }
74
75
76 void AccessibilityOnOffNotification(keynode_t* node, void* data)
77 {
78   AccessibilityAdaptor* adaptor = static_cast<AccessibilityAdaptor*>( data );
79
80   bool isEnabled = GetEnabledVConf();
81
82   DALI_LOG_INFO( gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, isEnabled ? "ENABLED" : "DISABLED" );
83
84   if( isEnabled )
85   {
86     adaptor->EnableAccessibility();
87   }
88   else
89   {
90     adaptor->DisableAccessibility();
91   }
92 }
93
94 BaseHandle Create()
95 {
96   BaseHandle handle( AccessibilityAdaptor::Get() );
97
98   if ( !handle )
99   {
100     Dali::SingletonService service( SingletonService::Get() );
101     if ( service )
102     {
103       Dali::AccessibilityAdaptor adaptor = Dali::AccessibilityAdaptor( new AccessibilityAdaptorMobile() );
104       AccessibilityAdaptorMobile& adaptorImpl = AccessibilityAdaptorMobile::GetImplementation( adaptor );
105
106       bool isEnabled = GetEnabledVConf();
107
108       if( isEnabled )
109       {
110         adaptorImpl.EnableAccessibility();
111       }
112       DALI_LOG_INFO( gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, isEnabled ? "ENABLED" : "DISABLED" );
113
114       vconf_notify_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS, AccessibilityOnOffNotification, &adaptorImpl );
115       vconf_notify_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, AccessibilityOnOffNotification, &adaptorImpl );
116
117       service.Register( typeid( adaptor ), adaptor );
118       handle = adaptor;
119     }
120   }
121
122   return handle;
123 }
124
125 TypeRegistration ACCESSIBILITY_ADAPTOR_TYPE( typeid(Dali::AccessibilityAdaptor), typeid(Dali::BaseHandle), Create, true /* Create Instance At Startup */ );
126
127 } // unnamed namespace
128
129 Dali::AccessibilityAdaptor AccessibilityAdaptor::Get()
130 {
131   Dali::AccessibilityAdaptor adaptor;
132
133   Dali::SingletonService service( SingletonService::Get() );
134   if ( service )
135   {
136     // Check whether the singleton is already created
137     Dali::BaseHandle handle = service.GetSingleton( typeid( Dali::AccessibilityAdaptor ) );
138     if(handle)
139     {
140       // If so, downcast the handle
141       adaptor = Dali::AccessibilityAdaptor( dynamic_cast< AccessibilityAdaptor* >( handle.GetObjectPtr() ) );
142     }
143   }
144
145   return adaptor;
146 }
147
148 void AccessibilityAdaptor::OnDestroy()
149 {
150   vconf_ignore_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, AccessibilityOnOffNotification );
151   vconf_ignore_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS, AccessibilityOnOffNotification );
152 }
153
154 AccessibilityAdaptorMobile::AccessibilityAdaptorMobile()
155 {
156 }
157
158 bool AccessibilityAdaptorMobile::HandleActionNextEvent(bool allowEndFeedback)
159 {
160   bool ret = false;
161
162 #ifndef WAYLAND
163   if( mIndicator && mIndicatorFocused )
164   {
165     Elm_Access_Action_Info actionInfo;
166     actionInfo.action_type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
167
168     ret = mIndicator->SendMessage(MSG_DOMAIN_CONTROL_ACCESS, actionInfo.action_type, &actionInfo, sizeof(actionInfo));
169   }
170   else if( mActionHandler )
171 #else
172   if( mActionHandler )
173 #endif
174   {
175     ret = mActionHandler->AccessibilityActionNext(allowEndFeedback);
176   }
177
178   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
179
180   return ret;
181 }
182
183 bool AccessibilityAdaptorMobile::HandleActionPreviousEvent(bool allowEndFeedback)
184 {
185   bool ret = false;
186
187 #ifndef WAYLAND
188   if( mIndicator && mIndicatorFocused )
189   {
190     Elm_Access_Action_Info actionInfo;
191     actionInfo.action_type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
192
193     ret = mIndicator->SendMessage(MSG_DOMAIN_CONTROL_ACCESS, actionInfo.action_type, &actionInfo, sizeof(actionInfo));
194   }
195   else if( mActionHandler )
196 #else
197   if( mActionHandler )
198 #endif
199   {
200     ret = mActionHandler->AccessibilityActionPrevious(allowEndFeedback);
201   }
202
203   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
204
205   return ret;
206 }
207
208 bool AccessibilityAdaptorMobile::HandleActionActivateEvent()
209 {
210   bool ret = false;
211
212 #ifndef WAYLAND
213   if( mIndicator && mIndicatorFocused )
214   {
215     Elm_Access_Action_Info actionInfo;
216     actionInfo.action_type = ELM_ACCESS_ACTION_ACTIVATE;
217
218     ret = mIndicator->SendMessage(MSG_DOMAIN_CONTROL_ACCESS, actionInfo.action_type, &actionInfo, sizeof(actionInfo));
219   }
220   else if( mActionHandler )
221 #else
222   if( mActionHandler )
223 #endif
224   {
225     ret = mActionHandler->AccessibilityActionActivate();
226   }
227
228   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
229
230   return ret;
231 }
232
233 bool AccessibilityAdaptorMobile::HandleActionReadEvent(unsigned int x, unsigned int y, bool allowReadAgain)
234 {
235   bool ret = false;
236
237   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %d , %d\n", __FUNCTION__, __LINE__, x, y);
238
239   mReadPosition.x = x;
240   mReadPosition.y = y;
241
242   Dali::AccessibilityAdaptor handle( this );
243
244   bool indicatorFocused = false;
245
246   // Check whether the Indicator is focused
247   if( mIndicator && mIndicator->IsConnected() )
248   {
249     // Check the position and size of Indicator actor
250     Dali::Actor indicatorActor = mIndicator->GetActor();
251     Vector3 position = Vector3(0.0f, 0.0f, 0.0f);
252     Vector3 size = indicatorActor.GetCurrentSize();
253
254     if(mReadPosition.x >= position.x &&
255        mReadPosition.x <= position.x + size.width &&
256        mReadPosition.y >= position.y &&
257        mReadPosition.y <= position.y + size.height)
258     {
259       indicatorFocused = true;
260       DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] Indicator area!!!!\n", __FUNCTION__, __LINE__);
261     }
262   }
263
264   if( mIndicator )
265   {
266     if( !mIndicatorFocused && indicatorFocused )
267     {
268       // If Indicator is focused, the focus should be cleared in Dali focus chain.
269       if( mActionHandler )
270       {
271         mActionHandler->ClearAccessibilityFocus();
272       }
273     }
274     else if( mIndicatorFocused && !indicatorFocused )
275     {
276 #ifndef WAYLAND
277       Elm_Access_Action_Info actionInfo;
278       actionInfo.action_type = ELM_ACCESS_ACTION_UNHIGHLIGHT;
279
280       // Indicator should be unhighlighted
281       ret = mIndicator->SendMessage(MSG_DOMAIN_CONTROL_ACCESS, actionInfo.action_type, &actionInfo, sizeof(actionInfo));
282       DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] Send unhighlight message to indicator!!!!\n", __FUNCTION__, __LINE__);
283 #endif
284     }
285
286     mIndicatorFocused = indicatorFocused;
287
288     // Send accessibility READ action information to Indicator
289     if( mIndicatorFocused )
290     {
291 #ifndef WAYLAND
292       Elm_Access_Action_Info actionInfo;
293       actionInfo.x = mReadPosition.x;
294       actionInfo.y = mReadPosition.y;
295
296       if(allowReadAgain)
297       {
298         actionInfo.action_type = ELM_ACCESS_ACTION_READ;
299       }
300       else
301       {
302         actionInfo.action_type = static_cast<Elm_Access_Action_Type>( GetElmAccessActionOver() );
303       }
304
305       ret = mIndicator->SendMessage(MSG_DOMAIN_CONTROL_ACCESS, actionInfo.action_type, &actionInfo, sizeof(actionInfo));
306
307       DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] Send READ message to indicator!!!!\n", __FUNCTION__, __LINE__);
308 #endif
309     }
310   }
311
312   if( mActionHandler && !mIndicatorFocused)
313   {
314     // If Indicator is not focused, the accessibility actions should be handled by the registered
315     // accessibility action handler (e.g. focus manager)
316     ret = mActionHandler->AccessibilityActionRead(allowReadAgain);
317     DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
318   }
319
320   return ret;
321 }
322
323 bool AccessibilityAdaptorMobile::HandleActionReadNextEvent(bool allowEndFeedback)
324 {
325   bool ret = false;
326
327 #ifndef WAYLAND
328   if( mIndicator && mIndicatorFocused )
329   {
330     Elm_Access_Action_Info actionInfo;
331     actionInfo.action_type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
332
333     ret = mIndicator->SendMessage(MSG_DOMAIN_CONTROL_ACCESS, actionInfo.action_type, &actionInfo, sizeof(actionInfo));
334   }
335   else if( mActionHandler )
336 #else
337   if( mActionHandler )
338 #endif
339   {
340     ret = mActionHandler->AccessibilityActionReadNext(allowEndFeedback);
341   }
342
343   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
344
345   return ret;
346 }
347
348 bool AccessibilityAdaptorMobile::HandleActionReadPreviousEvent(bool allowEndFeedback)
349 {
350   bool ret = false;
351
352 #ifndef WAYLAND
353   if( mIndicator && mIndicatorFocused )
354   {
355     Elm_Access_Action_Info actionInfo;
356     actionInfo.action_type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
357
358     ret = mIndicator->SendMessage(MSG_DOMAIN_CONTROL_ACCESS, actionInfo.action_type, &actionInfo, sizeof(actionInfo));
359   }
360   else if( mActionHandler )
361 #else
362   if( mActionHandler )
363 #endif
364   {
365     ret = mActionHandler->AccessibilityActionReadPrevious(allowEndFeedback);
366   }
367
368   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
369
370   return ret;
371 }
372
373 bool AccessibilityAdaptorMobile::HandleActionUpEvent()
374 {
375   bool ret = false;
376
377 #ifndef WAYLAND
378   if( mIndicator && mIndicatorFocused )
379   {
380     Elm_Access_Action_Info actionInfo;
381     actionInfo.action_type = ELM_ACCESS_ACTION_UP;
382
383     ret = mIndicator->SendMessage(MSG_DOMAIN_CONTROL_ACCESS, actionInfo.action_type, &actionInfo, sizeof(actionInfo));
384   }
385   else if( mActionHandler )
386 #else
387   if( mActionHandler )
388 #endif
389   {
390     ret = mActionHandler->AccessibilityActionUp();
391   }
392
393   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
394
395   return ret;
396 }
397
398 bool AccessibilityAdaptorMobile::HandleActionDownEvent()
399 {
400   bool ret = false;
401
402 #ifndef WAYLAND
403   if( mIndicator && mIndicatorFocused )
404   {
405     Elm_Access_Action_Info actionInfo;
406     actionInfo.action_type = ELM_ACCESS_ACTION_DOWN;
407
408     ret = mIndicator->SendMessage(MSG_DOMAIN_CONTROL_ACCESS, actionInfo.action_type, &actionInfo, sizeof(actionInfo));
409   }
410   else if( mActionHandler )
411 #else
412   if( mActionHandler )
413 #endif
414   {
415     ret = mActionHandler->AccessibilityActionDown();
416   }
417
418   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
419
420   return ret;
421 }
422
423 AccessibilityAdaptorMobile::~AccessibilityAdaptorMobile()
424 {
425 }
426
427 } // namespace Adaptor
428
429 } // namespace Internal
430
431 } // namespace Dali