[Tizen] Make Adaptor request event process regardless of state
[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/clipboard/common/clipboard-impl.h>
59 #include <dali/internal/graphics/common/egl-image-extensions.h>
60 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
61 #include <dali/internal/graphics/gles/gl-implementation.h>
62 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
63 #include <dali/internal/system/common/callback-manager.h>
64 #include <dali/internal/system/common/object-profiler.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 = CallbackManager::New();
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   defaultWindow->SetAdaptor(Get());
185
186   Dali::Integration::SceneHolder defaultSceneHolder(defaultWindow);
187
188   mWindowCreatedSignal.Emit(defaultSceneHolder);
189
190   const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
191   if(0u < timeInterval)
192   {
193     mObjectProfiler = new ObjectProfiler(mCore->GetObjectRegistry(), timeInterval);
194   }
195
196   mNotificationTrigger = TriggerEventFactory::CreateTriggerEvent(MakeCallback(this, &Adaptor::ProcessCoreEvents), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
197
198   mDisplayConnection = Dali::DisplayConnection::New(*mGraphics, defaultWindow->GetSurface()->GetSurfaceType());
199
200   mThreadController = new ThreadController(*this, *mEnvironmentOptions, mThreadMode);
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   if(mEnvironmentOptions->GetMinimumPanDistance() >= 0)
268   {
269     Integration::SetPanGestureMinimumDistance(mEnvironmentOptions->GetMinimumPanDistance());
270   }
271   if(mEnvironmentOptions->GetMinimumPanEvents() >= 0)
272   {
273     Integration::SetPanGestureMinimumPanEvents(mEnvironmentOptions->GetMinimumPanEvents());
274   }
275   if(mEnvironmentOptions->GetMinimumPinchDistance() >= 0)
276   {
277     Integration::SetPinchGestureMinimumDistance(mEnvironmentOptions->GetMinimumPinchDistance());
278   }
279   if(mEnvironmentOptions->GetMinimumPinchTouchEvents() >= 0)
280   {
281     Integration::SetPinchGestureMinimumTouchEvents(mEnvironmentOptions->GetMinimumPinchTouchEvents());
282   }
283   if(mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart() >= 0)
284   {
285     Integration::SetPinchGestureMinimumTouchEventsAfterStart(mEnvironmentOptions->GetMinimumPinchTouchEventsAfterStart());
286   }
287   if(mEnvironmentOptions->GetMinimumRotationTouchEvents() >= 0)
288   {
289     Integration::SetRotationGestureMinimumTouchEvents(mEnvironmentOptions->GetMinimumRotationTouchEvents());
290   }
291   if(mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart() >= 0)
292   {
293     Integration::SetRotationGestureMinimumTouchEventsAfterStart(mEnvironmentOptions->GetMinimumRotationTouchEventsAfterStart());
294   }
295   if(mEnvironmentOptions->GetLongPressMinimumHoldingTime() >= 0)
296   {
297     Integration::SetLongPressMinimumHoldingTime(mEnvironmentOptions->GetLongPressMinimumHoldingTime());
298   }
299   if(mEnvironmentOptions->GetTapMaximumAllowedTime() > 0)
300   {
301     Integration::SetTapMaximumAllowedTime(mEnvironmentOptions->GetTapMaximumAllowedTime());
302   }
303
304   std::string systemCachePath = GetSystemCachePath();
305   if(!systemCachePath.empty())
306   {
307     const int dir_err = mkdir(systemCachePath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
308     if(0 != dir_err && errno != EEXIST)
309     {
310       DALI_LOG_ERROR("Error creating system cache directory: %s!\n", systemCachePath.c_str());
311     }
312   }
313
314   mConfigurationManager = Utils::MakeUnique<ConfigurationManager>(systemCachePath, mGraphics.get(), mThreadController);
315 }
316
317 void Adaptor::AccessibilityObserver::OnAccessibleKeyEvent(const Dali::KeyEvent& event)
318 {
319   Accessibility::KeyEventType type;
320   if(event.GetState() == Dali::KeyEvent::DOWN)
321   {
322     type = Accessibility::KeyEventType::KEY_PRESSED;
323   }
324   else if(event.GetState() == Dali::KeyEvent::UP)
325   {
326     type = Accessibility::KeyEventType::KEY_RELEASED;
327   }
328   else
329   {
330     return;
331   }
332   Dali::Accessibility::Bridge::GetCurrentBridge()->Emit(type, event.GetKeyCode(), event.GetKeyName(), event.GetTime(), !event.GetKeyString().empty());
333 }
334
335 Adaptor::~Adaptor()
336 {
337   Accessibility::Bridge::GetCurrentBridge()->Terminate();
338
339   // Ensure stop status
340   Stop();
341
342   // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
343   gThreadLocalAdaptor = NULL;
344
345   for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
346   {
347     (*iter)->OnDestroy();
348   }
349
350   // Clear out all the handles to Windows
351   mWindows.clear();
352
353   delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
354   delete mObjectProfiler;
355
356   delete mCore;
357
358   delete mDisplayConnection;
359   delete mPlatformAbstraction;
360   delete mCallbackManager;
361   delete mPerformanceInterface;
362
363   mGraphics->Destroy();
364
365   // uninstall it on this thread (main actor thread)
366   Dali::Integration::Log::UninstallLogFunction();
367
368   // Delete environment options if we own it
369   if(mEnvironmentOptionsOwned)
370   {
371     delete mEnvironmentOptions;
372   }
373 }
374
375 void Adaptor::Start()
376 {
377   // It doesn't support restart after stop at this moment to support restarting, need more testing
378   if(READY != mState)
379   {
380     return;
381   }
382
383   mCore->Initialize();
384
385   SetupSystemInformation();
386
387   // Start the callback manager
388   mCallbackManager->Start();
389
390   // Initialize accessibility bridge after callback manager is started to use Idler callback
391   auto appName = GetApplicationPackageName();
392   auto bridge  = Accessibility::Bridge::GetCurrentBridge();
393   bridge->SetApplicationName(appName);
394   bridge->Initialize();
395   Dali::Stage::GetCurrent().KeyEventSignal().Connect(&mAccessibilityObserver, &AccessibilityObserver::OnAccessibleKeyEvent);
396
397   Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
398
399   unsigned int dpiHor, dpiVer;
400   dpiHor = dpiVer = 0;
401
402   defaultWindow->GetSurface()->GetDpi(dpiHor, dpiVer);
403   Dali::Internal::Adaptor::WindowSystem::SetDpi(dpiHor, dpiVer);
404
405   // Initialize the thread controller
406   mThreadController->Initialize();
407
408   // Set max texture size
409   if(mEnvironmentOptions->GetMaxTextureSize() > 0)
410   {
411     Dali::TizenPlatform::ImageLoader::SetMaxTextureSize(mEnvironmentOptions->GetMaxTextureSize());
412   }
413   else
414   {
415     unsigned int maxTextureSize = mConfigurationManager->GetMaxTextureSize();
416     Dali::TizenPlatform::ImageLoader::SetMaxTextureSize(maxTextureSize);
417   }
418
419   // cache advanced blending and shader language version
420   mGraphics->CacheConfigurations(*mConfigurationManager.get());
421
422   ProcessCoreEvents(); // Ensure any startup messages are processed.
423
424   // Initialize the image loader plugin
425   auto enablePluginString = Dali::EnvironmentVariable::GetEnvironmentVariable(ENABLE_IMAGE_LOADER_PLUGIN_ENV);
426   bool enablePlugin       = enablePluginString ? std::atoi(enablePluginString) : false;
427   if(enablePlugin)
428   {
429     Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
430   }
431
432   for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
433   {
434     (*iter)->OnStart();
435   }
436
437   if(mAddOnManager)
438   {
439     mAddOnManager->Start();
440   }
441 }
442
443 // Dali::Internal::Adaptor::Adaptor::Pause
444 void Adaptor::Pause()
445 {
446   // Only pause the adaptor if we're actually running.
447   if(RUNNING == mState)
448   {
449     // Inform observers that we are about to be paused.
450     for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
451     {
452       (*iter)->OnPause();
453     }
454
455     // Extensions
456     if(mAddOnManager)
457     {
458       mAddOnManager->Pause();
459     }
460
461     // Pause all windows event handlers when adaptor paused
462     for(auto window : mWindows)
463     {
464       window->Pause();
465     }
466
467     mThreadController->Pause();
468     mState = PAUSED;
469
470     // Ensure any messages queued during pause callbacks are processed by doing another update.
471     RequestUpdateOnce();
472
473     DALI_LOG_RELEASE_INFO("Adaptor::Pause: Paused\n");
474   }
475   else
476   {
477     DALI_LOG_RELEASE_INFO("Adaptor::Pause: Not paused [%d]\n", mState);
478   }
479 }
480
481 // Dali::Internal::Adaptor::Adaptor::Resume
482 void Adaptor::Resume()
483 {
484   // Only resume the adaptor if we are in the suspended state.
485   if(PAUSED == mState)
486   {
487     mState = RUNNING;
488
489     // Reset the event handlers when adaptor resumed
490     for(auto window : mWindows)
491     {
492       window->Resume();
493     }
494
495     // Resume AddOnManager
496     if(mAddOnManager)
497     {
498       mAddOnManager->Resume();
499     }
500
501     // Inform observers that we have resumed.
502     for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
503     {
504       (*iter)->OnResume();
505     }
506
507     // Trigger processing of events queued up while paused
508     mCore->ProcessEvents();
509
510     // Do at end to ensure our first update/render after resumption includes the processed messages as well
511     mThreadController->Resume();
512
513     DALI_LOG_RELEASE_INFO("Adaptor::Resume: Resumed\n");
514   }
515   else
516   {
517     DALI_LOG_RELEASE_INFO("Adaptor::Resume: Not resumed [%d]\n", mState);
518   }
519 }
520
521 void Adaptor::Stop()
522 {
523   if(RUNNING == mState ||
524      PAUSED == mState ||
525      PAUSED_WHILE_HIDDEN == mState)
526   {
527     for(ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter)
528     {
529       (*iter)->OnStop();
530     }
531
532     if(mAddOnManager)
533     {
534       mAddOnManager->Stop();
535     }
536
537     mThreadController->Stop();
538
539     // Delete the TTS player
540     for(int i = 0; i < Dali::TtsPlayer::MODE_NUM; i++)
541     {
542       if(mTtsPlayers[i])
543       {
544         mTtsPlayers[i].Reset();
545       }
546     }
547
548     // Destroy the image loader plugin
549     auto enablePluginString = Dali::EnvironmentVariable::GetEnvironmentVariable(ENABLE_IMAGE_LOADER_PLUGIN_ENV);
550     bool enablePlugin       = enablePluginString ? std::atoi(enablePluginString) : false;
551     if(enablePlugin)
552     {
553       Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
554     }
555
556     delete mNotificationTrigger;
557     mNotificationTrigger = NULL;
558
559     mCallbackManager->Stop();
560
561     mState = STOPPED;
562
563     DALI_LOG_RELEASE_INFO("Adaptor::Stop\n");
564   }
565 }
566
567 void Adaptor::ContextLost()
568 {
569   mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
570 }
571
572 void Adaptor::ContextRegained()
573 {
574   // Inform core, so that texture resources can be reloaded
575   mCore->RecoverFromContextLoss();
576
577   mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
578 }
579
580 void Adaptor::FeedTouchPoint(TouchPoint& point, int timeStamp)
581 {
582   Integration::Point convertedPoint(point);
583   mWindows.front()->FeedTouchPoint(convertedPoint, timeStamp);
584 }
585
586 void Adaptor::FeedWheelEvent(Dali::WheelEvent& wheelEvent)
587 {
588   Integration::WheelEvent event(static_cast<Integration::WheelEvent::Type>(wheelEvent.GetType()), wheelEvent.GetDirection(), wheelEvent.GetModifiers(), wheelEvent.GetPoint(), wheelEvent.GetDelta(), wheelEvent.GetTime());
589   mWindows.front()->FeedWheelEvent(event);
590 }
591
592 void Adaptor::FeedKeyEvent(Dali::KeyEvent& keyEvent)
593 {
594   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());
595   mWindows.front()->FeedKeyEvent(convertedEvent);
596 }
597
598 void Adaptor::ReplaceSurface(Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface)
599 {
600   Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation(window);
601   for(auto windowPtr : mWindows)
602   {
603     if(windowPtr == windowImpl) // the window is not deleted
604     {
605       mResizedSignal.Emit(mAdaptor);
606
607       windowImpl->SetSurface(&newSurface);
608
609       // Flush the event queue to give the update-render thread chance
610       // to start processing messages for new camera setup etc as soon as possible
611       ProcessCoreEvents();
612
613       // This method blocks until the render thread has completed the replace.
614       mThreadController->ReplaceSurface(&newSurface);
615       break;
616     }
617   }
618 }
619
620 void Adaptor::DeleteSurface(Dali::RenderSurfaceInterface& surface)
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 finished rendering the current surface.
627   mThreadController->DeleteSurface(&surface);
628 }
629
630 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
631 {
632   return *mWindows.front()->GetSurface();
633 }
634
635 void Adaptor::ReleaseSurfaceLock()
636 {
637   mWindows.front()->GetSurface()->ReleaseLock();
638 }
639
640 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
641 {
642   if(!mTtsPlayers[mode])
643   {
644     // Create the TTS player when it needed, because it can reduce launching time.
645     mTtsPlayers[mode] = TtsPlayer::New(mode);
646   }
647
648   return mTtsPlayers[mode];
649 }
650
651 bool Adaptor::AddIdle(CallbackBase* callback, bool hasReturnValue, bool forceAdd)
652 {
653   bool idleAdded(false);
654
655   // Only add an idle if the Adaptor is actually running
656   if(RUNNING == mState || READY == mState || forceAdd)
657   {
658     idleAdded = mCallbackManager->AddIdleCallback(callback, hasReturnValue);
659   }
660
661   return idleAdded;
662 }
663
664 void Adaptor::RemoveIdle(CallbackBase* callback)
665 {
666   mCallbackManager->RemoveIdleCallback(callback);
667 }
668
669 void Adaptor::ProcessIdle()
670 {
671   bool idleProcessed           = mCallbackManager->ProcessIdle();
672   mNotificationOnIdleInstalled = mNotificationOnIdleInstalled && !idleProcessed;
673 }
674
675 void Adaptor::SetPreRenderCallback(CallbackBase* callback)
676 {
677   mThreadController->SetPreRenderCallback(callback);
678 }
679
680 bool Adaptor::AddWindow(Dali::Integration::SceneHolder childWindow)
681 {
682   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(childWindow);
683   windowImpl.SetAdaptor(Get());
684
685   // ChildWindow is set to the layout direction of the default window.
686   windowImpl.GetRootLayer().SetProperty(Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection);
687
688   // Add the new Window to the container - the order is not important
689   {
690     Dali::Mutex::ScopedLock lock(mMutex);
691     mWindows.push_back(&windowImpl);
692   }
693
694   Dali::RenderSurfaceInterface* surface = windowImpl.GetSurface();
695
696   mThreadController->AddSurface(surface);
697
698   mWindowCreatedSignal.Emit(childWindow);
699
700   return true;
701 }
702
703 bool Adaptor::RemoveWindow(Dali::Integration::SceneHolder* childWindow)
704 {
705   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation(*childWindow);
706   for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
707   {
708     if(*iter == &windowImpl)
709     {
710       Dali::Mutex::ScopedLock lock(mMutex);
711       mWindows.erase(iter);
712       return true;
713     }
714   }
715
716   return false;
717 }
718
719 bool Adaptor::RemoveWindow(std::string childWindowName)
720 {
721   for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
722   {
723     if((*iter)->GetName() == childWindowName)
724     {
725       Dali::Mutex::ScopedLock lock(mMutex);
726       mWindows.erase(iter);
727       return true;
728     }
729   }
730
731   return false;
732 }
733
734 bool Adaptor::RemoveWindow(Internal::Adaptor::SceneHolder* childWindow)
735 {
736   for(WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter)
737   {
738     if((*iter)->GetId() == childWindow->GetId())
739     {
740       Dali::Mutex::ScopedLock lock(mMutex);
741       mWindows.erase(iter);
742       return true;
743     }
744   }
745
746   return false;
747 }
748
749 Dali::Adaptor& Adaptor::Get()
750 {
751   DALI_ASSERT_ALWAYS(IsAvailable() && "Adaptor not instantiated");
752   return gThreadLocalAdaptor->mAdaptor;
753 }
754
755 bool Adaptor::IsAvailable()
756 {
757   return gThreadLocalAdaptor != NULL;
758 }
759
760 void Adaptor::SceneCreated()
761 {
762   mCore->SceneCreated();
763 }
764
765 Dali::Integration::Core& Adaptor::GetCore()
766 {
767   return *mCore;
768 }
769
770 void Adaptor::SetRenderRefreshRate(unsigned int numberOfVSyncsPerRender)
771 {
772   mThreadController->SetRenderRefreshRate(numberOfVSyncsPerRender);
773 }
774
775 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
776 {
777   DALI_ASSERT_DEBUG(mDisplayConnection && "Display connection not created");
778   return *mDisplayConnection;
779 }
780
781 GraphicsInterface& Adaptor::GetGraphicsInterface()
782 {
783   DALI_ASSERT_DEBUG(mGraphics && "Graphics interface not created");
784   return *(mGraphics.get());
785 }
786
787 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
788 {
789   return *mPlatformAbstraction;
790 }
791
792 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
793 {
794   return *mNotificationTrigger;
795 }
796
797 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
798 {
799   return mSocketFactory;
800 }
801
802 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
803 {
804   if(!mWindows.empty())
805   {
806     return mWindows.front()->GetSurface();
807   }
808
809   return nullptr;
810 }
811
812 TraceInterface& Adaptor::GetKernelTraceInterface()
813 {
814   return mKernelTracer;
815 }
816
817 TraceInterface& Adaptor::GetSystemTraceInterface()
818 {
819   return mSystemTracer;
820 }
821
822 PerformanceInterface* Adaptor::GetPerformanceInterface()
823 {
824   return mPerformanceInterface;
825 }
826
827 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
828 {
829   DALI_ASSERT_DEBUG(mPlatformAbstraction && "PlatformAbstraction not created");
830   return *mPlatformAbstraction;
831 }
832
833 void Adaptor::GetWindowContainerInterface(WindowContainer& windows)
834 {
835   Dali::Mutex::ScopedLock lock(mMutex);
836   windows = mWindows;
837 }
838
839 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
840 {
841   if(mTtsPlayers[mode])
842   {
843     mTtsPlayers[mode].Reset();
844   }
845 }
846
847 Any Adaptor::GetNativeWindowHandle()
848 {
849   return mWindows.front()->GetNativeHandle();
850 }
851
852 Any Adaptor::GetNativeWindowHandle(Dali::Actor actor)
853 {
854   Any nativeWindowHandle;
855
856   Dali::Integration::Scene scene = Dali::Integration::Scene::Get(actor);
857
858   for(auto sceneHolder : mWindows)
859   {
860     if(scene == sceneHolder->GetScene())
861     {
862       nativeWindowHandle = sceneHolder->GetNativeHandle();
863       break;
864     }
865   }
866
867   return nativeWindowHandle;
868 }
869
870 Any Adaptor::GetGraphicsDisplay()
871 {
872   Any display;
873
874   if(mGraphics)
875   {
876     GraphicsInterface* graphics    = mGraphics.get(); // This interface is temporary until Core has been updated to match
877     auto               eglGraphics = static_cast<EglGraphics*>(graphics);
878
879     EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
880     display                    = eglImpl.GetDisplay();
881   }
882
883   return display;
884 }
885
886 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
887 {
888   mUseRemoteSurface = useRemoteSurface;
889 }
890
891 void Adaptor::AddObserver(LifeCycleObserver& observer)
892 {
893   ObserverContainer::iterator match(find(mObservers.begin(), mObservers.end(), &observer));
894
895   if(match == mObservers.end())
896   {
897     mObservers.push_back(&observer);
898   }
899 }
900
901 void Adaptor::RemoveObserver(LifeCycleObserver& observer)
902 {
903   ObserverContainer::iterator match(find(mObservers.begin(), mObservers.end(), &observer));
904
905   if(match != mObservers.end())
906   {
907     mObservers.erase(match);
908   }
909 }
910
911 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
912 {
913   if(mCore)
914   {
915     mCore->QueueEvent(event);
916   }
917 }
918
919 void Adaptor::ProcessCoreEvents()
920 {
921   if(mCore)
922   {
923     if(mPerformanceInterface)
924     {
925       mPerformanceInterface->AddMarker(PerformanceInterface::PROCESS_EVENTS_START);
926     }
927
928     DALI_TRACE_BEGIN(gTraceFilter, "DALI_PROCESS_CORE_EVENTS");
929
930     mCore->ProcessEvents();
931
932     DALI_TRACE_END(gTraceFilter, "DALI_PROCESS_CORE_EVENTS");
933
934     if(mPerformanceInterface)
935     {
936       mPerformanceInterface->AddMarker(PerformanceInterface::PROCESS_EVENTS_END);
937     }
938   }
939 }
940
941 void Adaptor::RequestUpdate()
942 {
943   switch(mState)
944   {
945     case RUNNING:
946     {
947       mThreadController->RequestUpdate();
948       break;
949     }
950     case PAUSED:
951     case PAUSED_WHILE_HIDDEN:
952     {
953       // Update (and resource upload) without rendering
954       mThreadController->RequestUpdateOnce(UpdateMode::SKIP_RENDER);
955       break;
956     }
957     default:
958     {
959       // Do nothing
960       break;
961     }
962   }
963 }
964
965 void Adaptor::RequestProcessEventsOnIdle()
966 {
967   // Only request a notification if we haven't installed the idle notification
968   // We want to run the processes even when paused
969   if(!mNotificationOnIdleInstalled && STOPPED != mState)
970   {
971     mNotificationOnIdleInstalled = AddIdleEnterer(MakeCallback(this, &Adaptor::ProcessCoreEventsFromIdle), true);
972   }
973 }
974
975 void Adaptor::OnWindowShown()
976 {
977   if(PAUSED_WHILE_HIDDEN == mState)
978   {
979     // Adaptor can now be resumed
980     mState = PAUSED;
981
982     Resume();
983
984     // Force a render task
985     RequestUpdateOnce();
986   }
987   else if(RUNNING == mState)
988   {
989     // Force a render task
990     RequestUpdateOnce();
991
992     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowShown: Update requested.\n");
993   }
994   else if(PAUSED_WHILE_INITIALIZING == mState)
995   {
996     // Change the state to READY again. It will be changed to RUNNING after the adaptor is started.
997     mState = READY;
998   }
999   else
1000   {
1001     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState);
1002   }
1003 }
1004
1005 void Adaptor::OnWindowHidden()
1006 {
1007   if(RUNNING == mState || READY == mState)
1008   {
1009     bool allWindowsHidden = true;
1010
1011     for(auto window : mWindows)
1012     {
1013       if(window->IsVisible())
1014       {
1015         allWindowsHidden = false;
1016         break;
1017       }
1018     }
1019
1020     // Only pause the adaptor when all the windows are hidden
1021     if(allWindowsHidden)
1022     {
1023       if(mState == RUNNING)
1024       {
1025         Pause();
1026
1027         // Adaptor cannot be resumed until any window is shown
1028         mState = PAUSED_WHILE_HIDDEN;
1029       }
1030       else // mState is READY
1031       {
1032         // Pause the adaptor after the state gets RUNNING
1033         mState = PAUSED_WHILE_INITIALIZING;
1034       }
1035     }
1036     else
1037     {
1038       DALI_LOG_RELEASE_INFO("Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n");
1039     }
1040   }
1041   else
1042   {
1043     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState);
1044   }
1045 }
1046
1047 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1048 void Adaptor::OnDamaged(const DamageArea& area)
1049 {
1050   // This is needed for the case where Dali window is partially obscured
1051   RequestUpdate();
1052 }
1053
1054 void Adaptor::SurfaceResizePrepare(Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize)
1055 {
1056   mResizedSignal.Emit(mAdaptor);
1057 }
1058
1059 void Adaptor::SurfaceResizeComplete(Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize)
1060 {
1061   // Nofify surface resizing before flushing event queue
1062   mThreadController->ResizeSurface();
1063
1064   // Flush the event queue to give the update-render thread chance
1065   // to start processing messages for new camera setup etc as soon as possible
1066   ProcessCoreEvents();
1067 }
1068
1069 void Adaptor::NotifySceneCreated()
1070 {
1071   GetCore().SceneCreated();
1072
1073   // Flush the event queue to give the update-render thread chance
1074   // to start processing messages for new camera setup etc as soon as possible
1075   ProcessCoreEvents();
1076
1077   // Start thread controller after the scene has been created
1078   mThreadController->Start();
1079
1080   // Process after surface is created (registering to remote surface provider if required)
1081   SurfaceInitialized();
1082
1083   if(mState != PAUSED_WHILE_INITIALIZING)
1084   {
1085     mState = RUNNING;
1086
1087     DALI_LOG_RELEASE_INFO("Adaptor::NotifySceneCreated: Adaptor is running\n");
1088   }
1089   else
1090   {
1091     mState = RUNNING;
1092
1093     Pause();
1094
1095     mState = PAUSED_WHILE_HIDDEN;
1096
1097     DALI_LOG_RELEASE_INFO("Adaptor::NotifySceneCreated: Adaptor is paused\n");
1098   }
1099 }
1100
1101 void Adaptor::NotifyLanguageChanged()
1102 {
1103   mLanguageChangedSignal.Emit(mAdaptor);
1104 }
1105
1106 void Adaptor::RenderOnce()
1107 {
1108   if(mThreadController)
1109   {
1110     UpdateMode updateMode;
1111     if(mThreadMode == ThreadMode::NORMAL)
1112     {
1113       updateMode = UpdateMode::NORMAL;
1114     }
1115     else
1116     {
1117       updateMode = UpdateMode::FORCE_RENDER;
1118
1119       ProcessCoreEvents();
1120     }
1121     mThreadController->RequestUpdateOnce(updateMode);
1122   }
1123 }
1124
1125 const LogFactoryInterface& Adaptor::GetLogFactory()
1126 {
1127   return *mEnvironmentOptions;
1128 }
1129
1130 void Adaptor::RegisterProcessor(Integration::Processor& processor, bool postProcessor)
1131 {
1132   GetCore().RegisterProcessor(processor, postProcessor);
1133 }
1134
1135 void Adaptor::UnregisterProcessor(Integration::Processor& processor, bool postProcessor)
1136 {
1137   GetCore().UnregisterProcessor(processor, postProcessor);
1138 }
1139
1140 bool Adaptor::IsMultipleWindowSupported() const
1141 {
1142   return mConfigurationManager->IsMultipleWindowSupported();
1143 }
1144
1145 int32_t Adaptor::GetRenderThreadId() const
1146 {
1147   if(mThreadController)
1148   {
1149     return mThreadController->GetThreadId();
1150   }
1151   return 0;
1152 }
1153
1154 void Adaptor::RequestUpdateOnce()
1155 {
1156   if(mThreadController)
1157   {
1158     mThreadController->RequestUpdateOnce(UpdateMode::NORMAL);
1159   }
1160 }
1161
1162 bool Adaptor::ProcessCoreEventsFromIdle()
1163 {
1164   ProcessCoreEvents();
1165
1166   // the idle handle automatically un-installs itself
1167   mNotificationOnIdleInstalled = false;
1168
1169   return false;
1170 }
1171
1172 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow(Dali::Actor& actor)
1173 {
1174   Dali::Integration::Scene scene = Dali::Integration::Scene::Get(actor);
1175
1176   for(auto window : mWindows)
1177   {
1178     if(scene == window->GetScene())
1179     {
1180       return window;
1181     }
1182   }
1183
1184   return nullptr;
1185 }
1186
1187 Dali::WindowContainer Adaptor::GetWindows() const
1188 {
1189   Dali::WindowContainer windows;
1190
1191   for(auto iter = mWindows.begin(); iter != mWindows.end(); ++iter)
1192   {
1193     // Downcast to Dali::Window
1194     Dali::Window window(dynamic_cast<Dali::Internal::Adaptor::Window*>(*iter));
1195     if(window)
1196     {
1197       windows.push_back(window);
1198     }
1199   }
1200
1201   return windows;
1202 }
1203
1204 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1205 {
1206   Dali::SceneHolderList sceneHolderList;
1207
1208   for(auto iter = mWindows.begin(); iter != mWindows.end(); ++iter)
1209   {
1210     sceneHolderList.push_back(Dali::Integration::SceneHolder(*iter));
1211   }
1212
1213   return sceneHolderList;
1214 }
1215
1216 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1217 {
1218   Dali::ObjectRegistry registry;
1219   if(mCore)
1220   {
1221     registry = mCore->GetObjectRegistry();
1222   }
1223   return registry;
1224 }
1225
1226 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode)
1227 : mResizedSignal(),
1228   mLanguageChangedSignal(),
1229   mWindowCreatedSignal(),
1230   mAdaptor(adaptor),
1231   mState(READY),
1232   mCore(nullptr),
1233   mThreadController(nullptr),
1234   mGraphics(nullptr),
1235   mDisplayConnection(nullptr),
1236   mWindows(),
1237   mConfigurationManager(nullptr),
1238   mPlatformAbstraction(nullptr),
1239   mCallbackManager(nullptr),
1240   mNotificationOnIdleInstalled(false),
1241   mNotificationTrigger(nullptr),
1242   mDaliFeedbackPlugin(),
1243   mFeedbackController(nullptr),
1244   mTtsPlayers(),
1245   mObservers(),
1246   mEnvironmentOptions(environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1247   mPerformanceInterface(nullptr),
1248   mKernelTracer(),
1249   mSystemTracer(),
1250   mObjectProfiler(nullptr),
1251   mSocketFactory(),
1252   mMutex(),
1253   mThreadMode(threadMode),
1254   mEnvironmentOptionsOwned(environmentOptions ? false : true /* If not provided then we own the object */),
1255   mUseRemoteSurface(false),
1256   mRootLayoutDirection(Dali::LayoutDirection::LEFT_TO_RIGHT)
1257 {
1258   DALI_ASSERT_ALWAYS(!IsAvailable() && "Cannot create more than one Adaptor per thread");
1259   mWindows.insert(mWindows.begin(), &Dali::GetImplementation(window));
1260
1261   gThreadLocalAdaptor = this;
1262 }
1263
1264 void Adaptor::SetRootLayoutDirection(std::string locale)
1265 {
1266   mRootLayoutDirection = static_cast<LayoutDirection::Type>(Internal::Adaptor::Locale::GetDirection(std::string(locale)));
1267   for(auto& window : mWindows)
1268   {
1269     Dali::Actor root = window->GetRootLayer();
1270     root.SetProperty(Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection);
1271   }
1272 }
1273
1274 bool Adaptor::AddIdleEnterer(CallbackBase* callback, bool forceAdd)
1275 {
1276   bool idleAdded(false);
1277
1278   // Only add an idle if the Adaptor is actually running
1279   if(RUNNING == mState || READY == mState || forceAdd)
1280   {
1281     idleAdded = mCallbackManager->AddIdleEntererCallback(callback);
1282   }
1283
1284   if(!idleAdded)
1285   {
1286     // Delete callback
1287     delete callback;
1288   }
1289
1290   return idleAdded;
1291 }
1292
1293 void Adaptor::RemoveIdleEnterer(CallbackBase* callback)
1294 {
1295   mCallbackManager->RemoveIdleEntererCallback(callback);
1296 }
1297
1298 } // namespace Adaptor
1299
1300 } // namespace Internal
1301
1302 } // namespace Dali