Tizen 2.1 base
[framework/osp/uifw.git] / src / app / FApp_UiAppImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17
18 /**
19  * @file        FApp_UiAppImpl.cpp
20  * @brief       This is the implementation for the _UiAppImpl class.
21  */
22
23 #include <bundle.h>
24 #include <appsvc/appsvc.h>
25
26 #include <FBaseSysLog.h>
27 #include <FBaseColArrayList.h>
28 #include <FAppAppRegistry.h>
29 #include <FUiCtrlFrame.h>
30
31 #include <FBaseRt_Process.h>
32 #include <FUi_ControlImplManager.h>
33 #include <FUi_KeyEventManager.h>
34 #include <FUi_WindowImpl.h>
35 #include <FUi_EcoreEvasMgr.h>
36 #include <FUi_EcoreEvas.h>
37 #include <FUiCtrl_FrameImpl.h>
38 #include <FSys_PowerManagerImpl.h>
39
40 #include "FApp_AppFrame.h"
41 #include "FApp_AppInfo.h"
42 #include "FApp_AppImpl.h"
43 #include "FApp_UiAppImpl.h"
44 #include "FApp_AppArg.h"
45
46 using namespace Tizen::App;
47 using namespace Tizen::Base;
48 using namespace Tizen::Base::Collection;
49 using namespace Tizen::Base::Runtime;
50 using namespace Tizen::Ui;
51 using namespace Tizen::Ui::Controls;
52 using namespace Tizen::System;
53 using namespace Tizen::Graphics;
54
55
56 extern "C" int appsvc_request_transient_app(bundle*, Ecore_X_Window, appsvc_host_res_fn, void*);
57
58 namespace Tizen { namespace App
59 {
60
61 _UiAppImpl* _UiAppImpl::__pUiAppImpl = null;
62
63
64 _UiAppImpl::_UiAppImpl(UiApp* pUiApp)
65         : __pAppFrame(null)
66         , __pAppImpl(_AppImpl::GetInstance())
67         , __appUiState(APP_UI_STATE_BACKGROUND)
68         , __pFrameList(null)
69         , __pUiApp(pUiApp)
70 {
71         __pUiAppImpl = this;
72         __pFrameList = new (std::nothrow) ArrayList();
73         SysTryReturnVoidResult(NID_APP, __pFrameList != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
74         __pFrameList->Construct();
75         SysTryReturnVoidResult(NID_APP, __pAppImpl != null, E_INVALID_STATE, "[E_INVALID_STATE] Getting internal instance failed.");
76 }
77
78
79 _UiAppImpl::~_UiAppImpl(void)
80 {
81         RemoveAllFrames();
82
83         delete __pAppFrame;
84         __pUiAppImpl = null;
85 }
86
87
88 bool
89 _UiAppImpl::OnCreate(void)
90 {
91         SysLog(NID_APP, "Platform creation event.");
92
93         _AppInfo::SetAppState(INITIALIZING);
94
95         return true;
96 }
97
98
99 static int
100 TransientResponseCb(void* pData)
101 {
102         SysLog(NID_APP, "Handling cleanup for submode app.");
103
104         // platform invokes ecore_main_loop_quit() after returning this callback
105         return 0;
106 }
107
108 void
109 _UiAppImpl::OnService(service_s* service, bool initial)
110 {
111         Frame* pFrame = dynamic_cast<Frame*>(__pFrameList->GetAt(0));
112
113         // [INFO] to confirm that the window is not foreground
114         _EcoreEvas* pEvas = GetEcoreEvasMgr()->GetEcoreEvas();
115         if (pEvas)
116         {
117                 int pid = pEvas->GetProcessId(pEvas->GetActiveWindow());
118                 SysLog(NID_APP, "%d -> %d", pid, _AppInfo::GetProcessId());
119                 if (pid != _AppInfo::GetProcessId())
120                 {
121                         if (!initial)
122                         {
123                                 if (pFrame != null)
124                                 {
125                                         _FrameImpl* pFrameImpl = _FrameImpl::GetInstance(*pFrame);
126
127                                         // [FIXME] Multi window handling
128                                         if (pFrameImpl != null)
129                                         {
130                                                 pEvas->ActivateWindow(pFrameImpl->GetCore());
131                                         }
132                                 }
133                         }
134                 }
135         }
136
137         // make OnForeground event
138         if (pFrame != null)
139         {
140                 // handle submode
141                 if (pEvas && _AppInfo::IsSubMode())
142                 {
143                         _FrameImpl* pFrameImpl = _FrameImpl::GetInstance(*pFrame);
144                         if (pFrameImpl != null)
145                         {
146                                 unsigned int curHandle = pFrameImpl->GetNativeHandle();
147
148                                 bundle* pBundle = _AppArg::GetBundleFromSvc(service);
149                                 int ret = appsvc_request_transient_app(pBundle, curHandle, TransientResponseCb, NULL);
150
151                                 SysLog(NID_APP, "Transient sets for (0x%x) with result (%d).", curHandle, ret);
152                         }
153                 }
154
155                 OnResume();
156                 //pFrame->Show();
157         }
158 }
159
160
161 void
162 _UiAppImpl::OnTerminate(void)
163 {
164         SysLog(NID_APP, "Termination event 0x%x state", _AppInfo::GetAppState());
165
166         if (OnUiAppImplTerminating() != true)
167         {
168                 SysLog(NID_APP, "[E_SYSTEM] The Termination of application failed.");
169         }
170 }
171
172
173 void
174 _UiAppImpl::OnResume(void)
175 {
176         SysLog(NID_APP, "System resume event on 0x%x state", _AppInfo::GetAppState());
177
178         if (_AppInfo::GetAppState() == RUNNING)
179         {
180                 OnForeground();
181         }
182 }
183
184
185 void
186 _UiAppImpl::OnPause(void)
187 {
188         SysLog(NID_APP, "System pause event on 0x%x state", _AppInfo::GetAppState());
189
190         if (_AppInfo::GetAppState() == RUNNING)
191         {
192                 OnBackground();
193         }
194 }
195
196
197 void
198 _UiAppImpl::OnDeviceOrientationChanged(app_device_orientation_e orientation)
199 {
200         SysLog(NID_APP, "System device orientation event.");
201
202         _ControlImplManager* pControlImplManager = _ControlImplManager::GetInstance();
203         if (pControlImplManager == null)
204         {
205                 SysLog(NID_APP, "Device orientation event arrived too early.");
206                 return;
207         }
208
209         pControlImplManager->OnScreenRotated(orientation);
210 }
211
212
213 long
214 _UiAppImpl::OnWindowHandleRequest(void)
215 {
216         const _EcoreEvas* const pEvas = GetEcoreEvasMgr()->GetEcoreEvas();
217         return (pEvas) ? static_cast<long>(pEvas->GetXWindow()) : -1;
218 }
219
220
221 result
222 _UiAppImpl::AddFrame(const Frame& frame)
223 {
224         result r = E_SUCCESS;
225         Frame& tmpFrame = const_cast <Frame&>(frame);
226
227         SysTryReturnResult(NID_APP, __pFrameList != null, E_INVALID_STATE, "Getting FrameList failed.");
228         SysTryReturnResult(NID_APP, !__pFrameList->Contains(tmpFrame), E_OBJ_ALREADY_EXIST, "The frame is already registered.");
229
230         _WindowImpl* pFrameImpl = _WindowImpl::GetInstance(tmpFrame);
231         SysTryReturnResult(NID_APP, pFrameImpl != null, E_INVALID_ARG, "The frame is not constructed yet.");
232
233         __pFrameList->Add(tmpFrame);
234         r = pFrameImpl->Open(false); // Attach to the main tree without 'draw & show'.
235         if (IsFailed(r))
236         {
237                 SysLog(NID_UI, "Failed to attach frame.");
238                 __pFrameList->Remove(tmpFrame);
239         }
240
241         return r;
242 }
243
244
245 IAppFrame*
246 _UiAppImpl::GetAppFrame(void)
247 {
248         SysTryReturn(NID_APP, __pFrameList != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Getting FrameList failed.");
249         int frameCount = __pFrameList->GetCount();
250
251         if (frameCount <= 0)
252         {
253                 SysLogException(NID_APP, E_OBJ_NOT_FOUND, "There is no frame !!! use AddFrame() before call GetAppFrame()");
254                 SysAssertf(false, "There is no frame !!! use AddFrame() before call GetAppFrame()");
255         }
256
257         Frame* pFrame = dynamic_cast <Frame*>(__pFrameList->GetAt(frameCount - 1));
258
259         if (pFrame == null)
260         {
261                 SysLogException(NID_APP, E_OBJ_NOT_FOUND, "There is no frame !!! use AddFrame() before call GetAppFrame()");
262                 SysAssertf(false, "There is no frame !!! use AddFrame() before call GetAppFrame()");
263         }
264
265         if (__pAppFrame == null)
266         {
267                 __pAppFrame = new (std::nothrow) _AppFrame(*pFrame);
268                 SysTryReturn(NID_APP, __pAppFrame != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
269                 __pAppFrame->Construct();
270         }
271         else if (__pAppFrame->GetFrame() != pFrame)
272         {
273                 __pAppFrame->SetFrame(pFrame);
274         }
275
276         return __pAppFrame;
277 }
278
279
280 result
281 _UiAppImpl::RemoveFrame(const Frame& frame)
282 {
283         result r = E_SUCCESS;
284         SysTryReturnResult(NID_APP, __pFrameList != null, E_INVALID_STATE, "Getting FrameList failed.");
285
286         r = __pFrameList->Remove(frame);
287         if (!IsFailed(r))
288         {
289                 delete &frame;
290         }
291
292         return r;
293 }
294
295
296 result
297 _UiAppImpl::RemoveAllFrames(void)
298 {
299         result r = E_SUCCESS;
300         SysTryReturnResult(NID_APP, __pFrameList != null, E_INVALID_STATE, "Getting FrameList failed.");
301
302         if (__pFrameList->GetCount() > 0)
303         {
304                 __pFrameList->RemoveAll(true);
305         }
306
307         delete __pFrameList;
308         __pFrameList = null;
309
310         return r;
311 }
312
313
314 IList*
315 _UiAppImpl::GetFrameList(void)
316 {
317         return __pFrameList;
318 }
319
320
321 Frame*
322 _UiAppImpl::GetFrame(const String& name)
323 {
324         Frame* pFrame = null;
325         SysTryReturn(NID_APP, __pFrameList != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Getting FrameList failed.");
326         int frameCount = __pFrameList->GetCount();
327
328         for (int i = 0; i < frameCount; i++)
329         {
330                 pFrame = dynamic_cast <Frame*>(__pFrameList->GetAt(i));
331
332                 if (pFrame != null && pFrame->GetName() == name)
333                 {
334                         return pFrame;
335                 }
336         }
337
338         return null;
339 }
340
341
342 Frame*
343 _UiAppImpl::GetFrameAt(int index)
344 {
345         Frame* pFrame = null;
346         SysTryReturn(NID_APP, __pFrameList != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Getting FrameList failed.");
347         SysTryReturn(NID_APP, index >= 0, null, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The index is less than 0.");
348
349         int frameCount = __pFrameList->GetCount();
350         SysTryReturn(NID_APP, index < frameCount, null, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The index is greater than the number of frames.");
351
352         pFrame = dynamic_cast <Frame*>(__pFrameList->GetAt(index));
353
354         return pFrame;
355 }
356
357 // For header inclusion dependency, elementary-1/elm_config.h is not included
358 extern "C" const char* elm_config_preferred_engine_set(const char*);
359
360 bool
361 _UiAppImpl::OnAppInitializing(void)
362 {
363         // Do Ui related initializing for UiApp
364         result r = InitializeUiFramework();
365         if (IsFailed(r))
366         {
367                 SysLogException(NID_APP, E_SYSTEM, "Getting resolution information failure. Application may not be installed correctly.");
368                 _Process::Exit(-1);
369         }
370
371         _KeyEventManager* pKeyManager = _KeyEventManager::GetInstance();
372         if (pKeyManager)
373         {
374                 pKeyManager->AddKeyEventListener(*this);
375         }
376
377         // API versioning for initial frame creation
378   if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
379         {       // if API version is less than 3.0, create initial frame
380                 Frame* pDefaultFrame = new (std::nothrow) Frame();
381                 SysTryReturn(NID_APP, pDefaultFrame != null, false, r = E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Frame creation failed.");
382                 pDefaultFrame->Construct();
383                 AddFrame(*pDefaultFrame);
384                 SysLog(NID_APP, "Default frame is added for API version %d.", _AppInfo::GetApiVersion());
385         }
386
387         SysTryReturn(NID_APP, __pUiApp != null, false, E_INVALID_STATE, "[E_INVALID_STATE] Getting UiApp instance failed.");
388
389         SysLog(NID_APP, "Entering user OnAppInitializing().");
390         const bool bReturn = __pUiApp->OnAppInitializing(*(AppRegistry::GetInstance()));
391
392         SysLog(NID_APP, "Back to the platform initializing routine.");
393         return bReturn;
394 }
395
396
397 bool
398 _UiAppImpl::OnAppInitialized(void)
399 {
400         SysTryReturn(NID_APP, __pUiApp != null, false, E_INVALID_STATE, "[E_INVALID_STATE] Getting UiApp instance failed.");
401
402         if (__pUiApp->OnAppInitialized())
403         {
404                 if (__pFrameList->GetCount() > 0)
405                 {
406                         return true;
407                 }
408                 else
409                 {
410                         SysLogException(NID_APP, E_OBJ_NOT_FOUND, "There is no frame !!! use AddFrame() before returning OnAppInitialized()");
411                         SysAssertf(false, "There is no frame !!! use AddFrame() before returning OnAppInitialized()");
412                 }
413         }
414         return false;
415 }
416
417
418 bool
419 _UiAppImpl::OnUiAppImplTerminating(void)
420 {
421         bool result = false;
422
423         RemoveAllFrames();
424
425         if (_AppInfo::GetAppState() != TERMINATED)
426         {
427                 result = __pUiApp->OnAppTerminating(*(AppRegistry::GetInstance()), false);
428                 _AppInfo::SetAppState(TERMINATED);
429         }
430
431         // Do Ui related finalizing for UiApp
432         FinalizeUiFramework();
433
434         return result;
435 }
436
437
438 bool
439 _UiAppImpl::OnKeyPressed(const _Control& source, const _KeyInfo& keyInfo)
440 {
441         return false;
442 }
443
444
445 bool
446 _UiAppImpl::OnKeyReleased(const _Control& source, const _KeyInfo& keyInfo)
447 {
448         if (__appUiState == APP_UI_STATE_FOREGROUND)
449         {
450                 if (keyInfo.GetKeyCode() == _KEY_END)
451                 {
452                         SysTryReturn(NID_APP, __pUiApp != null, false, E_INVALID_STATE, "[E_INVALID_STATE] Getting UI App instance failed.");
453
454                         if (__pUiApp->OnAppWillTerminate())
455                         {
456                                 __pUiApp->Terminate();
457                                 return true;
458                         }
459                 }
460         }
461         return false;
462 }
463
464
465 void
466 _UiAppImpl::OnForeground(void)
467 {
468         result r = E_SUCCESS;
469
470         SysLog(NID_APP, "Invoking application callback.");
471
472         __appUiState = APP_UI_STATE_FOREGROUND;
473         __pUiApp->OnForeground();
474
475         SysLog(NID_APP, "Returned from application callback.");
476
477         r = _PowerManagerImpl::OnForeground();
478
479         SysTryLog(NID_APP, !IsFailed(r), "Failed to send foreground event to powermanager");
480 }
481
482
483 void
484 _UiAppImpl::OnBackground(void)
485 {
486         result r = E_SUCCESS;
487
488         SysLog(NID_APP, "Invoking application callback.");
489
490         __appUiState = APP_UI_STATE_BACKGROUND;
491         __pUiApp->OnBackground();
492
493         SysLog(NID_APP, "Returned from application callback.");
494
495         r = _PowerManagerImpl::OnBackground();
496
497         SysTryLog(NID_APP, !IsFailed(r), "Failed to send background event to powermanager");
498 }
499
500
501 AppUiState
502 _UiAppImpl::GetAppUiState(void) const
503 {
504         return __appUiState;
505 }
506
507
508 _UiAppImpl*
509 _UiAppImpl::GetInstance(void)
510 {
511         return __pUiAppImpl;
512 }
513
514
515 UiApp*
516 _UiAppImpl::GetUiAppInstance(void)
517 {
518         return __pUiApp;
519 }
520
521
522 } } //Tizen::App