Fix the Prevent CID 48468 Dereference after null check.
[framework/osp/uifw.git] / src / ui / scenes / FUiScenes_SceneManagerImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 #include <new>
19 #include <unique_ptr.h>
20 #include <FAppUiApp.h>
21 #include <FAppIAppFrame.h>
22 #include <FIo.h>
23 #include <FUiControl.h>
24 #include <FUiCtrlFrame.h>
25 #include <FUiCtrlForm.h>
26 #include <FUiCtrlPanel.h>
27 #include <FUiAnimFrameAnimator.h>
28 #include <FUiAnimControlAnimator.h>
29 #include <FUiAnimAnimationTransaction.h>
30 #include <FUiScenesSceneManager.h>
31 #include <FUiScenesScene.h>
32 #include <FUiScenesISceneEventListener.h>
33 #include <FUiScenesISceneManagerEventListener.h>
34 #include <FUiScenesISceneTransitionPolicyProvider.h>
35 #include <FUiScenesIFormFactory.h>
36 #include <FUiScenesIPanelFactory.h>
37 #include <FUiScenesForwardSceneTransition.h>
38 #include <FUiScenesBackwardSceneTransition.h>
39 #include <FBaseSysLog.h>
40 #include "FUiScenes_SceneImpl.h"
41 #include "FUiScenes_SceneManagerImpl.h"
42 #include "FUiScenes_SceneTransitionImpl.h"
43 #include "FUiAnim_FrameAnimatorImpl.h"
44 #include "FUi_Control.h"
45 #include "FUi_ControlManager.h"
46 #include "FUi_ContainerImpl.h"
47 #include "FUiCtrl_FrameImpl.h"
48
49
50 using namespace Tizen::Base;
51 using namespace Tizen::Base::Runtime;
52 using namespace Tizen::Base::Collection;
53 using namespace Tizen::App;
54 using namespace Tizen::Io;
55 using namespace Tizen::Ui;
56 using namespace Tizen::Ui::Controls;
57 using namespace Tizen::Ui::Animations;
58 using namespace Tizen::Graphics;
59
60
61 namespace Tizen { namespace Ui { namespace Scenes
62 {
63
64 // HashMapT assist template
65 template<class T>
66 class _StringHashCodeProvider
67         : public IHashCodeProviderT <T>
68 {
69 public:
70         virtual int
71         GetHashCode(const T& obj) const
72         {
73                 String& objString = static_cast <String&>(const_cast <T&>(obj));
74                 return objString.GetHashCode();
75         }
76 };
77 template<class T>
78 class _StringComparer
79         : public IComparerT <T>
80 {
81 public:
82         virtual result
83         Compare(const T& obj1, const T& obj2, int& cmp) const
84         {
85                 String& objString1 = static_cast <String&>(const_cast <T&>(obj1));
86                 String& objString2 = static_cast <String&>(const_cast <T&>(obj2));
87                 cmp = objString1.CompareTo(objString2);
88                 return E_SUCCESS;
89         }
90 };
91
92
93 _SceneManagerImpl::_SceneDescription::_SceneDescription(const String& descriptionFormId, const String& descriptionPanelId)
94         : formId(descriptionFormId)
95         , panelId(descriptionPanelId)
96 {
97
98 }
99
100 _SceneManagerImpl::_SceneManagerImpl(void)
101         : __currentSceneId(L"")
102         , __pCurrentScene(null)
103         , __pFormFactory(null)
104         , __pPanelFactory(null)
105         , __pPolicyProvider(null)
106         , __destroyReservedScene(L"")
107         , __pCorrespondFrame(null)
108         , __correspondFrameControlHandle()
109         , __sceneTransitionProgressing(false)
110         , __pDisabledForm(null)
111 {
112         for (int i = 0; i < FRAME_ANIMATOR_FORM_TRANSITION_ANIMATION_MAX; i++)
113         {
114                 static const long ANIMATION_DURATION = 250L;
115                 __animationDescriptions[i].animationType = FrameAnimatorFormTransitionAnimation(i);
116                 __animationDescriptions[i].duration = ANIMATION_DURATION;
117                 __animationDescriptions[i].interpolatorType = ANIMATION_INTERPOLATOR_LINEAR;
118         }
119         __sceneTransitionMutex.Create();
120 }
121
122 _SceneManagerImpl::~_SceneManagerImpl(void)
123 {
124         std::unique_ptr<IMapEnumeratorT<String, _SceneDescription*> > pMapEnum(__sceneMap.GetMapEnumeratorN());
125         if (pMapEnum)
126         {
127                 while (pMapEnum->MoveNext() == E_SUCCESS)
128                 {
129                         _SceneDescription* pValue = null;
130                         pMapEnum->GetValue(pValue);
131                         delete pValue;
132                 }
133         }
134         else
135         {
136                 SysLogException(NID_UI_SCENES, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
137         }
138
139         std::unique_ptr<IMapEnumeratorT<String, SceneTransition*> > pTransitionMapEnum(__transitionMap.GetMapEnumeratorN());
140         if (pTransitionMapEnum)
141         {
142                 while (pTransitionMapEnum->MoveNext() == E_SUCCESS)
143                 {
144                         SceneTransition* pValue = null;
145                         pTransitionMapEnum->GetValue(pValue);
146                         delete pValue;
147                 }
148         }
149         else
150         {
151                 SysLogException(NID_UI_SCENES, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
152         }
153 }
154
155 result
156 _SceneManagerImpl::Construct(void)
157 {
158         result r = E_SUCCESS;
159         static _StringHashCodeProvider <String> sceneHashCodeProvider;
160         static _StringComparer <String> strComparer;
161
162         r = __sceneContainer.Construct(0, 0, sceneHashCodeProvider, strComparer);
163         SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
164         r = __formContainer.Construct(0, 0, sceneHashCodeProvider, strComparer);
165         SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
166         r = __formToPanelMultiMap.Construct(0, 0, sceneHashCodeProvider, strComparer);
167         SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
168         r = __sceneMap.Construct(0, 0, sceneHashCodeProvider, strComparer);
169         SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
170         r = __transitionMap.Construct(0, 0, sceneHashCodeProvider, strComparer);
171         SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
172         r = __formIdMap.Construct(0, 0, sceneHashCodeProvider, strComparer);
173         SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
174
175         r = __sceneControlEvent.Construct();
176         SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
177         r = __sceneControlEvent.AddListener(dynamic_cast<_ISceneControlEventListener&>(*this));
178         SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
179
180         UiApp* pUiApp = UiApp::GetInstance();
181         SysTryReturn(NID_UI_SCENES, pUiApp != null, null, E_SYSTEM,
182                                  "[%s] A system error has been occurred. UiApp::GetInstance failed.", GetErrorMessage(E_SYSTEM));
183         Frame* pFrame = pUiApp->GetFrameAt(0);
184         SysTryReturn(NID_UI_SCENES, pFrame != null, null, E_SYSTEM,
185                                  "[%s] A system error has been occurred. pUiApp->GetFrameAt(0) return null.", GetErrorMessage(E_SYSTEM));
186         __pCorrespondFrame = pFrame;
187         _ContainerImpl* pFrameWindowImpl = _ContainerImpl::GetInstance(*__pCorrespondFrame);
188         SysTryReturn(NID_UI_SCENES, pFrameWindowImpl != null, null, E_SYSTEM,
189                                  "[%s] A system error has been occurred. _ContainerImpl::GetInstance failed.", GetErrorMessage(E_SYSTEM));
190         __correspondFrameControlHandle = pFrameWindowImpl->GetCore().GetHandle();
191
192         return E_SUCCESS;
193 }
194
195 result
196 _SceneManagerImpl::RegisterFormFactory(const IFormFactory& formFactory)
197 {
198         __pFormFactory = const_cast <IFormFactory*>(&formFactory);
199
200         return E_SUCCESS;
201 }
202
203 result
204 _SceneManagerImpl::RegisterPanelFactory(const IPanelFactory& panelFactory)
205 {
206         __pPanelFactory = const_cast <IPanelFactory*>(&panelFactory);
207
208         return E_SUCCESS;
209 }
210
211 result
212 _SceneManagerImpl::RegisterScene(const SceneId& sceneId, const String& formId, const String& panelId)
213 {
214         result r = E_SUCCESS;
215         _SceneDescription* pSceneDescription = null;
216         bool isContains = false;
217
218         SysTryReturnResult(NID_UI_SCENES, !(sceneId.IsEmpty() || formId.IsEmpty()), E_INVALID_ARG,
219                                            "Invalid argument is used. String length of sceneId=%d, formId=%d",
220                                            sceneId.GetLength(), formId.GetLength());
221
222         r = __sceneMap.ContainsKey(sceneId, isContains);
223         SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
224         SysTryReturnResult(NID_UI_SCENES, !isContains, E_OBJ_ALREADY_EXIST, "Specified sceneId already exist.");
225
226         __formIdMap.ContainsKey(formId, isContains);
227         if (panelId.IsEmpty())
228         {
229                 SysTryReturnResult(NID_UI_SCENES, !isContains, E_INVALID_ARG, "Specified formId already exist. Only 'PanelScene' can share a formId for use as base form.");
230         }
231
232         if (!isContains)
233         {
234                 __formIdMap.Add(formId, 1);
235         }
236         else
237         {
238                 int refCount = 0;
239                 __formIdMap.GetValue(formId, refCount);
240                 ++refCount;
241                 __formIdMap.SetValue(formId, refCount);
242         }
243
244         pSceneDescription = new (std::nothrow) _SceneDescription(formId, panelId);
245         SysTryReturnResult(NID_UI_SCENES, pSceneDescription != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
246
247         r = __sceneMap.Add(sceneId, pSceneDescription);
248         SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
249         return r;
250
251 CATCH:
252         delete pSceneDescription;
253         return r;
254 }
255
256 result
257 _SceneManagerImpl::RegisterScene(const String& resourceId)
258 {
259         static const wchar_t RESOUCE_FILE_PATH[] = L"res/";
260         static const wchar_t RESOUCE_FILE_EXT[] = L".xml";
261         static const wchar_t RESOUCE_FILE_NORMAL[] = L"screen-size-normal/";
262         static const xmlChar* pElementWorkflow = reinterpret_cast<const xmlChar*>("Workflow");
263         static const xmlChar* pElementScene = reinterpret_cast<const xmlChar*>("Scene");
264         static const xmlChar* pElementSceneTransition = reinterpret_cast<const xmlChar*>("SceneTransition");
265         result r = E_SUCCESS;
266
267         _ControlManager* pControlManager = _ControlManager::GetInstance();
268         SysTryReturnResult(NID_UI_SCENES, pControlManager != null, E_SYSTEM,
269                                            "A system error has been occurred. Unable to get the control manager.");
270         Dimension screenSize = pControlManager->GetScreenSize();
271
272         const String appRootPath = Tizen::App::App::GetInstance()->GetAppRootPath();
273         String filePath;
274         // Formating path for current resolution: [AppRootPath/][res/][width]x[height]/[resourceId][.xml]
275         r = filePath.Format(FILENAME_MAX, L"%ls%ls%dx%d/%ls%ls",
276                                                 appRootPath.GetPointer(), RESOUCE_FILE_PATH, screenSize.width, screenSize.height,
277                                                 resourceId.GetPointer(), RESOUCE_FILE_EXT);
278         SysTryReturnResult(NID_UI_SCENES, !IsFailed(r), E_SYSTEM, "A system error has been occurred. File path formatting failed.");
279         SysLog(NID_UI_SCENES, "RegisterScene: res path: %ls", filePath.GetPointer());
280
281         if (!File::IsFileExist(filePath))
282         {       // File not exist on specific resolution then try again: [AppRootPath/][res/][screen-size-normal/][resourceId][.xml]
283                 filePath.Format(FILENAME_MAX, L"%ls%ls%ls%ls%ls",
284                                                 appRootPath.GetPointer(), RESOUCE_FILE_PATH, RESOUCE_FILE_NORMAL,
285                                                 resourceId.GetPointer(), RESOUCE_FILE_EXT);
286                 SysTryReturnResult(NID_UI_SCENES, !IsFailed(r), E_SYSTEM, "A system error has been occurred. File path formatting failed.");
287                 SysLog(NID_UI_SCENES, "RegisterScene: 2nd try - res path: %ls", filePath.GetPointer());
288                 if (!pControlManager->IsCoordinateSystemLogical() || !File::IsFileExist(filePath))
289                 {
290                         SysLogException(NID_UI_SCENES, E_FILE_NOT_FOUND, "[%s] File could not be found. File path=%ls",
291                                                         GetErrorMessage(E_FILE_NOT_FOUND), filePath.GetPointer());
292                         return E_FILE_NOT_FOUND;
293                 }
294         }
295
296         std::unique_ptr<ByteBuffer> pfilePathBuffer(Tizen::Base::Utility::StringUtil::StringToUtf8N(filePath));
297         SysTryReturnResult(NID_UI_SCENES, pfilePathBuffer != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
298
299         xmlDocPtr docPtr = xmlParseFile(reinterpret_cast<const char*>(pfilePathBuffer->GetPointer()));
300         SysTryReturnResult(NID_UI_SCENES, docPtr != null, E_SYSTEM,
301                                            "A system error has been occurred. Can not parse xml file: %ls", filePath.GetPointer());
302
303         xmlNodePtr rootNodePtr = xmlDocGetRootElement(docPtr);
304         SysTryReturnResult(NID_UI_SCENES, rootNodePtr != null, E_SYSTEM,
305                                            "A system error has been occurred. Can not find root node");
306
307         // Visit xml nodes
308         for (xmlNodePtr nodePtr = rootNodePtr; nodePtr != null; nodePtr = nodePtr->next)        // Visit sibling node
309         {       // Get element 'Workflow'
310                 if ((nodePtr->type == XML_ELEMENT_NODE) && (xmlStrcmp(nodePtr->name, pElementWorkflow) == 0))
311                 {       // and Get child - 'Scene's and 'SceneTransition's
312                         for (xmlNodePtr childNodePtr = nodePtr->children; childNodePtr != null; childNodePtr = childNodePtr->next) // Visit sibling
313                         {       // Get element 'Scene's and 'SceneTransition's
314                                 if (childNodePtr->type == XML_ELEMENT_NODE)
315                                 {       // Check E_OBJ_ALREADY_EXIST(continue) and E_OUT_OF_MEMORY(break) for all case.
316                                         if (xmlStrcmp(childNodePtr->name, pElementScene) == 0)
317                                         {
318                                                 result regResult = RegisterScene(childNodePtr);
319                                                 if (IsFailed(regResult))
320                                                 {
321                                                         SysTryCatch(NID_UI_SCENES, regResult != E_OUT_OF_MEMORY, r = regResult, regResult,
322                                                                                 "[%s] Propagating.", GetErrorMessage(regResult));
323                                                         if (regResult == E_OBJ_ALREADY_EXIST)
324                                                         {
325                                                                 r = regResult;
326                                                         }
327                                                 }
328                                         }
329                                         else
330                                         if (xmlStrcmp(childNodePtr->name, pElementSceneTransition) == 0)
331                                         {
332                                                 result regResult = RegisterSceneTransition(childNodePtr);
333                                                 if (IsFailed(regResult))
334                                                 {
335                                                         SysTryCatch(NID_UI_SCENES, regResult != E_OUT_OF_MEMORY, r = regResult, regResult,
336                                                                                 "[%s] Propagating.", GetErrorMessage(regResult));
337                                                         if (regResult == E_OBJ_ALREADY_EXIST)
338                                                         {
339                                                                 r = regResult;
340                                                         }
341                                                 }
342                                         }
343                                 } // 'Scene' and 'SceneTransition'
344                         } // Children of 'Workflow'
345                 } // Element 'Workflow'
346         }// Root node sibling
347
348         xmlFreeDoc(docPtr);
349         return r;
350
351 CATCH:
352         xmlFreeDoc(docPtr);
353         return r;
354 }
355
356 result
357 _SceneManagerImpl::UnregisterScene(const SceneId& sceneId)
358 {
359         result r = E_SUCCESS;
360         _SceneDescription* pSceneDescription = null;
361
362         SysTryReturnResult(NID_UI_SCENES, !sceneId.IsEmpty(), E_INVALID_ARG, "Invalid argument is used. sceneId is empty.");
363
364         r = __sceneMap.GetValue(sceneId, pSceneDescription);
365         SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
366
367         // Remove FormId from __formIdMap
368         if (pSceneDescription)
369         {
370                 bool isContains = false;
371                 __formIdMap.ContainsKey(pSceneDescription->formId, isContains);
372                 if (isContains)
373                 {
374                         int refCount = 0;
375                         __formIdMap.GetValue(pSceneDescription->formId, refCount);
376                         --refCount;
377                         if (refCount <= 0)
378                         {
379                                 __formIdMap.Remove(pSceneDescription->formId);
380                         }
381                         else
382                         {
383                                 __formIdMap.SetValue(pSceneDescription->formId, refCount);
384                         }
385                 }
386         }
387
388         r = __sceneMap.Remove(sceneId);
389         SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
390
391         delete pSceneDescription;
392         return r;
393 }
394
395 result
396 _SceneManagerImpl::AddSceneManagerEventListener(ISceneManagerEventListener& sceneManagerEventListener)
397 {
398         result r = E_SUCCESS;
399         ISceneManagerEventListener* pListener = &sceneManagerEventListener;
400         bool alreadyExist = __sceneManagerEventListenerList.Contains(pListener);
401         SysTryReturnResult(NID_UI_SCENES, !alreadyExist, E_OBJ_ALREADY_EXIST, "The event listener already exist.");
402         r = __sceneManagerEventListenerList.Add(pListener);
403         SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
404
405         return E_SUCCESS;
406 }
407
408 result
409 _SceneManagerImpl::RemoveSceneManagerEventListener(ISceneManagerEventListener& sceneManagerEventListener)
410 {
411         result r = E_SUCCESS;
412         ISceneManagerEventListener* pListener = &sceneManagerEventListener;
413         r = __sceneManagerEventListenerList.Remove(pListener);
414         SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
415
416         return E_SUCCESS;
417 }
418
419 result
420 _SceneManagerImpl::AddSceneEventListener(const SceneId& sceneId, ISceneEventListener& sceneEventListener)
421 {
422         result r = E_SUCCESS;
423         Scene* pScene = null;
424         _SceneImpl* pSceneImpl = null;
425
426         pScene = GetSceneFromContainer(sceneId);
427         SysTryReturnResult(NID_UI_SCENES, pScene != null, E_INVALID_ARG, "Invalid argument is used. The sceneId is not valid.");
428         pSceneImpl = _SceneImpl::GetInstance(*pScene);
429         SysTryReturnResult(NID_UI_SCENES, pSceneImpl != null, E_INVALID_ARG, "Invalid argument is used. The sceneId is not valid.");
430         r = pSceneImpl->AddSceneEventListener(sceneEventListener);
431         SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
432
433         return E_SUCCESS;
434 }
435
436 result
437 _SceneManagerImpl::RemoveSceneEventListener(const SceneId& sceneId, ISceneEventListener& sceneEventListener)
438 {
439         result r = E_SUCCESS;
440         Scene* pScene = null;
441         _SceneImpl* pSceneImpl = null;
442
443         pScene = GetSceneFromContainer(sceneId);
444         SysTryReturnResult(NID_UI_SCENES, pScene != null, E_INVALID_ARG, "Invalid argument is used. The sceneId is not valid.");
445         pSceneImpl = _SceneImpl::GetInstance(*pScene);
446         SysTryReturnResult(NID_UI_SCENES, pSceneImpl != null, E_INVALID_ARG, "Invalid argument is used. The sceneId is not valid.");
447         r = pSceneImpl->RemoveSceneEventListener(sceneEventListener);
448         SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
449
450         return E_SUCCESS;
451 }
452
453 result
454 _SceneManagerImpl::SetSceneAnimationProvider(const SceneId& sceneId, ISceneAnimationProvider* pSceneAnimationProvider)
455 {
456         result r = E_SUCCESS;
457         Scene* pScene = null;
458         _SceneImpl* pSceneImpl = null;
459
460         pScene = GetSceneFromContainer(sceneId);
461         SysTryReturnResult(NID_UI_SCENES, pScene != null, E_INVALID_ARG, "Invalid argument is used. The sceneId is not valid.");
462         pSceneImpl = _SceneImpl::GetInstance(*pScene);
463         SysTryReturnResult(NID_UI_SCENES, pSceneImpl != null, E_INVALID_ARG, "Invalid argument is used. The sceneId is not valid.");
464         r = pSceneImpl->SetSceneAnimationProvider(pSceneAnimationProvider);
465         SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
466
467         return E_SUCCESS;
468 }
469
470 result
471 _SceneManagerImpl::SetSceneTransitionPolicyProvider(ISceneTransitionPolicyProvider* pSceneTransitionPolicyProvider)
472 {
473         __pPolicyProvider = pSceneTransitionPolicyProvider;
474
475         return E_SUCCESS;
476 }
477
478 result
479 _SceneManagerImpl::SetFormTransitionAnimationDefaultValues(SceneTransitionAnimationType animationType, long duration,
480                                                                                                                    AnimationInterpolatorType interpolatorType)
481 {
482         static const long DURATION_MIN = 0;
483         static const long DURATION_MAX = 1000;
484
485         SysTryReturnResult(NID_UI_SCENES, (SCENE_TRANSITION_ANIMATION_TYPE_LEFT <= animationType &&
486                                            animationType <= SCENE_TRANSITION_ANIMATION_TYPE_DEPTH_OUT), E_INVALID_ARG,
487                                            "Invalid argument is used. animationType=%d", animationType);
488         SysTryReturnResult(NID_UI_SCENES, (DURATION_MIN <= duration && duration <= DURATION_MAX), E_INVALID_ARG,
489                                            "Invalid argument is used. duration=%d", duration);
490         __animationDescriptions[animationType - SCENE_TRANSITION_ANIMATION_TYPE_LEFT].duration = duration;
491         __animationDescriptions[animationType - SCENE_TRANSITION_ANIMATION_TYPE_LEFT].interpolatorType = interpolatorType;
492
493         return E_SUCCESS;
494 }
495
496 result
497 _SceneManagerImpl::GoForward(const ForwardSceneTransition& sceneTransition, const Tizen::Base::Collection::IList* pArgs)
498 {
499         //## Temporary - Currently no support Non-Recursive Lock(Mutex).
500         SysTryReturnResult(NID_UI_SCENES, !__sceneTransitionProgressing, E_IN_PROGRESS, "Previous operation in progressing");
501
502         result r = __sceneTransitionMutex.TryToAcquire();
503         SysTryReturnResult(NID_UI_SCENES, r != E_OBJECT_LOCKED, E_IN_PROGRESS, "Previous operation in progressing");
504         SysTryReturnResult(NID_UI_SCENES, r != E_SYSTEM, E_SYSTEM, "A system error has been occurred.");
505         r = __sceneTransitionMutex.Acquire();
506         SysTryReturnResult(NID_UI_SCENES, !IsFailed(r), E_SYSTEM, "A system error has been occurred. Mutex acquire failed.");
507         __sceneTransitionProgressing = true;    //## Temporary
508
509         SceneId sceneId;
510         _SceneTransitionImpl forwardSceneTransition;
511
512         forwardSceneTransition = *_SceneTransitionImpl::GetInstance(static_cast<const SceneTransition&>(sceneTransition));
513         SysTryCatch(NID_UI_SCENES, forwardSceneTransition.GetDirection() == SCENE_TRANSITION_DIRECTION_FORWARD, r= E_INVALID_ARG,
514                                 E_INVALID_ARG, "[%s] Invalid argument is used. sceneTransition's direction is not SCENE_TRANSITION_DIRECTION_FORWARD.", GetErrorMessage(E_INVALID_ARG));
515
516         sceneId = forwardSceneTransition.GetDestinationSceneId();
517         if (sceneId.GetLength() > 0)
518         {
519                 // Prevent transit to current scene
520                 SysTryCatch(NID_UI_SCENES, __currentSceneId != sceneId, r = E_INVALID_ARG, E_INVALID_ARG,
521                                         "[%s] Invalid argument is used. Can't forward to current Scene.", GetErrorMessage(E_INVALID_ARG));
522
523                 // Stop animation
524                 if (!IsAnimationCompleted())
525                 {
526                         r = StopAllAnimations();
527                         SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
528                 }
529
530                 // Go to the specified scene
531                 r = GotoScene(true, sceneId, forwardSceneTransition.GetAnimationType(),
532                                           forwardSceneTransition.GetHistoryOption(), forwardSceneTransition.GetDestroyOption(), pArgs);
533                 SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
534         }
535         else
536         {       // Transition via PolicyProvider
537                 SysTryCatch(NID_UI_SCENES, __pPolicyProvider != null, r = E_INVALID_STATE, E_INVALID_STATE,
538                                         "[%s] SceneManager is in an invalid state. Policy provider not registered.", GetErrorMessage(E_INVALID_STATE));
539
540                 SceneId nextSceneId = __pPolicyProvider->GetNextScene(__currentSceneId, pArgs);
541                 SysTryCatch(NID_UI_SCENES, !nextSceneId.IsEmpty(), r = E_INVALID_STATE, E_INVALID_STATE,
542                                         "[%s] SceneManager is in an invalid state. Policy provider does not know next scene. Current scene= %ls",
543                                         GetErrorMessage(E_INVALID_STATE), __currentSceneId.GetPointer());
544
545                 // Prevent transit to current scene
546                 SysTryCatch(NID_UI_SCENES, __currentSceneId != nextSceneId, r = E_INVALID_ARG, E_INVALID_ARG,
547                                         "[%s] Invalid argument is used. Can't forward to current Scene.", GetErrorMessage(E_INVALID_ARG));
548
549                 // Stop animation
550                 if (!IsAnimationCompleted())
551                 {
552                         r = StopAllAnimations();
553                         SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
554                 }
555
556                 r = GotoScene(true, nextSceneId, forwardSceneTransition.GetAnimationType(),
557                                           forwardSceneTransition.GetHistoryOption(), forwardSceneTransition.GetDestroyOption(), pArgs);
558                 SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
559         }
560
561         r = E_SUCCESS;
562
563 CATCH:
564         __sceneTransitionProgressing = false;   //## Temporary
565         SysTryReturnResult(NID_UI_SCENES, !IsFailed(__sceneTransitionMutex.Release()), E_SYSTEM,
566                                            "A system error has been occurred. Mutext release failed.");
567         return r;
568 }
569
570 result
571 _SceneManagerImpl::GoForward(const SceneTransitionId& transitionId, const Tizen::Base::Collection::IList* pArgs)
572 {
573         ForwardSceneTransition forwardTransition;
574
575         result r = GetSceneTransition(transitionId, forwardTransition);
576         SysTryReturnResult(NID_UI_SCENES, !IsFailed(r), E_INVALID_ARG, "Cannot get transition from Id.");
577
578         return GoForward(forwardTransition, pArgs);
579 }
580
581 result
582 _SceneManagerImpl::GoBackward(const BackwardSceneTransition& sceneTransition, const Tizen::Base::Collection::IList* pArgs)
583 {
584         //## Temporary - Currently no support Non-Recursive Lock(Mutex).
585         SysTryReturnResult(NID_UI_SCENES, !__sceneTransitionProgressing, E_IN_PROGRESS, "Previous operation in progressing");
586
587         result r = __sceneTransitionMutex.TryToAcquire();
588         SysTryReturnResult(NID_UI_SCENES, r != E_OBJECT_LOCKED, E_IN_PROGRESS, "Previous operation in progressing");
589         SysTryReturnResult(NID_UI_SCENES, r != E_SYSTEM, E_SYSTEM, "A system error has been occurred.");
590         r = __sceneTransitionMutex.Acquire();
591         SysTryReturnResult(NID_UI_SCENES, !IsFailed(r), E_SYSTEM, "A system error has been occurred. Mutex acquire failed.");
592         __sceneTransitionProgressing = true;    //## Temporary
593
594         int historyCount = 0;
595         _SceneTransitionImpl backwardSceneTransition;
596         SceneId sceneId;
597
598         historyCount = __sceneHistory.GetCount();
599         SysTryCatch(NID_UI_SCENES, historyCount != 0, r = E_UNDERFLOW, E_UNDERFLOW, "[%s] The Scene history is empty.",
600                                 GetErrorMessage(E_UNDERFLOW));
601
602         backwardSceneTransition = *_SceneTransitionImpl::GetInstance(sceneTransition);
603         SysTryCatch(NID_UI_SCENES, backwardSceneTransition.GetDirection() == SCENE_TRANSITION_DIRECTION_BACKWARD,
604                                 r = E_INVALID_ARG, E_INVALID_ARG,
605                                 "[%s] Invalid argument is used. sceneTransition's direction is not SCENE_TRANSITION_DIRECTION_BACKWARD!", GetErrorMessage(E_INVALID_ARG));
606         SysTryCatch(NID_UI_SCENES, backwardSceneTransition.GetHistoryOption() == SCENE_HISTORY_OPTION_NO_HISTORY,
607                                 r = E_INVALID_ARG, E_INVALID_ARG,
608                                 "[%s] Invalid argument is used. sceneTransition's history option is not SCENE_HISTORY_OPTION_NO_HISTORY!", GetErrorMessage(E_INVALID_ARG));
609
610         sceneId = backwardSceneTransition.GetDestinationSceneId();
611         if (sceneId.GetLength() > 0)
612         {       // Back to specific scene and clean up history between destination and last point.
613                 int historyIndex = -1;
614                 SceneId destinationSceneId;
615
616                 // 1. Back tracking and pick a first matching sceneId
617                 r = __sceneHistory.LastIndexOf(sceneId, historyIndex);
618                 SysTryCatch(NID_UI_SCENES, !IsFailed(r), r = E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND,
619                                         "[%s] The given sceneId was not found in the registered scenes.", GetErrorMessage(E_OBJ_NOT_FOUND));
620                 r = __sceneHistory.GetAt(historyIndex, destinationSceneId);
621                 SysTryCatch(NID_UI_SCENES, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.",
622                                         GetErrorMessage(E_SYSTEM));
623
624                 // 2. if destoryOption == SCENE_DESTROY_OPTION_DESTROY then destroy all scenes except matching scene.
625                 if (backwardSceneTransition.GetDestroyOption() == SCENE_DESTROY_OPTION_DESTROY)
626                 {
627                         for (int i = historyIndex+1; i < historyCount; i++)
628                         {
629                                 SceneId destroyTargetSceneId;
630                                 __sceneHistory.GetAt(i, destroyTargetSceneId);
631                                 // Scene instance is not always valid.
632                                 Scene* pScene = GetSceneFromContainer(destroyTargetSceneId);
633                                 if (pScene)
634                                 {
635                                         // If Panel Scene then destroy sibling Panel Scene(s).
636                                         if (pScene->GetPanel())
637                                         {
638                                                 DestroySiblingPanelScene(destroyTargetSceneId);
639                                         }
640                                         DestroyScene(destroyTargetSceneId);
641                                 }
642                         }
643                 }
644
645                 // 3. Remove all scenes on history between latest scene to matching scene.
646                 r = __sceneHistory.RemoveItems(historyIndex, historyCount-historyIndex);
647                 SysTryCatch(NID_UI_SCENES, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.",
648                                         GetErrorMessage(E_SYSTEM));
649
650                 // Prevent transit to current scene
651                 SysTryCatch(NID_UI_SCENES, __currentSceneId != destinationSceneId, r = E_INVALID_ARG, E_INVALID_ARG,
652                                         "[%s] Invalid argument is used. Can't backward to current Scene.", GetErrorMessage(E_INVALID_ARG));
653
654                 // Stop previous animation
655                 if (!IsAnimationCompleted())
656                 {
657                         r = StopAllAnimations();
658                         SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
659                 }
660
661                 // Transition
662                 r = GotoScene(false, destinationSceneId, backwardSceneTransition.GetAnimationType(),
663                                           SCENE_HISTORY_OPTION_NO_HISTORY, backwardSceneTransition.GetDestroyOption(), pArgs);
664                 SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
665         }
666         else
667         {       // Adjacent backward transition
668                 SceneId previousSceneId;
669
670                 r = __sceneHistory.GetAt(historyCount-1, previousSceneId);
671                 SysTryCatch(NID_UI_SCENES, !IsFailed(r), r = E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND,
672                                         "[%s] The given sceneId was not found in the registered scenes.", GetErrorMessage(E_OBJ_NOT_FOUND));
673                 r = __sceneHistory.RemoveAt(historyCount-1);
674                 SysTryCatch(NID_UI_SCENES, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.",
675                                         GetErrorMessage(E_SYSTEM));
676
677                 // Prevent transit to current scene
678                 SysTryCatch(NID_UI_SCENES, __currentSceneId != previousSceneId, r = E_INVALID_ARG, E_INVALID_ARG,
679                                         "[%s] Invalid argument is used. Can't backward to current Scene.", GetErrorMessage(E_INVALID_ARG));
680
681                 // Stop previous animation
682                 if (!IsAnimationCompleted())
683                 {
684                         r = StopAllAnimations();
685                         SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
686                 }
687
688                 r = GotoScene(false, previousSceneId, backwardSceneTransition.GetAnimationType(),
689                                           SCENE_HISTORY_OPTION_NO_HISTORY, backwardSceneTransition.GetDestroyOption(), pArgs);
690                 SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
691         }
692
693         r = E_SUCCESS;
694
695 CATCH:
696         __sceneTransitionProgressing = false;   //## Temporary
697         SysTryReturnResult(NID_UI_SCENES, !IsFailed(__sceneTransitionMutex.Release()), E_SYSTEM,
698                                            "A system error has been occurred. Mutext release failed.");
699         return r;
700 }
701
702 result
703 _SceneManagerImpl::GoBackward(const SceneTransitionId& transitionId, const Tizen::Base::Collection::IList* pArgs)
704 {
705         BackwardSceneTransition backwardTransition;
706
707         result r = GetSceneTransition(transitionId, backwardTransition);
708         SysTryReturnResult(NID_UI_SCENES, !IsFailed(r), E_INVALID_ARG, "Cannot get transition from Id.");
709
710         return GoBackward(backwardTransition, pArgs);
711 }
712
713 Scene*
714 _SceneManagerImpl::GetCurrentScene(void) const
715 {
716         return __pCurrentScene;
717 }
718
719 SceneId
720 _SceneManagerImpl::GetCurrentSceneId(void) const
721 {
722         return __currentSceneId;
723 }
724
725 bool
726 _SceneManagerImpl::IsSceneAlive(const SceneId& sceneId) const
727 {
728         return  (GetSceneFromContainer(sceneId)) ? true : false;
729 }
730
731 result
732 _SceneManagerImpl::DestroyScene(const SceneId& sceneId)
733 {
734         result r = E_SUCCESS;
735         Scene* pScene = null;
736         bool isFormScene = false;
737         bool isLastPanel = false;
738         int panelCount = 0;
739
740         SysTryReturnResult(NID_UI_SCENES, __currentSceneId != sceneId, E_INVALID_ARG,
741                                            "Invalid argument is used. The current Scene can not be destroy.");
742         pScene = GetSceneFromContainer(sceneId);
743         SysTryReturnResult(NID_UI_SCENES, pScene != null, E_OBJ_NOT_FOUND, "Specified sceneId does not exist.");
744
745         // Ok now destroy associated Ui controls
746         // Form scene: Destroy Form - that's all.
747         // Panel scene: Normal case - destroy Panel only but the current scene is the last panel then destroy Form.
748         // Correspondent internal data item should be destroy.
749         if (!pScene->GetPanel())
750         {
751                 isFormScene = true;
752         }
753         else
754         {
755                 r = __formToPanelMultiMap.GetCount(pScene->GetFormId(), panelCount);
756                 SysTryReturnResult(NID_UI_SCENES, !IsFailed(r), E_SYSTEM,
757                                                    "A system error has been occurred. Form(SceneId:%ls) is not valid.", sceneId.GetPointer());
758                 if (panelCount <= 1)
759                 {
760                         isLastPanel = true;
761                 }
762         }
763
764         if (isFormScene)
765         {       // 1. Remove Form control(Associated on Scene) from Frame
766                 RemoveControlFromFrame(*pScene->GetForm());
767                 // 2. Remove Form from Form container
768                 RemoveFormFromFormContainer(pScene->GetFormId());
769         }
770         else
771         if (isLastPanel)
772         {       // 1. Remove Panel from Panel container.
773                 RemovePanelFromPanelContainer(pScene);
774                 // 2. Remove Form control from Frame. (Associated Panel automatically removed by Ui)
775                 RemoveControlFromFrame(*pScene->GetForm());
776                 // 3. Remove Form from Form container.
777                 RemoveFormFromFormContainer(pScene->GetFormId());
778         }
779         else
780         {       // 1. Remove Panel from Panel container.
781                 RemovePanelFromPanelContainer(pScene);
782                 // 2. Remove Panel control from base Form
783                 bool panelFromFormResouce = false;
784                 _SceneImpl* pSceneImpl = _SceneImpl::GetInstance(*pScene);
785                 if (pSceneImpl)
786                 {
787                         panelFromFormResouce = pSceneImpl->IsPanelCreatedFromFormResource();
788                 }
789                 if (!panelFromFormResouce)
790                 {
791                         RemoveControlFromForm(*pScene->GetForm(), *pScene->GetPanel());
792                 }
793         }
794
795         // Finally remove Scene
796         RemoveSceneFromContainer(sceneId);
797         delete pScene;
798
799         return E_SUCCESS;
800 }
801
802 result
803 _SceneManagerImpl::BringCurrentSceneToTop(void)
804 {
805         Form* pForm = null;
806         Scene* pCurrentScene = GetCurrentScene();
807
808         SysTryReturnResult(NID_UI_SCENES, pCurrentScene != null, E_OPERATION_FAILED, "The current Scene is not valid.");
809         pForm = pCurrentScene->GetForm();
810         SysTryReturnResult(NID_UI_SCENES, pForm != null, E_SYSTEM, "A system error has been occurred. The Form is not valid.");
811         result r = SetCurrentForm(*pForm);
812         SysTryReturnResult(NID_UI_SCENES, !IsFailed(r), E_SYSTEM, "A system error has been occurred.");
813
814         return E_SUCCESS;
815 }
816
817 result
818 _SceneManagerImpl::ClearSceneHistory(void)
819 {
820         __sceneHistory.RemoveAll();
821
822         return E_SUCCESS;
823 }
824
825 result
826 _SceneManagerImpl::AddToSceneHistory(const SceneId& sceneId)
827 {
828         result r = E_SUCCESS;
829         bool isContains = false;
830
831         SysTryReturnResult(NID_UI_SCENES, !sceneId.IsEmpty(), E_INVALID_ARG, "Invalid argument is used. sceneId length is 0.");
832         r = __sceneMap.ContainsKey(sceneId, isContains);
833         SysTryReturnResult(NID_UI_SCENES, isContains, E_OBJ_NOT_FOUND, "The sceneId is not registered.");
834         r = AddHistory(sceneId);
835         SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
836
837         return E_SUCCESS;
838 }
839
840 IListT<SceneId>*
841 _SceneManagerImpl::GetSceneHistoryN(void) const
842 {
843         std::unique_ptr<IListT<String> > pSceneList(new (std::nothrow) ArrayListT<String>);
844         SysTryReturn(NID_UI_SCENES, pSceneList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
845                                  GetErrorMessage(E_OUT_OF_MEMORY));
846
847         pSceneList->AddItems(__sceneHistory);
848         return pSceneList.release();
849 }
850
851 _SceneManagerImpl*
852 _SceneManagerImpl::GetInstance(SceneManager& pSceneManager)
853 {
854         return pSceneManager.__pSceneManagerImpl;
855 }
856
857 const _SceneManagerImpl*
858 _SceneManagerImpl::GetInstance(const SceneManager& pSceneManager)
859 {
860         return pSceneManager.__pSceneManagerImpl;
861 }
862
863 // Event handelers to asynchronous destroy the Scene.
864 void
865 _SceneManagerImpl::OnFormTransitionAnimationFinished(FrameAnimator& source, Frame& frame, Form& form1, Form& form2)
866 {
867         SetInputEventEnableState(form1, true);
868         SetInputEventEnableState(form2, true);
869
870         source.RemoveFrameAnimatorEventListener(*this);
871         DestroyReservedScene();
872 }
873
874 void
875 _SceneManagerImpl::OnFormTransitionAnimationStarted(FrameAnimator& source, Frame& frame, Form& form1, Form& form2)
876 {
877         // Nothing to do.
878 }
879
880 void
881 _SceneManagerImpl::OnFormTransitionAnimationStopped(FrameAnimator& source, Frame& frame, Form& form1, Form& form2)
882 {
883         SetInputEventEnableState(form1, true);
884         SetInputEventEnableState(form2, true);
885
886         source.RemoveFrameAnimatorEventListener(*this);
887         DestroyReservedScene();
888 }
889
890 void
891 _SceneManagerImpl::OnAnimationTransactionFinished(int transactionId)
892 {
893         if (__pDisabledForm)
894         {
895                 SetInputEventEnableState(*__pDisabledForm, true);
896                 __pDisabledForm = null;
897         }
898         AnimationTransaction::SetCurrentTransactionEventListener(null);
899 }
900
901 void
902 _SceneManagerImpl::OnAnimationTransactionStarted(int transactionId)
903 {
904         // Nothing to do.
905 }
906
907 void
908 _SceneManagerImpl::OnAnimationTransactionStopped(int transactionId)
909 {
910         if (__pDisabledForm)
911         {
912                 SetInputEventEnableState(*__pDisabledForm, true);
913                 __pDisabledForm = null;
914         }
915         AnimationTransaction::SetCurrentTransactionEventListener(null);
916 }
917
918 void
919 _SceneManagerImpl::OnSceneControlEventReceived(_SceneControlEventArg::SceneControlEventType eventType, const SceneId& sceneId)
920 {
921         SysLog(NID_UI_SCENES, "Received type= 0x%x, sceneId=%ls", eventType, &sceneId);
922
923         switch (eventType)
924         {
925         case _SceneControlEventArg::SCENE_CONTROL_EVENT_TYPE_DESTROY:
926                 DestroyScene(sceneId);
927                 break;
928
929         default:
930                 SysLog(NID_UI_SCENES, "Invalid SceneControlEventType x0%x", eventType);
931                 break;
932         }
933 }
934
935 // Internal operations
936 Scene*
937 _SceneManagerImpl::GetScene(SceneId& sceneId)
938 {
939         return GetSceneFromContainer(sceneId);
940 }
941
942 IListT<Scene*>*
943 _SceneManagerImpl::GetLiveSceneN(void) const
944 {
945         std::unique_ptr<ArrayListT<Scene*> > pSceneList(new (std::nothrow) ArrayListT<Scene*>);
946         SysTryReturn(NID_UI_SCENES, pSceneList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
947                                  GetErrorMessage(E_OUT_OF_MEMORY));
948
949         std::unique_ptr<IMapEnumeratorT<SceneId, Scene*> > pMapEnum(__sceneContainer.GetMapEnumeratorN());
950         SysTryReturn(NID_UI_SCENES, pMapEnum != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
951                                  GetErrorMessage(E_OUT_OF_MEMORY));
952
953         while (pMapEnum->MoveNext() == E_SUCCESS)
954         {
955                 Scene* pScene = null;
956                 pMapEnum->GetValue(pScene);
957                 pSceneList->Add(pScene);
958         }
959         return pSceneList.release();
960 }
961
962 // Private method
963 result
964 _SceneManagerImpl::GotoScene(bool forward, const SceneId& sceneId, SceneTransitionAnimationType animationType,
965                                                          SceneHistoryOption historyOption, SceneDestroyOption destroyOption, const IList* pArgs)
966 {
967         // 1. Initialize for Scene transition.
968         result r = E_SUCCESS;
969         bool sceneAlreadyCreated = false;
970         bool formAlreadyCreated = false;
971         bool panelAlreadyCreated = false;
972         bool doAnimation = false;
973         bool formTransition = false;
974         Scene* pScene = null;
975         Form* pForm = null;
976         Panel* pPanel = null;
977         SceneId previousSceneId = __currentSceneId;             // Save for later
978         String previousFormId = (__pCurrentScene) ? __pCurrentScene->GetFormId() : L"";
979         bool previousIsPanelScene = (__pCurrentScene) ? (__pCurrentScene->GetPanel()) : false;
980         Frame* pFrame = null;
981         FrameAnimator* pFrameAnimator = null;
982         // Exception handling hintings
983         bool onExceptionDeletepScene = false;
984         bool onExceptionRemovesceneIdFromSceneContainer = false;
985         bool onExceptionDeletepForm = false;
986         bool onExceptionRemoveFormIdFromFormContainer = false;
987         bool onExceptionRemovepPanel = false;
988
989         // Prevent self forward
990         SysTryCatch(NID_UI_SCENES, __currentSceneId != sceneId, r = E_INVALID_ARG, E_INVALID_ARG,
991                                 "[%s] Invalid argument is used. Can't transit to current Scene.", GetErrorMessage(E_INVALID_ARG));
992         CallListenerOnSceneTransitionStarted(__currentSceneId, sceneId);        // Call listener - ISceneManagerEventListener's
993         if (__pCurrentScene)
994         {       // Call listener - ISceneEventListener's
995                 CallListenerOnSceneDeactivated(*__pCurrentScene, sceneId, __pCurrentScene->GetSceneId());
996         }
997
998         // 2. Find the Scene on SceneContainer - Scene and correspond UI control has same life time.
999         pScene = GetSceneFromContainer(sceneId);
1000         if (pScene) // Activate pScene: Scene already existing then Re-activate associated a Form and a Panel.
1001         {
1002                 sceneAlreadyCreated = true;
1003                 pForm = GetFormFromContainer(pScene->GetFormId());
1004                 SysTryCatch(NID_UI_SCENES, pForm == pScene->GetForm(), r = E_SYSTEM, E_SYSTEM,
1005                                         "[%s] A system error has been occurred. FormId mismatch with associated From instance.",
1006                                         GetErrorMessage(E_SYSTEM));
1007                 formAlreadyCreated = true;
1008                 pPanel = pScene->GetPanel();
1009                 if (pPanel)
1010                 {
1011                         panelAlreadyCreated = true;
1012                 }
1013         }
1014         else
1015         {       // 3. Scene not found- Create new Scene
1016                 _SceneDescription* pSceneValue = null;
1017                 __sceneMap.GetValue(sceneId, pSceneValue);
1018                 SysTryCatch(NID_UI_SCENES, pSceneValue != null, r = E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND,
1019                                         "[%s] The given sceneId was not found in the registered scenes.", GetErrorMessage(E_OBJ_NOT_FOUND));
1020                 // 4. Setup the new Scene
1021                 pScene = _SceneImpl::CreateSceneN(sceneId, pSceneValue->formId, pSceneValue->panelId);
1022                 SysTryCatch(NID_UI_SCENES, pScene != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
1023                                         "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
1024                 onExceptionDeletepScene = true;                                                         // On the CATCH [delete pScene]
1025                 _SceneImpl* pSceneImpl = _SceneImpl::GetInstance(*pScene);
1026                 SysTryCatch(NID_UI_SCENES, pSceneImpl != null, r = E_SYSTEM, E_SYSTEM,
1027                                         "[%s] A system error has been occurred. pSceneImpl not valid", GetErrorMessage(E_SYSTEM));
1028                 // 5. Register Scene
1029                 AddSceneToContainer(sceneId, pScene);
1030                 onExceptionRemovesceneIdFromSceneContainer = true;                      // On the CATCH [remove 'sceneId' from SceneContainer]
1031                 // 6. Find the Form on FormContainer
1032                 pForm = GetFormFromContainer(pScene->GetFormId());
1033                 if (pForm) // Form existing: just call SetCurrentForm
1034                 {   // If the Scene is panel scene then add new panel to pForm or change showState.
1035                         formAlreadyCreated = true;
1036                         pSceneImpl->SetForm(pForm);             // Panel Scene share same Form intance
1037                 }
1038                 else// 7. Form not found- Create new Form
1039                 {       // 8. Get the new Form from the FormFactory
1040                         SysTryCatch(NID_UI_SCENES, __pFormFactory != null, r = E_INVALID_STATE, E_INVALID_STATE,
1041                                                 "[%s] SceneManager is in an invalid state. Form factory is not registered.",
1042                                                 GetErrorMessage(E_INVALID_STATE));
1043                         String  formId(pScene->GetFormId());
1044                         pForm = __pFormFactory->CreateFormN(formId, sceneId);   // On the CATCH [delete pForm]
1045                         SysTryCatch(NID_UI_SCENES, pForm != null, r = E_SYSTEM, E_SYSTEM,
1046                                                 "[%s] A system error has been occurred. Form(Id=%ls) creation failed on form factroy.",
1047                                                 GetErrorMessage(E_SYSTEM), formId.GetPointer());
1048                         onExceptionDeletepForm = true;                                                  // On the CATCH [remove pForm from FormContainer]
1049                         // 9. Register Form
1050                         AddFormToContainer(pScene->GetFormId(), pForm);
1051                         pSceneImpl->SetForm(pForm);
1052                         onExceptionRemoveFormIdFromFormContainer = true;
1053                 }
1054                 // 10. Create panel for Panel Scene
1055                 // * One Panel instance for each Panel-Scene so no need to check duplicated panel instance for same panel Id.
1056                 if (!pScene->GetPanelId().IsEmpty())
1057                 {
1058                         String panelId(pScene->GetPanelId());
1059                         // First of all, get the Panel from the based Form.
1060                         // Because, base Form loaded from the resources, the child Panel also loaded and created.
1061                         // So, do not create a new Panel instance but get from base Form with panelId as resource Id.
1062                         pPanel = dynamic_cast<Panel*>(pForm->GetControl(panelId));
1063                         if (pPanel)
1064                         {
1065                                 pSceneImpl->SetPanelCreatedFromFormResource(true);      // Prevent RemoveControl - It's not creatable via Panel factory.
1066                         }
1067                         else
1068                         {
1069                                 SysTryCatch(NID_UI_SCENES, __pPanelFactory != null, r = E_INVALID_STATE, E_INVALID_STATE,
1070                                                         "[%s] SceneManager is in an invalid state. Panel factory is not registered.",
1071                                                         GetErrorMessage(E_INVALID_STATE));
1072                                 pPanel = __pPanelFactory->CreatePanelN(panelId, sceneId); // On the CATCH [delete pPanel]
1073                                 SysTryCatch(NID_UI_SCENES, pPanel != null, r = E_SYSTEM, E_SYSTEM,
1074                                                         "[%s] A system error has been occurred. Panel(Id=%ls) creation failed on PanelFactory.",
1075                                                         GetErrorMessage(E_SYSTEM), panelId.GetPointer());
1076                                 onExceptionRemovepPanel = true;                                         // On the CATCH [remove pPanel from __formToPanelMultiMap]
1077                         }
1078                         AddPanelToPanelContainer(pScene);
1079                         pSceneImpl->SetPanel(pPanel);
1080                 }
1081         }
1082
1083         // For animation logic should be divide Animator section and normal section for proper operations.
1084         // If (showAnimation && forwardAnimation is Not NONE) then doing animator related logic /
1085         // Setup default animation setting / Add listener to get animation stop/finishing
1086         formTransition = (previousFormId != pScene->GetFormId()) ? true : false;
1087         doAnimation = (animationType > SCENE_TRANSITION_ANIMATION_TYPE_NONE) ? true : false;
1088         if (doAnimation && (animationType != SCENE_TRANSITION_ANIMATION_TYPE_CUSTOM && !formTransition))
1089         {
1090                 doAnimation = false;
1091         }
1092         if (doAnimation && (GetCurrentForm() == null))
1093         {
1094                 doAnimation = false;
1095         }
1096
1097         if (doAnimation)
1098         {
1099                 // Initialize Frame animator
1100                 pFrame = GetFrame();
1101                 SysTryCatch(NID_UI_SCENES, pFrame != null, r = E_SYSTEM, E_SYSTEM,
1102                                         "[%s] A system error has been occurred. Cannot get Frame.", GetErrorMessage(E_SYSTEM));
1103                 pFrameAnimator = pFrame->GetFrameAnimator();
1104                 SysTryCatch(NID_UI_SCENES, pFrameAnimator != null, r = E_SYSTEM, E_SYSTEM,
1105                                         "[%s] A system error has been occurred. Cannot get FrameAnimator.", GetErrorMessage(E_SYSTEM));
1106                 pFrameAnimator->StopAllAnimations();
1107
1108                 // Initialize Control animator if needed.
1109                 if (!formTransition && pPanel)
1110                 {
1111                         ControlAnimator* pControlAnimator = pPanel->GetControlAnimator();
1112                         SysTryCatch(NID_UI_SCENES, pControlAnimator != null, r = E_SYSTEM, E_SYSTEM,
1113                                                 "[%s] A system error has been occurred. Cannot get ControlAnimator.", GetErrorMessage(E_SYSTEM));
1114                         pControlAnimator->StopAllAnimations();
1115                 }
1116
1117                 // Set default value for formTransition
1118                 if (formTransition && (animationType >= SCENE_TRANSITION_ANIMATION_TYPE_LEFT) &&
1119                         (pFrameAnimator->GetStatus() == ANIMATOR_STATUS_STOPPED))
1120                 {
1121                         pFrameAnimator->SetFormTransitionAnimation(
1122                                         __animationDescriptions[animationType-SCENE_TRANSITION_ANIMATION_TYPE_LEFT].animationType,
1123                                         __animationDescriptions[animationType-SCENE_TRANSITION_ANIMATION_TYPE_LEFT].duration,
1124                                         __animationDescriptions[animationType-SCENE_TRANSITION_ANIMATION_TYPE_LEFT].interpolatorType);
1125                 }
1126
1127                 if (formTransition)
1128                 {       // Disable user input
1129                         if (__pCurrentScene)
1130                         {
1131                                 r = SetInputEventEnableState(*__pCurrentScene->GetForm(), false);
1132                                 SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1133                         }
1134                         r = SetInputEventEnableState(*pForm, false);
1135                         if (IsFailed(r))
1136                         {
1137                                 if (__pCurrentScene)
1138                                 {
1139                                         SetInputEventEnableState(*__pCurrentScene->GetForm(), true);
1140                                 }
1141                         }
1142                         SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1143                 }
1144         }
1145
1146         // Prepare animation for customization.
1147         CallListenerPrepareAnimation(*pScene, sceneId, const_cast<IList*>(pArgs), animationType, formTransition );
1148         // Setup Ui controls to show the result.
1149         if (sceneAlreadyCreated)
1150         {
1151                 if (formTransition)
1152                 {
1153                         if (pPanel)
1154                         {
1155                                 SwitchToPanel(pScene->GetFormId(), pPanel);
1156                         }
1157                         r = SetCurrentForm(*pForm, doAnimation); // FrameAnimator
1158                         SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1159                 }
1160                 else
1161                 {
1162                         r = SetCurrentForm(*pForm);
1163                         SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1164                         if (pPanel)
1165                         {
1166                                 SwitchToPanel(pScene->GetFormId(), pPanel, doAnimation); // ControlAnimator
1167                         }
1168                 }
1169         }
1170         else // Scene newly created
1171         {
1172                 if (formAlreadyCreated) // Panel scene created but base form already created - reuse base form.
1173                 {
1174                         if (formTransition)
1175                         {
1176                                 if (pPanel)
1177                                 {
1178                                         if (!panelAlreadyCreated)       // If a new panel created then Add Panel to Form
1179                                         {
1180                                                 AddControlToForm(*pForm, *pPanel);
1181                                         }
1182                                         SwitchToPanel(pScene->GetFormId(), pPanel);
1183                                 }
1184                                 r = SetCurrentForm(*pForm, (doAnimation));      // FrameAnimator
1185                                 SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1186                         }
1187                         else
1188                         {
1189                                 r = SetCurrentForm(*pForm);
1190                                 SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1191                                 if (pPanel)
1192                                 {
1193                                         if (!panelAlreadyCreated)
1194                                         {
1195                                                 AddControlToForm(*pForm, *pPanel);
1196                                         }
1197                                         SwitchToPanel(pScene->GetFormId(), pPanel, doAnimation); // ControlAnimator
1198                                 }
1199                         }
1200                 }
1201                 else    // New Form created!
1202                 {
1203                         if (pPanel)
1204                         {
1205                                 // New panel
1206                                 AddControlToForm(*pForm, *pPanel);
1207                                 SwitchToPanel(pScene->GetFormId(), pPanel);
1208                         }
1209                         AddControlToFrame(*pForm, doAnimation);         // Form add to frame
1210                         if (!doAnimation)
1211                         {
1212                                 SetCurrentForm(*pForm);
1213                         }
1214                 }
1215         }
1216
1217         UpdateCurrentScene(pScene);
1218         if ((historyOption == SCENE_HISTORY_OPTION_ADD_HISTORY) && (!previousSceneId.IsEmpty()))
1219         {
1220                 r = AddHistory(previousSceneId);
1221                 // Too late revert to previous scene, so just return the error code but not revert to previous state.
1222                 SysTryLog(NID_UI_SCENES, !IsFailed(r), "[%s] History adding failed.", GetErrorMessage(r));
1223         }
1224
1225         CallListenerOnSceneActivatedN(*pScene, previousSceneId, sceneId, const_cast<IList*>(pArgs));
1226         CallListenerOnSceneTransitionCompleted(previousSceneId, __currentSceneId);
1227
1228         if (destroyOption == SCENE_DESTROY_OPTION_DESTROY )
1229         {
1230                 if (previousIsPanelScene)
1231                 {
1232                         DestroySiblingPanelScene(previousSceneId);      // Destroy sibling Panel Scene
1233                 }
1234                 if (doAnimation)
1235                 {
1236                         ReserveDestroyingScene(previousSceneId);                // Destroy the Scene after animator finished(stopped).
1237                 }
1238                 else
1239                 {
1240                         DestroySceneAsync(previousSceneId);
1241                 }
1242         }
1243
1244         DrawForm(*pScene->GetForm());
1245         return r;
1246
1247 CATCH:
1248         // Check all exception case for proper delete the instances: Scene, Form, Panel and item corresponding container.
1249         if (onExceptionRemovepPanel)
1250         {
1251                 RemovePanelFromPanelContainer(pScene);
1252                 delete pPanel;  // Also needed it.
1253                 pPanel = null;
1254         }
1255         if (onExceptionRemoveFormIdFromFormContainer)
1256         {
1257                 RemoveFormFromFormContainer(pScene->GetFormId());
1258         }
1259         if (onExceptionDeletepForm)
1260         {
1261                 delete pForm;
1262                 pForm = null;
1263         }
1264         if (onExceptionRemovesceneIdFromSceneContainer)
1265         {
1266                 RemoveSceneFromContainer(sceneId);
1267         }
1268         if (onExceptionDeletepScene)
1269         {
1270                 delete pScene;
1271                 pScene = null;
1272         }
1273
1274         return r;
1275 }
1276
1277 Scene*
1278 _SceneManagerImpl::GetSceneFromContainer(const SceneId& sceneId) const
1279 {
1280         Scene* pScene = null;
1281         __sceneContainer.GetValue(sceneId, pScene);
1282         return pScene;
1283 }
1284
1285 Form*
1286 _SceneManagerImpl::GetFormFromContainer(const String& formId)
1287 {
1288         Form* pForm = null;
1289         __formContainer.GetValue(formId, pForm);
1290         return pForm;
1291 }
1292
1293 void
1294 _SceneManagerImpl::AddSceneToContainer(const SceneId& sceneId, Scene* pScene)
1295 {
1296         __sceneContainer.Add(sceneId, pScene);
1297 }
1298
1299 void
1300 _SceneManagerImpl::RemoveSceneFromContainer(const SceneId& sceneId)
1301 {
1302         __sceneContainer.Remove(sceneId);
1303 }
1304
1305 void
1306 _SceneManagerImpl::AddFormToContainer(const String& formId, Form* pForm)
1307 {
1308         __formContainer.Add(formId, pForm);
1309 }
1310
1311 void
1312 _SceneManagerImpl::RemoveFormFromFormContainer(const String& formId)
1313 {
1314         __formContainer.Remove(formId);
1315 }
1316
1317 void
1318 _SceneManagerImpl::AddPanelToPanelContainer(Scene* pScene)
1319 {
1320         __formToPanelMultiMap.Add(pScene->GetFormId(), pScene);
1321 }
1322
1323 void
1324 _SceneManagerImpl::RemovePanelFromPanelContainer(Scene* pScene)
1325 {
1326         __formToPanelMultiMap.Remove(pScene->GetFormId(), pScene);
1327 }
1328
1329 void
1330 _SceneManagerImpl::UpdateCurrentScene(Scene* pScene)
1331 {
1332         __pCurrentScene = pScene;
1333         __currentSceneId = pScene->GetSceneId();
1334 }
1335
1336 result
1337 _SceneManagerImpl::AddHistory(const SceneId& sceneId)
1338 {
1339         return __sceneHistory.Add(sceneId);
1340 }
1341
1342 void
1343 _SceneManagerImpl::SwitchToPanel(const String& formId, Panel* pPanel, bool useAnimator)
1344 {
1345         Panel* pShowPanel = null;
1346         Form* pBaseForm = null;
1347         if (useAnimator)
1348         {
1349                 pBaseForm = dynamic_cast<Form*>(pPanel->GetParent());
1350                 if (pBaseForm == null)
1351                 {
1352                         useAnimator = false;
1353                 }
1354         }
1355
1356         std::unique_ptr<IEnumeratorT<Scene*> > pSceneEnum(__formToPanelMultiMap.GetValuesN(formId));
1357         SysTryReturnVoidResult(NID_UI_SCENES, pSceneEnum != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
1358                                                    GetErrorMessage(E_OUT_OF_MEMORY));
1359         while (pSceneEnum->MoveNext() == E_SUCCESS)
1360         {
1361                 Scene* pCurrentScene = null;
1362                 pSceneEnum->GetCurrent(pCurrentScene);
1363                 SysTryReturnVoidResult(NID_UI_SCENES, pCurrentScene != null, E_SYSTEM, "[%s] Memory allocation failed.",
1364                                                            GetErrorMessage(E_OUT_OF_MEMORY));
1365                 if (pCurrentScene->GetPanel() != pPanel)
1366                 {
1367                         if (pCurrentScene->GetPanel()->GetShowState())
1368                         {
1369                                 pShowPanel = pCurrentScene->GetPanel();
1370                         }
1371                 }
1372         }
1373
1374         if (useAnimator && pShowPanel && pPanel)
1375         {
1376                 int transactionId = 0;
1377                 AnimationTransaction::Begin(transactionId);     // transactionId was set
1378         }
1379
1380         if (pShowPanel)
1381         {
1382                 if (useAnimator)
1383                 {
1384                         ControlAnimator* pControlAnimator = pShowPanel->GetControlAnimator();
1385                         if (pControlAnimator)
1386                         {
1387                                 pControlAnimator->SetShowState(false);
1388                         }
1389                         else
1390                         {
1391                                 pShowPanel->SetShowState(false);
1392                         }
1393                 }
1394                 else
1395                 {
1396                         pShowPanel->SetShowState(false);
1397                 }
1398         }
1399         if (pPanel)
1400         {
1401                 if (useAnimator)
1402                 {
1403                         ControlAnimator* pControlAnimator = pPanel->GetControlAnimator();
1404                         if (pControlAnimator)
1405                         {
1406                                 pControlAnimator->SetShowState(true);
1407                         }
1408                         else
1409                         {
1410                                 pPanel->SetShowState(true);
1411                         }
1412                 }
1413                 else
1414                 {
1415                         pPanel->SetShowState(true);
1416                 }
1417         }
1418
1419         if (useAnimator && pShowPanel && pPanel)
1420         {
1421                 // Set event listener & start animations
1422                 AnimationTransaction::SetCurrentTransactionEventListener(this);
1423                 result r = AnimationTransaction::Commit();
1424                 if (!IsFailed(r))
1425                 {
1426                         // Disable input for base Form
1427                         if (pBaseForm)
1428                         {
1429                                 __pDisabledForm = pBaseForm;
1430                                 SetInputEventEnableState(*pBaseForm, false);
1431                         }
1432                 }
1433                 else
1434                 {
1435                         SysLog(NID_UI_SCENES, "Animation Commit() failed");
1436                 }
1437         }
1438 }
1439
1440 void
1441 _SceneManagerImpl::AddControlToFrame(Form& form, bool useAnimator)
1442 {
1443         Frame* pFrame = GetFrame();
1444         if (pFrame)
1445         {
1446                 if (useAnimator)
1447                 {
1448                         FrameAnimator* pFrameAnimator = pFrame->GetFrameAnimator();
1449                         if (pFrameAnimator)
1450                         {
1451                                 // Add animator listener to asynchronous scene destroy for safe deletion.
1452                                 pFrameAnimator->AddFrameAnimatorEventListener(*this);
1453                                 _FrameAnimatorImpl* pFrameAnimatorImpl = _FrameAnimatorImpl::GetInstance(*pFrameAnimator);
1454                                 if (pFrameAnimatorImpl)
1455                                 {
1456                                         pFrameAnimatorImpl->AddControl(form);
1457                                         return;
1458                                 }
1459                         }
1460                         SysLog(NID_UI_SCENES, "pFrameAnimator or pFrameAnimatorImpl is not valid.");
1461                 }
1462                 pFrame->AddControl(form);
1463         }
1464 }
1465
1466 void
1467 _SceneManagerImpl::RemoveControlFromFrame(Form& form)
1468 {
1469         Frame* pFrame = GetFrame();
1470         if (pFrame)
1471         {
1472                 // Control validation check for safe operation on termination(Ui destroy before asynchronous scene destroy process).
1473                 _ControlManager* pControlManager = _ControlManager::GetInstance();
1474                 if (pControlManager)
1475                 {
1476                         _Control* pControl = pControlManager->GetObject(__correspondFrameControlHandle);
1477                         if (pControl)
1478                         {
1479                                 pFrame->RemoveControl(form);
1480                                 return;
1481                         }
1482                         else
1483                         {
1484                                 SysLog(NID_UI_SCENES, "FrameWindow already destroyed. Skip remove control to form.");
1485                         }
1486                 }
1487                 else
1488                 {
1489                         SysLog(NID_UI_SCENES, "Window system already shutdown.");
1490                 }
1491         }
1492 }
1493
1494 result
1495 _SceneManagerImpl::SetCurrentForm(Form& form, bool useAnimator)
1496 {
1497         result r = E_SUCCESS;
1498         Frame* pFrame = GetFrame();
1499
1500         SysTryReturnResult(NID_UI_SCENES, pFrame != null, E_SYSTEM,
1501                                            "A system error has been occurred. Can not get the Frame window.");
1502         if (useAnimator)
1503         {
1504                 FrameAnimator* pFrameAnimator = pFrame->GetFrameAnimator();
1505                 if (pFrameAnimator)
1506                 {
1507                         // Add animator listener to asynchronous scene destroy for safe deletion.
1508                         pFrameAnimator->AddFrameAnimatorEventListener(*this);
1509                         r = pFrameAnimator->SetCurrentForm(form);
1510                         if (r != E_SYSTEM)
1511                         {
1512                                 return E_SUCCESS;
1513                         }
1514                 }
1515                 SysLog(NID_UI_SCENES, "Safety operation ongoing. Animation may not working, Please check the problems!");
1516         }
1517
1518         r = pFrame->SetCurrentForm(form);
1519         SysTryReturnResult(NID_UI_SCENES, !IsFailed(r), E_SYSTEM, "A system error has been occurred. Can not set current form.");
1520         return E_SUCCESS;
1521 }
1522
1523 Form*
1524 _SceneManagerImpl::GetCurrentForm(void)
1525 {
1526         Frame* pFrame = GetFrame();
1527         if (pFrame)
1528         {
1529                 return pFrame->GetCurrentForm();
1530         }
1531         return null;
1532 }
1533
1534 void
1535 _SceneManagerImpl::AddControlToForm(Form& baseForm, const Panel& panel)
1536 {
1537         baseForm.AddControl(panel);
1538 }
1539
1540 void
1541 _SceneManagerImpl::RemoveControlFromForm(Form& baseForm, const Panel& panel)
1542 {
1543         baseForm.RemoveControl(panel);
1544 }
1545
1546 void
1547 _SceneManagerImpl::SetShowState(Panel& targetPanel, bool state)
1548 {
1549         targetPanel.SetShowState(state);
1550 }
1551
1552 void
1553 _SceneManagerImpl::DrawForm(Form& form)
1554 {
1555         form.Invalidate(true);
1556 }
1557
1558 bool
1559 _SceneManagerImpl::CallListenerOnSceneTransitionStarted(const SceneId& currentSceneId, const SceneId& nextSceneId)
1560 {
1561         std::unique_ptr<IEnumeratorT<ISceneManagerEventListener*> > pEnum(__sceneManagerEventListenerList.GetEnumeratorN());
1562         if (!pEnum)
1563         {
1564                 return false;
1565         }
1566
1567         while (pEnum->MoveNext() == E_SUCCESS)
1568         {
1569                 ISceneManagerEventListener*     pListener = null;
1570                 pEnum->GetCurrent(pListener);
1571                 if (pListener)
1572                 {
1573                         pListener->OnSceneTransitionStarted(currentSceneId, nextSceneId);
1574                 }
1575         }
1576         return true;
1577 }
1578
1579 bool
1580 _SceneManagerImpl::CallListenerOnSceneTransitionCompleted(const SceneId& previousSceneId, const SceneId& currentSceneId)
1581 {
1582         std::unique_ptr<IEnumeratorT<ISceneManagerEventListener*> > pEnum(__sceneManagerEventListenerList.GetEnumeratorN());
1583         if (!pEnum)
1584         {
1585                 return false;
1586         }
1587
1588         while (pEnum->MoveNext() == E_SUCCESS)
1589         {
1590                 ISceneManagerEventListener*     pListener = null;
1591                 pEnum->GetCurrent(pListener);
1592                 if (pListener)
1593                 {
1594                         pListener->OnSceneTransitionCompleted(previousSceneId, currentSceneId);
1595                 }
1596         }
1597         return true;
1598 }
1599
1600 bool
1601 _SceneManagerImpl::CallListenerPrepareAnimation(Scene& scene, const SceneId& sceneId, IList* pArgs,
1602                                                                                                 SceneTransitionAnimationType type, bool formTransition)
1603 {
1604         _SceneImpl* pSceneImpl = _SceneImpl::GetInstance(scene);
1605         SysTryReturn(NID_UI_SCENES, pSceneImpl, false, E_INVALID_STATE,
1606                                  "[%s] SceneManager is in an invalid state. scene is not valid.",
1607                                  GetErrorMessage(E_INVALID_STATE));
1608
1609         return pSceneImpl->PrepareAnimation(sceneId, pArgs, type, formTransition);
1610 }
1611
1612 bool
1613 _SceneManagerImpl::CallListenerOnSceneActivatedN(Scene& scene, const SceneId& previousSceneId, const SceneId& currentSceneId,
1614                                                                                                  IList* pArgs)
1615 {
1616         _SceneImpl* pSceneImpl = _SceneImpl::GetInstance(scene);
1617         SysTryReturn(NID_UI_SCENES, pSceneImpl, false, E_INVALID_STATE,
1618                                  "[%s] SceneManager is in an invalid state. scene is not valid.",
1619                                  GetErrorMessage(E_INVALID_STATE));
1620
1621         return pSceneImpl->OnSceneActivatedN(previousSceneId, currentSceneId, pArgs);
1622 }
1623
1624 bool
1625 _SceneManagerImpl::CallListenerOnSceneDeactivated(Scene& scene, const SceneId& currentSceneId, const SceneId& nextSceneId)
1626 {
1627         _SceneImpl* pSceneImpl = _SceneImpl::GetInstance(scene);
1628         SysTryReturn(NID_UI_SCENES, pSceneImpl, false, E_INVALID_STATE,
1629                                  "[%s] SceneManager is in an invalid state. scene is not valid.",
1630                                  GetErrorMessage(E_INVALID_STATE));
1631
1632         return pSceneImpl->OnSceneDeactivated(currentSceneId, nextSceneId);
1633 }
1634
1635 SceneId
1636 _SceneManagerImpl::CallStretegyGetNextScene(const SceneId& currentSceneId, const IList* pArgs)
1637 {
1638         SceneId nextScene(L"");
1639         if (__pPolicyProvider)
1640         {
1641                 nextScene = __pPolicyProvider->GetNextScene(currentSceneId, pArgs);
1642         }
1643         return nextScene;
1644 }
1645
1646 void
1647 _SceneManagerImpl::DestroySceneAsync(const SceneId& sceneId)
1648 {
1649         _SceneControlEventArg* pArg = new (std::nothrow) _SceneControlEventArg(
1650                                                                                                                 _SceneControlEventArg::SCENE_CONTROL_EVENT_TYPE_DESTROY, sceneId);
1651         SysTryReturnVoidResult(NID_UI_SCENES, pArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
1652                                                    GetErrorMessage(E_OUT_OF_MEMORY));
1653         __sceneControlEvent.FireAsync(*pArg);
1654 }
1655
1656 void
1657 _SceneManagerImpl::ReserveDestroyingScene(const SceneId& sceneId)
1658 {
1659         if (!__destroyReservedScene.IsEmpty())
1660         {
1661                 SysLog(NID_UI_SCENES, "Previous reserved sceneId=%ls", __destroyReservedScene.GetPointer());
1662         }
1663         __destroyReservedScene = sceneId;
1664 }
1665
1666 void
1667 _SceneManagerImpl::DestroyReservedScene(void)
1668 {
1669         if (!__destroyReservedScene.IsEmpty())
1670         {
1671                 DestroySceneAsync(__destroyReservedScene);
1672                 __destroyReservedScene.Clear();
1673         }
1674 }
1675
1676 void
1677 _SceneManagerImpl::DestroySiblingPanelScene(const SceneId& sceneId)
1678 {
1679         Scene* pScene = null;
1680         pScene = GetSceneFromContainer(sceneId);
1681         SysTryReturnVoidResult(NID_UI_SCENES, pScene != null, E_OBJ_NOT_FOUND, "[%s] Specified sceneId does not exist.",
1682                                                    GetErrorMessage(E_OBJ_NOT_FOUND));
1683
1684         Panel* pPanel = pScene->GetPanel();
1685         if (pPanel)
1686         {
1687                 int panelCount = 0;
1688                 result r = __formToPanelMultiMap.GetCount(pScene->GetFormId(), panelCount);
1689                 SysTryReturnVoidResult(NID_UI_SCENES, !IsFailed(r), E_SYSTEM,
1690                                                            "[%s] A system error has been occurred. Form(SceneId:%ls) not valid.",
1691                                                            GetErrorMessage(E_SYSTEM), sceneId.GetPointer());
1692                 if (panelCount <= 1)
1693                 {
1694                         return;
1695                 }
1696
1697                 ArrayListT<Scene*> destroyList;
1698                 std::unique_ptr<IEnumeratorT<Scene*> > pSceneEnum(__formToPanelMultiMap.GetValuesN(pScene->GetFormId()));
1699                 SysTryReturnVoidResult(NID_UI_SCENES, pSceneEnum != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
1700                                                            GetErrorMessage(E_OUT_OF_MEMORY));
1701                 while (pSceneEnum->MoveNext() == E_SUCCESS)
1702                 {
1703                         Scene* pCurrentScene = null;
1704                         pSceneEnum->GetCurrent(pCurrentScene);
1705                         SysTryReturnVoidResult(NID_UI_SCENES, pCurrentScene != null, E_SYSTEM,
1706                                                                    "[%s] A system error has been occurred. Current scene is not valid.",
1707                                                                    GetErrorMessage(E_SYSTEM));
1708                         if (pCurrentScene->GetPanel() != pPanel)
1709                         {
1710                                 destroyList.Add(pCurrentScene);                 // DestroyScene modify __formToPanelMultiMap so can't destroy here.
1711                         }
1712                 }
1713
1714                 for (int i = 0; i < destroyList.GetCount(); i++)
1715                 {
1716                         Scene* pCurrentScene = null;
1717                         destroyList.GetAt(i, pCurrentScene);
1718                         if (pCurrentScene)
1719                         {
1720                                 DestroyScene(pCurrentScene->GetSceneId());
1721                         }
1722                 }
1723         }
1724 }
1725
1726 Frame*
1727 _SceneManagerImpl::GetFrame(void)
1728 {
1729         if (__pCorrespondFrame == null)
1730         {
1731                 SysLog(NID_UI_SCENES, "WARNING! - Initialize error!. First GetInstance must call after set a FrameWindow.");
1732                 UiApp* pUiApp = UiApp::GetInstance();
1733                 SysTryReturn(NID_UI_SCENES, pUiApp != null, null, E_SYSTEM,
1734                                          "[%s] A system error has been occurred. UiApp::GetInstance failed.", GetErrorMessage(E_SYSTEM));
1735                 Frame* pFrame = pUiApp->GetFrameAt(0);
1736                 SysTryReturn(NID_UI_SCENES, pFrame != null, null, E_SYSTEM,
1737                                          "[%s] A system error has been occurred. pUiApp->GetFrameAt(0) return null.", GetErrorMessage(E_SYSTEM));
1738                 __pCorrespondFrame = pFrame;
1739                 _ContainerImpl* pFrameWindowImpl = _ContainerImpl::GetInstance(*__pCorrespondFrame);
1740                 if (pFrameWindowImpl)
1741                 {
1742                         __correspondFrameControlHandle = pFrameWindowImpl->GetCore().GetHandle();
1743                 }
1744         }
1745         return __pCorrespondFrame;
1746 }
1747
1748 bool
1749 _SceneManagerImpl::IsAnimationCompleted(void)
1750 {
1751         Frame* pFrame = GetFrame();
1752         SysTryReturn(NID_UI_SCENES, pFrame != null, true, E_SYSTEM, "[%s] A system error has been occurred. Cannot get Frame.",
1753                                  GetErrorMessage(E_SYSTEM));
1754         FrameAnimator* pFrameAnimator = pFrame->GetFrameAnimator();
1755
1756         if (pFrameAnimator)
1757         {
1758                 bool completed = (pFrameAnimator->GetStatus() == ANIMATOR_STATUS_STOPPED) ? true : false;
1759                 return completed;
1760         }
1761         return true;
1762 }
1763
1764 result
1765 _SceneManagerImpl::SetInputEventEnableState(Tizen::Ui::Control& control, bool enableState)
1766 {
1767         _ControlImpl* pControlImpl = _ControlImpl::GetInstance(control);
1768         SysTryReturnResult(NID_UI_SCENES, pControlImpl != null, E_SYSTEM, "A system error has been occurred. Cannot get _ControlImpl.");
1769         _Control& controlCore = pControlImpl->GetCore();
1770
1771         if (enableState == false)
1772         {
1773                 controlCore.LockInputEvent();
1774         }
1775         else
1776         {
1777                 controlCore.UnlockInputEvent();
1778         }
1779         return E_SUCCESS;
1780 }
1781
1782 result
1783 _SceneManagerImpl::GetSceneTransition(const SceneTransitionId& transitionId, SceneTransition& sceneTransition) const
1784 {
1785         result r = E_SUCCESS;
1786         SysTryReturnResult(NID_UI_SCENES, !transitionId.IsEmpty(), E_INVALID_ARG,
1787                                            "Invalid argument is used. The transitionId is empty.");
1788
1789         SceneTransition* pSceneTransition = null;
1790         r = __transitionMap.GetValue(transitionId, pSceneTransition);
1791         SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
1792         sceneTransition = *pSceneTransition;
1793
1794         return r;
1795 }
1796
1797 result
1798 _SceneManagerImpl::RegisterScene(xmlNodePtr pNode)
1799 {
1800         static const char* pPropId = "Id";
1801         static const char* pPropFormId = "Form";
1802         static const char* pPropPanelId = "Panel";
1803         result r = E_SUCCESS;
1804         _SceneDescription* pSceneDescription = null;
1805
1806         SysTryReturn(NID_UI_SCENES, pNode != null, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. pNode is null.",
1807                                  GetErrorMessage(E_INVALID_ARG));
1808
1809         xmlChar* pSceneId = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropId));
1810         if (pSceneId)
1811         {
1812                 String strSceneId(reinterpret_cast<char*>(pSceneId));
1813                 xmlFree(pSceneId);
1814
1815                 xmlChar* pFormId = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropFormId));
1816                 if (pFormId)
1817                 {
1818                         String strFormId(reinterpret_cast<char*>(pFormId));
1819                         xmlFree(pFormId);
1820
1821                         String strPanelId;
1822                         xmlChar* pPanelId = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropPanelId));
1823                         if (pPanelId)
1824                         {
1825                                 strPanelId = reinterpret_cast<char*>(pPanelId);
1826                                 xmlFree(pPanelId);
1827                         }
1828
1829                         // Register a Scene item
1830                         bool isContains = false;
1831                         r = __sceneMap.ContainsKey(strSceneId, isContains);
1832                         SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
1833                         SysTryReturnResult(NID_UI_SCENES, !isContains, E_OBJ_ALREADY_EXIST, "Specified sceneId already exist.");
1834
1835                         pSceneDescription = new (std::nothrow) _SceneDescription(strFormId, strPanelId);
1836                         SysTryReturnResult(NID_UI_SCENES, pSceneDescription != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1837
1838                         r = __sceneMap.Add(strSceneId, pSceneDescription);
1839                         SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1840                 }
1841         }
1842         return r;
1843
1844 CATCH:
1845         delete pSceneDescription;
1846         return r;
1847 }
1848
1849 result
1850 _SceneManagerImpl::RegisterSceneTransition(xmlNodePtr pNode)
1851 {
1852         static const xmlChar* pPropId = reinterpret_cast<const xmlChar*>("Id");
1853         static const char* pPropDestinationSceneId = "TargetId";
1854         static const char* pPropDirectionType = "DirectionType";
1855         static const char* pPropAnimationType = "AnimationType";
1856         static const char* pPropHistoryOption = "HistoryOption";
1857         static const char* pPropDestroyOption = "DestroyOption";
1858
1859         static const String strValueDirectionForward(L"forward");
1860         static const String strValueDirectionBackward(L"backward");
1861         static const String strValueDirectionAdjacentBackward(L"adjacentBackward");
1862         static const String strValueAnimationType[] = {L"none", L"custom", L"left", L"right", L"fade_in_out",
1863                                                                                                    L"zoom_in", L"zoom_out", L"depth_in", "depth_out"};
1864         static const String strValueHistoryOptionNoHistory(L"no");
1865         static const String strValueDestroyOptionKeep(L"keep");
1866         static const String strValueDestroyOptionDestroy(L"destroy");
1867
1868         static const SceneTransitionAnimationType valueAnimation[] = {
1869                 SCENE_TRANSITION_ANIMATION_TYPE_NONE, SCENE_TRANSITION_ANIMATION_TYPE_CUSTOM,
1870                 SCENE_TRANSITION_ANIMATION_TYPE_LEFT, SCENE_TRANSITION_ANIMATION_TYPE_RIGHT,
1871                 SCENE_TRANSITION_ANIMATION_TYPE_FADE_IN_OUT, SCENE_TRANSITION_ANIMATION_TYPE_ZOOM_IN,
1872                 SCENE_TRANSITION_ANIMATION_TYPE_ZOOM_OUT, SCENE_TRANSITION_ANIMATION_TYPE_DEPTH_IN,
1873                 SCENE_TRANSITION_ANIMATION_TYPE_DEPTH_OUT };
1874
1875         SceneTransition* pSceneTransition = null;
1876         result r = E_SUCCESS;
1877         SysTryReturn(NID_UI_SCENES, pNode != null, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. pNode is null.",
1878                                  GetErrorMessage(E_INVALID_ARG));
1879
1880         xmlChar* pTransitionId = xmlGetProp(pNode, pPropId);
1881         if (pTransitionId)
1882         {
1883                 String strTransitionId(reinterpret_cast<char*>(pTransitionId));
1884                 xmlFree(pTransitionId);
1885                 if (strTransitionId.GetLength() > 0)
1886                 {
1887                         xmlChar* pDirectionType = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropDirectionType));
1888                         if (pDirectionType)
1889                         {
1890                                 String strDirectionType(reinterpret_cast<char*>(pDirectionType));
1891                                 xmlFree(pDirectionType);
1892
1893                                 // Mandatory item: transitionId, direction
1894                                 // forward: destinationSceneId(mandatory), animationType, historyOption, destroyOption
1895                                 // backward: destinationSceneId(mandatory), animationType, destroyOption [ Don't care: historyOption ]
1896                                 // adjacentBackward: animationType, destroyOption [ Don't care: destinationSceneId, historyOption]
1897                                 String strDestinationSceneId;
1898                                 String strAnimationType;
1899                                 String strHistoryOption;
1900                                 String strDestroyOption;
1901                                 SceneTransitionAnimationType animationType = SCENE_TRANSITION_ANIMATION_TYPE_NONE;
1902
1903                                 // Get animationType and destroyOption (common property)
1904                                 xmlChar* pAnimationType = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropAnimationType));
1905                                 if (pAnimationType)
1906                                 {
1907                                         strAnimationType = reinterpret_cast<char*>(pAnimationType);
1908                                         xmlFree(pAnimationType);
1909                                         if (strAnimationType.GetLength() > 0)
1910                                         {
1911                                                 for (unsigned int i = 0; i < sizeof(valueAnimation)/sizeof(valueAnimation[0]); i++)
1912                                                 {       // Consider to use map collection.
1913                                                         if (strAnimationType == strValueAnimationType[i])
1914                                                         {
1915                                                                 animationType = valueAnimation[i];
1916                                                                 break;
1917                                                         }
1918                                                 }
1919                                         }
1920                                 }
1921
1922                                 xmlChar* pDestroyOption = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropDestroyOption));
1923                                 if (pDestroyOption)
1924                                 {
1925                                         strDestroyOption = reinterpret_cast<char*>(pDestroyOption);
1926                                         xmlFree(pDestroyOption);
1927                                 }
1928
1929                                 // Compose SceneTransition
1930                                 if (strDirectionType == strValueDirectionAdjacentBackward)      // Adjacent backward
1931                                 {
1932                                         SceneDestroyOption destroyOption = SCENE_DESTROY_OPTION_DESTROY;        // Default is destroy
1933                                         if ((strDestroyOption.GetLength() > 0) && (strDestroyOption == strValueDestroyOptionKeep))
1934                                         {
1935                                                 destroyOption = SCENE_DESTROY_OPTION_KEEP;
1936                                         }
1937
1938                                         pSceneTransition = new (std::nothrow) BackwardSceneTransition(animationType, destroyOption);
1939                                         SysTryReturnResult(NID_UI_SCENES, pSceneTransition != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1940                                         r = __transitionMap.Add(strTransitionId, pSceneTransition);
1941                                         SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1942                                         return r;
1943                                 }
1944
1945                                 // Get destinationSceneId
1946                                 xmlChar* pDestinationSceneId = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropDestinationSceneId));
1947                                 if (pDestinationSceneId)
1948                                 {
1949                                         strDestinationSceneId = reinterpret_cast<char*>(pDestinationSceneId);
1950                                         xmlFree(pDestinationSceneId);
1951                                 }
1952                                 SysTryReturn(NID_UI_SCENES, strDestinationSceneId.GetLength() > 0, E_INVALID_ARG, E_INVALID_ARG,
1953                                                          "[%s] Invalid argument is used. strDestinationSceneId is empty.", GetErrorMessage(E_INVALID_ARG));
1954
1955                                 if (strDirectionType == strValueDirectionBackward)              // Backward
1956                                 {
1957                                         SceneDestroyOption destroyOption = SCENE_DESTROY_OPTION_DESTROY;        // Default is destroy
1958                                         if ((strDestroyOption.GetLength() > 0) && (strDestroyOption == strValueDestroyOptionKeep))
1959                                         {
1960                                                 destroyOption = SCENE_DESTROY_OPTION_KEEP;
1961                                         }
1962
1963                                         pSceneTransition =
1964                                                         new (std::nothrow) BackwardSceneTransition(strDestinationSceneId, animationType, destroyOption);
1965                                         SysTryReturnResult(NID_UI_SCENES, pSceneTransition != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1966                                         r = __transitionMap.Add(strTransitionId, pSceneTransition);
1967                                         SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1968                                         return r;
1969                                 }
1970
1971                                 if (strDirectionType == strValueDirectionForward)               // Forward
1972                                 {
1973                                         SceneDestroyOption destroyOption = SCENE_DESTROY_OPTION_KEEP;           // Default is keep
1974                                         if ((strDestroyOption.GetLength() > 0) && (strDestroyOption == strValueDestroyOptionDestroy))
1975                                         {
1976                                                 destroyOption = SCENE_DESTROY_OPTION_DESTROY;
1977                                         }
1978
1979                                         xmlChar* pHistoryOption = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropHistoryOption));
1980                                         if (pHistoryOption)
1981                                         {
1982                                                 strHistoryOption = reinterpret_cast<char*>(pHistoryOption);
1983                                                 xmlFree(pHistoryOption);
1984                                         }
1985                                         SceneHistoryOption historyOption = SCENE_HISTORY_OPTION_ADD_HISTORY;    // Default is add to history
1986                                         if ((strHistoryOption.GetLength() > 0) && (strHistoryOption == strValueHistoryOptionNoHistory))
1987                                         {
1988                                                 historyOption = SCENE_HISTORY_OPTION_NO_HISTORY;
1989                                         }
1990
1991                                         pSceneTransition = new (std::nothrow) ForwardSceneTransition(strDestinationSceneId, animationType,
1992                                                                                                                                                                  historyOption, destroyOption);
1993                                         SysTryReturnResult(NID_UI_SCENES, pSceneTransition != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1994                                         r = __transitionMap.Add(strTransitionId, pSceneTransition);
1995                                         SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1996                                         return r;
1997                                 }
1998                                 else
1999                                 {
2000                                         SysLog(NID_UI_SCENES, "Unknown direction type!");
2001                                 }
2002                         }
2003                 }
2004         }
2005         return r;
2006
2007 CATCH:
2008         delete pSceneTransition;
2009         return r;
2010 }
2011
2012 result
2013 _SceneManagerImpl::StopAllAnimations(void)
2014 {
2015         Frame* pFrame = GetFrame();
2016         SysTryReturnResult(NID_UI_SCENES, pFrame != null, E_SYSTEM, "A system error has been occurred. Cannot get Frame.");
2017         FrameAnimator* pFrameAnimator = pFrame->GetFrameAnimator();
2018         SysTryReturnResult(NID_UI_SCENES, pFrameAnimator != null, E_SYSTEM, "A system error has been occurred. Cannot get FrameAnimator.");
2019         pFrameAnimator->StopAllAnimations();
2020         if (!__destroyReservedScene.IsEmpty())
2021         {
2022                 DestroyScene(__destroyReservedScene);
2023                 __destroyReservedScene.Clear();
2024         }
2025         return E_SUCCESS;
2026 }
2027
2028 } } } // Tizen::Ui::Scenes