2 * Copyright (c) 2022 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->CreateWindow(); // Only create window
88 gPreInitializedApplication->mLaunchpadState = Launchpad::PRE_INITIALIZED;
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(),
103 mCommandLineOptions(nullptr),
104 mAdaptorBuilder(nullptr),
107 mMainWindowMode(windowMode),
109 mStylesheet(stylesheet),
110 mEnvironmentOptions(),
111 mWindowPositionSize(positionSize),
112 mLaunchpadState(Launchpad::NONE),
113 mDefaultWindowType(type),
114 mUseUiThread(useUiThread),
117 // Get mName from environment options
118 mMainWindowName = mEnvironmentOptions.GetWindowName();
119 if(mMainWindowName.empty() && argc && (*argc > 0))
121 // Set mName from command-line args if environment option not set
122 mMainWindowName = (*argv)[0];
125 const char* uiThreadEnabled = Dali::EnvironmentVariable::GetEnvironmentVariable(DALI_ENV_ENABLE_UI_THREAD);
126 if(uiThreadEnabled && std::atoi(uiThreadEnabled) != 0)
131 mCommandLineOptions = new CommandLineOptions(argc, argv);
132 mFramework = new Framework(*this, *this, argc, argv, applicationType, mUseUiThread);
133 mUseRemoteSurface = (applicationType == Framework::WATCH);
136 Application::~Application()
138 SingletonService service = SingletonService::Get();
139 // Note this can be false i.e. if Application has never created a Core instance
142 service.UnregisterAll();
147 delete mAdaptorBuilder;
148 delete mCommandLineOptions;
152 void Application::StoreWindowPositionSize(PositionSize positionSize)
154 mWindowPositionSize = positionSize;
157 void Application::ChangePreInitializedWindowSize()
159 // The real screen size may be different from the value of the preinitialized state. Update it.
160 Dali::Internal::Adaptor::WindowSystem::UpdateScreenSize();
162 int screenWidth, screenHeight;
163 Dali::Internal::Adaptor::WindowSystem::GetScreenSize(screenWidth, screenHeight);
165 if(mWindowPositionSize != PositionSize(0, 0, 0, 0))
167 Dali::DevelWindow::SetPositionSize(mMainWindow, mWindowPositionSize);
169 else if(mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0)
171 // Command line options override environment options and full screen
172 mWindowPositionSize.width = mCommandLineOptions->stageWidth;
173 mWindowPositionSize.height = mCommandLineOptions->stageHeight;
174 mMainWindow.SetSize(Dali::Window::WindowSize(mWindowPositionSize.width, mWindowPositionSize.height));
176 else if(mEnvironmentOptions.GetWindowWidth() && mEnvironmentOptions.GetWindowHeight())
178 // Environment options override full screen functionality if command line arguments not provided
179 mWindowPositionSize.width = mEnvironmentOptions.GetWindowWidth();
180 mWindowPositionSize.height = mEnvironmentOptions.GetWindowHeight();
181 mMainWindow.SetSize(Dali::Window::WindowSize(mWindowPositionSize.width, mWindowPositionSize.height));
183 else if(screenWidth != mWindowPositionSize.width || screenHeight != mWindowPositionSize.height)
185 // Some apps can receive screen size differently after launching by specifying size in manifest.
186 mWindowPositionSize.width = screenWidth;
187 mWindowPositionSize.height = screenHeight;
188 mMainWindow.SetSize(Dali::Window::WindowSize(mWindowPositionSize.width, mWindowPositionSize.height));
192 void Application::CreateWindow()
194 if(mWindowPositionSize.width == 0 && mWindowPositionSize.height == 0)
196 if(mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0)
198 // Command line options override environment options and full screen
199 mWindowPositionSize.width = mCommandLineOptions->stageWidth;
200 mWindowPositionSize.height = mCommandLineOptions->stageHeight;
202 else if(mEnvironmentOptions.GetWindowWidth() && mEnvironmentOptions.GetWindowHeight())
204 // Environment options override full screen functionality if command line arguments not provided
205 mWindowPositionSize.width = mEnvironmentOptions.GetWindowWidth();
206 mWindowPositionSize.height = mEnvironmentOptions.GetWindowHeight();
210 const std::string& windowClassName = mEnvironmentOptions.GetWindowClassName();
212 Internal::Adaptor::Window* window = Internal::Adaptor::Window::New(mWindowPositionSize, mMainWindowName, windowClassName, mDefaultWindowType, mMainWindowMode == Dali::Application::TRANSPARENT);
213 mMainWindow = Dali::Window(window);
215 // Quit the application when the window is closed
216 GetImplementation(mMainWindow).DeleteRequestSignal().Connect(mSlotDelegate, &Application::Quit);
219 void Application::CreateAdaptor()
221 DALI_ASSERT_ALWAYS(mMainWindow && "Window required to create adaptor");
223 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
225 Integration::SceneHolder sceneHolder = Integration::SceneHolder(&Dali::GetImplementation(mMainWindow));
227 mAdaptor = Adaptor::New(graphicsFactory, sceneHolder, &mEnvironmentOptions);
229 Adaptor::GetImplementation(*mAdaptor).SetUseRemoteSurface(mUseRemoteSurface);
232 void Application::CreateAdaptorBuilder()
234 mAdaptorBuilder = new AdaptorBuilder(mEnvironmentOptions);
237 void Application::MainLoop()
239 // Run the application
243 void Application::Lower()
245 // Lower the application without quitting it.
249 void Application::Quit()
251 // Actually quit the application.
252 // Force a call to Quit even if adaptor is not running.
253 Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).AddIdle(MakeCallback(this, &Application::QuitFromMainLoop), false, true);
256 void Application::QuitFromMainLoop()
258 Accessibility::Bridge::GetCurrentBridge()->Terminate();
263 // This will trigger OnTerminate(), below, after the main loop has completed.
266 void Application::OnInit()
268 mFramework->AddAbortCallback(MakeCallback(this, &Application::QuitFromMainLoop));
270 CreateAdaptorBuilder();
271 // If an application was pre-initialized, a window was made in advance
272 if(mLaunchpadState == Launchpad::NONE)
279 if(mLaunchpadState == Launchpad::PRE_INITIALIZED)
281 ChangePreInitializedWindowSize();
285 DALI_TRACE_BEGIN(gTraceFilter, "DALI_APP_ADAPTOR_START");
287 DALI_TRACE_END(gTraceFilter, "DALI_APP_ADAPTOR_START");
288 Accessibility::Accessible::SetObjectRegistry(mAdaptor->GetObjectRegistry());
290 if(!mStylesheet.empty())
292 Dali::StyleMonitor::Get().SetTheme(mStylesheet);
295 // Wire up the LifecycleController
296 Dali::LifecycleController lifecycleController = Dali::LifecycleController::Get();
298 InitSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnInit);
299 TerminateSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnTerminate);
300 PauseSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnPause);
301 ResumeSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnResume);
302 ResetSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnReset);
303 LanguageChangedSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnLanguageChanged);
305 Dali::Application application(this);
307 DALI_TRACE_BEGIN(gTraceFilter, "DALI_APP_EMIT_INIT_SIGNAL");
308 mInitSignal.Emit(application);
309 DALI_TRACE_END(gTraceFilter, "DALI_APP_EMIT_INIT_SIGNAL");
311 mAdaptor->NotifySceneCreated();
313 // Ensure the join of Font thread at this point
314 Dali::TextAbstraction::FontClientJoinFontThreads();
317 void Application::OnTerminate()
319 // We've been told to quit by AppCore, ecore_x_destroy has been called, need to quit synchronously
320 // delete the window as ecore_x has been destroyed by AppCore
322 Dali::Application application(this);
323 mTerminateSignal.Emit(application);
327 // Ensure that the render-thread is not using the surface(window) after we delete it
331 mMainWindow.Reset(); // This only resets (clears) the default Window
334 void Application::OnPause()
336 // A DALi app should handle Pause/Resume events.
337 // DALi just delivers the framework Pause event to the application, but not actually pause DALi core.
338 // Pausing DALi core only occurs on the Window Hidden framework event
339 Dali::Application application(this);
340 mPauseSignal.Emit(application);
343 void Application::OnResume()
345 // Emit the signal first so the application can queue any messages before we do an update/render
346 // This ensures we do not just redraw the last frame before pausing if that's not required
347 Dali::Application application(this);
348 mResumeSignal.Emit(application);
350 // DALi just delivers the framework Resume event to the application.
351 // Resuming DALi core only occurs on the Window Show framework event
353 // Trigger processing of events queued up while paused
354 CoreEventInterface& coreEventInterface = Internal::Adaptor::Adaptor::GetImplementation(GetAdaptor());
355 coreEventInterface.ProcessCoreEvents();
358 void Application::OnReset()
361 * usually, reset callback was called when a caller request to launch this application via aul.
362 * because Application class already handled initialization in OnInit(), OnReset do nothing.
364 Dali::Application application(this);
365 mResetSignal.Emit(application);
368 void Application::OnAppControl(void* data)
370 Dali::Application application(this);
371 mAppControlSignal.Emit(application, data);
374 void Application::OnLanguageChanged()
376 mAdaptor->NotifyLanguageChanged();
377 Dali::Application application(this);
378 mLanguageChangedSignal.Emit(application);
381 void Application::OnRegionChanged()
383 Dali::Application application(this);
384 mRegionChangedSignal.Emit(application);
387 void Application::OnBatteryLow(Dali::DeviceStatus::Battery::Status status)
389 Dali::Application application(this);
390 mLowBatterySignal.Emit(status);
393 void Application::OnMemoryLow(Dali::DeviceStatus::Memory::Status status)
395 Dali::Application application(this);
396 mLowMemorySignal.Emit(status);
399 void Application::OnDeviceOrientationChanged(Dali::DeviceStatus::Orientation::Status status)
401 Dali::Application application(this);
402 mDeviceOrientationChangedSignal.Emit(status);
405 void Application::OnSurfaceCreated(Any newSurface)
407 void* newWindow = AnyCast<void*>(newSurface);
408 void* oldWindow = AnyCast<void*>(mMainWindow.GetNativeHandle());
409 if(oldWindow != newWindow)
411 auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
412 std::unique_ptr<WindowRenderSurface> newSurfacePtr = renderSurfaceFactory->CreateWindowRenderSurface(PositionSize(), newSurface, true);
414 mAdaptor->ReplaceSurface(mMainWindow, *newSurfacePtr.release());
418 void Application::OnSurfaceDestroyed(Any surface)
422 void Application::OnTaskInit()
424 Dali::Application application(this);
425 mTaskInitSignal.Emit(application);
428 void Application::OnTaskTerminate()
430 Dali::Application application(this);
431 mTaskTerminateSignal.Emit(application);
434 void Application::OnTaskAppControl(void* data)
436 Dali::Application application(this);
437 mTaskAppControlSignal.Emit(application, data);
440 void Application::OnTaskLanguageChanged()
442 Dali::Application application(this);
443 mTaskLanguageChangedSignal.Emit(application);
446 void Application::OnTaskRegionChanged()
448 Dali::Application application(this);
449 mTaskRegionChangedSignal.Emit(application);
452 void Application::OnTaskBatteryLow(Dali::DeviceStatus::Battery::Status status)
454 Dali::Application application(this);
455 mTaskLowBatterySignal.Emit(status);
458 void Application::OnTaskMemoryLow(Dali::DeviceStatus::Memory::Status status)
460 Dali::Application application(this);
461 mTaskLowMemorySignal.Emit(status);
464 void Application::OnTaskDeviceOrientationChanged(Dali::DeviceStatus::Orientation::Status status)
466 Dali::Application application(this);
467 mTaskDeviceOrientationChangedSignal.Emit(status);
470 bool Application::AddIdle(CallbackBase* callback, bool hasReturnValue)
472 return mAdaptor->AddIdle(callback, hasReturnValue);
475 std::string Application::GetRegion() const
477 return mFramework->GetRegion();
480 std::string Application::GetLanguage() const
482 return mFramework->GetLanguage();
485 Dali::ObjectRegistry Application::GetObjectRegistry() const
487 Dali::ObjectRegistry objectRegistry;
490 objectRegistry = mAdaptor->GetObjectRegistry();
492 return objectRegistry;
495 Dali::Adaptor& Application::GetAdaptor()
500 Dali::Window Application::GetWindow()
505 std::string Application::GetResourcePath()
507 return Internal::Adaptor::Framework::GetResourcePath();
510 std::string Application::GetDataPath()
512 return Internal::Adaptor::Framework::GetDataPath();
515 void Application::SetStyleSheet(const std::string& stylesheet)
517 mStylesheet = stylesheet;
520 void Application::SetCommandLineOptions(int* argc, char** argv[])
522 delete mCommandLineOptions;
524 mCommandLineOptions = new CommandLineOptions(argc, argv);
526 mFramework->SetCommandLineOptions(argc, argv);
529 void Application::SetDefaultWindowType(WindowType type)
531 mDefaultWindowType = type;
532 mMainWindow.SetType(type);
535 int32_t Application::GetRenderThreadId() const
539 return Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).GetRenderThreadId();
544 ApplicationPtr Application::GetPreInitializedApplication()
546 // Reset the handle to decrease the reference count
547 ApplicationPtr application = gPreInitializedApplication;
548 gPreInitializedApplication.Reset();
553 } // namespace Adaptor
555 } // namespace Internal