Add support for new accessibility actions
[platform/core/uifw/dali-adaptor.git] / adaptors / ubuntu / accessibility-adaptor-impl-ubuntu.cpp
1 /*
2  * Copyright (c) 2014 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.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/object/type-registry.h>
23 #include <dali/integration-api/debug.h>
24 #include <dali/integration-api/events/touch-event-integ.h>
25 #include <dali/integration-api/events/hover-event-integ.h>
26 #include <dali/integration-api/events/gesture-requests.h>
27
28 // INTERNAL INCLUDES
29 #include <singleton-service-impl.h>
30 #include "system-settings.h"
31
32 namespace Dali
33 {
34
35 namespace Internal
36 {
37
38 namespace Adaptor
39 {
40
41 namespace
42 {
43 #if defined(DEBUG_ENABLED)
44 Debug::Filter* gAccessibilityAdaptorLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_ACCESSIBILITY_ADAPTOR");
45 #endif
46
47 BaseHandle Create()
48 {
49   BaseHandle handle( AccessibilityAdaptor::Get() );
50
51   if ( !handle )
52   {
53     Dali::SingletonService service( SingletonService::Get() );
54     if ( service )
55     {
56       Dali::AccessibilityAdaptor adaptor = Dali::AccessibilityAdaptor( new AccessibilityAdaptor() );
57       service.Register( typeid( adaptor ), adaptor );
58       handle = adaptor;
59     }
60   }
61
62   return handle;
63 }
64 TypeRegistration ACCESSIBILITY_ADAPTOR_TYPE( typeid(Dali::AccessibilityAdaptor), typeid(Dali::BaseHandle), Create, true /* Create Instance At Startup */ );
65
66 } // unnamed namespace
67
68 Dali::AccessibilityAdaptor AccessibilityAdaptor::Get()
69 {
70   Dali::AccessibilityAdaptor adaptor;
71
72   Dali::SingletonService service( SingletonService::Get() );
73   if ( service )
74   {
75     // Check whether the singleton is already created
76     Dali::BaseHandle handle = service.GetSingleton( typeid( Dali::AccessibilityAdaptor ) );
77     if(handle)
78     {
79       // If so, downcast the handle
80       adaptor = Dali::AccessibilityAdaptor( dynamic_cast< AccessibilityAdaptor* >( handle.GetObjectPtr() ) );
81     }
82   }
83
84   return adaptor;
85 }
86
87 Vector2 AccessibilityAdaptor::GetReadPosition() const
88 {
89   return mReadPosition;
90 }
91
92 void AccessibilityAdaptor::SetActionHandler(AccessibilityActionHandler& handler)
93 {
94   mActionHandler = &handler;
95 }
96
97 void AccessibilityAdaptor::SetGestureHandler(AccessibilityGestureHandler& handler)
98 {
99   if( mAccessibilityGestureDetector )
100   {
101     mAccessibilityGestureDetector->SetGestureHandler(handler);
102   }
103 }
104
105 bool AccessibilityAdaptor::HandleActionClearFocusEvent()
106 {
107   bool ret = false;
108
109   if( mActionHandler )
110   {
111     ret = mActionHandler->ClearAccessibilityFocus();
112   }
113
114   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
115
116   return ret;
117 }
118
119 bool AccessibilityAdaptor::HandleActionScrollEvent(const TouchPoint& point, unsigned long timeStamp)
120 {
121   bool ret = false;
122
123   // We always need to emit a scroll signal, whether it's only a hover or not,
124   // so always send the action to the action handler.
125   if( mActionHandler )
126   {
127     Dali::TouchEvent event(timeStamp);
128     event.points.push_back(point);
129     ret = mActionHandler->AccessibilityActionScroll( event );
130   }
131
132   Integration::TouchEvent touchEvent;
133   Integration::HoverEvent hoverEvent;
134   Integration::TouchEventCombiner::EventDispatchType type = mCombiner.GetNextTouchEvent(point, timeStamp, touchEvent, hoverEvent);
135   if( type == Integration::TouchEventCombiner::DispatchTouch || type == Integration::TouchEventCombiner::DispatchBoth ) // hover event is ignored
136   {
137     // Process the touch event in accessibility gesture detector
138     if( mAccessibilityGestureDetector )
139     {
140       mAccessibilityGestureDetector->SendEvent( touchEvent );
141       ret = true;
142     }
143   }
144
145   return ret;
146 }
147
148 bool AccessibilityAdaptor::HandleActionTouchEvent(const TouchPoint& point, unsigned long timeStamp)
149 {
150   bool ret = false;
151
152   Dali::TouchEvent touchEvent(timeStamp);
153   touchEvent.points.push_back(point);
154
155   if( mActionHandler )
156   {
157     ret = mActionHandler->AccessibilityActionTouch(touchEvent);
158   }
159   return ret;
160 }
161
162 bool AccessibilityAdaptor::HandleActionBackEvent()
163 {
164   bool ret = false;
165
166   if( mActionHandler )
167   {
168     ret = mActionHandler->AccessibilityActionBack();
169   }
170
171   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
172
173   return ret;
174 }
175
176 void AccessibilityAdaptor::HandleActionEnableEvent()
177 {
178   EnableAccessibility();
179 }
180
181 void AccessibilityAdaptor::HandleActionDisableEvent()
182 {
183   DisableAccessibility();
184 }
185
186 void AccessibilityAdaptor::EnableAccessibility()
187 {
188   if(mIsEnabled == false)
189   {
190     mIsEnabled = true;
191
192     if( mActionHandler )
193     {
194       mActionHandler->ChangeAccessibilityStatus();
195     }
196   }
197 }
198
199 void AccessibilityAdaptor::DisableAccessibility()
200 {
201   if(mIsEnabled == true)
202   {
203     mIsEnabled = false;
204
205     if( mActionHandler )
206     {
207       mActionHandler->ChangeAccessibilityStatus();
208     }
209
210     // Destroy the TtsPlayer if exists.
211     if ( Adaptor::IsAvailable() )
212     {
213       Dali::Adaptor& adaptor = Dali::Adaptor::Get();
214       Adaptor::GetImplementation( adaptor ).DestroyTtsPlayer( Dali::TtsPlayer::SCREEN_READER );
215     }
216   }
217 }
218
219 bool AccessibilityAdaptor::IsEnabled() const
220 {
221   return mIsEnabled;
222 }
223
224 void AccessibilityAdaptor::SetIndicator(Indicator* indicator)
225 {
226   mIndicator = indicator;
227 }
228
229 AccessibilityAdaptor::AccessibilityAdaptor()
230 : mIsEnabled(false),
231   mActionHandler(NULL),
232   mIndicator(NULL),
233   mIndicatorFocused(false)
234 {
235   int isEnabled = 0;
236   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, isEnabled?"ENABLED":"DISABLED");
237
238   if(isEnabled == 1)
239   {
240     mIsEnabled = true;
241   }
242   else
243   {
244     mIsEnabled = false;
245   }
246
247   mAccessibilityGestureDetector = new AccessibilityGestureDetector();
248 }
249
250 AccessibilityAdaptor::~AccessibilityAdaptor()
251 {
252 }
253
254 bool AccessibilityAdaptor::HandleActionNextEvent(bool allowEndFeedback)
255 {
256   bool ret = false;
257
258   if( mActionHandler )
259   {
260     ret = mActionHandler->AccessibilityActionNext(allowEndFeedback);
261   }
262
263   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
264
265   return ret;
266 }
267
268 bool AccessibilityAdaptor::HandleActionPreviousEvent(bool allowEndFeedback)
269 {
270   bool ret = false;
271
272   if( mActionHandler )
273   {
274     ret = mActionHandler->AccessibilityActionPrevious(allowEndFeedback);
275   }
276
277   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
278
279   return ret;
280 }
281
282 bool AccessibilityAdaptor::HandleActionActivateEvent()
283 {
284   bool ret = false;
285
286   if( mActionHandler )
287   {
288     ret = mActionHandler->AccessibilityActionActivate();
289   }
290
291   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
292
293   return ret;
294 }
295
296 bool AccessibilityAdaptor::HandleActionReadEvent(unsigned int x, unsigned int y, bool allowReadAgain)
297 {
298   bool ret = false;
299
300   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %d , %d\n", __FUNCTION__, __LINE__, x, y);
301
302   mReadPosition.x = x;
303   mReadPosition.y = y;
304
305   bool indicatorFocused = false;
306
307   // Check whether the Indicator is focused
308   if( mIndicator && mIndicator->IsConnected() )
309   {
310     // Check the position and size of Indicator actor
311     Dali::Actor indicatorActor = mIndicator->GetActor();
312     Vector3 position = Vector3(0.0f, 0.0f, 0.0f);
313     Vector3 size = indicatorActor.GetCurrentSize();
314
315     if(mReadPosition.x >= position.x &&
316        mReadPosition.x <= position.x + size.width &&
317        mReadPosition.y >= position.y &&
318        mReadPosition.y <= position.y + size.height)
319     {
320       indicatorFocused = true;
321       DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] Indicator area!!!!\n", __FUNCTION__, __LINE__);
322     }
323   }
324
325   if( mIndicator )
326   {
327     if( !mIndicatorFocused && indicatorFocused )
328     {
329       // If Indicator is focused, the focus should be cleared in Dali focus chain.
330       if( mActionHandler )
331       {
332         mActionHandler->ClearAccessibilityFocus();
333       }
334     }
335
336     mIndicatorFocused = indicatorFocused;
337
338     // Send accessibility READ action information to Indicator
339     if( mIndicatorFocused )
340     {
341       DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] Send READ message to indicator!!!!\n", __FUNCTION__, __LINE__);
342     }
343   }
344
345   if( mActionHandler && !mIndicatorFocused)
346   {
347     // If Indicator is not focused, the accessibility actions should be handled by the registered
348     // accessibility action handler (e.g. focus manager)
349     ret = mActionHandler->AccessibilityActionRead( allowReadAgain );
350     DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
351   }
352
353   return ret;
354 }
355
356 bool AccessibilityAdaptor::HandleActionReadNextEvent(bool allowEndFeedback)
357 {
358   bool ret = false;
359
360   if( mActionHandler )
361   {
362     ret = mActionHandler->AccessibilityActionReadNext(allowEndFeedback);
363   }
364
365   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
366
367   return ret;
368 }
369
370 bool AccessibilityAdaptor::HandleActionReadPreviousEvent(bool allowEndFeedback)
371 {
372   bool ret = false;
373
374   if( mActionHandler )
375   {
376     ret = mActionHandler->AccessibilityActionReadPrevious(allowEndFeedback);
377   }
378
379   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
380
381   return ret;
382 }
383
384 bool AccessibilityAdaptor::HandleActionUpEvent()
385 {
386   bool ret = false;
387
388   if( mActionHandler )
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 AccessibilityAdaptor::HandleActionDownEvent()
399 {
400   bool ret = false;
401
402   if( mActionHandler )
403   {
404     ret = mActionHandler->AccessibilityActionDown();
405   }
406
407   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
408
409   return ret;
410 }
411
412 bool AccessibilityAdaptor::HandleActionScrollUpEvent()
413 {
414   bool ret = false;
415
416   if( mActionHandler )
417   {
418     ret = mActionHandler->AccessibilityActionScrollUp();
419   }
420
421   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
422
423   return ret;
424 }
425
426
427 bool AccessibilityAdaptor::HandleActionScrollDownEvent()
428 {
429   bool ret = false;
430
431   if( mActionHandler )
432   {
433     ret = mActionHandler->AccessibilityActionScrollDown();
434   }
435
436   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
437
438   return ret;
439 }
440
441 bool AccessibilityAdaptor::HandleActionPageLeftEvent()
442 {
443   bool ret = false;
444
445   if( mActionHandler )
446   {
447     ret = mActionHandler->AccessibilityActionPageLeft();
448   }
449
450   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
451
452   return ret;
453 }
454
455 bool AccessibilityAdaptor::HandleActionPageRightEvent()
456 {
457   bool ret = false;
458
459   if( mActionHandler )
460   {
461     ret = mActionHandler->AccessibilityActionPageRight();
462   }
463
464   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
465
466   return ret;
467 }
468
469 bool AccessibilityAdaptor::HandleActionPageUpEvent()
470 {
471   bool ret = false;
472
473   if( mActionHandler )
474   {
475     ret = mActionHandler->AccessibilityActionPageUp();
476   }
477
478   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
479
480   return ret;
481 }
482
483 bool AccessibilityAdaptor::HandleActionPageDownEvent()
484 {
485   bool ret = false;
486
487   if( mActionHandler )
488   {
489     ret = mActionHandler->AccessibilityActionPageDown();
490   }
491
492   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
493
494   return ret;
495 }
496
497 bool AccessibilityAdaptor::HandleActionMoveToFirstEvent()
498 {
499   bool ret = false;
500
501   if( mActionHandler )
502   {
503     ret = mActionHandler->AccessibilityActionMoveToFirst();
504   }
505
506   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
507
508   return ret;
509 }
510
511 bool AccessibilityAdaptor::HandleActionMoveToLastEvent()
512 {
513   bool ret = false;
514
515   if( mActionHandler )
516   {
517     ret = mActionHandler->AccessibilityActionMoveToLast();
518   }
519
520   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
521
522   return ret;
523 }
524
525 bool AccessibilityAdaptor::HandleActionReadFromTopEvent()
526 {
527   bool ret = false;
528
529   if( mActionHandler )
530   {
531     ret = mActionHandler->AccessibilityActionReadFromTop();
532   }
533
534   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
535
536   return ret;
537 }
538
539 bool AccessibilityAdaptor::HandleActionReadFromNextEvent()
540 {
541   bool ret = false;
542
543   if( mActionHandler )
544   {
545     ret = mActionHandler->AccessibilityActionReadFromNext();
546   }
547
548   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
549
550   return ret;
551 }
552
553 bool AccessibilityAdaptor::HandleActionZoomEvent()
554 {
555   bool ret = false;
556
557   if( mActionHandler )
558   {
559     ret = mActionHandler->AccessibilityActionZoom();
560   }
561
562   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
563
564   return ret;
565 }
566
567 bool AccessibilityAdaptor::HandleActionReadIndicatorInformationEvent()
568 {
569   bool ret = false;
570
571   if( mActionHandler )
572   {
573     ret = mActionHandler->AccessibilityActionReadIndicatorInformation();
574   }
575
576   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
577
578   return ret;
579 }
580
581 bool AccessibilityAdaptor::HandleActionReadPauseResumeEvent()
582 {
583   bool ret = false;
584
585   if( mActionHandler )
586   {
587     ret = mActionHandler->AccessibilityActionReadPauseResume();
588   }
589
590   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
591
592   return ret;
593 }
594
595 bool AccessibilityAdaptor::HandleActionStartStopEvent()
596 {
597   bool ret = false;
598
599   if( mActionHandler )
600   {
601     ret = mActionHandler->AccessibilityActionStartStop();
602   }
603
604   DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
605
606   return ret;
607 }
608
609 } // namespace Adaptor
610
611 } // namespace Internal
612
613 } // namespace Dali