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.h>
35 #include <dali/internal/adaptor/common/lifecycle-controller-impl.h>
36 #include <dali/internal/system/common/command-line-options.h>
37 #include <dali/internal/system/common/environment-variables.h>
38 #include <dali/internal/window-system/common/render-surface-factory.h>
39 #include <dali/internal/window-system/common/window-impl.h>
40 #include <dali/internal/window-system/common/window-render-surface.h>
41 #include <dali/internal/window-system/common/window-system.h>
43 // To disable a macro with the same name from one of OpenGL headers
48 namespace TizenPlatform
50 class TizenPlatformAbstraction;
62 DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_APPLICATION, true);
64 ApplicationPtr Application::gPreInitializedApplication(NULL);
66 ApplicationPtr Application::New(
69 const std::string& stylesheet,
70 Dali::Application::WINDOW_MODE windowMode,
71 const PositionSize& positionSize,
72 Framework::Type applicationType,
76 ApplicationPtr application(new Application(argc, argv, stylesheet, windowMode, positionSize, applicationType, type, useUiThread));
80 void Application::PreInitialize(int* argc, char** argv[])
82 if(!gPreInitializedApplication)
84 Dali::TextAbstraction::FontClientPreInitialize();
86 gPreInitializedApplication = new Application(argc, argv, "", Dali::Application::OPAQUE, PositionSize(), Framework::NORMAL, WindowType::NORMAL, false);
87 gPreInitializedApplication->mLaunchpadState = Launchpad::PRE_INITIALIZED;
88 gPreInitializedApplication->CreateWindow(); // Only create window
92 Application::Application(int* argc, char** argv[], const std::string& stylesheet, Dali::Application::WINDOW_MODE windowMode, const PositionSize& positionSize, Framework::Type applicationType, WindowType type, bool useUiThread)
99 mLanguageChangedSignal(),
100 mRegionChangedSignal(),
102 mCommandLineOptions(nullptr),
103 mAdaptorBuilder(nullptr),
105 mEnvironmentOptions(nullptr),
107 mMainWindowMode(windowMode),
109 mStylesheet(stylesheet),
110 mWindowPositionSize(positionSize),
111 mLaunchpadState(Launchpad::NONE),
112 mDefaultWindowType(type),
113 mUseUiThread(useUiThread),
116 // Set mName from command-line args
117 if(argc && (*argc > 0))
119 mMainWindowName = (*argv)[0];
122 const char* uiThreadEnabled = Dali::EnvironmentVariable::GetEnvironmentVariable(DALI_ENV_ENABLE_UI_THREAD);
123 if(uiThreadEnabled && std::atoi(uiThreadEnabled) != 0)
128 WindowSystem::Initialize();
130 mCommandLineOptions = new CommandLineOptions(argc, argv);
131 mFramework = new Framework(*this, *this, argc, argv, applicationType, mUseUiThread);
132 mUseRemoteSurface = (applicationType == Framework::WATCH);
135 Application::~Application()
137 SingletonService service = SingletonService::Get();
138 // Note this can be false i.e. if Application has never created a Core instance
141 service.UnregisterAll();
146 delete mAdaptorBuilder;
147 delete mCommandLineOptions;
150 WindowSystem::Shutdown();
153 void Application::StoreWindowPositionSize(PositionSize positionSize)
155 mWindowPositionSize = positionSize;
158 void Application::ChangePreInitializedWindowInfo()
161 auto windowClassName = mEnvironmentOptions->GetWindowClassName();
162 auto windowName = mEnvironmentOptions->GetWindowName();
163 if(!windowName.empty())
165 mMainWindowName = windowName;
167 mMainWindow.SetClass(mMainWindowName, windowClassName);
169 // The real screen size may be different from the value of the preinitialized state. Update it.
170 Dali::Internal::Adaptor::WindowSystem::UpdateScreenSize();
172 int screenWidth, screenHeight;
173 Dali::Internal::Adaptor::WindowSystem::GetScreenSize(screenWidth, screenHeight);
175 // Set window position / size
176 if(mWindowPositionSize != PositionSize(0, 0, 0, 0))
178 Dali::DevelWindow::SetPositionSize(mMainWindow, mWindowPositionSize);
180 else if(mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0)
182 // Command line options override environment options and full screen
183 mWindowPositionSize.width = mCommandLineOptions->stageWidth;
184 mWindowPositionSize.height = mCommandLineOptions->stageHeight;
185 mMainWindow.SetSize(Dali::Window::WindowSize(mWindowPositionSize.width, mWindowPositionSize.height));
187 else if(mEnvironmentOptions->GetWindowWidth() && mEnvironmentOptions->GetWindowHeight())
189 // Environment options override full screen functionality if command line arguments not provided
190 mWindowPositionSize.width = mEnvironmentOptions->GetWindowWidth();
191 mWindowPositionSize.height = mEnvironmentOptions->GetWindowHeight();
192 mMainWindow.SetSize(Dali::Window::WindowSize(mWindowPositionSize.width, mWindowPositionSize.height));
194 else if(screenWidth != mWindowPositionSize.width || screenHeight != mWindowPositionSize.height)
196 // Some apps can receive screen size differently after launching by specifying size in manifest.
197 mWindowPositionSize.width = screenWidth;
198 mWindowPositionSize.height = screenHeight;
199 mMainWindow.SetSize(Dali::Window::WindowSize(mWindowPositionSize.width, mWindowPositionSize.height));
203 void Application::CreateWindow()
205 Internal::Adaptor::Window* window;
207 if(mLaunchpadState != Launchpad::PRE_INITIALIZED)
209 if(mWindowPositionSize.width == 0 && mWindowPositionSize.height == 0)
211 if(mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0)
213 // Command line options override environment options and full screen
214 mWindowPositionSize.width = mCommandLineOptions->stageWidth;
215 mWindowPositionSize.height = mCommandLineOptions->stageHeight;
217 else if(mEnvironmentOptions->GetWindowWidth() && mEnvironmentOptions->GetWindowHeight())
219 // Environment options override full screen functionality if command line arguments not provided
220 mWindowPositionSize.width = mEnvironmentOptions->GetWindowWidth();
221 mWindowPositionSize.height = mEnvironmentOptions->GetWindowHeight();
225 auto windowClassName = mEnvironmentOptions->GetWindowClassName();
226 auto windowName = mEnvironmentOptions->GetWindowName();
227 if(!windowName.empty())
229 mMainWindowName = windowName;
232 window = Internal::Adaptor::Window::New(mWindowPositionSize, mMainWindowName, windowClassName, mDefaultWindowType, mMainWindowMode == Dali::Application::TRANSPARENT);
236 // The position, size and the window name of the pre-initialized application will be updated in ChangePreInitializedWindowInfo()
237 // when the real application is launched.
238 window = Internal::Adaptor::Window::New(mWindowPositionSize, "", "", mDefaultWindowType, mMainWindowMode == Dali::Application::TRANSPARENT);
241 mMainWindow = Dali::Window(window);
243 // Quit the application when the window is closed
244 GetImplementation(mMainWindow).DeleteRequestSignal().Connect(mSlotDelegate, &Application::Quit);
247 void Application::CreateAdaptor()
249 DALI_ASSERT_ALWAYS(mMainWindow && "Window required to create adaptor");
251 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
253 Integration::SceneHolder sceneHolder = Integration::SceneHolder(&Dali::GetImplementation(mMainWindow));
255 mAdaptor = Adaptor::New(graphicsFactory, sceneHolder, mEnvironmentOptions.get());
257 Adaptor::GetImplementation(*mAdaptor).SetUseRemoteSurface(mUseRemoteSurface);
260 void Application::CreateAdaptorBuilder()
262 mAdaptorBuilder = new AdaptorBuilder(*mEnvironmentOptions);
265 void Application::MainLoop()
267 // Run the application
271 void Application::Lower()
273 // Lower the application without quitting it.
277 void Application::Quit()
279 // Actually quit the application.
280 // Force a call to Quit even if adaptor is not running.
281 Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).AddIdle(MakeCallback(this, &Application::QuitFromMainLoop), false, true);
284 void Application::QuitFromMainLoop()
286 Accessibility::Bridge::GetCurrentBridge()->Terminate();
291 // This will trigger OnTerminate(), below, after the main loop has completed.
294 void Application::OnInit()
296 mEnvironmentOptions = std::unique_ptr<EnvironmentOptions>(new EnvironmentOptions());
298 mFramework->AddAbortCallback(MakeCallback(this, &Application::QuitFromMainLoop));
300 CreateAdaptorBuilder();
301 // If an application was pre-initialized, a window was made in advance
302 if(mLaunchpadState == Launchpad::NONE)
309 if(mLaunchpadState == Launchpad::PRE_INITIALIZED)
311 ChangePreInitializedWindowInfo();
315 DALI_TRACE_BEGIN(gTraceFilter, "DALI_APP_ADAPTOR_START");
317 DALI_TRACE_END(gTraceFilter, "DALI_APP_ADAPTOR_START");
318 Accessibility::Accessible::SetObjectRegistry(mAdaptor->GetObjectRegistry());
320 if(!mStylesheet.empty())
322 Dali::StyleMonitor::Get().SetTheme(mStylesheet);
325 // Wire up the LifecycleController
326 Dali::LifecycleController lifecycleController = Dali::LifecycleController::Get();
328 InitSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnInit);
329 TerminateSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnTerminate);
330 PauseSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnPause);
331 ResumeSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnResume);
332 ResetSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnReset);
333 LanguageChangedSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnLanguageChanged);
335 Dali::Application application(this);
337 DALI_TRACE_BEGIN(gTraceFilter, "DALI_APP_EMIT_INIT_SIGNAL");
338 mInitSignal.Emit(application);
339 DALI_TRACE_END(gTraceFilter, "DALI_APP_EMIT_INIT_SIGNAL");
341 mAdaptor->NotifySceneCreated();
344 void Application::OnTerminate()
346 // We've been told to quit by AppCore, ecore_x_destroy has been called, need to quit synchronously
347 // delete the window as ecore_x has been destroyed by AppCore
349 Dali::Application application(this);
350 mTerminateSignal.Emit(application);
354 // Ensure that the render-thread is not using the surface(window) after we delete it
358 mMainWindow.Reset(); // This only resets (clears) the default Window
361 void Application::OnPause()
363 // A DALi app should handle Pause/Resume events.
364 // DALi just delivers the framework Pause event to the application, but not actually pause DALi core.
365 // Pausing DALi core only occurs on the Window Hidden framework event
366 Dali::Application application(this);
367 mPauseSignal.Emit(application);
370 void Application::OnResume()
372 // Emit the signal first so the application can queue any messages before we do an update/render
373 // This ensures we do not just redraw the last frame before pausing if that's not required
374 Dali::Application application(this);
375 mResumeSignal.Emit(application);
377 // DALi just delivers the framework Resume event to the application.
378 // Resuming DALi core only occurs on the Window Show framework event
380 // Trigger processing of events queued up while paused
381 CoreEventInterface& coreEventInterface = Internal::Adaptor::Adaptor::GetImplementation(GetAdaptor());
382 coreEventInterface.ProcessCoreEvents();
385 void Application::OnReset()
388 * usually, reset callback was called when a caller request to launch this application via aul.
389 * because Application class already handled initialization in OnInit(), OnReset do nothing.
391 Dali::Application application(this);
392 mResetSignal.Emit(application);
395 void Application::OnAppControl(void* data)
397 Dali::Application application(this);
398 mAppControlSignal.Emit(application, data);
401 void Application::OnLanguageChanged()
403 mAdaptor->NotifyLanguageChanged();
404 Dali::Application application(this);
405 mLanguageChangedSignal.Emit(application);
408 void Application::OnRegionChanged()
410 Dali::Application application(this);
411 mRegionChangedSignal.Emit(application);
414 void Application::OnBatteryLow(Dali::DeviceStatus::Battery::Status status)
416 Dali::Application application(this);
417 mLowBatterySignal.Emit(status);
420 void Application::OnMemoryLow(Dali::DeviceStatus::Memory::Status status)
422 Dali::Application application(this);
423 mLowMemorySignal.Emit(status);
426 void Application::OnDeviceOrientationChanged(Dali::DeviceStatus::Orientation::Status status)
428 Dali::Application application(this);
429 mDeviceOrientationChangedSignal.Emit(status);
432 void Application::OnSurfaceCreated(Any newSurface)
434 void* newWindow = AnyCast<void*>(newSurface);
435 void* oldWindow = AnyCast<void*>(mMainWindow.GetNativeHandle());
436 if(oldWindow != newWindow)
438 auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
439 std::unique_ptr<WindowRenderSurface> newSurfacePtr = renderSurfaceFactory->CreateWindowRenderSurface(PositionSize(), newSurface, true);
441 mAdaptor->ReplaceSurface(mMainWindow, *newSurfacePtr.release());
445 void Application::OnSurfaceDestroyed(Any surface)
449 void Application::OnTaskInit()
451 Dali::Application application(this);
452 mTaskInitSignal.Emit(application);
455 void Application::OnTaskTerminate()
457 Dali::Application application(this);
458 mTaskTerminateSignal.Emit(application);
461 void Application::OnTaskAppControl(void* data)
463 Dali::Application application(this);
464 mTaskAppControlSignal.Emit(application, data);
467 void Application::OnTaskLanguageChanged()
469 Dali::Application application(this);
470 mTaskLanguageChangedSignal.Emit(application);
473 void Application::OnTaskRegionChanged()
475 Dali::Application application(this);
476 mTaskRegionChangedSignal.Emit(application);
479 void Application::OnTaskBatteryLow(Dali::DeviceStatus::Battery::Status status)
481 Dali::Application application(this);
482 mTaskLowBatterySignal.Emit(status);
485 void Application::OnTaskMemoryLow(Dali::DeviceStatus::Memory::Status status)
487 Dali::Application application(this);
488 mTaskLowMemorySignal.Emit(status);
491 void Application::OnTaskDeviceOrientationChanged(Dali::DeviceStatus::Orientation::Status status)
493 Dali::Application application(this);
494 mTaskDeviceOrientationChangedSignal.Emit(status);
497 bool Application::AddIdle(CallbackBase* callback, bool hasReturnValue)
499 return mAdaptor->AddIdle(callback, hasReturnValue);
502 std::string Application::GetRegion() const
504 return mFramework->GetRegion();
507 std::string Application::GetLanguage() const
509 return mFramework->GetLanguage();
512 Dali::ObjectRegistry Application::GetObjectRegistry() const
514 Dali::ObjectRegistry objectRegistry;
517 objectRegistry = mAdaptor->GetObjectRegistry();
519 return objectRegistry;
522 Dali::Adaptor& Application::GetAdaptor()
527 Dali::Window Application::GetWindow()
532 std::string Application::GetResourcePath()
534 return Internal::Adaptor::Framework::GetResourcePath();
537 std::string Application::GetDataPath()
539 return Internal::Adaptor::Framework::GetDataPath();
542 void Application::SetStyleSheet(const std::string& stylesheet)
544 mStylesheet = stylesheet;
547 void Application::SetCommandLineOptions(int* argc, char** argv[])
549 delete mCommandLineOptions;
551 mCommandLineOptions = new CommandLineOptions(argc, argv);
553 mFramework->SetCommandLineOptions(argc, argv);
555 if(argc && (*argc > 0))
557 // Set mName from command-line args
558 mMainWindowName = (*argv)[0];
562 void Application::SetDefaultWindowType(WindowType type)
564 mDefaultWindowType = type;
565 mMainWindow.SetType(type);
568 int32_t Application::GetRenderThreadId() const
572 return Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).GetRenderThreadId();
577 ApplicationPtr Application::GetPreInitializedApplication()
579 // Reset the handle to decrease the reference count
580 ApplicationPtr application = gPreInitializedApplication;
581 gPreInitializedApplication.Reset();
586 } // namespace Adaptor
588 } // namespace Internal