Merge "Revert "[Tizen] Remove to call key consumed event in ATSPI bridge"" into tizen
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / common / adaptor-impl.cpp
1 /*
2  * Copyright (c) 2024 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-builder-impl.h>
20 #include <dali/internal/adaptor/common/adaptor-impl.h>
21 #include <dali/internal/addons/common/addon-manager-factory.h>
22 #include <dali/internal/addons/common/addon-manager-impl.h>
23
24 // EXTERNAL INCLUDES
25 #include <dali/devel-api/actors/actor-devel.h>
26 #include <dali/devel-api/common/stage.h>
27 #include <dali/integration-api/addon-manager.h>
28 #include <dali/integration-api/context-notifier.h>
29 #include <dali/integration-api/core.h>
30 #include <dali/integration-api/debug.h>
31 #include <dali/integration-api/events/key-event-integ.h>
32 #include <dali/integration-api/events/touch-event-integ.h>
33 #include <dali/integration-api/events/wheel-event-integ.h>
34 #include <dali/integration-api/input-options.h>
35 #include <dali/integration-api/processor-interface.h>
36 #include <dali/integration-api/profiling.h>
37 #include <dali/integration-api/trace.h>
38 #include <dali/public-api/actors/layer.h>
39 #include <dali/public-api/events/wheel-event.h>
40 #include <dali/public-api/object/any.h>
41 #include <dali/public-api/object/object-registry.h>
42 #include <errno.h>
43 #include <sys/stat.h>
44
45 // INTERNAL INCLUDES
46 #include <dali/internal/adaptor/common/lifecycle-observer.h>
47 #include <dali/internal/adaptor/common/thread-controller-interface.h>
48 #include <dali/internal/system/common/performance-interface-factory.h>
49 #include <dali/internal/system/common/thread-controller.h>
50 #include <dali/public-api/dali-adaptor-common.h>
51
52 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
53 #include <dali/internal/graphics/gles/egl-graphics.h>
54
55 #include <dali/devel-api/text-abstraction/font-client.h>
56
57 #include <dali/internal/accessibility/common/tts-player-impl.h>
58 #include <dali/internal/graphics/common/egl-image-extensions.h>
59 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
60 #include <dali/internal/graphics/gles/gl-implementation.h>
61 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
62 #include <dali/internal/system/common/callback-manager.h>
63 #include <dali/internal/system/common/object-profiler.h>
64 #include <dali/internal/system/common/system-factory.h>
65 #include <dali/internal/window-system/common/display-connection.h>
66 #include <dali/internal/window-system/common/display-utils.h> // For Utils::MakeUnique
67 #include <dali/internal/window-system/common/event-handler.h>
68 #include <dali/internal/window-system/common/window-impl.h>
69 #include <dali/internal/window-system/common/window-render-surface.h>
70 #include <dali/internal/window-system/common/window-system.h>
71
72 #include <dali/devel-api/adaptor-framework/accessibility-bridge.h>
73 #include <dali/internal/system/common/logging.h>
74
75 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
76 #include <dali/internal/imaging/common/image-loader.h>
77 #include <dali/internal/system/common/locale-utils.h>
78
79 #include <dali/devel-api/adaptor-framework/environment-variable.h>
80 #include <dali/internal/system/common/configuration-manager.h>
81 #include <dali/internal/system/common/environment-variables.h>
82
83 using Dali::TextAbstraction::FontClient;
84
85 extern std::string GetSystemCachePath();
86
87 namespace Dali
88 {
89 namespace Internal
90 {
91 namespace Adaptor
92 {
93 namespace
94 {
95 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
96
97 DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_PERFORMANCE_MARKER, false);
98
99 const char* ENABLE_IMAGE_LOADER_PLUGIN_ENV = "DALI_ENABLE_IMAGE_LOADER_PLUGIN";
100 } // unnamed namespace
101
102 Dali::Adaptor* Adaptor::New(Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode)
103 {
104   Dali::Adaptor* adaptor = new Dali::Adaptor;
105   Adaptor*       impl    = new Adaptor(window, *adaptor, surface, environmentOptions, threadMode);
106   adaptor->mImpl         = impl;
107
108   Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder(*(impl->mEnvironmentOptions));
109   auto                                     graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
110
111   impl->Initialize(graphicsFactory);
112   delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
113
114   return adaptor;
115 }
116
117 Dali::Adaptor* Adaptor::New(Dali::Integration::SceneHolder window, EnvironmentOptions* environmentOptions)
118 {
119   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(window);
120   Dali::Adaptor*                  adaptor    = New(window, windowImpl.GetSurface(), environmentOptions, ThreadMode::NORMAL);
121   windowImpl.SetAdaptor(*adaptor);
122   return adaptor;
123 }
124
125 Dali::Adaptor* Adaptor::New(GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode)
126 {
127   Dali::Adaptor* adaptor = new Dali::Adaptor;                                                      // Public adaptor
128   Adaptor*       impl    = new Adaptor(window, *adaptor, surface, environmentOptions, threadMode); // Impl adaptor
129   adaptor->mImpl         = impl;
130
131   impl->Initialize(graphicsFactory);
132
133   return adaptor;
134 } // Called second
135
136 Dali::Adaptor* Adaptor::New(GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, EnvironmentOptions* environmentOptions)
137 {
138   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(window);
139   Dali::Adaptor*                  adaptor    = New(graphicsFactory, window, windowImpl.GetSurface(), environmentOptions, ThreadMode::NORMAL);
140   windowImpl.SetAdaptor(*adaptor);
141   return adaptor;
142 } // Called first
143
144 void Adaptor::Initialize(GraphicsFactory& graphicsFactory)
145 {
146   // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
147   Dali::Integration::Log::LogFunction logFunction(Dali::TizenPlatform::LogMessage);
148   mEnvironmentOptions->SetLogFunction(logFunction);
149   mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
150
151   mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
152
153   std::string path;
154   GetDataStoragePath(path);
155   mPlatformAbstraction->SetDataStoragePath(path);
156
157   if(mEnvironmentOptions->PerformanceServerRequired())
158   {
159     mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface(*this, *mEnvironmentOptions);
160   }
161
162   mEnvironmentOptions->CreateTraceManager(mPerformanceInterface);
163   mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
164
165   mCallbackManager = Dali::Internal::Adaptor::GetSystemFactory()->CreateCallbackManager();
166
167   Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
168
169   DALI_ASSERT_DEBUG(defaultWindow->GetSurface() && "Surface not initialized");
170
171   mGraphics = std::unique_ptr<GraphicsInterface>(&graphicsFactory.Create());
172
173   // Create the AddOnManager
174   mAddOnManager.reset(Dali::Internal::AddOnManagerFactory::CreateAddOnManager());
175
176   mCore = Integration::Core::New(*this,
177                                  *mPlatformAbstraction,
178                                  mGraphics->GetController(),
179                                  (0u != mEnvironmentOptions->GetRenderToFboInterval()) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
180                                  mGraphics->GetDepthBufferRequired(),
181                                  mGraphics->GetStencilBufferRequired(),
182                                  mGraphics->GetPartialUpdateRequired());
183
184   // Create TextureUploadManager after mCore created
185   mTextureUploadManager = Dali::Devel::TextureUploadManager::Get();
186
187   defaultWindow->SetAdaptor(Get());
188
189   Dali::Integration::SceneHolder defaultSceneHolder(defaultWindow);
190
191   mWindowCreatedSignal.Emit(defaultSceneHolder);
192
193   const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
194   if(0u < timeInterval)
195   {
196     mObjectProfiler = new ObjectProfiler(mCore->GetObjectRegistry(), timeInterval);
197   }
198
199   const uint32_t poolTimeInterval = mEnvironmentOptions->GetMemoryPoolInterval();
200   if(0u < poolTimeInterval)
201   {
202     mMemoryPoolTimer = Dali::Timer::New(poolTimeInterval * 1000);
203     mMemoryPoolTimer.TickSignal().Connect(mMemoryPoolTimerSlotDelegate, &Adaptor::MemoryPoolTimeout);
204     mMemoryPoolTimer.Start();
205   }
206
207   mNotificationTrigger = TriggerEventFactory::CreateTriggerEvent(MakeCallback(this, &Adaptor::ProcessCoreEvents), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
208
209   mDisplayConnection = Dali::DisplayConnection::New(*mGraphics, defaultWindow->GetSurface()->GetSurfaceType());
210
211   mThreadController = new ThreadController(*this, *mEnvironmentOptions, mThreadMode);
212
213   // Should be called after Core creation
214   if(mEnvironmentOptions->GetPanGestureLoggingLevel())
215   {
216     Integration::EnableProfiling(Dali::Integration::PROFILING_TYPE_PAN_GESTURE);
217   }
218   if(mEnvironmentOptions->GetPanGesturePredictionMode() >= 0)
219   {
220     Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
221   }
222   if(mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0)
223   {
224     Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
225   }
226   if(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0)
227   {
228     Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
229   }
230   if(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0)
231   {
232     Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
233   }
234   if(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0)
235   {
236     Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
237   }
238   if(mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0)
239   {
240     Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
241   }
242   if(mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f)
243   {
244     Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
245   }
246   if(mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0)
247   {
248     Integration::SetPanGestureUseActualTimes(mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false);
249   }
250   if(mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0)
251   {
252     Integration::SetPanGestureInterpolationTimeRange(mEnvironmentOptions->GetPanGestureInterpolationTimeRange());
253   }
254   if(mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0)
255   {
256     Integration::SetPanGestureScalarOnlyPredictionEnabled(mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false);
257   }
258   if(mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0)
259   {
260     Integration::SetPanGestureTwoPointPredictionEnabled(mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false);
261   }
262   if(mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0)
263   {
264     Integration::SetPanGestureTwoPointInterpolatePastTime(mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime());
265   }
266   if(mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f)
267   {
268     Integration::SetPanGestureTwoPointVelocityBias(mEnvironmentOptions->GetPanGestureTwoPointVelocityBias());
269   }
270   if(mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f)
271   {
272     Integration::SetPanGestureTwoPointAccelerationBias(mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias());
273   }
274   if(mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0)
275   {
276     Integration::SetPanGestureMultitapSmoothingRange(mEnvironmentOptions->GetPanGestureMultitapSmoothingRange());
277   }
278   if(mEnvironmentOptions->GetMinimumPanDistance() >= 0)
279   {
280     Integration::SetPanGestureMinimumDistance(mEnvironmentOptions->GetMinimumPanDistance());
281   }
282   if(mEnvironmentOptions->GetMinimumPanEvents() >= 0)
283   {
284     Integration::SetPanGestureMinimumPanEvents(mEnvironmentOptions->GetMinimumPanEvents());
285   }
286   if(mEnvironmentOptions->GetMinimumPinchDistance() >= 0)
287   {
288     Integration::SetPinchGestureMinimumDistance(mEnvironmentOptions->GetMinimumPinchDistance());
289   }
290   if(mEnvironmentOptions->GetMinimumPinchTouchEvents() >= 0)
291   {
292     Integration::SetPinchGestureMinimumTouchEvents(mEnvironmentOptions->GetMinimumPinchTouchEvents());
293   }
294   if(mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() >= 0)
295   {
296     Integration::SetPinchGestureMinimumTouchEventsAfterStart(mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart());
297   }
298   if(mEnvironmentOptions->GetMinimumRotationTouchEvents() >= 0)
299   {
300     Integration::SetRotationGestureMinimumTouchEvents(mEnvironmentOptions->GetMinimumRotationTouchEvents());
301   }
302   if(mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() >= 0)
303   {
304     Integration::SetRotationGestureMinimumTouchEventsAfterStart(mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart());
305   }
306   if(mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0)
307   {
308     Integration::SetLongPressMinimumHoldingTime(mEnvironmentOptions->GetLongPressMinimumHoldingTime());
309   }
310   if(mEnvironmentOptions->GetTapMaximumAllowedTime() > 0)
311   {
312     Integration::SetTapMaximumAllowedTime(mEnvironmentOptions->GetTapMaximumAllowedTime());
313   }
314
315   std::string systemCachePath = GetSystemCachePath();
316   if(!systemCachePath.empty())
317   {
318     const int dir_err = mkdir(systemCachePath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
319     if(0 != dir_err && errno != EEXIST)
320     {
321       DALI_LOG_ERROR("Error creating system cache directory: %s!\n", systemCachePath.c_str());
322     }
323   }
324
325   mConfigurationManager = Utils::MakeUnique<ConfigurationManager>(systemCachePath, mGraphics.get(), mThreadController);
326 }
327
328 void Adaptor::AccessibilityObserver::OnAccessibleKeyEvent(const Dali::KeyEvent& event)
329 {
330   Accessibility::KeyEventType type;
331   if(event.GetState() == Dali::KeyEvent::DOWN)
332   {
333     type = Accessibility::KeyEventType::KEY_PRESSED;
334   }
335   else if(event.GetState() == Dali::KeyEvent::UP)
336   {
337     type = Accessibility::KeyEventType::KEY_RELEASED;
338   }
339   else
340   {
341     return;
342   }
343   Dali::Accessibility::Bridge::GetCurrentBridge()->Emit(type, event.GetKeyCode(), event.GetKeyName(), event.GetTime(), !event.GetKeyString().empty());
344 }
345
346 Adaptor::~Adaptor()
347 {
348   Accessibility::Bridge::GetCurrentBridge()->Terminate();
349
350   // Ensure stop status
351   Stop();
352
353   // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
354   gThreadLocalAdaptor = NULL;
355
356   for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
357   {
358     (*iter)->OnDestroy();
359   }
360
361   // Clear out all the handles to Windows
362   mWindows.clear();
363
364   delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
365   delete mObjectProfiler;
366
367   delete mCore;
368
369   delete mDisplayConnection;
370   delete mPlatformAbstraction;
371
372   mCallbackManager.reset();
373
374   delete mPerformanceInterface;
375
376   mGraphics->Destroy();
377
378   // uninstall it on this thread (main actor thread)
379   Dali::Integration::Log::UninstallLogFunction();
380
381   // Delete environment options if we own it
382   if(mEnvironmentOptionsOwned)
383   {
384     delete mEnvironmentOptions;
385   }
386 }
387
388 void Adaptor::Start()
389 {
390   // It doesn't support restart after stop at this moment to support restarting, need more testing
391   if(READY != mState)
392   {
393     return;
394   }
395
396   mCore->Initialize();
397
398   SetupSystemInformation();
399
400   // Start the callback manager
401   mCallbackManager->Start();
402
403   // Initialize accessibility bridge after callback manager is started to use Idler callback
404   auto appName = GetApplicationPackageName();
405   auto bridge  = Accessibility::Bridge::GetCurrentBridge();
406   bridge->SetApplicationName(appName);
407   bridge->Initialize();
408   Dali::Stage::GetCurrent().KeyEventSignal().Connect(&mAccessibilityObserver, &AccessibilityObserver::OnAccessibleKeyEvent);
409
410   Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
411
412   unsigned int dpiHor, dpiVer;
413   dpiHor = dpiVer = 0;
414
415   defaultWindow->GetSurface()->GetDpi(dpiHor, dpiVer);
416   Dali::Internal::Adaptor::WindowSystem::SetDpi(dpiHor, dpiVer);
417
418   // Initialize the thread controller
419   mThreadController->Initialize();
420
421   // Set max texture size
422   if(mEnvironmentOptions->GetMaxTextureSize() > 0)
423   {
424     Dali::TizenPlatform::ImageLoader::SetMaxTextureSize(mEnvironmentOptions->GetMaxTextureSize());
425   }
426   else
427   {
428     unsigned int maxTextureSize = mConfigurationManager->GetMaxTextureSize();
429     Dali::TizenPlatform::ImageLoader::SetMaxTextureSize(maxTextureSize);
430   }
431
432   // cache advanced blending and shader language version
433   mGraphics->CacheConfigurations(*mConfigurationManager.get());
434
435   ProcessCoreEvents(); // Ensure any startup messages are processed.
436
437   // Initialize the image loader plugin
438   auto enablePluginString = Dali::EnvironmentVariable::GetEnvironmentVariable(ENABLE_IMAGE_LOADER_PLUGIN_ENV);
439   bool enablePlugin       = enablePluginString ? std::atoi(enablePluginString) : false;
440   if(enablePlugin)
441   {
442     Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
443   }
444
445   for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
446   {
447     (*iter)->OnStart();
448   }
449
450   if(mAddOnManager)
451   {
452     mAddOnManager->Start();
453   }
454 }
455
456 // Dali::Internal::Adaptor::Adaptor::Pause
457 void Adaptor::Pause()
458 {
459   // Only pause the adaptor if we're actually running.
460   if(RUNNING == mState)
461   {
462     // Inform observers that we are about to be paused.
463     for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
464     {
465       (*iter)->OnPause();
466     }
467
468     // Extensions
469     if(mAddOnManager)
470     {
471       mAddOnManager->Pause();
472     }
473
474     // Pause all windows event handlers when adaptor paused
475     for(auto window : mWindows)
476     {
477       window->Pause();
478     }
479
480     mThreadController->Pause();
481     mState = PAUSED;
482
483     // Ensure any messages queued during pause callbacks are processed by doing another update.
484     RequestUpdateOnce();
485
486     DALI_LOG_RELEASE_INFO("Adaptor::Pause: Paused\n");
487   }
488   else
489   {
490     DALI_LOG_RELEASE_INFO("Adaptor::Pause: Not paused [%d]\n", mState);
491   }
492 }
493
494 // Dali::Internal::Adaptor::Adaptor::Resume
495 void Adaptor::Resume()
496 {
497   // Only resume the adaptor if we are in the suspended state.
498   if(PAUSED == mState)
499   {
500     mState = RUNNING;
501
502     // Reset the event handlers when adaptor resumed
503     for(auto window : mWindows)
504     {
505       window->Resume();
506     }
507
508     // Resume AddOnManager
509     if(mAddOnManager)
510     {
511       mAddOnManager->Resume();
512     }
513
514     // Inform observers that we have resumed.
515     for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
516     {
517       (*iter)->OnResume();
518     }
519
520     // Trigger processing of events queued up while paused
521     mCore->ProcessEvents();
522
523     // Do at end to ensure our first update/render after resumption includes the processed messages as well
524     mThreadController->Resume();
525
526     DALI_LOG_RELEASE_INFO("Adaptor::Resume: Resumed\n");
527   }
528   else
529   {
530     DALI_LOG_RELEASE_INFO("Adaptor::Resume: Not resumed [%d]\n", mState);
531   }
532 }
533
534 void Adaptor::Stop()
535 {
536   if(RUNNING == mState ||
537      PAUSED == mState ||
538      PAUSED_WHILE_HIDDEN == mState)
539   {
540     for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
541     {
542       (*iter)->OnStop();
543     }
544
545     if(mAddOnManager)
546     {
547       mAddOnManager->Stop();
548     }
549
550     mThreadController->Stop();
551
552     // Delete the TTS player
553     for(int i = 0; i < Dali::TtsPlayer::MODE_NUM; i++)
554     {
555       if(mTtsPlayers[i])
556       {
557         mTtsPlayers[i].Reset();
558       }
559     }
560
561     // Destroy the image loader plugin
562     auto enablePluginString = Dali::EnvironmentVariable::GetEnvironmentVariable(ENABLE_IMAGE_LOADER_PLUGIN_ENV);
563     bool enablePlugin       = enablePluginString ? std::atoi(enablePluginString) : false;
564     if(enablePlugin)
565     {
566       Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
567     }
568
569     delete mNotificationTrigger;
570     mNotificationTrigger = NULL;
571
572     mCallbackManager->Stop();
573
574     mState = STOPPED;
575
576     RemoveSystemInformation();
577
578     DALI_LOG_RELEASE_INFO("Adaptor::Stop\n");
579   }
580 }
581
582 void Adaptor::ContextLost()
583 {
584   mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
585 }
586
587 void Adaptor::ContextRegained()
588 {
589   // Inform core, so that texture resources can be reloaded
590   mCore->RecoverFromContextLoss();
591
592   mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
593 }
594
595 void Adaptor::FeedTouchPoint(TouchPoint& point, int timeStamp)
596 {
597   Integration::Point convertedPoint(point);
598   mWindows.front()->FeedTouchPoint(convertedPoint, timeStamp);
599 }
600
601 void Adaptor::FeedWheelEvent(Dali::WheelEvent& wheelEvent)
602 {
603   Integration::WheelEvent event(static_cast<Integration::WheelEvent::Type>(wheelEvent.GetType()), wheelEvent.GetDirection(), wheelEvent.GetModifiers(), wheelEvent.GetPoint(), wheelEvent.GetDelta(), wheelEvent.GetTime());
604   mWindows.front()->FeedWheelEvent(event);
605 }
606
607 void Adaptor::FeedKeyEvent(Dali::KeyEvent& keyEvent)
608 {
609   Integration::KeyEvent convertedEvent(keyEvent.GetKeyName(), keyEvent.GetLogicalKey(), keyEvent.GetKeyString(), keyEvent.GetKeyCode(), keyEvent.GetKeyModifier(), keyEvent.GetTime(), static_cast<Integration::KeyEvent::State>(keyEvent.GetState()), keyEvent.GetCompose(), keyEvent.GetDeviceName(), keyEvent.GetDeviceClass(), keyEvent.GetDeviceSubclass());
610   mWindows.front()->FeedKeyEvent(convertedEvent);
611 }
612
613 void Adaptor::ReplaceSurface(Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface)
614 {
615   Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation(window);
616   for(auto windowPtr : mWindows)
617   {
618     if(windowPtr == windowImpl) // the window is not deleted
619     {
620       mResizedSignal.Emit(mAdaptor);
621
622       windowImpl->SetSurface(&newSurface);
623
624       // Flush the event queue to give the update-render thread chance
625       // to start processing messages for new camera setup etc as soon as possible
626       ProcessCoreEvents();
627
628       // This method blocks until the render thread has completed the replace.
629       mThreadController->ReplaceSurface(&newSurface);
630       break;
631     }
632   }
633 }
634
635 void Adaptor::DeleteSurface(Dali::RenderSurfaceInterface& surface)
636 {
637   // Flush the event queue to give the update-render thread chance
638   // to start processing messages for new camera setup etc as soon as possible
639   ProcessCoreEvents();
640
641   // This method blocks until the render thread has finished rendering the current surface.
642   mThreadController->DeleteSurface(&surface);
643 }
644
645 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
646 {
647   return *mWindows.front()->GetSurface();
648 }
649
650 void Adaptor::ReleaseSurfaceLock()
651 {
652   mWindows.front()->GetSurface()->ReleaseLock();
653 }
654
655 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
656 {
657   if(!mTtsPlayers[mode])
658   {
659     // Create the TTS player when it needed, because it can reduce launching time.
660     mTtsPlayers[mode] = TtsPlayer::New(mode);
661   }
662
663   return mTtsPlayers[mode];
664 }
665
666 bool Adaptor::AddIdle(CallbackBase* callback, bool hasReturnValue)
667 {
668   bool idleAdded(false);
669
670   // We want to run the processes even when paused
671   if(STOPPED != mState)
672   {
673     idleAdded = mCallbackManager->AddIdleCallback(callback, hasReturnValue);
674   }
675
676   if(!idleAdded)
677   {
678     // Delete callback
679     delete callback;
680   }
681
682   return idleAdded;
683 }
684
685 void Adaptor::RemoveIdle(CallbackBase* callback)
686 {
687   mCallbackManager->RemoveIdleCallback(callback);
688 }
689
690 void Adaptor::ProcessIdle()
691 {
692   bool idleProcessed           = mCallbackManager->ProcessIdle();
693   mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
694 }
695
696 void Adaptor::SetPreRenderCallback(CallbackBase* callback)
697 {
698   mThreadController->SetPreRenderCallback(callback);
699 }
700
701 bool Adaptor::AddWindow(Dali::Integration::SceneHolder childWindow)
702 {
703   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(childWindow);
704   windowImpl.SetAdaptor(Get());
705
706   // ChildWindow is set to the layout direction of the default window.
707   windowImpl.GetRootLayer().SetProperty(Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection);
708
709   // Add the new Window to the container - the order is not important
710   {
711     Dali::Mutex::ScopedLock lock(mMutex);
712     mWindows.push_back(&windowImpl);
713   }
714
715   Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
716
717   mThreadController->AddSurface(surface);
718
719   mWindowCreatedSignal.Emit(childWindow);
720
721   return true;
722 }
723
724 bool Adaptor::RemoveWindow(Dali::Integration::SceneHolder* childWindow)
725 {
726   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(*childWindow);
727   for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
728   {
729     if(*iter == &windowImpl)
730     {
731       Dali::Mutex::ScopedLock lock(mMutex);
732       mWindows.erase(iter);
733       return true;
734     }
735   }
736
737   return false;
738 }
739
740 bool Adaptor::RemoveWindow(std::string childWindowName)
741 {
742   for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
743   {
744     if((*iter)->GetName() == childWindowName)
745     {
746       Dali::Mutex::ScopedLock lock(mMutex);
747       mWindows.erase(iter);
748       return true;
749     }
750   }
751
752   return false;
753 }
754
755 bool Adaptor::RemoveWindow(Internal::Adaptor::SceneHolder* childWindow)
756 {
757   for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
758   {
759     if((*iter)->GetId() == childWindow->GetId())
760     {
761       Dali::Mutex::ScopedLock lock(mMutex);
762       mWindows.erase(iter);
763       return true;
764     }
765   }
766
767   return false;
768 }
769
770 Dali::Adaptor& Adaptor::Get()
771 {
772   DALI_ASSERT_ALWAYS(IsAvailable() && "Adaptor not instantiated");
773   return gThreadLocalAdaptor->mAdaptor;
774 }
775
776 bool Adaptor::IsAvailable()
777 {
778   return gThreadLocalAdaptor != NULL;
779 }
780
781 void Adaptor::SceneCreated()
782 {
783   mCore->SceneCreated();
784 }
785
786 Dali::Integration::Core& Adaptor::GetCore()
787 {
788   return *mCore;
789 }
790
791 void Adaptor::SetRenderRefreshRate(unsigned int numberOfVSyncsPerRender)
792 {
793   mThreadController->SetRenderRefreshRate(numberOfVSyncsPerRender);
794 }
795
796 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
797 {
798   DALI_ASSERT_DEBUG(mDisplayConnection && "Display connection not created");
799   return *mDisplayConnection;
800 }
801
802 GraphicsInterface& Adaptor::GetGraphicsInterface()
803 {
804   DALI_ASSERT_DEBUG(mGraphics && "Graphics interface not created");
805   return *(mGraphics.get());
806 }
807
808 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
809 {
810   return *mPlatformAbstraction;
811 }
812
813 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
814 {
815   return *mNotificationTrigger;
816 }
817
818 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
819 {
820   return mSocketFactory;
821 }
822
823 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
824 {
825   if(!mWindows.empty())
826   {
827     return mWindows.front()->GetSurface();
828   }
829
830   return nullptr;
831 }
832
833 TraceInterface& Adaptor::GetKernelTraceInterface()
834 {
835   return mKernelTracer;
836 }
837
838 TraceInterface& Adaptor::GetSystemTraceInterface()
839 {
840   return mSystemTracer;
841 }
842
843 PerformanceInterface* Adaptor::GetPerformanceInterface()
844 {
845   return mPerformanceInterface;
846 }
847
848 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
849 {
850   DALI_ASSERT_DEBUG(mPlatformAbstraction && "PlatformAbstraction not created");
851   return *mPlatformAbstraction;
852 }
853
854 void Adaptor::GetWindowContainerInterface(WindowContainer& windows)
855 {
856   Dali::Mutex::ScopedLock lock(mMutex);
857   windows = mWindows;
858 }
859
860 Devel::TextureUploadManager& Adaptor::GetTextureUploadManager()
861 {
862   return mTextureUploadManager;
863 }
864
865 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
866 {
867   if(mTtsPlayers[mode])
868   {
869     mTtsPlayers[mode].Reset();
870   }
871 }
872
873 Any Adaptor::GetNativeWindowHandle()
874 {
875   return mWindows.front()->GetNativeHandle();
876 }
877
878 Any Adaptor::GetNativeWindowHandle(Dali::Actor actor)
879 {
880   Any nativeWindowHandle;
881
882   Dali::Integration::Scene scene = Dali::Integration::Scene::Get(actor);
883
884   for(auto sceneHolder : mWindows)
885   {
886     if(scene == sceneHolder->GetScene())
887     {
888       nativeWindowHandle = sceneHolder->GetNativeHandle();
889       break;
890     }
891   }
892
893   return nativeWindowHandle;
894 }
895
896 Any Adaptor::GetGraphicsDisplay()
897 {
898   Any display;
899
900   if(mGraphics)
901   {
902     GraphicsInterface* graphics    = mGraphics.get(); // This interface is temporary until Core has been updated to match
903     auto               eglGraphics = static_cast<EglGraphics*>(graphics);
904
905     EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
906     display                    = eglImpl.GetDisplay();
907   }
908
909   return display;
910 }
911
912 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
913 {
914   mUseRemoteSurface = useRemoteSurface;
915 }
916
917 void Adaptor::AddObserver(LifeCycleObserver& observer)
918 {
919   ObserverContainer::iterator match(find(mObservers.begin(), mObservers.end(), &observer));
920
921   if(match == mObservers.end())
922   {
923     mObservers.push_back(&observer);
924   }
925 }
926
927 void Adaptor::RemoveObserver(LifeCycleObserver& observer)
928 {
929   ObserverContainer::iterator match(find(mObservers.begin(), mObservers.end(), &observer));
930
931   if(match != mObservers.end())
932   {
933     mObservers.erase(match);
934   }
935 }
936
937 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
938 {
939   if(mCore)
940   {
941     mCore->QueueEvent(event);
942   }
943 }
944
945 void Adaptor::FlushUpdateMessages()
946 {
947   if(mCore)
948   {
949     DALI_TRACE_SCOPE(gTraceFilter, "DALI_FLUSH_UPDATE_MESSAGES");
950
951     mCore->ForceRelayout();
952   }
953 }
954
955 void Adaptor::ProcessCoreEvents()
956 {
957   if(mCore)
958   {
959     DALI_TRACE_SCOPE(gTraceFilter, "DALI_PROCESS_CORE_EVENTS");
960
961     if(mPerformanceInterface)
962     {
963       mPerformanceInterface->AddMarker(PerformanceInterface::PROCESS_EVENTS_START);
964     }
965
966     mCore->ProcessEvents();
967
968     if(mPerformanceInterface)
969     {
970       mPerformanceInterface->AddMarker(PerformanceInterface::PROCESS_EVENTS_END);
971     }
972   }
973 }
974
975 void Adaptor::RequestUpdate()
976 {
977   switch(mState)
978   {
979     case RUNNING:
980     {
981       mThreadController->RequestUpdate();
982       break;
983     }
984     case PAUSED:
985     case PAUSED_WHILE_HIDDEN:
986     {
987       // Update (and resource upload) without rendering
988       mThreadController->RequestUpdateOnce(UpdateMode::SKIP_RENDER);
989       break;
990     }
991     default:
992     {
993       // Do nothing
994       break;
995     }
996   }
997 }
998
999 void Adaptor::RequestProcessEventsOnIdle()
1000 {
1001   // We want to run the processes even when paused
1002   if(STOPPED != mState)
1003   {
1004     if(!mNotificationOnIdleInstalled)
1005     {
1006       // If we haven't installed the idle notification, install it idle enterer.
1007       mNotificationOnIdleInstalled = AddIdleEnterer(MakeCallback(this, &Adaptor::ProcessCoreEventsFromIdle));
1008     }
1009     else
1010     {
1011       // Request comes during ProcessCoreEventsFromIdle running.
1012       // Mark as we need to call ProcessEvents in next idle events.
1013       mRequiredIdleRepeat = true;
1014     }
1015   }
1016 }
1017
1018 void Adaptor::OnWindowShown()
1019 {
1020   if(PAUSED_WHILE_HIDDEN == mState)
1021   {
1022     // Adaptor can now be resumed
1023     mState = PAUSED;
1024
1025     Resume();
1026
1027     // Force a render task
1028     RequestUpdateOnce();
1029   }
1030   else if(RUNNING == mState)
1031   {
1032     // Force a render task
1033     RequestUpdateOnce();
1034
1035     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowShown: Update requested.\n");
1036   }
1037   else if(PAUSED_WHILE_INITIALIZING == mState)
1038   {
1039     // Change the state to READY again. It will be changed to RUNNING after the adaptor is started.
1040     mState = READY;
1041   }
1042   else
1043   {
1044     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState);
1045   }
1046 }
1047
1048 void Adaptor::OnWindowHidden()
1049 {
1050   if(RUNNING == mState || READY == mState)
1051   {
1052     bool allWindowsHidden = true;
1053
1054     for(auto window : mWindows)
1055     {
1056       if(window->IsVisible())
1057       {
1058         allWindowsHidden = false;
1059         break;
1060       }
1061     }
1062
1063     // Only pause the adaptor when all the windows are hidden
1064     if(allWindowsHidden)
1065     {
1066       if(mState == RUNNING)
1067       {
1068         Pause();
1069
1070         // Adaptor cannot be resumed until any window is shown
1071         mState = PAUSED_WHILE_HIDDEN;
1072       }
1073       else // mState is READY
1074       {
1075         // Pause the adaptor after the state gets RUNNING
1076         mState = PAUSED_WHILE_INITIALIZING;
1077       }
1078     }
1079     else
1080     {
1081       DALI_LOG_RELEASE_INFO("Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n");
1082     }
1083   }
1084   else
1085   {
1086     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState);
1087   }
1088 }
1089
1090 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1091 void Adaptor::OnDamaged(const DamageArea& area)
1092 {
1093   // This is needed for the case where Dali window is partially obscured
1094   RequestUpdate();
1095 }
1096
1097 void Adaptor::SurfaceResizePrepare(Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize)
1098 {
1099   mResizedSignal.Emit(mAdaptor);
1100 }
1101
1102 void Adaptor::SurfaceResizeComplete(Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize)
1103 {
1104   // Nofify surface resizing before flushing event queue
1105   mThreadController->ResizeSurface();
1106
1107   // Flush the event queue to give the update-render thread chance
1108   // to start processing messages for new camera setup etc as soon as possible
1109   ProcessCoreEvents();
1110 }
1111
1112 void Adaptor::IncreaseSurfaceResizeCounter()
1113 {
1114   // Nofify surface resizing before flushing event queue
1115   if(mThreadController)
1116   {
1117     mThreadController->ResizeSurface();
1118   }
1119 }
1120
1121 void Adaptor::NotifySceneCreated()
1122 {
1123   GetCore().SceneCreated();
1124
1125   // Flush the event queue to give the update-render thread chance
1126   // to start processing messages for new camera setup etc as soon as possible
1127   ProcessCoreEvents();
1128
1129   // Start thread controller after the scene has been created
1130   mThreadController->Start();
1131
1132   // Process after surface is created (registering to remote surface provider if required)
1133   SurfaceInitialized();
1134
1135   if(mState != PAUSED_WHILE_INITIALIZING)
1136   {
1137     mState = RUNNING;
1138
1139     DALI_LOG_RELEASE_INFO("Adaptor::NotifySceneCreated: Adaptor is running\n");
1140   }
1141   else
1142   {
1143     mState = RUNNING;
1144
1145     Pause();
1146
1147     mState = PAUSED_WHILE_HIDDEN;
1148
1149     DALI_LOG_RELEASE_INFO("Adaptor::NotifySceneCreated: Adaptor is paused\n");
1150   }
1151 }
1152
1153 void Adaptor::NotifyLanguageChanged()
1154 {
1155   mLanguageChangedSignal.Emit(mAdaptor);
1156 }
1157
1158 void Adaptor::RenderOnce()
1159 {
1160   if(mThreadController)
1161   {
1162     UpdateMode updateMode;
1163     if(mThreadMode == ThreadMode::NORMAL)
1164     {
1165       updateMode = UpdateMode::NORMAL;
1166     }
1167     else
1168     {
1169       updateMode = UpdateMode::FORCE_RENDER;
1170
1171       ProcessCoreEvents();
1172     }
1173
1174     // Force rendering
1175     for(auto&& iter : mWindows)
1176     {
1177       iter->GetSurface()->SetFullSwapNextFrame();
1178     }
1179
1180     mThreadController->RequestUpdateOnce(updateMode);
1181   }
1182 }
1183
1184 const LogFactoryInterface& Adaptor::GetLogFactory()
1185 {
1186   return *mEnvironmentOptions;
1187 }
1188
1189 const TraceFactoryInterface& Adaptor::GetTraceFactory()
1190 {
1191   return *mEnvironmentOptions;
1192 }
1193
1194 void Adaptor::RegisterProcessor(Integration::Processor& processor, bool postProcessor)
1195 {
1196   GetCore().RegisterProcessor(processor, postProcessor);
1197 }
1198
1199 void Adaptor::UnregisterProcessor(Integration::Processor& processor, bool postProcessor)
1200 {
1201   GetCore().UnregisterProcessor(processor, postProcessor);
1202 }
1203
1204 bool Adaptor::IsMultipleWindowSupported() const
1205 {
1206   return mConfigurationManager->IsMultipleWindowSupported();
1207 }
1208
1209 int32_t Adaptor::GetRenderThreadId() const
1210 {
1211   if(mThreadController)
1212   {
1213     return mThreadController->GetThreadId();
1214   }
1215   return 0;
1216 }
1217
1218 void Adaptor::RequestUpdateOnce()
1219 {
1220   if(mThreadController)
1221   {
1222     mThreadController->RequestUpdateOnce(UpdateMode::NORMAL);
1223   }
1224 }
1225
1226 bool Adaptor::ProcessCoreEventsFromIdle()
1227 {
1228   // Reset repeat idler flag.
1229   mRequiredIdleRepeat = false;
1230   ProcessCoreEvents();
1231
1232   // If someone request ProcessCoreEvents during above ProcessCoreEvents call, we might need to run idle one more times.
1233   // Else, the idle handle automatically un-installs itself
1234   mNotificationOnIdleInstalled = mRequiredIdleRepeat;
1235
1236   if(mRequiredIdleRepeat)
1237   {
1238     DALI_LOG_DEBUG_INFO("Required ProcessCoreEvents one more times\n");
1239   }
1240
1241   return mRequiredIdleRepeat;
1242 }
1243
1244 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow(Dali::Actor& actor)
1245 {
1246   Dali::Integration::Scene scene = Dali::Integration::Scene::Get(actor);
1247
1248   for(auto window : mWindows)
1249   {
1250     if(scene == window->GetScene())
1251     {
1252       return window;
1253     }
1254   }
1255
1256   return nullptr;
1257 }
1258
1259 Dali::WindowContainer Adaptor::GetWindows() const
1260 {
1261   Dali::WindowContainer windows;
1262
1263   for(auto iter = mWindows.begin(); iter != mWindows.end(); ++iter)
1264   {
1265     // Downcast to Dali::Window
1266     Dali::Window window(dynamic_cast<Dali::Internal::Adaptor::Window*>(*iter));
1267     if(window)
1268     {
1269       windows.push_back(window);
1270     }
1271   }
1272
1273   return windows;
1274 }
1275
1276 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1277 {
1278   Dali::SceneHolderList sceneHolderList;
1279
1280   for(auto iter = mWindows.begin(); iter != mWindows.end(); ++iter)
1281   {
1282     sceneHolderList.push_back(Dali::Integration::SceneHolder(*iter));
1283   }
1284
1285   return sceneHolderList;
1286 }
1287
1288 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1289 {
1290   Dali::ObjectRegistry registry;
1291   if(mCore)
1292   {
1293     registry = mCore->GetObjectRegistry();
1294   }
1295   return registry;
1296 }
1297
1298 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode)
1299 : mResizedSignal(),
1300   mLanguageChangedSignal(),
1301   mWindowCreatedSignal(),
1302   mAdaptor(adaptor),
1303   mState(READY),
1304   mCore(nullptr),
1305   mThreadController(nullptr),
1306   mGraphics(nullptr),
1307   mDisplayConnection(nullptr),
1308   mWindows(),
1309   mConfigurationManager(nullptr),
1310   mPlatformAbstraction(nullptr),
1311   mCallbackManager(nullptr),
1312   mNotificationOnIdleInstalled(false),
1313   mRequiredIdleRepeat(false),
1314   mNotificationTrigger(nullptr),
1315   mDaliFeedbackPlugin(),
1316   mFeedbackController(nullptr),
1317   mTtsPlayers(),
1318   mObservers(),
1319   mEnvironmentOptions(environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1320   mPerformanceInterface(nullptr),
1321   mKernelTracer(),
1322   mSystemTracer(),
1323   mTextureUploadManager(),
1324   mObjectProfiler(nullptr),
1325   mMemoryPoolTimerSlotDelegate(this),
1326   mSocketFactory(),
1327   mMutex(),
1328   mThreadMode(threadMode),
1329   mEnvironmentOptionsOwned(environmentOptions ? false : true /* If not provided then we own the object */),
1330   mUseRemoteSurface(false),
1331   mRootLayoutDirection(Dali::LayoutDirection::LEFT_TO_RIGHT)
1332 {
1333   DALI_ASSERT_ALWAYS(!IsAvailable() && "Cannot create more than one Adaptor per thread");
1334   mWindows.insert(mWindows.begin(), &Dali::GetImplementation(window));
1335
1336   gThreadLocalAdaptor = this;
1337 }
1338
1339 void Adaptor::SetRootLayoutDirection(std::string locale)
1340 {
1341   mRootLayoutDirection = static_cast<LayoutDirection::Type>(Internal::Adaptor::Locale::GetDirection(std::string(locale)));
1342   for(auto& window : mWindows)
1343   {
1344     Dali::Actor root = window->GetRootLayer();
1345     root.SetProperty(Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection);
1346   }
1347 }
1348
1349 bool Adaptor::AddIdleEnterer(CallbackBase* callback)
1350 {
1351   bool idleAdded(false);
1352
1353   // We want to run the processes even when paused
1354   if(STOPPED != mState)
1355   {
1356     idleAdded = mCallbackManager->AddIdleEntererCallback(callback);
1357   }
1358
1359   if(!idleAdded)
1360   {
1361     // Delete callback
1362     delete callback;
1363   }
1364
1365   return idleAdded;
1366 }
1367
1368 void Adaptor::RemoveIdleEnterer(CallbackBase* callback)
1369 {
1370   mCallbackManager->RemoveIdleEntererCallback(callback);
1371 }
1372
1373 bool Adaptor::MemoryPoolTimeout()
1374 {
1375   mCore->LogMemoryPools();
1376   return true; // Keep logging forever
1377 }
1378
1379 } // namespace Adaptor
1380
1381 } // namespace Internal
1382
1383 } // namespace Dali