Merge "modified direction of kk_KZ locale, Kazakh language is LTR." into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / common / adaptor-impl.cpp
1 /*
2  * Copyright (c) 2018 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/adaptor/common/adaptor-impl.h>
20 #include <dali/internal/adaptor/common/adaptor-builder-impl.h>
21
22 // EXTERNAL INCLUDES
23 #include <dali/public-api/common/stage.h>
24 #include <dali/public-api/actors/layer.h>
25 #include <dali/public-api/object/any.h>
26 #include <dali/devel-api/actors/actor-devel.h>
27 #include <dali/integration-api/debug.h>
28 #include <dali/integration-api/core.h>
29 #include <dali/integration-api/context-notifier.h>
30 #include <dali/integration-api/profiling.h>
31 #include <dali/integration-api/input-options.h>
32 #include <dali/integration-api/events/touch-event-integ.h>
33
34 // INTERNAL INCLUDES
35 #include <dali/public-api/dali-adaptor-common.h>
36 #include <dali/internal/system/common/thread-controller.h>
37 #include <dali/internal/system/common/performance-interface-factory.h>
38 #include <dali/internal/adaptor/common/lifecycle-observer.h>
39
40 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
41 #include <dali/internal/graphics/gles/egl-graphics.h> // Temporary until Core is abstracted
42
43 #include <dali/devel-api/text-abstraction/font-client.h>
44
45 #include <dali/internal/system/common/callback-manager.h>
46 #include <dali/internal/accessibility/common/tts-player-impl.h>
47 #include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
48 #include <dali/internal/input/common/gesture-manager.h>
49 #include <dali/internal/window-system/common/event-handler.h>
50 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
51 #include <dali/internal/graphics/gles/gl-implementation.h>
52 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
53 #include <dali/internal/graphics/common/egl-image-extensions.h>
54 #include <dali/internal/clipboard/common/clipboard-impl.h>
55 #include <dali/internal/graphics/common/vsync-monitor.h>
56 #include <dali/internal/system/common/object-profiler.h>
57 #include <dali/internal/window-system/common/display-connection.h>
58 #include <dali/internal/window-system/common/window-impl.h>
59 #include <dali/internal/window-system/common/window-render-surface.h>
60
61 #include <dali/internal/system/common/logging.h>
62
63 #include <dali/internal/system/common/locale-utils.h>
64 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
65 #include <dali/internal/imaging/common/image-loader.h>
66
67
68 using Dali::TextAbstraction::FontClient;
69
70 namespace Dali
71 {
72
73 namespace Internal
74 {
75
76 namespace Adaptor
77 {
78
79 namespace
80 {
81 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
82 } // unnamed namespace
83
84
85 Dali::Adaptor* Adaptor::New( Any nativeWindow, RenderSurface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
86 {
87   Dali::Adaptor* adaptor = new Dali::Adaptor;
88   Adaptor* impl = new Adaptor( nativeWindow, *adaptor, surface, environmentOptions );
89   adaptor->mImpl = impl;
90
91   Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
92   auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
93
94   impl->Initialize( graphicsFactory, configuration );
95   delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
96
97   return adaptor;
98 }
99
100 Dali::Adaptor* Adaptor::New( Dali::Window window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
101 {
102   Any winId = window.GetNativeHandle();
103
104   Window& windowImpl = Dali::GetImplementation( window );
105   Dali::Adaptor* adaptor = New( winId, windowImpl.GetSurface(), configuration, environmentOptions );
106   windowImpl.SetAdaptor( *adaptor );
107   return adaptor;
108 }
109
110 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Any nativeWindow, RenderSurface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
111 {
112   Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
113   Adaptor* impl = new Adaptor( nativeWindow, *adaptor, surface, environmentOptions ); // Impl adaptor
114   adaptor->mImpl = impl;
115
116   impl->Initialize( graphicsFactory, configuration );
117
118   return adaptor;
119 } // Called second
120
121 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Window window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
122 {
123   Any winId = window.GetNativeHandle();
124
125   Window& windowImpl = Dali::GetImplementation( window );
126   Dali::Adaptor* adaptor = New( graphicsFactory, winId, windowImpl.GetSurface(), configuration, environmentOptions );
127   windowImpl.SetAdaptor( *adaptor );
128   return adaptor;
129 } // Called first
130
131 void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration::ContextLoss configuration )
132 {
133   // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
134   Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
135   mEnvironmentOptions->SetLogFunction( logFunction );
136   mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
137
138   mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
139
140   std::string path;
141   GetDataStoragePath( path );
142   mPlatformAbstraction->SetDataStoragePath( path );
143
144   ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
145   if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
146   {
147     dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
148   }
149
150   // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from files automatically.
151
152   if( mEnvironmentOptions->PerformanceServerRequired() )
153   {
154     mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
155   }
156
157   mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
158   mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
159
160   mCallbackManager = CallbackManager::New();
161
162   WindowPane defaultWindow = mWindowFrame.front();
163
164   DALI_ASSERT_DEBUG( defaultWindow.surface && "Surface not initialized" );
165
166   PositionSize size = defaultWindow.surface->GetPositionSize();
167
168   mGestureManager = new GestureManager(*this, Vector2(size.width, size.height), mCallbackManager, *mEnvironmentOptions);
169
170   mGraphics = &( graphicsFactory.Create() );
171   mGraphics->Initialize( mEnvironmentOptions );
172
173   auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
174
175   GlImplementation& mGLES = eglGraphics->GetGlesInterface();
176   EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
177
178   mCore = Integration::Core::New( *this,
179                                   *mPlatformAbstraction,
180                                   mGLES,
181                                   eglSyncImpl,
182                                   *mGestureManager,
183                                   dataRetentionPolicy ,
184                                   ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
185                                   mGraphics->GetDepthBufferRequired(),
186                                   mGraphics->GetStencilBufferRequired() );
187
188   const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
189   if( 0u < timeInterval )
190   {
191     mObjectProfiler = new ObjectProfiler( timeInterval );
192   }
193
194   mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
195
196   mVSyncMonitor = new VSyncMonitor;
197
198   mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow.surface->GetSurfaceType() );
199
200   mThreadController = new ThreadController( *this, *mEnvironmentOptions );
201
202   // Should be called after Core creation
203   if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
204   {
205     Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
206   }
207   if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
208   {
209     Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
210   }
211   if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
212   {
213     Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
214   }
215   if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
216   {
217     Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
218   }
219   if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
220   {
221     Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
222   }
223   if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
224   {
225     Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
226   }
227   if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
228   {
229     Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
230   }
231   if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
232   {
233     Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
234   }
235   if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
236   {
237     Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
238   }
239   if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
240   {
241     Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
242   }
243   if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
244   {
245     Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false  );
246   }
247   if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
248   {
249     Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false  );
250   }
251   if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
252   {
253     Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
254   }
255   if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
256   {
257     Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
258   }
259   if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
260   {
261     Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
262   }
263   if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
264   {
265     Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
266   }
267
268   // Set max texture size
269   if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
270   {
271     Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
272   }
273
274   SetupSystemInformation();
275 }
276
277 Adaptor::~Adaptor()
278 {
279   // Ensure stop status
280   Stop();
281
282   // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
283   gThreadLocalAdaptor = NULL;
284
285   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
286   {
287     (*iter)->OnDestroy();
288   }
289
290   delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
291   delete mVSyncMonitor;
292   delete mEventHandler;
293   delete mObjectProfiler;
294
295   delete mCore;
296
297   delete mGestureManager;
298   delete mDisplayConnection;
299   delete mPlatformAbstraction;
300   delete mCallbackManager;
301   delete mPerformanceInterface;
302
303   mGraphics->Destroy();
304
305   // uninstall it on this thread (main actor thread)
306   Dali::Integration::Log::UninstallLogFunction();
307
308   // Delete environment options if we own it
309   if( mEnvironmentOptionsOwned )
310   {
311     delete mEnvironmentOptions;
312   }
313 }
314
315 void Adaptor::Start()
316 {
317   // It doesn't support restart after stop at this moment to support restarting, need more testing
318   if( READY != mState )
319   {
320     return;
321   }
322
323   // Start the callback manager
324   mCallbackManager->Start();
325
326   WindowPane defaultWindow = mWindowFrame.front();
327
328   // Create event handler
329   mEventHandler = new EventHandler( defaultWindow.surface, *this, *mGestureManager, *this, mDragAndDropDetector );
330
331   if( mDeferredRotationObserver != NULL )
332   {
333     mEventHandler->SetRotationObserver(mDeferredRotationObserver);
334     mDeferredRotationObserver = NULL;
335   }
336
337   unsigned int dpiHor, dpiVer;
338   dpiHor = dpiVer = 0;
339
340   defaultWindow.surface->GetDpi( dpiHor, dpiVer );
341
342   // tell core about the DPI value
343   mCore->SetDpi(dpiHor, dpiVer);
344
345   // set the DPI value for font rendering
346   FontClient fontClient = FontClient::Get();
347   fontClient.SetDpi( dpiHor, dpiVer );
348
349   // Tell the core the size of the surface just before we start the render-thread
350   PositionSize size = defaultWindow.surface->GetPositionSize();
351
352   mCore->SurfaceResized( size.width, size.height );
353
354   // Initialize the thread controller
355   mThreadController->Initialize();
356
357   ProcessCoreEvents(); // Ensure any startup messages are processed.
358
359   // Initialize the image loader plugin
360   Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
361
362   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
363   {
364     (*iter)->OnStart();
365   }
366 }
367
368 // Dali::Internal::Adaptor::Adaptor::Pause
369 void Adaptor::Pause()
370 {
371   // Only pause the adaptor if we're actually running.
372   if( RUNNING == mState )
373   {
374     // Inform observers that we are about to be paused.
375     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
376     {
377       (*iter)->OnPause();
378     }
379
380     // Reset the event handler when adaptor paused
381     if( mEventHandler )
382     {
383       mEventHandler->Pause();
384     }
385
386     mThreadController->Pause();
387     mState = PAUSED;
388
389     // Ensure any messages queued during pause callbacks are processed by doing another update.
390     RequestUpdateOnce();
391   }
392 }
393
394 // Dali::Internal::Adaptor::Adaptor::Resume
395 void Adaptor::Resume()
396 {
397   // Only resume the adaptor if we are in the suspended state.
398   if( PAUSED == mState )
399   {
400     mState = RUNNING;
401
402     // Reset the event handler when adaptor resumed
403     if( mEventHandler )
404     {
405       mEventHandler->Resume();
406     }
407
408     // Inform observers that we have resumed.
409     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
410     {
411       (*iter)->OnResume();
412     }
413
414     // Trigger processing of events queued up while paused
415     mCore->ProcessEvents();
416
417     // Do at end to ensure our first update/render after resumption includes the processed messages as well
418     mThreadController->Resume();
419   }
420 }
421
422 void Adaptor::Stop()
423 {
424   if( RUNNING == mState ||
425       PAUSED  == mState ||
426       PAUSED_WHILE_HIDDEN == mState )
427   {
428     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
429     {
430       (*iter)->OnStop();
431     }
432
433     mThreadController->Stop();
434
435     // Clear out all the handles to Windows
436     mWindowFrame.clear();
437
438     // Delete the TTS player
439     for(int i =0; i < Dali::TtsPlayer::MODE_NUM; i++)
440     {
441       if(mTtsPlayers[i])
442       {
443         mTtsPlayers[i].Reset();
444       }
445     }
446
447     // Destroy the image loader plugin
448     Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
449
450     delete mEventHandler;
451     mEventHandler = NULL;
452
453     delete mNotificationTrigger;
454     mNotificationTrigger = NULL;
455
456     mCallbackManager->Stop();
457
458     mState = STOPPED;
459   }
460 }
461
462 void Adaptor::ContextLost()
463 {
464   mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
465 }
466
467 void Adaptor::ContextRegained()
468 {
469   // Inform core, so that texture resources can be reloaded
470   mCore->RecoverFromContextLoss();
471
472   mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
473 }
474
475 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
476 {
477   mEventHandler->FeedTouchPoint( point, timeStamp );
478 }
479
480 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
481 {
482   mEventHandler->FeedWheelEvent( wheelEvent );
483 }
484
485 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
486 {
487   mEventHandler->FeedKeyEvent( keyEvent );
488 }
489
490 void Adaptor::ReplaceSurface( Any nativeWindow, RenderSurface& newSurface )
491 {
492   PositionSize positionSize = newSurface.GetPositionSize();
493
494   // Let the core know the surface size has changed
495   mCore->SurfaceResized( positionSize.width, positionSize.height );
496
497   mResizedSignal.Emit( mAdaptor );
498
499   WindowPane newDefaultWindow;
500   newDefaultWindow.nativeWindow = nativeWindow;
501   newDefaultWindow.surface = &newSurface;
502
503   WindowPane oldDefaultWindow = mWindowFrame.front();
504
505   // Update WindowFrame
506   std::vector<WindowPane>::iterator iter = mWindowFrame.begin();
507   iter = mWindowFrame.insert( iter, newDefaultWindow );
508
509   // Flush the event queue to give the update-render thread chance
510   // to start processing messages for new camera setup etc as soon as possible
511   ProcessCoreEvents();
512
513   // This method blocks until the render thread has completed the replace.
514   mThreadController->ReplaceSurface( newDefaultWindow.surface );
515
516   // Must delete the old Window only after the render thread has completed the replace
517   oldDefaultWindow.surface->DestroySurface();
518   oldDefaultWindow.surface = nullptr;
519 }
520
521 RenderSurface& Adaptor::GetSurface() const
522 {
523   WindowPane defaultWindow = mWindowFrame.front();
524   return *(defaultWindow.surface);
525 }
526
527 void Adaptor::ReleaseSurfaceLock()
528 {
529   WindowPane defaultWindow = mWindowFrame.front();
530   defaultWindow.surface->ReleaseLock();
531 }
532
533 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
534 {
535   if(!mTtsPlayers[mode])
536   {
537     // Create the TTS player when it needed, because it can reduce launching time.
538     mTtsPlayers[mode] = TtsPlayer::New(mode);
539   }
540
541   return mTtsPlayers[mode];
542 }
543
544 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
545 {
546   bool idleAdded(false);
547
548   // Only add an idle if the Adaptor is actually running
549   if( RUNNING == mState || READY == mState || forceAdd )
550   {
551     idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
552   }
553
554   return idleAdded;
555 }
556
557 void Adaptor::RemoveIdle( CallbackBase* callback )
558 {
559   mCallbackManager->RemoveIdleCallback( callback );
560 }
561
562 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
563 {
564   mThreadController->SetPreRenderCallback( callback );
565 }
566
567 bool Adaptor::AddWindow( Dali::Window* childWindow, const std::string& childWindowName, const std::string& childWindowClassName, const bool& childWindowMode )
568 {
569   // This is any Window that is not the main (default) one
570   WindowPane additionalWindow;
571   additionalWindow.instance = childWindow;
572   additionalWindow.window_name = childWindowName;
573   additionalWindow.class_name = childWindowClassName;
574   additionalWindow.window_mode = childWindowMode;
575
576   // Add the new Window to the Frame - the order is not important
577   mWindowFrame.push_back( additionalWindow );
578
579   Window& windowImpl = Dali::GetImplementation( *childWindow );
580   windowImpl.SetAdaptor( Get() );
581
582   return true;
583 }
584
585 bool Adaptor::RemoveWindow( Dali::Window* childWindow )
586 {
587   for ( WindowFrames::iterator iter = mWindowFrame.begin(); iter != mWindowFrame.end(); ++iter )
588   {
589     if( iter->instance == childWindow )
590     {
591       mWindowFrame.erase( iter );
592       return true;
593     }
594   }
595
596   return false;
597 }
598
599 bool Adaptor::RemoveWindow( std::string childWindowName )
600 {
601   for ( WindowFrames::iterator iter = mWindowFrame.begin(); iter != mWindowFrame.end(); ++iter )
602   {
603     if( iter->window_name == childWindowName )
604     {
605       mWindowFrame.erase( iter );
606       return true;
607     }
608   }
609
610   return false;
611 }
612
613 Dali::Adaptor& Adaptor::Get()
614 {
615   DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
616   return gThreadLocalAdaptor->mAdaptor;
617 }
618
619 bool Adaptor::IsAvailable()
620 {
621   return gThreadLocalAdaptor != NULL;
622 }
623
624 void Adaptor::SceneCreated()
625 {
626   mCore->SceneCreated();
627 }
628
629 Dali::Integration::Core& Adaptor::GetCore()
630 {
631   return *mCore;
632 }
633
634 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
635 {
636   mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
637 }
638
639 void Adaptor::SetUseHardwareVSync( bool useHardware )
640 {
641   mVSyncMonitor->SetUseHardwareVSync( useHardware );
642 }
643
644 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
645 {
646   DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
647   return *mDisplayConnection;
648 }
649
650 GraphicsInterface& Adaptor::GetGraphicsInterface()
651 {
652   DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
653   return *mGraphics;
654 }
655
656 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
657 {
658   return *mPlatformAbstraction;
659 }
660
661 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
662 {
663   return *mNotificationTrigger;
664 }
665
666 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
667 {
668   return mTriggerEventFactory;
669 }
670
671 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
672 {
673   return mSocketFactory;
674 }
675
676 RenderSurface* Adaptor::GetRenderSurfaceInterface()
677 {
678   if( !mWindowFrame.empty())
679   {
680     WindowPane defaultWindow = mWindowFrame.front();
681     return defaultWindow.surface;
682   }
683   else
684   {
685     return nullptr;
686   }
687 }
688
689 VSyncMonitorInterface* Adaptor::GetVSyncMonitorInterface()
690 {
691   return mVSyncMonitor;
692 }
693
694 TraceInterface& Adaptor::GetKernelTraceInterface()
695 {
696   return mKernelTracer;
697 }
698
699 TraceInterface& Adaptor::GetSystemTraceInterface()
700 {
701   return mSystemTracer;
702 }
703
704 PerformanceInterface* Adaptor::GetPerformanceInterface()
705 {
706   return mPerformanceInterface;
707 }
708
709 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
710 {
711   DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
712   return *mPlatformAbstraction;
713 }
714
715 void Adaptor::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
716 {
717   mDragAndDropDetector = detector;
718
719   if ( mEventHandler )
720   {
721     mEventHandler->SetDragAndDropDetector( detector );
722   }
723 }
724
725 void Adaptor::SetRotationObserver( RotationObserver* observer )
726 {
727   if( mEventHandler )
728   {
729     mEventHandler->SetRotationObserver( observer );
730   }
731   else if( mState == READY )
732   {
733     // Set once event handler exists
734     mDeferredRotationObserver = observer;
735   }
736 }
737
738 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
739 {
740   if(mTtsPlayers[mode])
741   {
742     mTtsPlayers[mode].Reset();
743   }
744 }
745
746 void Adaptor::SetMinimumPinchDistance(float distance)
747 {
748   if( mGestureManager )
749   {
750     mGestureManager->SetMinimumPinchDistance(distance);
751   }
752 }
753
754 Any Adaptor::GetNativeWindowHandle()
755 {
756   WindowPane defaultWindow = mWindowFrame.front();
757   return defaultWindow.nativeWindow;
758 }
759
760 Any Adaptor::GetGraphicsDisplay()
761 {
762   Any display;
763
764   if (mGraphics)
765   {
766     auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
767
768     EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
769     display = eglImpl.GetDisplay();
770   }
771
772   return display;
773 }
774
775 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
776 {
777   mUseRemoteSurface = useRemoteSurface;
778 }
779
780 void Adaptor::AddObserver( LifeCycleObserver& observer )
781 {
782   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
783
784   if ( match == mObservers.end() )
785   {
786     mObservers.push_back( &observer );
787   }
788 }
789
790 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
791 {
792   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
793
794   if ( match != mObservers.end() )
795   {
796     mObservers.erase( match );
797   }
798 }
799
800 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
801 {
802   if( mCore )
803   {
804     mCore->QueueEvent(event);
805   }
806 }
807
808 void Adaptor::ProcessCoreEvents()
809 {
810   if( mCore )
811   {
812     if( mPerformanceInterface )
813     {
814       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
815     }
816
817     mCore->ProcessEvents();
818
819     if( mPerformanceInterface )
820     {
821       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
822     }
823   }
824 }
825
826 void Adaptor::RequestUpdate( bool forceUpdate )
827 {
828   switch( mState )
829   {
830     case RUNNING:
831     {
832       mThreadController->RequestUpdate();
833       break;
834     }
835     case PAUSED:
836     case PAUSED_WHILE_HIDDEN:
837     {
838       // When Dali applications are partially visible behind the lock-screen,
839       // the indicator must be updated (therefore allow updates in the PAUSED state)
840       if( forceUpdate )
841       {
842         mThreadController->RequestUpdateOnce();
843       }
844       break;
845     }
846     default:
847     {
848       // Do nothing
849       break;
850     }
851   }
852 }
853
854 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
855 {
856   // Only request a notification if the Adaptor is actually running
857   // and we haven't installed the idle notification
858   if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
859   {
860     mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
861   }
862 }
863
864 void Adaptor::OnWindowShown()
865 {
866   if ( PAUSED_WHILE_HIDDEN == mState )
867   {
868     // Adaptor can now be resumed
869     mState = PAUSED;
870
871     Resume();
872
873     // Force a render task
874     RequestUpdateOnce();
875   }
876 }
877
878 void Adaptor::OnWindowHidden()
879 {
880   if ( RUNNING == mState )
881   {
882     Pause();
883
884     // Adaptor cannot be resumed until the window is shown
885     mState = PAUSED_WHILE_HIDDEN;
886   }
887 }
888
889 // Dali::Internal::Adaptor::Adaptor::OnDamaged
890 void Adaptor::OnDamaged( const DamageArea& area )
891 {
892   // This is needed for the case where Dali window is partially obscured
893   RequestUpdate( false );
894 }
895
896 void Adaptor::SurfaceResizePrepare( SurfaceSize surfaceSize )
897 {
898   // Let the core know the surface size has changed
899   mCore->SurfaceResized( surfaceSize.GetWidth(), surfaceSize.GetHeight() );
900
901   mResizedSignal.Emit( mAdaptor );
902 }
903
904 void Adaptor::SurfaceResizeComplete( SurfaceSize surfaceSize )
905 {
906   // Flush the event queue to give the update-render thread chance
907   // to start processing messages for new camera setup etc as soon as possible
908   ProcessCoreEvents();
909
910   mThreadController->ResizeSurface();
911 }
912
913 void Adaptor::NotifySceneCreated()
914 {
915   GetCore().SceneCreated();
916
917   // Start thread controller after the scene has been created
918   mThreadController->Start();
919
920   // Process after surface is created (registering to remote surface provider if required)
921   SurfaceInitialized();
922
923   mState = RUNNING;
924 }
925
926 void Adaptor::NotifyLanguageChanged()
927 {
928   mLanguageChangedSignal.Emit( mAdaptor );
929 }
930
931 void Adaptor::RenderOnce()
932 {
933   RequestUpdateOnce();
934 }
935
936 const LogFactoryInterface& Adaptor::GetLogFactory()
937 {
938   return *mEnvironmentOptions;
939 }
940
941 void Adaptor::RequestUpdateOnce()
942 {
943   if( mThreadController )
944   {
945     mThreadController->RequestUpdateOnce();
946   }
947 }
948
949 void Adaptor::IndicatorSizeChanged(int height)
950 {
951   // Let the core know the indicator height is changed
952   mCore->SetTopMargin(height);
953 }
954
955 bool Adaptor::ProcessCoreEventsFromIdle()
956 {
957   ProcessCoreEvents();
958
959   // the idle handle automatically un-installs itself
960   mNotificationOnIdleInstalled = false;
961
962   return false;
963 }
964
965 Adaptor::Adaptor(Any nativeWindow, Dali::Adaptor& adaptor, RenderSurface* surface, EnvironmentOptions* environmentOptions)
966 : mResizedSignal(),
967   mLanguageChangedSignal(),
968   mAdaptor( adaptor ),
969   mState( READY ),
970   mCore( nullptr ),
971   mThreadController( nullptr ),
972   mVSyncMonitor( nullptr ),
973   mGraphics( nullptr ),
974   mDisplayConnection( nullptr ),
975   mWindowFrame(),
976   mPlatformAbstraction( nullptr ),
977   mEventHandler( nullptr ),
978   mCallbackManager( nullptr ),
979   mNotificationOnIdleInstalled( false ),
980   mNotificationTrigger( nullptr ),
981   mGestureManager( nullptr ),
982   mDaliFeedbackPlugin(),
983   mFeedbackController( nullptr ),
984   mTtsPlayers(),
985   mObservers(),
986   mDragAndDropDetector(),
987   mDeferredRotationObserver( nullptr ),
988   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
989   mPerformanceInterface( nullptr ),
990   mKernelTracer(),
991   mSystemTracer(),
992   mTriggerEventFactory(),
993   mObjectProfiler( nullptr ),
994   mSocketFactory(),
995   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
996   mUseRemoteSurface( false )
997 {
998   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
999
1000   WindowPane defaultWindow;
1001   defaultWindow.nativeWindow = nativeWindow;
1002   defaultWindow.surface = surface;
1003
1004   std::vector<WindowPane>::iterator iter = mWindowFrame.begin();
1005   iter = mWindowFrame.insert( iter, defaultWindow );
1006
1007   gThreadLocalAdaptor = this;
1008 }
1009
1010 void Adaptor::SetRootLayoutDirection( std::string locale )
1011 {
1012   Dali::Stage stage = Dali::Stage::GetCurrent();
1013
1014   stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1015                                     static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1016 }
1017
1018 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1019 {
1020   bool idleAdded( false );
1021
1022   // Only add an idle if the Adaptor is actually running
1023   if( RUNNING == mState || READY == mState || forceAdd )
1024   {
1025     idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1026   }
1027
1028   return idleAdded;
1029 }
1030
1031 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1032 {
1033   mCallbackManager->RemoveIdleEntererCallback( callback );
1034 }
1035
1036 } // namespace Adaptor
1037
1038 } // namespace Internal
1039
1040 } // namespace Dali