2 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/adaptor/common/application-impl.h>
22 #include <dali/devel-api/common/singleton-service.h>
23 #include <dali/integration-api/debug.h>
24 #include <dali/integration-api/trace.h>
25 #include <dali/public-api/object/object-registry.h>
28 #include <dali/devel-api/adaptor-framework/accessibility-bridge.h>
29 #include <dali/devel-api/adaptor-framework/environment-variable.h>
30 #include <dali/devel-api/adaptor-framework/style-monitor.h>
31 #include <dali/devel-api/atspi-interfaces/accessible.h>
32 #include <dali/devel-api/text-abstraction/font-client.h>
33 #include <dali/internal/adaptor/common/adaptor-impl.h>
34 #include <dali/internal/adaptor/common/framework-factory.h>
35 #include <dali/internal/adaptor/common/framework.h>
36 #include <dali/internal/adaptor/common/lifecycle-controller-impl.h>
37 #include <dali/internal/system/common/command-line-options.h>
38 #include <dali/internal/system/common/environment-variables.h>
39 #include <dali/internal/system/common/system-settings.h>
40 #include <dali/internal/window-system/common/render-surface-factory.h>
41 #include <dali/internal/window-system/common/window-impl.h>
42 #include <dali/internal/window-system/common/window-render-surface.h>
43 #include <dali/internal/window-system/common/window-system.h>
45 // To disable a macro with the same name from one of OpenGL headers
50 namespace TizenPlatform
52 class TizenPlatformAbstraction;
64 DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_APPLICATION, true);
66 ApplicationPtr Application::gPreInitializedApplication(NULL);
68 ApplicationPtr Application::New(
71 const std::string& stylesheet,
72 Framework::Type applicationType,
74 const WindowData& windowData)
76 ApplicationPtr application(new Application(argc, argv, stylesheet, applicationType, useUiThread, windowData));
80 void Application::PreInitialize(int* argc, char** argv[])
82 if(!gPreInitializedApplication)
84 bool isUseUIThread = false;
86 #ifdef UI_THREAD_AVAILABLE
87 char* retEnv = std::getenv("TIZEN_UI_THREAD");
90 std::string uiThreadEnv = retEnv;
91 std::string enabledString = "true";
92 if(uiThreadEnv == enabledString)
99 Dali::TextAbstraction::FontClientPreInitialize();
100 WindowData windowData;
101 gPreInitializedApplication = new Application(argc, argv, "", Framework::NORMAL, isUseUIThread, windowData);
102 gPreInitializedApplication->mLaunchpadState = Launchpad::PRE_INITIALIZED;
104 #ifdef UI_THREAD_AVAILABLE
107 DALI_LOG_RELEASE_INFO("PRE_INITIALIZED with UI Threading");
108 gPreInitializedApplication->mUIThreadLoader = new UIThreadLoader(argc, argv);
109 gPreInitializedApplication->mUIThreadLoader->Run([&]() { gPreInitializedApplication->CreateWindow(); });
114 DALI_LOG_RELEASE_INFO("Only PRE_INITIALIZED");
115 gPreInitializedApplication->CreateWindow(); // Only create window
120 Application::Application(int* argc, char** argv[], const std::string& stylesheet, Framework::Type applicationType, bool useUiThread, const WindowData& windowData)
127 mLanguageChangedSignal(),
128 mRegionChangedSignal(),
130 mFrameworkFactory(nullptr),
131 mCommandLineOptions(nullptr),
132 mAdaptorBuilder(nullptr),
134 mEnvironmentOptions(nullptr),
136 mMainWindowMode(windowData.GetTransparency() ? WINDOW_MODE::TRANSPARENT : WINDOW_MODE::OPAQUE),
138 mIsMainWindowFrontBufferRendering(windowData.GetFrontBufferRendering()),
139 mStylesheet(stylesheet),
140 mWindowPositionSize(windowData.GetPositionSize()),
141 mLaunchpadState(Launchpad::NONE),
142 mDefaultWindowType(windowData.GetWindowType()),
143 mUseUiThread(useUiThread),
144 mIsSystemInitialized(false),
146 mUIThreadLoader(nullptr)
148 // Set mName from command-line args
149 if(argc && (*argc > 0))
151 mMainWindowName = (*argv)[0];
154 const char* uiThreadEnabled = Dali::EnvironmentVariable::GetEnvironmentVariable(DALI_ENV_ENABLE_UI_THREAD);
155 if(uiThreadEnabled && std::atoi(uiThreadEnabled) != 0)
160 mCommandLineOptions = new CommandLineOptions(argc, argv);
162 mFrameworkFactory = std::unique_ptr<FrameworkFactory>(Dali::Internal::Adaptor::CreateFrameworkFactory());
163 mFramework = mFrameworkFactory->CreateFramework(FrameworkBackend::DEFAULT, *this, *this, argc, argv, applicationType, mUseUiThread);
165 mUseRemoteSurface = (applicationType == Framework::WATCH);
168 Application::~Application()
170 SingletonService service = SingletonService::Get();
171 // Note this can be false i.e. if Application has never created a Core instance
174 service.UnregisterAll();
179 delete mCommandLineOptions;
181 // Application is created in Main thread whether UI Threading is enabled or not.
182 // But some resources are created in Main thread or UI thread.
183 // The below code is for the resource are created in Main thread.
187 delete mAdaptorBuilder;
188 if(mIsSystemInitialized)
190 WindowSystem::Shutdown();
197 delete mUIThreadLoader;
202 void Application::StoreWindowPositionSize(PositionSize positionSize)
204 mWindowPositionSize = positionSize;
207 void Application::StoreFrontBufferRendering(bool enable)
209 mIsMainWindowFrontBufferRendering = enable;
212 void Application::ChangePreInitializedWindowInfo()
215 auto windowClassName = mEnvironmentOptions->GetWindowClassName();
216 auto windowName = mEnvironmentOptions->GetWindowName();
217 if(!windowName.empty())
219 mMainWindowName = windowName;
221 mMainWindow.SetClass(mMainWindowName, windowClassName);
223 // The real screen size may be different from the value of the preinitialized state. Update it.
224 Dali::Internal::Adaptor::WindowSystem::UpdateScreenSize();
226 int screenWidth, screenHeight;
227 Dali::Internal::Adaptor::WindowSystem::GetScreenSize(screenWidth, screenHeight);
229 // Set window position / size
230 if(mWindowPositionSize != PositionSize(0, 0, 0, 0))
232 Dali::DevelWindow::SetPositionSize(mMainWindow, mWindowPositionSize);
234 else if(mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0)
236 // Command line options override environment options and full screen
237 mWindowPositionSize.width = mCommandLineOptions->stageWidth;
238 mWindowPositionSize.height = mCommandLineOptions->stageHeight;
239 mMainWindow.SetSize(Dali::Window::WindowSize(mWindowPositionSize.width, mWindowPositionSize.height));
241 else if(mEnvironmentOptions->GetWindowWidth() && mEnvironmentOptions->GetWindowHeight())
243 // Environment options override full screen functionality if command line arguments not provided
244 mWindowPositionSize.width = mEnvironmentOptions->GetWindowWidth();
245 mWindowPositionSize.height = mEnvironmentOptions->GetWindowHeight();
246 mMainWindow.SetSize(Dali::Window::WindowSize(mWindowPositionSize.width, mWindowPositionSize.height));
248 else if(screenWidth != mWindowPositionSize.width || screenHeight != mWindowPositionSize.height)
250 // Some apps can receive screen size differently after launching by specifying size in manifest.
251 mWindowPositionSize.width = screenWidth;
252 mWindowPositionSize.height = screenHeight;
253 mMainWindow.SetSize(Dali::Window::WindowSize(mWindowPositionSize.width, mWindowPositionSize.height));
256 // Set front buffer rendering
257 Dali::DevelWindow::SetFrontBufferRendering(mMainWindow, mIsMainWindowFrontBufferRendering);
260 void Application::CreateWindow()
262 Internal::Adaptor::Window* window;
263 WindowData windowData;
264 windowData.SetTransparency(mMainWindowMode);
265 windowData.SetWindowType(mDefaultWindowType);
266 windowData.SetFrontBufferRendering(mIsMainWindowFrontBufferRendering);
268 DALI_LOG_RELEASE_INFO("Create Default Window");
270 WindowSystem::Initialize();
271 mIsSystemInitialized = true;
273 if(mLaunchpadState != Launchpad::PRE_INITIALIZED)
275 if(mWindowPositionSize.width == 0 && mWindowPositionSize.height == 0)
277 if(mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0)
279 // Command line options override environment options and full screen
280 mWindowPositionSize.width = mCommandLineOptions->stageWidth;
281 mWindowPositionSize.height = mCommandLineOptions->stageHeight;
283 else if(mEnvironmentOptions->GetWindowWidth() && mEnvironmentOptions->GetWindowHeight())
285 // Environment options override full screen functionality if command line arguments not provided
286 mWindowPositionSize.width = mEnvironmentOptions->GetWindowWidth();
287 mWindowPositionSize.height = mEnvironmentOptions->GetWindowHeight();
291 auto windowClassName = mEnvironmentOptions->GetWindowClassName();
292 auto windowName = mEnvironmentOptions->GetWindowName();
293 if(!windowName.empty())
295 mMainWindowName = windowName;
298 windowData.SetPositionSize(mWindowPositionSize);
299 window = Internal::Adaptor::Window::New(mMainWindowName, windowClassName, windowData);
303 // The position, size, window name, and frontbuffering of the pre-initialized application
304 // will be updated in ChangePreInitializedWindowInfo() when the real application is launched.
305 windowData.SetPositionSize(mWindowPositionSize);
306 window = Internal::Adaptor::Window::New("", "", windowData);
309 mMainWindow = Dali::Window(window);
311 // Quit the application when the window is closed
312 GetImplementation(mMainWindow).DeleteRequestSignal().Connect(mSlotDelegate, &Application::Quit);
315 void Application::CreateAdaptor()
317 DALI_ASSERT_ALWAYS(mMainWindow && "Window required to create adaptor");
319 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
321 Integration::SceneHolder sceneHolder = Integration::SceneHolder(&Dali::GetImplementation(mMainWindow));
323 mAdaptor = Adaptor::New(graphicsFactory, sceneHolder, mEnvironmentOptions.get());
325 Adaptor::GetImplementation(*mAdaptor).SetUseRemoteSurface(mUseRemoteSurface);
328 void Application::CreateAdaptorBuilder()
330 mAdaptorBuilder = new AdaptorBuilder(*mEnvironmentOptions);
333 void Application::MainLoop()
335 // Run the application
339 void Application::Lower()
341 // Lower the application without quitting it.
345 void Application::Quit()
347 // Actually quit the application.
348 // Force a call to Quit even if adaptor is not running.
349 Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).AddIdle(MakeCallback(this, &Application::QuitFromMainLoop), false);
352 void Application::QuitFromMainLoop()
354 Accessibility::Bridge::GetCurrentBridge()->Terminate();
359 // This will trigger OnTerminate(), below, after the main loop has completed.
362 void Application::OnInit()
364 mEnvironmentOptions = std::unique_ptr<EnvironmentOptions>(new EnvironmentOptions());
366 mFramework->AddAbortCallback(MakeCallback(this, &Application::QuitFromMainLoop));
368 CreateAdaptorBuilder();
369 // If an application was pre-initialized, a window was made in advance
370 if(mLaunchpadState == Launchpad::NONE)
372 DALI_LOG_RELEASE_INFO("default Window is created in standalone");
378 if(mLaunchpadState == Launchpad::PRE_INITIALIZED)
380 ChangePreInitializedWindowInfo();
384 DALI_TRACE_BEGIN(gTraceFilter, "DALI_APP_ADAPTOR_START");
386 DALI_TRACE_END(gTraceFilter, "DALI_APP_ADAPTOR_START");
387 Accessibility::Accessible::SetObjectRegistry(mAdaptor->GetObjectRegistry());
389 if(!mStylesheet.empty())
391 Dali::StyleMonitor::Get().SetTheme(mStylesheet);
394 // Wire up the LifecycleController
395 Dali::LifecycleController lifecycleController = Dali::LifecycleController::Get();
397 InitSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnInit);
398 TerminateSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnTerminate);
399 PauseSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnPause);
400 ResumeSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnResume);
401 ResetSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnReset);
402 LanguageChangedSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnLanguageChanged);
404 Dali::Application application(this);
406 DALI_TRACE_BEGIN(gTraceFilter, "DALI_APP_EMIT_INIT_SIGNAL");
407 mInitSignal.Emit(application);
408 DALI_TRACE_END(gTraceFilter, "DALI_APP_EMIT_INIT_SIGNAL");
410 mAdaptor->NotifySceneCreated();
412 // Ensure the join of Font thread at this point
413 Dali::TextAbstraction::FontClientJoinFontThreads();
416 void Application::OnTerminate()
418 // We've been told to quit by AppCore, ecore_x_destroy has been called, need to quit synchronously
419 // delete the window as ecore_x has been destroyed by AppCore
421 Dali::Application application(this);
422 mTerminateSignal.Emit(application);
426 // Ensure that the render-thread is not using the surface(window) after we delete it
430 mMainWindow.Reset(); // This only resets (clears) the default Window
432 // If DALi's UI Thread works, some resources are created in UI Thread, not Main thread.
433 // For that case, these resource should be deleted in UI Thread.
437 delete mAdaptorBuilder;
438 WindowSystem::Shutdown();
442 void Application::OnPause()
444 // A DALi app should handle Pause/Resume events.
445 // DALi just delivers the framework Pause event to the application, but not actually pause DALi core.
446 // Pausing DALi core only occurs on the Window Hidden framework event
447 Dali::Application application(this);
448 mPauseSignal.Emit(application);
451 void Application::OnResume()
453 // Emit the signal first so the application can queue any messages before we do an update/render
454 // This ensures we do not just redraw the last frame before pausing if that's not required
455 Dali::Application application(this);
456 mResumeSignal.Emit(application);
458 // DALi just delivers the framework Resume event to the application.
459 // Resuming DALi core only occurs on the Window Show framework event
461 // Trigger processing of events queued up while paused
462 CoreEventInterface& coreEventInterface = Internal::Adaptor::Adaptor::GetImplementation(GetAdaptor());
463 coreEventInterface.ProcessCoreEvents();
466 void Application::OnReset()
469 * usually, reset callback was called when a caller request to launch this application via aul.
470 * because Application class already handled initialization in OnInit(), OnReset do nothing.
472 Dali::Application application(this);
473 mResetSignal.Emit(application);
476 void Application::OnAppControl(void* data)
478 Dali::Application application(this);
479 mAppControlSignal.Emit(application, data);
482 void Application::OnLanguageChanged()
484 mAdaptor->NotifyLanguageChanged();
485 Dali::Application application(this);
486 mLanguageChangedSignal.Emit(application);
489 void Application::OnRegionChanged()
491 Dali::Application application(this);
492 mRegionChangedSignal.Emit(application);
495 void Application::OnBatteryLow(Dali::DeviceStatus::Battery::Status status)
497 Dali::Application application(this);
498 mLowBatterySignal.Emit(status);
501 void Application::OnMemoryLow(Dali::DeviceStatus::Memory::Status status)
503 Dali::Application application(this);
504 mLowMemorySignal.Emit(status);
507 void Application::OnDeviceOrientationChanged(Dali::DeviceStatus::Orientation::Status status)
509 Dali::Application application(this);
510 mDeviceOrientationChangedSignal.Emit(status);
513 void Application::OnSurfaceCreated(Any newSurface)
515 void* newWindow = AnyCast<void*>(newSurface);
516 void* oldWindow = AnyCast<void*>(mMainWindow.GetNativeHandle());
517 if(oldWindow != newWindow)
519 auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
520 std::unique_ptr<WindowRenderSurface> newSurfacePtr = renderSurfaceFactory->CreateWindowRenderSurface(PositionSize(), newSurface, true);
522 mAdaptor->ReplaceSurface(mMainWindow, *newSurfacePtr.release());
526 void Application::OnSurfaceDestroyed(Any surface)
530 void Application::OnTaskInit()
532 Dali::Application application(this);
533 mTaskInitSignal.Emit(application);
536 void Application::OnTaskTerminate()
538 Dali::Application application(this);
539 mTaskTerminateSignal.Emit(application);
542 void Application::OnTaskAppControl(void* data)
544 Dali::Application application(this);
545 mTaskAppControlSignal.Emit(application, data);
548 void Application::OnTaskLanguageChanged()
550 Dali::Application application(this);
551 mTaskLanguageChangedSignal.Emit(application);
554 void Application::OnTaskRegionChanged()
556 Dali::Application application(this);
557 mTaskRegionChangedSignal.Emit(application);
560 void Application::OnTaskBatteryLow(Dali::DeviceStatus::Battery::Status status)
562 Dali::Application application(this);
563 mTaskLowBatterySignal.Emit(status);
566 void Application::OnTaskMemoryLow(Dali::DeviceStatus::Memory::Status status)
568 Dali::Application application(this);
569 mTaskLowMemorySignal.Emit(status);
572 void Application::OnTaskDeviceOrientationChanged(Dali::DeviceStatus::Orientation::Status status)
574 Dali::Application application(this);
575 mTaskDeviceOrientationChangedSignal.Emit(status);
578 bool Application::AddIdle(CallbackBase* callback, bool hasReturnValue)
580 return mAdaptor->AddIdle(callback, hasReturnValue);
583 std::string Application::GetRegion() const
585 return mFramework->GetRegion();
588 std::string Application::GetLanguage() const
590 return mFramework->GetLanguage();
593 Dali::ObjectRegistry Application::GetObjectRegistry() const
595 Dali::ObjectRegistry objectRegistry;
598 objectRegistry = mAdaptor->GetObjectRegistry();
600 return objectRegistry;
603 Dali::Adaptor& Application::GetAdaptor()
608 Dali::Window Application::GetWindow()
613 std::string Application::GetResourcePath()
615 return SystemSettings::GetResourcePath();
618 std::string Application::GetDataPath()
620 return SystemSettings::GetDataPath();
623 void Application::FlushUpdateMessages()
625 Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).FlushUpdateMessages();
628 void Application::SetStyleSheet(const std::string& stylesheet)
630 mStylesheet = stylesheet;
633 void Application::SetCommandLineOptions(int* argc, char** argv[])
635 delete mCommandLineOptions;
637 mCommandLineOptions = new CommandLineOptions(argc, argv);
639 mFramework->SetCommandLineOptions(argc, argv);
641 if(argc && (*argc > 0))
643 // Set mName from command-line args
644 mMainWindowName = (*argv)[0];
648 void Application::SetDefaultWindowType(WindowType type)
650 mDefaultWindowType = type;
651 mMainWindow.SetType(type);
654 int32_t Application::GetRenderThreadId() const
658 return Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).GetRenderThreadId();
663 ApplicationPtr Application::GetPreInitializedApplication()
665 // Reset the handle to decrease the reference count
666 ApplicationPtr application = gPreInitializedApplication;
667 gPreInitializedApplication.Reset();
672 } // namespace Adaptor
674 } // namespace Internal