Merge "Remove callback when idle not added" into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / common / adaptor-impl.cpp
1 /*
2  * Copyright (c) 2023 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> // Temporary until Core is abstracted
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     DALI_LOG_RELEASE_INFO("Adaptor::Stop\n");
577   }
578 }
579
580 void Adaptor::ContextLost()
581 {
582   mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
583 }
584
585 void Adaptor::ContextRegained()
586 {
587   // Inform core, so that texture resources can be reloaded
588   mCore->RecoverFromContextLoss();
589
590   mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
591 }
592
593 void Adaptor::FeedTouchPoint(TouchPoint& point, int timeStamp)
594 {
595   Integration::Point convertedPoint(point);
596   mWindows.front()->FeedTouchPoint(convertedPoint, timeStamp);
597 }
598
599 void Adaptor::FeedWheelEvent(Dali::WheelEvent& wheelEvent)
600 {
601   Integration::WheelEvent event(static_cast<Integration::WheelEvent::Type>(wheelEvent.GetType()), wheelEvent.GetDirection(), wheelEvent.GetModifiers(), wheelEvent.GetPoint(), wheelEvent.GetDelta(), wheelEvent.GetTime());
602   mWindows.front()->FeedWheelEvent(event);
603 }
604
605 void Adaptor::FeedKeyEvent(Dali::KeyEvent& keyEvent)
606 {
607   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());
608   mWindows.front()->FeedKeyEvent(convertedEvent);
609 }
610
611 void Adaptor::ReplaceSurface(Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface)
612 {
613   Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation(window);
614   for(auto windowPtr : mWindows)
615   {
616     if(windowPtr == windowImpl) // the window is not deleted
617     {
618       mResizedSignal.Emit(mAdaptor);
619
620       windowImpl->SetSurface(&newSurface);
621
622       // Flush the event queue to give the update-render thread chance
623       // to start processing messages for new camera setup etc as soon as possible
624       ProcessCoreEvents();
625
626       // This method blocks until the render thread has completed the replace.
627       mThreadController->ReplaceSurface(&newSurface);
628       break;
629     }
630   }
631 }
632
633 void Adaptor::DeleteSurface(Dali::RenderSurfaceInterface& surface)
634 {
635   // Flush the event queue to give the update-render thread chance
636   // to start processing messages for new camera setup etc as soon as possible
637   ProcessCoreEvents();
638
639   // This method blocks until the render thread has finished rendering the current surface.
640   mThreadController->DeleteSurface(&surface);
641 }
642
643 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
644 {
645   return *mWindows.front()->GetSurface();
646 }
647
648 void Adaptor::ReleaseSurfaceLock()
649 {
650   mWindows.front()->GetSurface()->ReleaseLock();
651 }
652
653 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
654 {
655   if(!mTtsPlayers[mode])
656   {
657     // Create the TTS player when it needed, because it can reduce launching time.
658     mTtsPlayers[mode] = TtsPlayer::New(mode);
659   }
660
661   return mTtsPlayers[mode];
662 }
663
664 bool Adaptor::AddIdle(CallbackBase* callback, bool hasReturnValue, bool forceAdd)
665 {
666   bool idleAdded(false);
667
668   // Only add an idle if the Adaptor is actually running
669   if(RUNNING == mState || READY == mState || forceAdd)
670   {
671     idleAdded = mCallbackManager->AddIdleCallback(callback, hasReturnValue);
672   }
673
674   if(!idleAdded)
675   {
676     // Delete callback
677     delete callback;
678   }
679
680   return idleAdded;
681 }
682
683 void Adaptor::RemoveIdle(CallbackBase* callback)
684 {
685   mCallbackManager->RemoveIdleCallback(callback);
686 }
687
688 void Adaptor::ProcessIdle()
689 {
690   bool idleProcessed           = mCallbackManager->ProcessIdle();
691   mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
692 }
693
694 void Adaptor::SetPreRenderCallback(CallbackBase* callback)
695 {
696   mThreadController->SetPreRenderCallback(callback);
697 }
698
699 bool Adaptor::AddWindow(Dali::Integration::SceneHolder childWindow)
700 {
701   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(childWindow);
702   windowImpl.SetAdaptor(Get());
703
704   // ChildWindow is set to the layout direction of the default window.
705   windowImpl.GetRootLayer().SetProperty(Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection);
706
707   // Add the new Window to the container - the order is not important
708   {
709     Dali::Mutex::ScopedLock lock(mMutex);
710     mWindows.push_back(&windowImpl);
711   }
712
713   Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
714
715   mThreadController->AddSurface(surface);
716
717   mWindowCreatedSignal.Emit(childWindow);
718
719   return true;
720 }
721
722 bool Adaptor::RemoveWindow(Dali::Integration::SceneHolder* childWindow)
723 {
724   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(*childWindow);
725   for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
726   {
727     if(*iter == &windowImpl)
728     {
729       Dali::Mutex::ScopedLock lock(mMutex);
730       mWindows.erase(iter);
731       return true;
732     }
733   }
734
735   return false;
736 }
737
738 bool Adaptor::RemoveWindow(std::string childWindowName)
739 {
740   for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
741   {
742     if((*iter)->GetName() == childWindowName)
743     {
744       Dali::Mutex::ScopedLock lock(mMutex);
745       mWindows.erase(iter);
746       return true;
747     }
748   }
749
750   return false;
751 }
752
753 bool Adaptor::RemoveWindow(Internal::Adaptor::SceneHolder* childWindow)
754 {
755   for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
756   {
757     if((*iter)->GetId() == childWindow->GetId())
758     {
759       Dali::Mutex::ScopedLock lock(mMutex);
760       mWindows.erase(iter);
761       return true;
762     }
763   }
764
765   return false;
766 }
767
768 Dali::Adaptor& Adaptor::Get()
769 {
770   DALI_ASSERT_ALWAYS(IsAvailable() && "Adaptor not instantiated");
771   return gThreadLocalAdaptor->mAdaptor;
772 }
773
774 bool Adaptor::IsAvailable()
775 {
776   return gThreadLocalAdaptor != NULL;
777 }
778
779 void Adaptor::SceneCreated()
780 {
781   mCore->SceneCreated();
782 }
783
784 Dali::Integration::Core& Adaptor::GetCore()
785 {
786   return *mCore;
787 }
788
789 void Adaptor::SetRenderRefreshRate(unsigned int numberOfVSyncsPerRender)
790 {
791   mThreadController->SetRenderRefreshRate(numberOfVSyncsPerRender);
792 }
793
794 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
795 {
796   DALI_ASSERT_DEBUG(mDisplayConnection && "Display connection not created");
797   return *mDisplayConnection;
798 }
799
800 GraphicsInterface& Adaptor::GetGraphicsInterface()
801 {
802   DALI_ASSERT_DEBUG(mGraphics && "Graphics interface not created");
803   return *(mGraphics.get());
804 }
805
806 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
807 {
808   return *mPlatformAbstraction;
809 }
810
811 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
812 {
813   return *mNotificationTrigger;
814 }
815
816 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
817 {
818   return mSocketFactory;
819 }
820
821 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
822 {
823   if(!mWindows.empty())
824   {
825     return mWindows.front()->GetSurface();
826   }
827
828   return nullptr;
829 }
830
831 TraceInterface& Adaptor::GetKernelTraceInterface()
832 {
833   return mKernelTracer;
834 }
835
836 TraceInterface& Adaptor::GetSystemTraceInterface()
837 {
838   return mSystemTracer;
839 }
840
841 PerformanceInterface* Adaptor::GetPerformanceInterface()
842 {
843   return mPerformanceInterface;
844 }
845
846 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
847 {
848   DALI_ASSERT_DEBUG(mPlatformAbstraction && "PlatformAbstraction not created");
849   return *mPlatformAbstraction;
850 }
851
852 void Adaptor::GetWindowContainerInterface(WindowContainer& windows)
853 {
854   Dali::Mutex::ScopedLock lock(mMutex);
855   windows = mWindows;
856 }
857
858 Devel::TextureUploadManager& Adaptor::GetTextureUploadManager()
859 {
860   return mTextureUploadManager;
861 }
862
863 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
864 {
865   if(mTtsPlayers[mode])
866   {
867     mTtsPlayers[mode].Reset();
868   }
869 }
870
871 Any Adaptor::GetNativeWindowHandle()
872 {
873   return mWindows.front()->GetNativeHandle();
874 }
875
876 Any Adaptor::GetNativeWindowHandle(Dali::Actor actor)
877 {
878   Any nativeWindowHandle;
879
880   Dali::Integration::Scene scene = Dali::Integration::Scene::Get(actor);
881
882   for(auto sceneHolder : mWindows)
883   {
884     if(scene == sceneHolder->GetScene())
885     {
886       nativeWindowHandle = sceneHolder->GetNativeHandle();
887       break;
888     }
889   }
890
891   return nativeWindowHandle;
892 }
893
894 Any Adaptor::GetGraphicsDisplay()
895 {
896   Any display;
897
898   if(mGraphics)
899   {
900     GraphicsInterface* graphics    = mGraphics.get(); // This interface is temporary until Core has been updated to match
901     auto               eglGraphics = static_cast<EglGraphics*>(graphics);
902
903     EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
904     display                    = eglImpl.GetDisplay();
905   }
906
907   return display;
908 }
909
910 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
911 {
912   mUseRemoteSurface = useRemoteSurface;
913 }
914
915 void Adaptor::AddObserver(LifeCycleObserver& observer)
916 {
917   ObserverContainer::iterator match(find(mObservers.begin(), mObservers.end(), &observer));
918
919   if(match == mObservers.end())
920   {
921     mObservers.push_back(&observer);
922   }
923 }
924
925 void Adaptor::RemoveObserver(LifeCycleObserver& observer)
926 {
927   ObserverContainer::iterator match(find(mObservers.begin(), mObservers.end(), &observer));
928
929   if(match != mObservers.end())
930   {
931     mObservers.erase(match);
932   }
933 }
934
935 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
936 {
937   if(mCore)
938   {
939     mCore->QueueEvent(event);
940   }
941 }
942
943 void Adaptor::ProcessCoreEvents()
944 {
945   if(mCore)
946   {
947     DALI_TRACE_SCOPE(gTraceFilter, "DALI_PROCESS_CORE_EVENTS");
948
949     if(mPerformanceInterface)
950     {
951       mPerformanceInterface->AddMarker(PerformanceInterface::PROCESS_EVENTS_START);
952     }
953
954     mCore->ProcessEvents();
955
956     if(mPerformanceInterface)
957     {
958       mPerformanceInterface->AddMarker(PerformanceInterface::PROCESS_EVENTS_END);
959     }
960   }
961 }
962
963 void Adaptor::RequestUpdate()
964 {
965   switch(mState)
966   {
967     case RUNNING:
968     {
969       mThreadController->RequestUpdate();
970       break;
971     }
972     case PAUSED:
973     case PAUSED_WHILE_HIDDEN:
974     {
975       // Update (and resource upload) without rendering
976       mThreadController->RequestUpdateOnce(UpdateMode::SKIP_RENDER);
977       break;
978     }
979     default:
980     {
981       // Do nothing
982       break;
983     }
984   }
985 }
986
987 void Adaptor::RequestProcessEventsOnIdle()
988 {
989   // We want to run the processes even when paused
990   if(STOPPED != mState)
991   {
992     if(!mNotificationOnIdleInstalled)
993     {
994       // If we haven't installed the idle notification, install it idle enterer.
995       mNotificationOnIdleInstalled = AddIdleEnterer(MakeCallback(this, &Adaptor::ProcessCoreEventsFromIdle), true);
996     }
997     else
998     {
999       // Request comes during ProcessCoreEventsFromIdle running.
1000       // Mark as we need to call ProcessEvents in next idle events.
1001       mRequiredIdleRepeat = true;
1002     }
1003   }
1004 }
1005
1006 void Adaptor::OnWindowShown()
1007 {
1008   if(PAUSED_WHILE_HIDDEN == mState)
1009   {
1010     // Adaptor can now be resumed
1011     mState = PAUSED;
1012
1013     Resume();
1014
1015     // Force a render task
1016     RequestUpdateOnce();
1017   }
1018   else if(RUNNING == mState)
1019   {
1020     // Force a render task
1021     RequestUpdateOnce();
1022
1023     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowShown: Update requested.\n");
1024   }
1025   else if(PAUSED_WHILE_INITIALIZING == mState)
1026   {
1027     // Change the state to READY again. It will be changed to RUNNING after the adaptor is started.
1028     mState = READY;
1029   }
1030   else
1031   {
1032     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState);
1033   }
1034 }
1035
1036 void Adaptor::OnWindowHidden()
1037 {
1038   if(RUNNING == mState || READY == mState)
1039   {
1040     bool allWindowsHidden = true;
1041
1042     for(auto window : mWindows)
1043     {
1044       if(window->IsVisible())
1045       {
1046         allWindowsHidden = false;
1047         break;
1048       }
1049     }
1050
1051     // Only pause the adaptor when all the windows are hidden
1052     if(allWindowsHidden)
1053     {
1054       if(mState == RUNNING)
1055       {
1056         Pause();
1057
1058         // Adaptor cannot be resumed until any window is shown
1059         mState = PAUSED_WHILE_HIDDEN;
1060       }
1061       else // mState is READY
1062       {
1063         // Pause the adaptor after the state gets RUNNING
1064         mState = PAUSED_WHILE_INITIALIZING;
1065       }
1066     }
1067     else
1068     {
1069       DALI_LOG_RELEASE_INFO("Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n");
1070     }
1071   }
1072   else
1073   {
1074     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState);
1075   }
1076 }
1077
1078 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1079 void Adaptor::OnDamaged(const DamageArea& area)
1080 {
1081   // This is needed for the case where Dali window is partially obscured
1082   RequestUpdate();
1083 }
1084
1085 void Adaptor::SurfaceResizePrepare(Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize)
1086 {
1087   mResizedSignal.Emit(mAdaptor);
1088 }
1089
1090 void Adaptor::SurfaceResizeComplete(Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize)
1091 {
1092   // Nofify surface resizing before flushing event queue
1093   mThreadController->ResizeSurface();
1094
1095   // Flush the event queue to give the update-render thread chance
1096   // to start processing messages for new camera setup etc as soon as possible
1097   ProcessCoreEvents();
1098 }
1099
1100 void Adaptor::NotifySceneCreated()
1101 {
1102   GetCore().SceneCreated();
1103
1104   // Flush the event queue to give the update-render thread chance
1105   // to start processing messages for new camera setup etc as soon as possible
1106   ProcessCoreEvents();
1107
1108   // Start thread controller after the scene has been created
1109   mThreadController->Start();
1110
1111   // Process after surface is created (registering to remote surface provider if required)
1112   SurfaceInitialized();
1113
1114   if(mState != PAUSED_WHILE_INITIALIZING)
1115   {
1116     mState = RUNNING;
1117
1118     DALI_LOG_RELEASE_INFO("Adaptor::NotifySceneCreated: Adaptor is running\n");
1119   }
1120   else
1121   {
1122     mState = RUNNING;
1123
1124     Pause();
1125
1126     mState = PAUSED_WHILE_HIDDEN;
1127
1128     DALI_LOG_RELEASE_INFO("Adaptor::NotifySceneCreated: Adaptor is paused\n");
1129   }
1130 }
1131
1132 void Adaptor::NotifyLanguageChanged()
1133 {
1134   mLanguageChangedSignal.Emit(mAdaptor);
1135 }
1136
1137 void Adaptor::RenderOnce()
1138 {
1139   if(mThreadController)
1140   {
1141     UpdateMode updateMode;
1142     if(mThreadMode == ThreadMode::NORMAL)
1143     {
1144       updateMode = UpdateMode::NORMAL;
1145     }
1146     else
1147     {
1148       updateMode = UpdateMode::FORCE_RENDER;
1149
1150       ProcessCoreEvents();
1151     }
1152
1153     // Force rendering
1154     for(auto&& iter : mWindows)
1155     {
1156       iter->GetSurface()->SetFullSwapNextFrame();
1157     }
1158
1159     mThreadController->RequestUpdateOnce(updateMode);
1160   }
1161 }
1162
1163 const LogFactoryInterface& Adaptor::GetLogFactory()
1164 {
1165   return *mEnvironmentOptions;
1166 }
1167
1168 const TraceFactoryInterface& Adaptor::GetTraceFactory()
1169 {
1170   return *mEnvironmentOptions;
1171 }
1172
1173 void Adaptor::RegisterProcessor(Integration::Processor& processor, bool postProcessor)
1174 {
1175   GetCore().RegisterProcessor(processor, postProcessor);
1176 }
1177
1178 void Adaptor::UnregisterProcessor(Integration::Processor& processor, bool postProcessor)
1179 {
1180   GetCore().UnregisterProcessor(processor, postProcessor);
1181 }
1182
1183 bool Adaptor::IsMultipleWindowSupported() const
1184 {
1185   return mConfigurationManager->IsMultipleWindowSupported();
1186 }
1187
1188 int32_t Adaptor::GetRenderThreadId() const
1189 {
1190   if(mThreadController)
1191   {
1192     return mThreadController->GetThreadId();
1193   }
1194   return 0;
1195 }
1196
1197 void Adaptor::RequestUpdateOnce()
1198 {
1199   if(mThreadController)
1200   {
1201     mThreadController->RequestUpdateOnce(UpdateMode::NORMAL);
1202   }
1203 }
1204
1205 bool Adaptor::ProcessCoreEventsFromIdle()
1206 {
1207   // Reset repeat idler flag.
1208   mRequiredIdleRepeat = false;
1209   ProcessCoreEvents();
1210
1211   // If someone request ProcessCoreEvents during above ProcessCoreEvents call, we might need to run idle one more times.
1212   // Else, the idle handle automatically un-installs itself
1213   mNotificationOnIdleInstalled = mRequiredIdleRepeat;
1214
1215   if(mRequiredIdleRepeat)
1216   {
1217     DALI_LOG_DEBUG_INFO("Required ProcessCoreEvents one more times\n");
1218   }
1219
1220   return mRequiredIdleRepeat;
1221 }
1222
1223 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow(Dali::Actor& actor)
1224 {
1225   Dali::Integration::Scene scene = Dali::Integration::Scene::Get(actor);
1226
1227   for(auto window : mWindows)
1228   {
1229     if(scene == window->GetScene())
1230     {
1231       return window;
1232     }
1233   }
1234
1235   return nullptr;
1236 }
1237
1238 Dali::WindowContainer Adaptor::GetWindows() const
1239 {
1240   Dali::WindowContainer windows;
1241
1242   for(auto iter = mWindows.begin(); iter != mWindows.end(); ++iter)
1243   {
1244     // Downcast to Dali::Window
1245     Dali::Window window(dynamic_cast<Dali::Internal::Adaptor::Window*>(*iter));
1246     if(window)
1247     {
1248       windows.push_back(window);
1249     }
1250   }
1251
1252   return windows;
1253 }
1254
1255 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1256 {
1257   Dali::SceneHolderList sceneHolderList;
1258
1259   for(auto iter = mWindows.begin(); iter != mWindows.end(); ++iter)
1260   {
1261     sceneHolderList.push_back(Dali::Integration::SceneHolder(*iter));
1262   }
1263
1264   return sceneHolderList;
1265 }
1266
1267 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1268 {
1269   Dali::ObjectRegistry registry;
1270   if(mCore)
1271   {
1272     registry = mCore->GetObjectRegistry();
1273   }
1274   return registry;
1275 }
1276
1277 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode)
1278 : mResizedSignal(),
1279   mLanguageChangedSignal(),
1280   mWindowCreatedSignal(),
1281   mAdaptor(adaptor),
1282   mState(READY),
1283   mCore(nullptr),
1284   mThreadController(nullptr),
1285   mGraphics(nullptr),
1286   mDisplayConnection(nullptr),
1287   mWindows(),
1288   mConfigurationManager(nullptr),
1289   mPlatformAbstraction(nullptr),
1290   mCallbackManager(nullptr),
1291   mNotificationOnIdleInstalled(false),
1292   mRequiredIdleRepeat(false),
1293   mNotificationTrigger(nullptr),
1294   mDaliFeedbackPlugin(),
1295   mFeedbackController(nullptr),
1296   mTtsPlayers(),
1297   mObservers(),
1298   mEnvironmentOptions(environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1299   mPerformanceInterface(nullptr),
1300   mKernelTracer(),
1301   mSystemTracer(),
1302   mTextureUploadManager(),
1303   mObjectProfiler(nullptr),
1304   mMemoryPoolTimerSlotDelegate(this),
1305   mSocketFactory(),
1306   mMutex(),
1307   mThreadMode(threadMode),
1308   mEnvironmentOptionsOwned(environmentOptions ? false : true /* If not provided then we own the object */),
1309   mUseRemoteSurface(false),
1310   mRootLayoutDirection(Dali::LayoutDirection::LEFT_TO_RIGHT)
1311 {
1312   DALI_ASSERT_ALWAYS(!IsAvailable() && "Cannot create more than one Adaptor per thread");
1313   mWindows.insert(mWindows.begin(), &Dali::GetImplementation(window));
1314
1315   gThreadLocalAdaptor = this;
1316 }
1317
1318 void Adaptor::SetRootLayoutDirection(std::string locale)
1319 {
1320   mRootLayoutDirection = static_cast<LayoutDirection::Type>(Internal::Adaptor::Locale::GetDirection(std::string(locale)));
1321   for(auto& window : mWindows)
1322   {
1323     Dali::Actor root = window->GetRootLayer();
1324     root.SetProperty(Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection);
1325   }
1326 }
1327
1328 bool Adaptor::AddIdleEnterer(CallbackBase* callback, bool forceAdd)
1329 {
1330   bool idleAdded(false);
1331
1332   // Only add an idle if the Adaptor is actually running
1333   if(RUNNING == mState || READY == mState || forceAdd)
1334   {
1335     idleAdded = mCallbackManager->AddIdleEntererCallback(callback);
1336   }
1337
1338   if(!idleAdded)
1339   {
1340     // Delete callback
1341     delete callback;
1342   }
1343
1344   return idleAdded;
1345 }
1346
1347 void Adaptor::RemoveIdleEnterer(CallbackBase* callback)
1348 {
1349   mCallbackManager->RemoveIdleEntererCallback(callback);
1350 }
1351
1352 bool Adaptor::MemoryPoolTimeout()
1353 {
1354   mCore->LogMemoryPools();
1355   return true; // Keep logging forever
1356 }
1357
1358 } // namespace Adaptor
1359
1360 } // namespace Internal
1361
1362 } // namespace Dali