2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FApp_UiAppImpl.cpp
20 * @brief This is the implementation for the _UiAppImpl class.
23 #include <appsvc/appsvc.h>
26 #include <unique_ptr.h>
27 #include <X11/Xatom.h>
30 #include <FBaseSysLog.h>
31 #include <FBaseColArrayList.h>
32 #include <FAppAppRegistry.h>
33 #include <FUiCtrlFrame.h>
35 #include <FBaseRt_Process.h>
36 #include <FUi_ControlImplManager.h>
37 #include <FUi_KeyEventManager.h>
38 #include <FUi_WindowImpl.h>
39 #include <FUi_EcoreEvasMgr.h>
40 #include <FUi_EcoreEvas.h>
41 #include <FUi_UiNotificationEvent.h>
42 #include <FUi_UiEventManager.h>
43 #include <FUiCtrl_FrameImpl.h>
44 #include <FSys_PowerManagerImpl.h>
45 #include <FSys_SettingInfoImpl.h>
47 #include "FApp_AppFrame.h"
48 #include "FApp_AppInfo.h"
49 #include "FApp_AppImpl.h"
50 #include "FApp_UiAppImpl.h"
51 #include "FApp_AppArg.h"
54 using namespace Tizen::App;
55 using namespace Tizen::Base;
56 using namespace Tizen::Base::Collection;
57 using namespace Tizen::Base::Runtime;
58 using namespace Tizen::Ui;
59 using namespace Tizen::Ui::Controls;
60 using namespace Tizen::System;
61 using namespace Tizen::Graphics;
64 extern "C" int appsvc_request_transient_app(bundle*, Ecore_X_Window, appsvc_host_res_fn, void*);
65 extern "C" int appcore_set_app_state(int);
67 namespace Tizen { namespace App
70 _UiAppImpl* _UiAppImpl::__pUiAppImpl = null;
73 _UiAppImpl::_UiAppImpl(UiApp* pUiApp)
75 , __pAppImpl(_AppImpl::GetInstance())
76 , __appUiState(APP_UI_STATE_BACKGROUND)
81 __pFrameList = new (std::nothrow) ArrayList();
82 SysTryReturnVoidResult(NID_APP, __pFrameList != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
83 __pFrameList->Construct();
84 SysTryReturnVoidResult(NID_APP, __pAppImpl != null, E_INVALID_STATE, "[E_INVALID_STATE] Getting internal instance failed.");
88 _UiAppImpl::~_UiAppImpl(void)
98 _UiAppImpl::OnCreate(void)
100 SysLog(NID_APP, "Platform creation event.");
102 _AppInfo::SetAppState(INITIALIZING);
109 _UiAppImpl::RaiseFrame(Frame& frame)
111 _FrameImpl* pFrameImpl = _FrameImpl::GetInstance(frame);
115 // [N_SE-39536] Window raise is requested as synchronous due to B/S issue
116 _EcoreEvas* pEvas = GetEcoreEvasMgr()->GetEcoreEvas();
119 pEvas->ActivateWindow(pFrameImpl->GetCore());
126 _UiAppImpl::GetTargetWindowHandle(void) const
128 result r = E_SUCCESS;
130 _EcoreEvasMgr* pEcoreEvasMgr = GetEcoreEvasMgr();
132 SysTryReturn(NID_APP, pEcoreEvasMgr, -1, r, "Propagating.");
134 _EcoreEvas* pEcoreEvas = pEcoreEvasMgr->GetEcoreEvas();
136 SysTryReturn(NID_APP, pEcoreEvas, -1, r, "Propagating.");
138 Atom actualTypeReturn;
139 int actualFormatReturn;
140 unsigned long nItemsReturn;
141 unsigned long bytesAfterReturn;
142 unsigned char* pPropReturn = null;
145 ret = XGetWindowProperty(static_cast<Display*>(ecore_x_display_get()),
146 ecore_x_window_root_get(pEcoreEvas->GetXWindow()),
147 ecore_x_atom_get("_ISF_ACTIVE_WINDOW"),
157 SysTryReturn(NID_APP, ret == Success, -1, E_SYSTEM, "A failure occurs from the underlying system.");
159 Ecore_X_Window targetWindow = 0;
163 if (actualTypeReturn == XA_WINDOW)
165 targetWindow = *(reinterpret_cast<Ecore_X_Window*>(pPropReturn));
166 SysLog(NID_APP, "The handle of the target window is %x.", targetWindow);
172 return targetWindow? targetWindow: -1;
177 TransientResponseCb(void* pData)
179 SysLog(NID_APP, "Handling cleanup for submode app.");
181 // platform invokes ecore_main_loop_quit() after returning this callback
186 _UiAppImpl::OnService(service_s* service, bool initial)
188 Frame* pFrame = dynamic_cast<Frame*>(__pFrameList->GetAt(0));
189 _EcoreEvas* pEvas = GetEcoreEvasMgr()->GetEcoreEvas();
191 // make OnForeground event
195 if (pEvas && _AppInfo::IsSubMode())
197 _FrameImpl* pFrameImpl = _FrameImpl::GetInstance(*pFrame);
198 if (pFrameImpl != null)
200 const unsigned int curHandle = pFrameImpl->GetNativeHandle();
202 bundle* pBundle = _AppArg::GetBundleFromSvc(service);
203 const int pid = _AppArg::GetCallerPid(pBundle);
204 if (pid <= 0 || ((kill(pid, 0) < 0) && errno == ESRCH))
206 SysLogException(NID_APP, E_SYSTEM, "Caller process %d not exist : terminating %d.", pid, getpid());
210 int ret = appsvc_request_transient_app(pBundle, curHandle, TransientResponseCb, NULL);
212 SysLog(NID_APP, "Transient sets for (0x%x) with result (%d).", curHandle, ret);
218 const int type = _AppInfo::GetAppType();
219 if (type & _APP_TYPE_IME_APP)
221 SysLog(NID_APP, "Skipping 1st resume for IME app.");
230 // [INFO] to confirm that the window is not foreground
233 int pid = pEvas->GetProcessId(pEvas->GetActiveWindow());
234 SysLog(NID_APP, "%d -> %d", pid, _AppInfo::GetProcessId());
235 if (pid != _AppInfo::GetProcessId())
241 _FrameImpl* pFrameImpl = _FrameImpl::GetInstance(*pFrame);
243 // [FIXME] Multi window handling
244 if (pFrameImpl != null)
246 //pEvas->ActivateWindow(pFrameImpl->GetCore());
248 unique_ptr<ArrayList> pEventArgs(new (std::nothrow) ArrayList());
249 SysTryReturnVoidResult(NID_APP, pEventArgs, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
250 pEventArgs->Construct();
252 unique_ptr<String> pString(new (std::nothrow) Tizen::Base::String(L"ActivateFrame"));
253 SysTryReturnVoidResult(NID_APP, pString, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
255 pEventArgs->Add(*(pString.get()));
257 _UiNotificationEvent event(pFrameImpl->GetCore().GetHandle(), pEventArgs.get());
259 result r = _UiEventManager::GetInstance()->PostEvent(event);
260 SysTryReturnVoidResult(NID_APP, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] A system error occurred.");
263 pEventArgs.release();
265 // N_SE-24616, N_SE-24383 for OnForground() and visibility issue
276 _UiAppImpl::OnTerminate(void)
278 SysLog(NID_APP, "Termination event 0x%x state", _AppInfo::GetAppState());
280 if (__pUiApp->GetAppUiState() == APP_UI_STATE_FOREGROUND)
285 if (OnUiAppImplTerminating() != true)
287 SysLog(NID_APP, "[E_SYSTEM] The Termination of application failed.");
293 _UiAppImpl::OnResume(void)
295 SysLog(NID_APP, "System resume event on 0x%x state", _AppInfo::GetAppState());
297 if (_AppInfo::GetAppState() == RUNNING)
305 _UiAppImpl::OnPause(void)
307 SysLog(NID_APP, "System pause event on 0x%x state", _AppInfo::GetAppState());
309 if (_AppInfo::GetAppState() == RUNNING)
317 _UiAppImpl::OnFrameRaiseRequested(void)
319 SysLog(NID_APP, "Frame raise is requested.");
321 Frame* pFrame = null;
322 if (__pFrameList == null || (pFrame = dynamic_cast<Frame*>(__pFrameList->GetAt(0))) == null)
324 SysLog(NID_APP, "No frame is available.");
328 if (__appUiState == APP_UI_STATE_FOREGROUND)
330 SysLog(NID_APP, "Already foreground state.");
340 _UiAppImpl::OnWindowHandleRequest(void)
343 int type = _AppInfo::GetAppType();
345 if (type & _APP_TYPE_IME_APP)
347 handle = GetTargetWindowHandle();
351 const _EcoreEvas* const pEvas = GetEcoreEvasMgr()->GetEcoreEvas();
352 handle = (pEvas) ? static_cast<long>(pEvas->GetXWindow()) : -1;
360 _UiAppImpl::AddFrame(const Frame& frame)
362 result r = E_SUCCESS;
363 Frame& tmpFrame = const_cast <Frame&>(frame);
365 SysTryReturnResult(NID_APP, __pFrameList != null, E_INVALID_STATE, "Getting FrameList failed.");
366 SysTryReturnResult(NID_APP, !__pFrameList->Contains(tmpFrame), E_OBJ_ALREADY_EXIST, "The frame is already registered.");
368 _WindowImpl* pFrameImpl = _WindowImpl::GetInstance(tmpFrame);
369 SysTryReturnResult(NID_APP, pFrameImpl != null, E_INVALID_ARG, "The frame is not constructed yet.");
371 __pFrameList->Add(tmpFrame);
372 r = pFrameImpl->Open(false); // Attach to the main tree without 'draw & show'.
375 SysLog(NID_UI, "Failed to attach frame.");
376 __pFrameList->Remove(tmpFrame);
384 _UiAppImpl::GetAppFrame(void)
386 SysTryReturn(NID_APP, __pFrameList != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Getting FrameList failed.");
387 int frameCount = __pFrameList->GetCount();
391 SysLogException(NID_APP, E_OBJ_NOT_FOUND, "There is no frame !!! use AddFrame() before call GetAppFrame()");
392 SysAssertf(false, "There is no frame !!! use AddFrame() before call GetAppFrame()");
395 Frame* pFrame = dynamic_cast <Frame*>(__pFrameList->GetAt(frameCount - 1));
399 SysLogException(NID_APP, E_OBJ_NOT_FOUND, "There is no frame !!! use AddFrame() before call GetAppFrame()");
400 SysAssertf(false, "There is no frame !!! use AddFrame() before call GetAppFrame()");
403 if (__pAppFrame == null)
405 __pAppFrame = new (std::nothrow) _AppFrame(*pFrame);
406 SysTryReturn(NID_APP, __pAppFrame != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
407 __pAppFrame->Construct();
409 else if (__pAppFrame->GetFrame() != pFrame)
411 __pAppFrame->SetFrame(pFrame);
419 _UiAppImpl::RemoveFrame(const Frame& frame)
421 result r = E_SUCCESS;
422 SysTryReturnResult(NID_APP, __pFrameList != null, E_INVALID_STATE, "Getting FrameList failed.");
424 Frame& tmpFrame = const_cast <Frame&>(frame);
425 _WindowImpl* pFrameImpl = _WindowImpl::GetInstance(tmpFrame);
427 r = __pFrameList->Remove(frame, false);
431 pFrameImpl->Destroy();
439 _UiAppImpl::RemoveAllFrames(void)
441 result r = E_SUCCESS;
442 SysTryReturnResult(NID_APP, __pFrameList != null, E_INVALID_STATE, "Getting FrameList failed.");
444 int frameCount = __pFrameList->GetCount();
445 for (int i = 0; i < frameCount; i++)
447 Frame* pFrame = dynamic_cast <Frame*>(__pFrameList->GetAt(i));
450 _WindowImpl* pFrameImpl = _WindowImpl::GetInstance(*pFrame);
453 pFrameImpl->Destroy();
458 if (__pFrameList->GetCount() > 0)
460 __pFrameList->RemoveAll(false);
471 _UiAppImpl::GetFrameList(void)
478 _UiAppImpl::GetFrame(const String& name)
480 Frame* pFrame = null;
481 SysTryReturn(NID_APP, __pFrameList != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Getting FrameList failed.");
482 int frameCount = __pFrameList->GetCount();
484 for (int i = 0; i < frameCount; i++)
486 pFrame = dynamic_cast <Frame*>(__pFrameList->GetAt(i));
488 if (pFrame != null && pFrame->GetName() == name)
499 _UiAppImpl::GetFrameAt(int index)
501 Frame* pFrame = null;
502 SysTryReturn(NID_APP, __pFrameList != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Getting FrameList failed.");
503 SysTryReturn(NID_APP, index >= 0, null, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The index is less than 0.");
505 int frameCount = __pFrameList->GetCount();
506 SysTryReturn(NID_APP, index < frameCount, null, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The index is greater than the number of frames.");
508 pFrame = dynamic_cast <Frame*>(__pFrameList->GetAt(index));
514 _UiAppImpl::OnAppInitializing(void)
516 // Do Ui related initializing for UiApp
517 result r = InitializeUiFramework();
520 SysLogException(NID_APP, E_SYSTEM, "Getting resolution information failure. Application may not be installed correctly.");
524 _KeyEventManager* pKeyManager = _KeyEventManager::GetInstance();
527 pKeyManager->AddKeyEventListener(*this);
530 // API versioning for initial frame creation
531 if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
532 { // if API version is less than 3.0, create initial frame
533 Frame* pDefaultFrame = new (std::nothrow) Frame();
534 SysTryReturn(NID_APP, pDefaultFrame != null, false, r = E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Frame creation failed.");
535 pDefaultFrame->Construct();
536 AddFrame(*pDefaultFrame);
537 SysLog(NID_APP, "Default frame is added for API version %d Compatibility.", _AppInfo::GetApiVersion());
540 SysTryReturn(NID_APP, __pUiApp != null, false, E_INVALID_STATE, "[E_INVALID_STATE] Getting UiApp instance failed.");
542 SysLog(NID_APP, "Entering user OnAppInitializing().");
543 const bool bReturn = __pUiApp->OnAppInitializing(*(AppRegistry::GetInstance()));
545 SysLog(NID_APP, "Back to the platform initializing routine.");
546 _SettingInfoImpl::AddSettingEventListenerForInternal(*this);
552 _UiAppImpl::OnAppInitialized(void)
554 SysTryReturn(NID_APP, __pUiApp != null, false, E_INVALID_STATE, "[E_INVALID_STATE] Getting UiApp instance failed.");
556 const bool b = __pUiApp->OnAppInitialized();
558 Frame* pFrame = dynamic_cast<Frame*>(__pFrameList->GetAt(0));
561 int type = _AppInfo::GetAppType();
562 if (type & _APP_TYPE_IME_APP)
564 SysLog(NID_APP, "Defering frame update for IME app.");
565 pFrame->SetShowState(false);
566 appcore_set_app_state(3);
572 if (__pFrameList->GetCount() > 0)
578 SysLogException(NID_APP, E_OBJ_NOT_FOUND, "There is no frame !!! use AddFrame() before returning OnAppInitialized()");
579 SysAssertf(false, "There is no frame !!! use AddFrame() before returning OnAppInitialized()");
587 _UiAppImpl::OnUiAppImplTerminating(void)
593 if (_AppInfo::GetAppState() != TERMINATED)
595 result = __pUiApp->OnAppTerminating(*(AppRegistry::GetInstance()), __pAppImpl->IsForcedTermination());
596 _AppInfo::SetAppState(TERMINATED);
599 // Do Ui related finalizing for UiApp
600 FinalizeUiFramework();
607 _UiAppImpl::OnKeyPressed(const _Control& source, const _KeyInfo& keyInfo)
614 _UiAppImpl::OnKeyReleased(const _Control& source, const _KeyInfo& keyInfo)
616 if (__appUiState == APP_UI_STATE_FOREGROUND)
618 if (keyInfo.GetKeyCode() == _KEY_END)
620 SysTryReturn(NID_APP, __pUiApp != null, false, E_INVALID_STATE, "[E_INVALID_STATE] Getting UI App instance failed.");
622 if (__pUiApp->OnAppWillTerminate())
624 __pUiApp->Terminate();
634 _UiAppImpl::OnForeground(void)
636 result r = E_SUCCESS;
638 SysLog(NID_APP, "Invoking application callback.");
640 __appUiState = APP_UI_STATE_FOREGROUND;
641 __pUiApp->OnForeground();
643 SysLog(NID_APP, "Returned from application callback.");
645 r = _PowerManagerImpl::OnForeground();
647 SysTryLog(NID_APP, !IsFailed(r), "Failed to send foreground event to powermanager");
652 _UiAppImpl::OnBackground(void)
654 result r = E_SUCCESS;
656 SysLog(NID_APP, "Invoking application callback.");
658 __appUiState = APP_UI_STATE_BACKGROUND;
659 __pUiApp->OnBackground();
661 SysLog(NID_APP, "Returned from application callback.");
663 r = _PowerManagerImpl::OnBackground();
665 SysTryLog(NID_APP, !IsFailed(r), "Failed to send background event to powermanager");
670 _UiAppImpl::GetAppUiState(void) const
677 _UiAppImpl::GetInstance(void)
684 _UiAppImpl::GetUiAppInstance(void)
690 _UiAppImpl::OnSettingChanged(String& key)
692 SysLog(NID_APP,"Changed Key: %ls", key.GetPointer());
694 if (key == L"http://tizen.org/setting/locale.language")
696 _AppImpl::OnLanguageChanged(null);