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 const int type = _AppInfo::GetAppType();
193 if (type & _APP_TYPE_IME_APP)
195 bundle* pBundle = _AppArg::GetBundleFromSvc(service);
196 const int pid = _AppArg::GetCallerPid(pBundle);
199 SysLogException(NID_APP, E_SYSTEM, "ImeApp should not be the target for launch API (caller : %d).", pid);
204 // make OnForeground event
208 if (pEvas && _AppInfo::IsSubMode())
210 unsigned int win = 0;
211 service_get_window(service, &win);
213 _FrameImpl* pFrameImpl = _FrameImpl::GetInstance(*pFrame);
214 if (static_cast<int>(win) > 0 && pFrameImpl != null)
216 const unsigned int curHandle = pFrameImpl->GetNativeHandle();
218 bundle* pBundle = _AppArg::GetBundleFromSvc(service);
219 const int pid = _AppArg::GetCallerPid(pBundle);
220 if (pid <= 0 || ((kill(pid, 0) < 0) && errno == ESRCH))
222 SysLogException(NID_APP, E_SYSTEM, "Caller process %d with %d not exist : terminating %d.", pid, win, getpid());
226 int ret = appsvc_request_transient_app(pBundle, curHandle, TransientResponseCb, NULL);
228 SysLog(NID_APP, "Transient sets for (0x%x) with result (%d).", curHandle, ret);
234 const int type = _AppInfo::GetAppType();
235 if (type & _APP_TYPE_IME_APP)
237 SysLog(NID_APP, "Skipping 1st resume for IME app.");
246 // [INFO] to confirm that the window is not foreground
249 int pid = pEvas->GetProcessId(pEvas->GetActiveWindow());
250 SysLog(NID_APP, "%d -> %d", pid, _AppInfo::GetProcessId());
251 if (pid != _AppInfo::GetProcessId())
257 _FrameImpl* pFrameImpl = _FrameImpl::GetInstance(*pFrame);
259 // [FIXME] Multi window handling
260 if (pFrameImpl != null)
262 //pEvas->ActivateWindow(pFrameImpl->GetCore());
264 unique_ptr<ArrayList> pEventArgs(new (std::nothrow) ArrayList());
265 SysTryReturnVoidResult(NID_APP, pEventArgs, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
266 pEventArgs->Construct();
268 unique_ptr<String> pString(new (std::nothrow) Tizen::Base::String(L"ActivateFrame"));
269 SysTryReturnVoidResult(NID_APP, pString, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
271 pEventArgs->Add(*(pString.get()));
273 _UiNotificationEvent event(pFrameImpl->GetCore().GetHandle(), pEventArgs.get());
275 result r = _UiEventManager::GetInstance()->PostEvent(event);
276 SysTryReturnVoidResult(NID_APP, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] A system error occurred.");
279 pEventArgs.release();
281 // N_SE-24616, N_SE-24383 for OnForground() and visibility issue
292 _UiAppImpl::OnTerminate(void)
294 SysLog(NID_APP, "Termination event 0x%x state", _AppInfo::GetAppState());
296 if (__pUiApp->GetAppUiState() == APP_UI_STATE_FOREGROUND)
301 if (OnUiAppImplTerminating() != true)
303 SysLog(NID_APP, "[E_SYSTEM] The Termination of application failed.");
309 _UiAppImpl::OnResume(void)
311 SysLog(NID_APP, "System resume event on 0x%x state", _AppInfo::GetAppState());
313 if (_AppInfo::GetAppState() == RUNNING)
321 _UiAppImpl::OnPause(void)
323 SysLog(NID_APP, "System pause event on 0x%x state", _AppInfo::GetAppState());
325 if (_AppInfo::GetAppState() == RUNNING)
333 _UiAppImpl::OnFrameRaiseRequested(void)
335 SysLog(NID_APP, "Frame raise is requested.");
337 Frame* pFrame = null;
338 if (__pFrameList == null || (pFrame = dynamic_cast<Frame*>(__pFrameList->GetAt(0))) == null)
340 SysLog(NID_APP, "No frame is available.");
344 if (__appUiState == APP_UI_STATE_FOREGROUND)
346 SysLog(NID_APP, "Already foreground state.");
356 _UiAppImpl::OnWindowHandleRequest(void)
359 const int type = _AppInfo::GetAppType();
361 if (type & _APP_TYPE_IME_APP)
363 handle = GetTargetWindowHandle();
367 const _EcoreEvas* const pEvas = GetEcoreEvasMgr()->GetEcoreEvas();
368 handle = (pEvas) ? static_cast<long>(pEvas->GetXWindow()) : -1;
376 _UiAppImpl::AddFrame(const Frame& frame)
378 result r = E_SUCCESS;
379 Frame& tmpFrame = const_cast <Frame&>(frame);
381 SysTryReturnResult(NID_APP, __pFrameList != null, E_INVALID_STATE, "Getting FrameList failed.");
382 SysTryReturnResult(NID_APP, !__pFrameList->Contains(tmpFrame), E_OBJ_ALREADY_EXIST, "The frame is already registered.");
384 _WindowImpl* pFrameImpl = _WindowImpl::GetInstance(tmpFrame);
385 SysTryReturnResult(NID_APP, pFrameImpl != null, E_INVALID_ARG, "The frame is not constructed yet.");
387 __pFrameList->Add(tmpFrame);
388 r = pFrameImpl->Open(false); // Attach to the main tree without 'draw & show'.
391 SysLog(NID_UI, "Failed to attach frame.");
392 __pFrameList->Remove(tmpFrame);
400 _UiAppImpl::GetAppFrame(void)
402 SysTryReturn(NID_APP, __pFrameList != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Getting FrameList failed.");
403 int frameCount = __pFrameList->GetCount();
407 SysLogException(NID_APP, E_OBJ_NOT_FOUND, "There is no frame !!! use AddFrame() before call GetAppFrame()");
408 SysAssertf(false, "There is no frame !!! use AddFrame() before call GetAppFrame()");
411 Frame* pFrame = dynamic_cast <Frame*>(__pFrameList->GetAt(frameCount - 1));
415 SysLogException(NID_APP, E_OBJ_NOT_FOUND, "There is no frame !!! use AddFrame() before call GetAppFrame()");
416 SysAssertf(false, "There is no frame !!! use AddFrame() before call GetAppFrame()");
419 if (__pAppFrame == null)
421 __pAppFrame = new (std::nothrow) _AppFrame(*pFrame);
422 SysTryReturn(NID_APP, __pAppFrame != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
423 __pAppFrame->Construct();
425 else if (__pAppFrame->GetFrame() != pFrame)
427 __pAppFrame->SetFrame(pFrame);
435 _UiAppImpl::RemoveFrame(const Frame& frame)
437 result r = E_SUCCESS;
438 SysTryReturnResult(NID_APP, __pFrameList != null, E_INVALID_STATE, "Getting FrameList failed.");
440 Frame& tmpFrame = const_cast <Frame&>(frame);
441 _WindowImpl* pFrameImpl = _WindowImpl::GetInstance(tmpFrame);
443 r = __pFrameList->Remove(frame, false);
447 pFrameImpl->Destroy();
455 _UiAppImpl::RemoveAllFrames(void)
457 result r = E_SUCCESS;
458 SysTryReturnResult(NID_APP, __pFrameList != null, E_INVALID_STATE, "Getting FrameList failed.");
460 int frameCount = __pFrameList->GetCount();
461 for (int i = 0; i < frameCount; i++)
463 Frame* pFrame = dynamic_cast <Frame*>(__pFrameList->GetAt(i));
466 _WindowImpl* pFrameImpl = _WindowImpl::GetInstance(*pFrame);
469 pFrameImpl->Destroy();
474 if (__pFrameList->GetCount() > 0)
476 __pFrameList->RemoveAll(false);
487 _UiAppImpl::GetFrameList(void)
494 _UiAppImpl::GetFrame(const String& name)
496 Frame* pFrame = null;
497 SysTryReturn(NID_APP, __pFrameList != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Getting FrameList failed.");
498 int frameCount = __pFrameList->GetCount();
500 for (int i = 0; i < frameCount; i++)
502 pFrame = dynamic_cast <Frame*>(__pFrameList->GetAt(i));
504 if (pFrame != null && pFrame->GetName() == name)
515 _UiAppImpl::GetFrameAt(int index)
517 Frame* pFrame = null;
518 SysTryReturn(NID_APP, __pFrameList != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Getting FrameList failed.");
519 SysTryReturn(NID_APP, index >= 0, null, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The index is less than 0.");
521 int frameCount = __pFrameList->GetCount();
522 SysTryReturn(NID_APP, index < frameCount, null, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The index is greater than the number of frames.");
524 pFrame = dynamic_cast <Frame*>(__pFrameList->GetAt(index));
530 _UiAppImpl::OnAppInitializing(void)
532 // Do Ui related initializing for UiApp
533 result r = InitializeUiFramework();
536 SysLogException(NID_APP, E_SYSTEM, "Getting resolution information failure. Application may not be installed correctly.");
540 _KeyEventManager* pKeyManager = _KeyEventManager::GetInstance();
543 pKeyManager->AddKeyEventListener(*this);
546 // API versioning for initial frame creation
547 if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
548 { // if API version is less than 3.0, create initial frame
549 Frame* pDefaultFrame = new (std::nothrow) Frame();
550 SysTryReturn(NID_APP, pDefaultFrame != null, false, r = E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Frame creation failed.");
551 pDefaultFrame->Construct();
552 AddFrame(*pDefaultFrame);
553 SysLog(NID_APP, "Default frame is added for API version %d Compatibility.", _AppInfo::GetApiVersion());
556 SysTryReturn(NID_APP, __pUiApp != null, false, E_INVALID_STATE, "[E_INVALID_STATE] Getting UiApp instance failed.");
558 SysLog(NID_APP, "Entering user OnAppInitializing().");
559 const bool bReturn = __pUiApp->OnAppInitializing(*(AppRegistry::GetInstance()));
561 SysLog(NID_APP, "Back to the platform initializing routine.");
562 _SettingInfoImpl::AddSettingEventListenerForInternal(*this);
568 _UiAppImpl::OnAppInitialized(void)
570 SysTryReturn(NID_APP, __pUiApp != null, false, E_INVALID_STATE, "[E_INVALID_STATE] Getting UiApp instance failed.");
572 const bool b = __pUiApp->OnAppInitialized();
574 Frame* pFrame = dynamic_cast<Frame*>(__pFrameList->GetAt(0));
577 int type = _AppInfo::GetAppType();
578 if (type & _APP_TYPE_IME_APP)
580 SysLog(NID_APP, "Defering frame update for IME app.");
581 pFrame->SetShowState(false);
582 appcore_set_app_state(3);
588 if (__pFrameList->GetCount() > 0)
594 SysLogException(NID_APP, E_OBJ_NOT_FOUND, "There is no frame !!! use AddFrame() before returning OnAppInitialized()");
595 SysAssertf(false, "There is no frame !!! use AddFrame() before returning OnAppInitialized()");
603 _UiAppImpl::OnUiAppImplTerminating(void)
609 if (_AppInfo::GetAppState() != TERMINATED)
611 result = __pUiApp->OnAppTerminating(*(AppRegistry::GetInstance()), __pAppImpl->IsForcedTermination());
612 _AppInfo::SetAppState(TERMINATED);
615 // Do Ui related finalizing for UiApp
616 FinalizeUiFramework();
623 _UiAppImpl::OnKeyPressed(const _Control& source, const _KeyInfo& keyInfo)
630 _UiAppImpl::OnKeyReleased(const _Control& source, const _KeyInfo& keyInfo)
632 if (__appUiState == APP_UI_STATE_FOREGROUND)
634 if (keyInfo.GetKeyCode() == _KEY_END)
636 SysTryReturn(NID_APP, __pUiApp != null, false, E_INVALID_STATE, "[E_INVALID_STATE] Getting UI App instance failed.");
638 if (__pUiApp->OnAppWillTerminate())
640 __pUiApp->Terminate();
650 _UiAppImpl::OnForeground(void)
652 result r = E_SUCCESS;
654 SysLog(NID_APP, "Invoking application callback.");
656 __appUiState = APP_UI_STATE_FOREGROUND;
657 __pUiApp->OnForeground();
659 SysLog(NID_APP, "Returned from application callback.");
661 r = _PowerManagerImpl::OnForeground();
663 SysTryLog(NID_APP, !IsFailed(r), "Failed to send foreground event to powermanager");
668 _UiAppImpl::OnBackground(void)
670 result r = E_SUCCESS;
672 SysLog(NID_APP, "Invoking application callback.");
674 __appUiState = APP_UI_STATE_BACKGROUND;
675 __pUiApp->OnBackground();
677 SysLog(NID_APP, "Returned from application callback.");
679 r = _PowerManagerImpl::OnBackground();
681 SysTryLog(NID_APP, !IsFailed(r), "Failed to send background event to powermanager");
686 _UiAppImpl::GetAppUiState(void) const
693 _UiAppImpl::GetInstance(void)
700 _UiAppImpl::GetUiAppInstance(void)
706 _UiAppImpl::OnSettingChanged(String& key)
708 SysLog(NID_APP,"Changed Key: %ls", key.GetPointer());
710 if (key == L"http://tizen.org/setting/locale.language")
712 _AppImpl::OnLanguageChanged(null);