[5.0] Pause adaptor when the window is hidden while initailizing
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / common / adaptor-impl.cpp
1 /*
2  * Copyright (c) 2019 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     DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
393   }
394   else
395   {
396     DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
397   }
398 }
399
400 // Dali::Internal::Adaptor::Adaptor::Resume
401 void Adaptor::Resume()
402 {
403   // Only resume the adaptor if we are in the suspended state.
404   if( PAUSED == mState )
405   {
406     mState = RUNNING;
407
408     // Reset the event handler when adaptor resumed
409     if( mEventHandler )
410     {
411       mEventHandler->Resume();
412     }
413
414     // Inform observers that we have resumed.
415     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
416     {
417       (*iter)->OnResume();
418     }
419
420     // Trigger processing of events queued up while paused
421     mCore->ProcessEvents();
422
423     // Do at end to ensure our first update/render after resumption includes the processed messages as well
424     mThreadController->Resume();
425
426     DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
427   }
428   else
429   {
430     DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
431   }
432 }
433
434 void Adaptor::Stop()
435 {
436   if( RUNNING == mState ||
437       PAUSED  == mState ||
438       PAUSED_WHILE_HIDDEN == mState )
439   {
440     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
441     {
442       (*iter)->OnStop();
443     }
444
445     mThreadController->Stop();
446
447     // Clear out all the handles to Windows
448     mWindowFrame.clear();
449
450     // Delete the TTS player
451     for(int i =0; i < Dali::TtsPlayer::MODE_NUM; i++)
452     {
453       if(mTtsPlayers[i])
454       {
455         mTtsPlayers[i].Reset();
456       }
457     }
458
459     // Destroy the image loader plugin
460     Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
461
462     delete mEventHandler;
463     mEventHandler = NULL;
464
465     delete mNotificationTrigger;
466     mNotificationTrigger = NULL;
467
468     mCallbackManager->Stop();
469
470     mState = STOPPED;
471
472     DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
473   }
474 }
475
476 void Adaptor::ContextLost()
477 {
478   mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
479 }
480
481 void Adaptor::ContextRegained()
482 {
483   // Inform core, so that texture resources can be reloaded
484   mCore->RecoverFromContextLoss();
485
486   mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
487 }
488
489 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
490 {
491   mEventHandler->FeedTouchPoint( point, timeStamp );
492 }
493
494 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
495 {
496   mEventHandler->FeedWheelEvent( wheelEvent );
497 }
498
499 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
500 {
501   mEventHandler->FeedKeyEvent( keyEvent );
502 }
503
504 void Adaptor::ReplaceSurface( Any nativeWindow, RenderSurface& newSurface )
505 {
506   PositionSize positionSize = newSurface.GetPositionSize();
507
508   // Let the core know the surface size has changed
509   mCore->SurfaceResized( positionSize.width, positionSize.height );
510
511   mResizedSignal.Emit( mAdaptor );
512
513   WindowPane newDefaultWindow;
514   newDefaultWindow.nativeWindow = nativeWindow;
515   newDefaultWindow.surface = &newSurface;
516
517   WindowPane oldDefaultWindow = mWindowFrame.front();
518
519   // Update WindowFrame
520   std::vector<WindowPane>::iterator iter = mWindowFrame.begin();
521   iter = mWindowFrame.insert( iter, newDefaultWindow );
522
523   // Flush the event queue to give the update-render thread chance
524   // to start processing messages for new camera setup etc as soon as possible
525   ProcessCoreEvents();
526
527   // This method blocks until the render thread has completed the replace.
528   mThreadController->ReplaceSurface( newDefaultWindow.surface );
529
530   // Must delete the old Window only after the render thread has completed the replace
531   oldDefaultWindow.surface->DestroySurface();
532   oldDefaultWindow.surface = nullptr;
533 }
534
535 RenderSurface& Adaptor::GetSurface() const
536 {
537   WindowPane defaultWindow = mWindowFrame.front();
538   return *(defaultWindow.surface);
539 }
540
541 void Adaptor::ReleaseSurfaceLock()
542 {
543   WindowPane defaultWindow = mWindowFrame.front();
544   defaultWindow.surface->ReleaseLock();
545 }
546
547 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
548 {
549   if(!mTtsPlayers[mode])
550   {
551     // Create the TTS player when it needed, because it can reduce launching time.
552     mTtsPlayers[mode] = TtsPlayer::New(mode);
553   }
554
555   return mTtsPlayers[mode];
556 }
557
558 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
559 {
560   bool idleAdded(false);
561
562   // Only add an idle if the Adaptor is actually running
563   if( RUNNING == mState || READY == mState || forceAdd )
564   {
565     idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
566   }
567
568   return idleAdded;
569 }
570
571 void Adaptor::RemoveIdle( CallbackBase* callback )
572 {
573   mCallbackManager->RemoveIdleCallback( callback );
574 }
575
576 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
577 {
578   mThreadController->SetPreRenderCallback( callback );
579 }
580
581 bool Adaptor::AddWindow( Dali::Window* childWindow, const std::string& childWindowName, const std::string& childWindowClassName, const bool& childWindowMode )
582 {
583   // This is any Window that is not the main (default) one
584   WindowPane additionalWindow;
585   additionalWindow.instance = childWindow;
586   additionalWindow.window_name = childWindowName;
587   additionalWindow.class_name = childWindowClassName;
588   additionalWindow.window_mode = childWindowMode;
589
590   // Add the new Window to the Frame - the order is not important
591   mWindowFrame.push_back( additionalWindow );
592
593   Window& windowImpl = Dali::GetImplementation( *childWindow );
594   windowImpl.SetAdaptor( Get() );
595
596   return true;
597 }
598
599 bool Adaptor::RemoveWindow( Dali::Window* childWindow )
600 {
601   for ( WindowFrames::iterator iter = mWindowFrame.begin(); iter != mWindowFrame.end(); ++iter )
602   {
603     if( iter->instance == childWindow )
604     {
605       mWindowFrame.erase( iter );
606       return true;
607     }
608   }
609
610   return false;
611 }
612
613 bool Adaptor::RemoveWindow( std::string childWindowName )
614 {
615   for ( WindowFrames::iterator iter = mWindowFrame.begin(); iter != mWindowFrame.end(); ++iter )
616   {
617     if( iter->window_name == childWindowName )
618     {
619       mWindowFrame.erase( iter );
620       return true;
621     }
622   }
623
624   return false;
625 }
626
627 Dali::Adaptor& Adaptor::Get()
628 {
629   DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
630   return gThreadLocalAdaptor->mAdaptor;
631 }
632
633 bool Adaptor::IsAvailable()
634 {
635   return gThreadLocalAdaptor != NULL;
636 }
637
638 void Adaptor::SceneCreated()
639 {
640   mCore->SceneCreated();
641 }
642
643 Dali::Integration::Core& Adaptor::GetCore()
644 {
645   return *mCore;
646 }
647
648 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
649 {
650   mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
651 }
652
653 void Adaptor::SetUseHardwareVSync( bool useHardware )
654 {
655   mVSyncMonitor->SetUseHardwareVSync( useHardware );
656 }
657
658 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
659 {
660   DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
661   return *mDisplayConnection;
662 }
663
664 GraphicsInterface& Adaptor::GetGraphicsInterface()
665 {
666   DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
667   return *mGraphics;
668 }
669
670 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
671 {
672   return *mPlatformAbstraction;
673 }
674
675 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
676 {
677   return *mNotificationTrigger;
678 }
679
680 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
681 {
682   return mTriggerEventFactory;
683 }
684
685 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
686 {
687   return mSocketFactory;
688 }
689
690 RenderSurface* Adaptor::GetRenderSurfaceInterface()
691 {
692   if( !mWindowFrame.empty())
693   {
694     WindowPane defaultWindow = mWindowFrame.front();
695     return defaultWindow.surface;
696   }
697   else
698   {
699     return nullptr;
700   }
701 }
702
703 VSyncMonitorInterface* Adaptor::GetVSyncMonitorInterface()
704 {
705   return mVSyncMonitor;
706 }
707
708 TraceInterface& Adaptor::GetKernelTraceInterface()
709 {
710   return mKernelTracer;
711 }
712
713 TraceInterface& Adaptor::GetSystemTraceInterface()
714 {
715   return mSystemTracer;
716 }
717
718 PerformanceInterface* Adaptor::GetPerformanceInterface()
719 {
720   return mPerformanceInterface;
721 }
722
723 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
724 {
725   DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
726   return *mPlatformAbstraction;
727 }
728
729 void Adaptor::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
730 {
731   mDragAndDropDetector = detector;
732
733   if ( mEventHandler )
734   {
735     mEventHandler->SetDragAndDropDetector( detector );
736   }
737 }
738
739 void Adaptor::SetRotationObserver( RotationObserver* observer )
740 {
741   if( mEventHandler )
742   {
743     mEventHandler->SetRotationObserver( observer );
744   }
745   else if( mState == READY )
746   {
747     // Set once event handler exists
748     mDeferredRotationObserver = observer;
749   }
750 }
751
752 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
753 {
754   if(mTtsPlayers[mode])
755   {
756     mTtsPlayers[mode].Reset();
757   }
758 }
759
760 void Adaptor::SetMinimumPinchDistance(float distance)
761 {
762   if( mGestureManager )
763   {
764     mGestureManager->SetMinimumPinchDistance(distance);
765   }
766 }
767
768 Any Adaptor::GetNativeWindowHandle()
769 {
770   WindowPane defaultWindow = mWindowFrame.front();
771   return defaultWindow.nativeWindow;
772 }
773
774 Any Adaptor::GetGraphicsDisplay()
775 {
776   Any display;
777
778   if (mGraphics)
779   {
780     auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
781
782     EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
783     display = eglImpl.GetDisplay();
784   }
785
786   return display;
787 }
788
789 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
790 {
791   mUseRemoteSurface = useRemoteSurface;
792 }
793
794 void Adaptor::AddObserver( LifeCycleObserver& observer )
795 {
796   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
797
798   if ( match == mObservers.end() )
799   {
800     mObservers.push_back( &observer );
801   }
802 }
803
804 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
805 {
806   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
807
808   if ( match != mObservers.end() )
809   {
810     mObservers.erase( match );
811   }
812 }
813
814 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
815 {
816   if( mCore )
817   {
818     mCore->QueueEvent(event);
819   }
820 }
821
822 void Adaptor::ProcessCoreEvents()
823 {
824   if( mCore )
825   {
826     if( mPerformanceInterface )
827     {
828       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
829     }
830
831     mCore->ProcessEvents();
832
833     if( mPerformanceInterface )
834     {
835       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
836     }
837   }
838 }
839
840 void Adaptor::RequestUpdate( bool forceUpdate )
841 {
842   switch( mState )
843   {
844     case RUNNING:
845     {
846       mThreadController->RequestUpdate();
847       break;
848     }
849     case PAUSED:
850     case PAUSED_WHILE_HIDDEN:
851     {
852       // When Dali applications are partially visible behind the lock-screen,
853       // the indicator must be updated (therefore allow updates in the PAUSED state)
854       if( forceUpdate )
855       {
856         mThreadController->RequestUpdateOnce();
857       }
858       break;
859     }
860     default:
861     {
862       // Do nothing
863       break;
864     }
865   }
866 }
867
868 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
869 {
870   // Only request a notification if the Adaptor is actually running
871   // and we haven't installed the idle notification
872   if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
873   {
874     mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
875   }
876 }
877
878 void Adaptor::OnWindowShown()
879 {
880   if( PAUSED_WHILE_HIDDEN == mState )
881   {
882     // Adaptor can now be resumed
883     mState = PAUSED;
884
885     Resume();
886
887     // Force a render task
888     RequestUpdateOnce();
889   }
890   else
891   {
892     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
893   }
894 }
895
896 void Adaptor::OnWindowHidden()
897 {
898   if( RUNNING == mState || READY == mState )
899   {
900     if( mState == RUNNING )
901     {
902       Pause();
903
904       // Adaptor cannot be resumed until the window is shown
905       mState = PAUSED_WHILE_HIDDEN;
906     }
907     else  // mState is READY
908     {
909       // Pause the adaptor after the state gets RUNNING
910       mState = PAUSED_WHILE_INITIALIZING;
911     }
912   }
913   else
914   {
915     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
916   }
917 }
918
919 // Dali::Internal::Adaptor::Adaptor::OnDamaged
920 void Adaptor::OnDamaged( const DamageArea& area )
921 {
922   // This is needed for the case where Dali window is partially obscured
923   RequestUpdate( false );
924 }
925
926 void Adaptor::SurfaceResizePrepare( SurfaceSize surfaceSize )
927 {
928   // Let the core know the surface size has changed
929   mCore->SurfaceResized( surfaceSize.GetWidth(), surfaceSize.GetHeight() );
930
931   mResizedSignal.Emit( mAdaptor );
932 }
933
934 void Adaptor::SurfaceResizeComplete( SurfaceSize surfaceSize )
935 {
936   // Flush the event queue to give the update-render thread chance
937   // to start processing messages for new camera setup etc as soon as possible
938   ProcessCoreEvents();
939
940   mThreadController->ResizeSurface();
941 }
942
943 void Adaptor::NotifySceneCreated()
944 {
945   GetCore().SceneCreated();
946
947   // Start thread controller after the scene has been created
948   mThreadController->Start();
949
950   // Process after surface is created (registering to remote surface provider if required)
951   SurfaceInitialized();
952
953   if( mState != PAUSED_WHILE_INITIALIZING )
954   {
955     mState = RUNNING;
956
957     DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
958   }
959   else
960   {
961     mState = RUNNING;
962
963     Pause();
964
965     mState = PAUSED_WHILE_HIDDEN;
966
967     DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
968   }
969 }
970
971 void Adaptor::NotifyLanguageChanged()
972 {
973   mLanguageChangedSignal.Emit( mAdaptor );
974 }
975
976 void Adaptor::RenderOnce()
977 {
978   RequestUpdateOnce();
979 }
980
981 const LogFactoryInterface& Adaptor::GetLogFactory()
982 {
983   return *mEnvironmentOptions;
984 }
985
986 void Adaptor::RequestUpdateOnce()
987 {
988   if( mThreadController )
989   {
990     mThreadController->RequestUpdateOnce();
991   }
992 }
993
994 void Adaptor::IndicatorSizeChanged(int height)
995 {
996   // Let the core know the indicator height is changed
997   mCore->SetTopMargin(height);
998 }
999
1000 bool Adaptor::ProcessCoreEventsFromIdle()
1001 {
1002   ProcessCoreEvents();
1003
1004   // the idle handle automatically un-installs itself
1005   mNotificationOnIdleInstalled = false;
1006
1007   return false;
1008 }
1009
1010 Adaptor::Adaptor(Any nativeWindow, Dali::Adaptor& adaptor, RenderSurface* surface, EnvironmentOptions* environmentOptions)
1011 : mResizedSignal(),
1012   mLanguageChangedSignal(),
1013   mAdaptor( adaptor ),
1014   mState( READY ),
1015   mCore( nullptr ),
1016   mThreadController( nullptr ),
1017   mVSyncMonitor( nullptr ),
1018   mGraphics( nullptr ),
1019   mDisplayConnection( nullptr ),
1020   mWindowFrame(),
1021   mPlatformAbstraction( nullptr ),
1022   mEventHandler( nullptr ),
1023   mCallbackManager( nullptr ),
1024   mNotificationOnIdleInstalled( false ),
1025   mNotificationTrigger( nullptr ),
1026   mGestureManager( nullptr ),
1027   mDaliFeedbackPlugin(),
1028   mFeedbackController( nullptr ),
1029   mTtsPlayers(),
1030   mObservers(),
1031   mDragAndDropDetector(),
1032   mDeferredRotationObserver( nullptr ),
1033   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1034   mPerformanceInterface( nullptr ),
1035   mKernelTracer(),
1036   mSystemTracer(),
1037   mTriggerEventFactory(),
1038   mObjectProfiler( nullptr ),
1039   mSocketFactory(),
1040   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1041   mUseRemoteSurface( false )
1042 {
1043   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1044
1045   WindowPane defaultWindow;
1046   defaultWindow.nativeWindow = nativeWindow;
1047   defaultWindow.surface = surface;
1048
1049   std::vector<WindowPane>::iterator iter = mWindowFrame.begin();
1050   iter = mWindowFrame.insert( iter, defaultWindow );
1051
1052   gThreadLocalAdaptor = this;
1053 }
1054
1055 // Stereoscopy
1056
1057 void Adaptor::SetViewMode( ViewMode viewMode )
1058 {
1059   WindowPane defaultWindow = mWindowFrame.front();
1060   defaultWindow.surface->SetViewMode( viewMode );
1061
1062   mCore->SetViewMode( viewMode );
1063 }
1064
1065 ViewMode Adaptor::GetViewMode() const
1066 {
1067   return mCore->GetViewMode();
1068 }
1069
1070 void Adaptor::SetStereoBase( float stereoBase )
1071 {
1072   mCore->SetStereoBase( stereoBase );
1073 }
1074
1075 float Adaptor::GetStereoBase() const
1076 {
1077   return mCore->GetStereoBase();
1078 }
1079
1080 void Adaptor::SetRootLayoutDirection( std::string locale )
1081 {
1082   Dali::Stage stage = Dali::Stage::GetCurrent();
1083
1084   stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1085                                     static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1086 }
1087
1088 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1089 {
1090   bool idleAdded( false );
1091
1092   // Only add an idle if the Adaptor is actually running
1093   if( RUNNING == mState || READY == mState || forceAdd )
1094   {
1095     idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1096   }
1097
1098   return idleAdded;
1099 }
1100
1101 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1102 {
1103   mCallbackManager->RemoveIdleEntererCallback( callback );
1104 }
1105
1106 } // namespace Adaptor
1107
1108 } // namespace Internal
1109
1110 } // namespace Dali