Adjust the position of the partial Frame
[platform/framework/native/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         _EcoreEvas* pEvas = GetEcoreEvasMgr()->GetEcoreEvas();
113
114         // make OnForeground event
115         if (pFrame != null)
116         {
117                 // handle submode
118                 if (pEvas && _AppInfo::IsSubMode())
119                 {
120                         _FrameImpl* pFrameImpl = _FrameImpl::GetInstance(*pFrame);
121                         if (pFrameImpl != null)
122                         {
123                                 unsigned int curHandle = pFrameImpl->GetNativeHandle();
124
125                                 bundle* pBundle = _AppArg::GetBundleFromSvc(service);
126                                 int ret = appsvc_request_transient_app(pBundle, curHandle, TransientResponseCb, NULL);
127
128                                 SysLog(NID_APP, "Transient sets for (0x%x) with result (%d).", curHandle, ret);
129                         }
130                 }
131
132                 if (initial)
133                 {
134                         const int type = _AppInfo::GetAppType();
135                         if (type & _APP_TYPE_IME_APP)
136                         {
137                                 SysLog(NID_APP, "Skipping 1st resume for IME app.");
138                         }
139                         else
140                         {
141                                 OnResume();
142                         }
143                 }
144         }
145
146         // [INFO] to confirm that the window is not foreground
147         if (pEvas)
148         {
149                 int pid = pEvas->GetProcessId(pEvas->GetActiveWindow());
150                 SysLog(NID_APP, "%d -> %d", pid, _AppInfo::GetProcessId());
151                 if (pid != _AppInfo::GetProcessId())
152                 {
153                         if (!initial)
154                         {
155                                 if (pFrame != null)
156                                 {
157                                         _FrameImpl* pFrameImpl = _FrameImpl::GetInstance(*pFrame);
158
159                                         // [FIXME] Multi window handling
160                                         if (pFrameImpl != null)
161                                         {
162                                                 // N_SE-24616, N_SE-24383 for OnForground() and visibility issue
163                                                 OnResume();
164                                                 pEvas->ActivateWindow(pFrameImpl->GetCore());
165                                         }
166                                 }
167                         }
168                 }
169         }
170 }
171
172
173 void
174 _UiAppImpl::OnTerminate(void)
175 {
176         SysLog(NID_APP, "Termination event 0x%x state", _AppInfo::GetAppState());
177
178         if (__pUiApp->GetAppUiState() == APP_UI_STATE_FOREGROUND)
179         {
180                 OnPause();
181         }
182
183         if (OnUiAppImplTerminating() != true)
184         {
185                 SysLog(NID_APP, "[E_SYSTEM] The Termination of application failed.");
186         }
187 }
188
189
190 void
191 _UiAppImpl::OnResume(void)
192 {
193         SysLog(NID_APP, "System resume event on 0x%x state", _AppInfo::GetAppState());
194
195         if (_AppInfo::GetAppState() == RUNNING)
196         {
197                 OnForeground();
198         }
199 }
200
201
202 void
203 _UiAppImpl::OnPause(void)
204 {
205         SysLog(NID_APP, "System pause event on 0x%x state", _AppInfo::GetAppState());
206
207         if (_AppInfo::GetAppState() == RUNNING)
208         {
209                 OnBackground();
210         }
211 }
212
213
214 void
215 _UiAppImpl::OnDeviceOrientationChanged(app_device_orientation_e orientation)
216 {
217         SysLog(NID_APP, "System device orientation event.");
218
219         _ControlImplManager* pControlImplManager = _ControlImplManager::GetInstance();
220         if (pControlImplManager == null)
221         {
222                 SysLog(NID_APP, "Device orientation event arrived too early.");
223                 return;
224         }
225
226         pControlImplManager->OnScreenRotated(orientation);
227 }
228
229
230 long
231 _UiAppImpl::OnWindowHandleRequest(void)
232 {
233         const _EcoreEvas* const pEvas = GetEcoreEvasMgr()->GetEcoreEvas();
234         return (pEvas) ? static_cast<long>(pEvas->GetXWindow()) : -1;
235 }
236
237
238 result
239 _UiAppImpl::AddFrame(const Frame& frame)
240 {
241         result r = E_SUCCESS;
242         Frame& tmpFrame = const_cast <Frame&>(frame);
243
244         SysTryReturnResult(NID_APP, __pFrameList != null, E_INVALID_STATE, "Getting FrameList failed.");
245         SysTryReturnResult(NID_APP, !__pFrameList->Contains(tmpFrame), E_OBJ_ALREADY_EXIST, "The frame is already registered.");
246
247         _WindowImpl* pFrameImpl = _WindowImpl::GetInstance(tmpFrame);
248         SysTryReturnResult(NID_APP, pFrameImpl != null, E_INVALID_ARG, "The frame is not constructed yet.");
249
250         __pFrameList->Add(tmpFrame);
251         r = pFrameImpl->Open(false); // Attach to the main tree without 'draw & show'.
252         if (IsFailed(r))
253         {
254                 SysLog(NID_UI, "Failed to attach frame.");
255                 __pFrameList->Remove(tmpFrame);
256         }
257
258         return r;
259 }
260
261
262 IAppFrame*
263 _UiAppImpl::GetAppFrame(void)
264 {
265         SysTryReturn(NID_APP, __pFrameList != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Getting FrameList failed.");
266         int frameCount = __pFrameList->GetCount();
267
268         if (frameCount <= 0)
269         {
270                 SysLogException(NID_APP, E_OBJ_NOT_FOUND, "There is no frame !!! use AddFrame() before call GetAppFrame()");
271                 SysAssertf(false, "There is no frame !!! use AddFrame() before call GetAppFrame()");
272         }
273
274         Frame* pFrame = dynamic_cast <Frame*>(__pFrameList->GetAt(frameCount - 1));
275
276         if (pFrame == null)
277         {
278                 SysLogException(NID_APP, E_OBJ_NOT_FOUND, "There is no frame !!! use AddFrame() before call GetAppFrame()");
279                 SysAssertf(false, "There is no frame !!! use AddFrame() before call GetAppFrame()");
280         }
281
282         if (__pAppFrame == null)
283         {
284                 __pAppFrame = new (std::nothrow) _AppFrame(*pFrame);
285                 SysTryReturn(NID_APP, __pAppFrame != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
286                 __pAppFrame->Construct();
287         }
288         else if (__pAppFrame->GetFrame() != pFrame)
289         {
290                 __pAppFrame->SetFrame(pFrame);
291         }
292
293         return __pAppFrame;
294 }
295
296
297 result
298 _UiAppImpl::RemoveFrame(const Frame& frame)
299 {
300         result r = E_SUCCESS;
301         SysTryReturnResult(NID_APP, __pFrameList != null, E_INVALID_STATE, "Getting FrameList failed.");
302
303         Frame& tmpFrame = const_cast <Frame&>(frame);
304         _WindowImpl* pFrameImpl = _WindowImpl::GetInstance(tmpFrame);
305
306         r = __pFrameList->Remove(frame, false);
307
308         if (pFrameImpl)
309         {
310                 pFrameImpl->Destroy();
311         }
312
313         return r;
314 }
315
316
317 result
318 _UiAppImpl::RemoveAllFrames(void)
319 {
320         result r = E_SUCCESS;
321         SysTryReturnResult(NID_APP, __pFrameList != null, E_INVALID_STATE, "Getting FrameList failed.");
322         
323         int frameCount = __pFrameList->GetCount();
324         for (int i = 0; i < frameCount; i++)
325         {
326                 Frame* pFrame = dynamic_cast <Frame*>(__pFrameList->GetAt(i));
327                 if (pFrame)
328                 {
329                         _WindowImpl* pFrameImpl = _WindowImpl::GetInstance(*pFrame);
330                         if (pFrameImpl)
331                         {
332                                 pFrameImpl->Destroy();
333                         }
334                 }
335         }
336
337         if (__pFrameList->GetCount() > 0)
338         {
339                 __pFrameList->RemoveAll(false);
340         }
341
342         delete __pFrameList;
343         __pFrameList = null;
344
345         return r;
346 }
347
348
349 IList*
350 _UiAppImpl::GetFrameList(void)
351 {
352         return __pFrameList;
353 }
354
355
356 Frame*
357 _UiAppImpl::GetFrame(const String& name)
358 {
359         Frame* pFrame = null;
360         SysTryReturn(NID_APP, __pFrameList != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Getting FrameList failed.");
361         int frameCount = __pFrameList->GetCount();
362
363         for (int i = 0; i < frameCount; i++)
364         {
365                 pFrame = dynamic_cast <Frame*>(__pFrameList->GetAt(i));
366
367                 if (pFrame != null && pFrame->GetName() == name)
368                 {
369                         return pFrame;
370                 }
371         }
372
373         return null;
374 }
375
376
377 Frame*
378 _UiAppImpl::GetFrameAt(int index)
379 {
380         Frame* pFrame = null;
381         SysTryReturn(NID_APP, __pFrameList != null, null, E_INVALID_STATE, "[E_INVALID_STATE] Getting FrameList failed.");
382         SysTryReturn(NID_APP, index >= 0, null, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The index is less than 0.");
383
384         int frameCount = __pFrameList->GetCount();
385         SysTryReturn(NID_APP, index < frameCount, null, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The index is greater than the number of frames.");
386
387         pFrame = dynamic_cast <Frame*>(__pFrameList->GetAt(index));
388
389         return pFrame;
390 }
391
392 bool
393 _UiAppImpl::OnAppInitializing(void)
394 {
395         // Do Ui related initializing for UiApp
396         result r = InitializeUiFramework();
397         if (IsFailed(r))
398         {
399                 SysLogException(NID_APP, E_SYSTEM, "Getting resolution information failure. Application may not be installed correctly.");
400                 _Process::Exit(-1);
401         }
402
403         _KeyEventManager* pKeyManager = _KeyEventManager::GetInstance();
404         if (pKeyManager)
405         {
406                 pKeyManager->AddKeyEventListener(*this);
407         }
408
409         // API versioning for initial frame creation
410         if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
411         {       // if API version is less than 3.0, create initial frame
412                 Frame* pDefaultFrame = new (std::nothrow) Frame();
413                 SysTryReturn(NID_APP, pDefaultFrame != null, false, r = E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Frame creation failed.");
414                 pDefaultFrame->Construct();
415                 AddFrame(*pDefaultFrame);
416                 SysLog(NID_APP, "Default frame is added for API version %d Compatibility.", _AppInfo::GetApiVersion());
417         }
418
419         SysTryReturn(NID_APP, __pUiApp != null, false, E_INVALID_STATE, "[E_INVALID_STATE] Getting UiApp instance failed.");
420
421         SysLog(NID_APP, "Entering user OnAppInitializing().");
422         const bool bReturn = __pUiApp->OnAppInitializing(*(AppRegistry::GetInstance()));
423
424         SysLog(NID_APP, "Back to the platform initializing routine.");
425         return bReturn;
426 }
427
428
429 bool
430 _UiAppImpl::OnAppInitialized(void)
431 {
432         SysTryReturn(NID_APP, __pUiApp != null, false, E_INVALID_STATE, "[E_INVALID_STATE] Getting UiApp instance failed.");
433
434         const bool b = __pUiApp->OnAppInitialized();
435
436         Frame* pFrame = dynamic_cast<Frame*>(__pFrameList->GetAt(0));
437         if (pFrame)
438         {
439                 int type = _AppInfo::GetAppType();
440                 if (type & _APP_TYPE_IME_APP)
441                 {
442                         SysLog(NID_APP, "Defering frame update for IME app.");
443                         pFrame->SetShowState(false);
444                 }
445         }
446
447         if (b)
448         {
449                 if (__pFrameList->GetCount() > 0)
450                 {
451                         return true;
452                 }
453                 else
454                 {
455                         SysLogException(NID_APP, E_OBJ_NOT_FOUND, "There is no frame !!! use AddFrame() before returning OnAppInitialized()");
456                         SysAssertf(false, "There is no frame !!! use AddFrame() before returning OnAppInitialized()");
457                 }
458         }
459         return false;
460 }
461
462
463 bool
464 _UiAppImpl::OnUiAppImplTerminating(void)
465 {
466         bool result = false;
467
468         RemoveAllFrames();
469
470         if (_AppInfo::GetAppState() != TERMINATED)
471         {
472                 result = __pUiApp->OnAppTerminating(*(AppRegistry::GetInstance()), __pAppImpl->IsForcedTermination());
473                 _AppInfo::SetAppState(TERMINATED);
474         }
475
476         // Do Ui related finalizing for UiApp
477         FinalizeUiFramework();
478
479         return result;
480 }
481
482
483 bool
484 _UiAppImpl::OnKeyPressed(const _Control& source, const _KeyInfo& keyInfo)
485 {
486         return false;
487 }
488
489
490 bool
491 _UiAppImpl::OnKeyReleased(const _Control& source, const _KeyInfo& keyInfo)
492 {
493         if (__appUiState == APP_UI_STATE_FOREGROUND)
494         {
495                 if (keyInfo.GetKeyCode() == _KEY_END)
496                 {
497                         SysTryReturn(NID_APP, __pUiApp != null, false, E_INVALID_STATE, "[E_INVALID_STATE] Getting UI App instance failed.");
498
499                         if (__pUiApp->OnAppWillTerminate())
500                         {
501                                 __pUiApp->Terminate();
502                                 return true;
503                         }
504                 }
505         }
506         return false;
507 }
508
509
510 void
511 _UiAppImpl::OnForeground(void)
512 {
513         result r = E_SUCCESS;
514
515         SysLog(NID_APP, "Invoking application callback.");
516
517         __appUiState = APP_UI_STATE_FOREGROUND;
518         __pUiApp->OnForeground();
519
520         SysLog(NID_APP, "Returned from application callback.");
521
522         r = _PowerManagerImpl::OnForeground();
523
524         SysTryLog(NID_APP, !IsFailed(r), "Failed to send foreground event to powermanager");
525 }
526
527
528 void
529 _UiAppImpl::OnBackground(void)
530 {
531         result r = E_SUCCESS;
532
533         SysLog(NID_APP, "Invoking application callback.");
534
535         __appUiState = APP_UI_STATE_BACKGROUND;
536         __pUiApp->OnBackground();
537
538         SysLog(NID_APP, "Returned from application callback.");
539
540         r = _PowerManagerImpl::OnBackground();
541
542         SysTryLog(NID_APP, !IsFailed(r), "Failed to send background event to powermanager");
543 }
544
545
546 AppUiState
547 _UiAppImpl::GetAppUiState(void) const
548 {
549         return __appUiState;
550 }
551
552
553 _UiAppImpl*
554 _UiAppImpl::GetInstance(void)
555 {
556         return __pUiAppImpl;
557 }
558
559
560 UiApp*
561 _UiAppImpl::GetUiAppInstance(void)
562 {
563         return __pUiApp;
564 }
565
566
567 } } //Tizen::App