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