Add logic for prevent duplicated form id using on Form based Scene registrations...
[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                                 SetInputEventEnableState(*__pCurrentScene->GetForm(), true);
1138                         }
1139                         SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1140                 }
1141         }
1142
1143         // Prepare animation for customization.
1144         CallListenerPrepareAnimation(*pScene, sceneId, const_cast<IList*>(pArgs), animationType, formTransition );
1145         // Setup Ui controls to show the result.
1146         if (sceneAlreadyCreated)
1147         {
1148                 if (formTransition)
1149                 {
1150                         if (pPanel)
1151                         {
1152                                 SwitchToPanel(pScene->GetFormId(), pPanel);
1153                         }
1154                         r = SetCurrentForm(*pForm, doAnimation); // FrameAnimator
1155                         SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1156                 }
1157                 else
1158                 {
1159                         r = SetCurrentForm(*pForm);
1160                         SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1161                         if (pPanel)
1162                         {
1163                                 SwitchToPanel(pScene->GetFormId(), pPanel, doAnimation); // ControlAnimator
1164                         }
1165                 }
1166         }
1167         else // Scene newly created
1168         {
1169                 if (formAlreadyCreated) // Panel scene created but base form already created - reuse base form.
1170                 {
1171                         if (formTransition)
1172                         {
1173                                 if (pPanel)
1174                                 {
1175                                         if (!panelAlreadyCreated)       // If a new panel created then Add Panel to Form
1176                                         {
1177                                                 AddControlToForm(*pForm, *pPanel);
1178                                         }
1179                                         SwitchToPanel(pScene->GetFormId(), pPanel);
1180                                 }
1181                                 r = SetCurrentForm(*pForm, (doAnimation));      // FrameAnimator
1182                                 SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1183                         }
1184                         else
1185                         {
1186                                 r = SetCurrentForm(*pForm);
1187                                 SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1188                                 if (pPanel)
1189                                 {
1190                                         if (!panelAlreadyCreated)
1191                                         {
1192                                                 AddControlToForm(*pForm, *pPanel);
1193                                         }
1194                                         SwitchToPanel(pScene->GetFormId(), pPanel, doAnimation); // ControlAnimator
1195                                 }
1196                         }
1197                 }
1198                 else    // New Form created!
1199                 {
1200                         if (pPanel)
1201                         {
1202                                 // New panel
1203                                 AddControlToForm(*pForm, *pPanel);
1204                                 SwitchToPanel(pScene->GetFormId(), pPanel);
1205                         }
1206                         AddControlToFrame(*pForm, doAnimation);         // Form add to frame
1207                         if (!doAnimation)
1208                         {
1209                                 SetCurrentForm(*pForm);
1210                         }
1211                 }
1212         }
1213
1214         UpdateCurrentScene(pScene);
1215         if ((historyOption == SCENE_HISTORY_OPTION_ADD_HISTORY) && (!previousSceneId.IsEmpty()))
1216         {
1217                 r = AddHistory(previousSceneId);
1218                 // Too late revert to previous scene, so just return the error code but not revert to previous state.
1219                 SysTryLog(NID_UI_SCENES, !IsFailed(r), "[%s] History adding failed.", GetErrorMessage(r));
1220         }
1221
1222         CallListenerOnSceneActivatedN(*pScene, previousSceneId, sceneId, const_cast<IList*>(pArgs));
1223         CallListenerOnSceneTransitionCompleted(previousSceneId, __currentSceneId);
1224
1225         if (destroyOption == SCENE_DESTROY_OPTION_DESTROY )
1226         {
1227                 if (previousIsPanelScene)
1228                 {
1229                         DestroySiblingPanelScene(previousSceneId);      // Destroy sibling Panel Scene
1230                 }
1231                 if (doAnimation)
1232                 {
1233                         ReserveDestroyingScene(previousSceneId);                // Destroy the Scene after animator finished(stopped).
1234                 }
1235                 else
1236                 {
1237                         DestroySceneAsync(previousSceneId);
1238                 }
1239         }
1240
1241         DrawForm(*pScene->GetForm());
1242         return r;
1243
1244 CATCH:
1245         // Check all exception case for proper delete the instances: Scene, Form, Panel and item corresponding container.
1246         if (onExceptionRemovepPanel)
1247         {
1248                 RemovePanelFromPanelContainer(pScene);
1249                 delete pPanel;  // Also needed it.
1250                 pPanel = null;
1251         }
1252         if (onExceptionRemoveFormIdFromFormContainer)
1253         {
1254                 RemoveFormFromFormContainer(pScene->GetFormId());
1255         }
1256         if (onExceptionDeletepForm)
1257         {
1258                 delete pForm;
1259                 pForm = null;
1260         }
1261         if (onExceptionRemovesceneIdFromSceneContainer)
1262         {
1263                 RemoveSceneFromContainer(sceneId);
1264         }
1265         if (onExceptionDeletepScene)
1266         {
1267                 delete pScene;
1268                 pScene = null;
1269         }
1270
1271         return r;
1272 }
1273
1274 Scene*
1275 _SceneManagerImpl::GetSceneFromContainer(const SceneId& sceneId) const
1276 {
1277         Scene* pScene = null;
1278         __sceneContainer.GetValue(sceneId, pScene);
1279         return pScene;
1280 }
1281
1282 Form*
1283 _SceneManagerImpl::GetFormFromContainer(const String& formId)
1284 {
1285         Form* pForm = null;
1286         __formContainer.GetValue(formId, pForm);
1287         return pForm;
1288 }
1289
1290 void
1291 _SceneManagerImpl::AddSceneToContainer(const SceneId& sceneId, Scene* pScene)
1292 {
1293         __sceneContainer.Add(sceneId, pScene);
1294 }
1295
1296 void
1297 _SceneManagerImpl::RemoveSceneFromContainer(const SceneId& sceneId)
1298 {
1299         __sceneContainer.Remove(sceneId);
1300 }
1301
1302 void
1303 _SceneManagerImpl::AddFormToContainer(const String& formId, Form* pForm)
1304 {
1305         __formContainer.Add(formId, pForm);
1306 }
1307
1308 void
1309 _SceneManagerImpl::RemoveFormFromFormContainer(const String& formId)
1310 {
1311         __formContainer.Remove(formId);
1312 }
1313
1314 void
1315 _SceneManagerImpl::AddPanelToPanelContainer(Scene* pScene)
1316 {
1317         __formToPanelMultiMap.Add(pScene->GetFormId(), pScene);
1318 }
1319
1320 void
1321 _SceneManagerImpl::RemovePanelFromPanelContainer(Scene* pScene)
1322 {
1323         __formToPanelMultiMap.Remove(pScene->GetFormId(), pScene);
1324 }
1325
1326 void
1327 _SceneManagerImpl::UpdateCurrentScene(Scene* pScene)
1328 {
1329         __pCurrentScene = pScene;
1330         __currentSceneId = pScene->GetSceneId();
1331 }
1332
1333 result
1334 _SceneManagerImpl::AddHistory(const SceneId& sceneId)
1335 {
1336         return __sceneHistory.Add(sceneId);
1337 }
1338
1339 void
1340 _SceneManagerImpl::SwitchToPanel(const String& formId, Panel* pPanel, bool useAnimator)
1341 {
1342         Panel* pShowPanel = null;
1343         Form* pBaseForm = null;
1344         if (useAnimator)
1345         {
1346                 pBaseForm = dynamic_cast<Form*>(pPanel->GetParent());
1347                 if (pBaseForm == null)
1348                 {
1349                         useAnimator = false;
1350                 }
1351         }
1352
1353         std::unique_ptr<IEnumeratorT<Scene*> > pSceneEnum(__formToPanelMultiMap.GetValuesN(formId));
1354         SysTryReturnVoidResult(NID_UI_SCENES, pSceneEnum != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
1355                                                    GetErrorMessage(E_OUT_OF_MEMORY));
1356         while (pSceneEnum->MoveNext() == E_SUCCESS)
1357         {
1358                 Scene* pCurrentScene = null;
1359                 pSceneEnum->GetCurrent(pCurrentScene);
1360                 SysTryReturnVoidResult(NID_UI_SCENES, pCurrentScene != null, E_SYSTEM, "[%s] Memory allocation failed.",
1361                                                            GetErrorMessage(E_OUT_OF_MEMORY));
1362                 if (pCurrentScene->GetPanel() != pPanel)
1363                 {
1364                         if (pCurrentScene->GetPanel()->GetShowState())
1365                         {
1366                                 pShowPanel = pCurrentScene->GetPanel();
1367                         }
1368                 }
1369         }
1370
1371         if (useAnimator && pShowPanel && pPanel)
1372         {
1373                 int transactionId = 0;
1374                 AnimationTransaction::Begin(transactionId);     // transactionId was set
1375         }
1376
1377         if (pShowPanel)
1378         {
1379                 if (useAnimator)
1380                 {
1381                         ControlAnimator* pControlAnimator = pShowPanel->GetControlAnimator();
1382                         if (pControlAnimator)
1383                         {
1384                                 pControlAnimator->SetShowState(false);
1385                         }
1386                         else
1387                         {
1388                                 pShowPanel->SetShowState(false);
1389                         }
1390                 }
1391                 else
1392                 {
1393                         pShowPanel->SetShowState(false);
1394                 }
1395         }
1396         if (pPanel)
1397         {
1398                 if (useAnimator)
1399                 {
1400                         ControlAnimator* pControlAnimator = pPanel->GetControlAnimator();
1401                         if (pControlAnimator)
1402                         {
1403                                 pControlAnimator->SetShowState(true);
1404                         }
1405                         else
1406                         {
1407                                 pPanel->SetShowState(true);
1408                         }
1409                 }
1410                 else
1411                 {
1412                         pPanel->SetShowState(true);
1413                 }
1414         }
1415
1416         if (useAnimator && pShowPanel && pPanel)
1417         {
1418                 // Set event listener & start animations
1419                 AnimationTransaction::SetCurrentTransactionEventListener(this);
1420                 result r = AnimationTransaction::Commit();
1421                 if (!IsFailed(r))
1422                 {
1423                         // Disable input for base Form
1424                         if (pBaseForm)
1425                         {
1426                                 __pDisabledForm = pBaseForm;
1427                                 SetInputEventEnableState(*pBaseForm, false);
1428                         }
1429                 }
1430                 else
1431                 {
1432                         SysLog(NID_UI_SCENES, "Animation Commit() failed");
1433                 }
1434         }
1435 }
1436
1437 void
1438 _SceneManagerImpl::AddControlToFrame(Form& form, bool useAnimator)
1439 {
1440         Frame* pFrame = GetFrame();
1441         if (pFrame)
1442         {
1443                 if (useAnimator)
1444                 {
1445                         FrameAnimator* pFrameAnimator = pFrame->GetFrameAnimator();
1446                         if (pFrameAnimator)
1447                         {
1448                                 // Add animator listener to asynchronous scene destroy for safe deletion.
1449                                 pFrameAnimator->AddFrameAnimatorEventListener(*this);
1450                                 _FrameAnimatorImpl* pFrameAnimatorImpl = _FrameAnimatorImpl::GetInstance(*pFrameAnimator);
1451                                 if (pFrameAnimatorImpl)
1452                                 {
1453                                         pFrameAnimatorImpl->AddControl(form);
1454                                         return;
1455                                 }
1456                         }
1457                         SysLog(NID_UI_SCENES, "pFrameAnimator or pFrameAnimatorImpl is not valid.");
1458                 }
1459                 pFrame->AddControl(form);
1460         }
1461 }
1462
1463 void
1464 _SceneManagerImpl::RemoveControlFromFrame(Form& form)
1465 {
1466         Frame* pFrame = GetFrame();
1467         if (pFrame)
1468         {
1469                 // Control validation check for safe operation on termination(Ui destroy before asynchronous scene destroy process).
1470                 _ControlManager* pControlManager = _ControlManager::GetInstance();
1471                 if (pControlManager)
1472                 {
1473                         _Control* pControl = pControlManager->GetObject(__correspondFrameControlHandle);
1474                         if (pControl)
1475                         {
1476                                 pFrame->RemoveControl(form);
1477                                 return;
1478                         }
1479                         else
1480                         {
1481                                 SysLog(NID_UI_SCENES, "FrameWindow already destroyed. Skip remove control to form.");
1482                         }
1483                 }
1484                 else
1485                 {
1486                         SysLog(NID_UI_SCENES, "Window system already shutdown.");
1487                 }
1488         }
1489 }
1490
1491 result
1492 _SceneManagerImpl::SetCurrentForm(Form& form, bool useAnimator)
1493 {
1494         result r = E_SUCCESS;
1495         Frame* pFrame = GetFrame();
1496
1497         SysTryReturnResult(NID_UI_SCENES, pFrame != null, E_SYSTEM,
1498                                            "A system error has been occurred. Can not get the Frame window.");
1499         if (useAnimator)
1500         {
1501                 FrameAnimator* pFrameAnimator = pFrame->GetFrameAnimator();
1502                 if (pFrameAnimator)
1503                 {
1504                         // Add animator listener to asynchronous scene destroy for safe deletion.
1505                         pFrameAnimator->AddFrameAnimatorEventListener(*this);
1506                         r = pFrameAnimator->SetCurrentForm(form);
1507                         if (r != E_SYSTEM)
1508                         {
1509                                 return E_SUCCESS;
1510                         }
1511                 }
1512                 SysLog(NID_UI_SCENES, "Safety operation ongoing. Animation may not working, Please check the problems!");
1513         }
1514
1515         r = pFrame->SetCurrentForm(form);
1516         SysTryReturnResult(NID_UI_SCENES, !IsFailed(r), E_SYSTEM, "A system error has been occurred. Can not set current form.");
1517         return E_SUCCESS;
1518 }
1519
1520 Form*
1521 _SceneManagerImpl::GetCurrentForm(void)
1522 {
1523         Frame* pFrame = GetFrame();
1524         if (pFrame)
1525         {
1526                 return pFrame->GetCurrentForm();
1527         }
1528         return null;
1529 }
1530
1531 void
1532 _SceneManagerImpl::AddControlToForm(Form& baseForm, const Panel& panel)
1533 {
1534         baseForm.AddControl(panel);
1535 }
1536
1537 void
1538 _SceneManagerImpl::RemoveControlFromForm(Form& baseForm, const Panel& panel)
1539 {
1540         baseForm.RemoveControl(panel);
1541 }
1542
1543 void
1544 _SceneManagerImpl::SetShowState(Panel& targetPanel, bool state)
1545 {
1546         targetPanel.SetShowState(state);
1547 }
1548
1549 void
1550 _SceneManagerImpl::DrawForm(Form& form)
1551 {
1552         form.Invalidate(true);
1553 }
1554
1555 bool
1556 _SceneManagerImpl::CallListenerOnSceneTransitionStarted(const SceneId& currentSceneId, const SceneId& nextSceneId)
1557 {
1558         std::unique_ptr<IEnumeratorT<ISceneManagerEventListener*> > pEnum(__sceneManagerEventListenerList.GetEnumeratorN());
1559         if (!pEnum)
1560         {
1561                 return false;
1562         }
1563
1564         while (pEnum->MoveNext() == E_SUCCESS)
1565         {
1566                 ISceneManagerEventListener*     pListener = null;
1567                 pEnum->GetCurrent(pListener);
1568                 if (pListener)
1569                 {
1570                         pListener->OnSceneTransitionStarted(currentSceneId, nextSceneId);
1571                 }
1572         }
1573         return true;
1574 }
1575
1576 bool
1577 _SceneManagerImpl::CallListenerOnSceneTransitionCompleted(const SceneId& previousSceneId, const SceneId& currentSceneId)
1578 {
1579         std::unique_ptr<IEnumeratorT<ISceneManagerEventListener*> > pEnum(__sceneManagerEventListenerList.GetEnumeratorN());
1580         if (!pEnum)
1581         {
1582                 return false;
1583         }
1584
1585         while (pEnum->MoveNext() == E_SUCCESS)
1586         {
1587                 ISceneManagerEventListener*     pListener = null;
1588                 pEnum->GetCurrent(pListener);
1589                 if (pListener)
1590                 {
1591                         pListener->OnSceneTransitionCompleted(previousSceneId, currentSceneId);
1592                 }
1593         }
1594         return true;
1595 }
1596
1597 bool
1598 _SceneManagerImpl::CallListenerPrepareAnimation(Scene& scene, const SceneId& sceneId, IList* pArgs,
1599                                                                                                 SceneTransitionAnimationType type, bool formTransition)
1600 {
1601         _SceneImpl* pSceneImpl = _SceneImpl::GetInstance(scene);
1602         SysTryReturn(NID_UI_SCENES, pSceneImpl, false, E_INVALID_STATE,
1603                                  "[%s] SceneManager is in an invalid state. scene is not valid.",
1604                                  GetErrorMessage(E_INVALID_STATE));
1605
1606         return pSceneImpl->PrepareAnimation(sceneId, pArgs, type, formTransition);
1607 }
1608
1609 bool
1610 _SceneManagerImpl::CallListenerOnSceneActivatedN(Scene& scene, const SceneId& previousSceneId, const SceneId& currentSceneId,
1611                                                                                                  IList* pArgs)
1612 {
1613         _SceneImpl* pSceneImpl = _SceneImpl::GetInstance(scene);
1614         SysTryReturn(NID_UI_SCENES, pSceneImpl, false, E_INVALID_STATE,
1615                                  "[%s] SceneManager is in an invalid state. scene is not valid.",
1616                                  GetErrorMessage(E_INVALID_STATE));
1617
1618         return pSceneImpl->OnSceneActivatedN(previousSceneId, currentSceneId, pArgs);
1619 }
1620
1621 bool
1622 _SceneManagerImpl::CallListenerOnSceneDeactivated(Scene& scene, const SceneId& currentSceneId, const SceneId& nextSceneId)
1623 {
1624         _SceneImpl* pSceneImpl = _SceneImpl::GetInstance(scene);
1625         SysTryReturn(NID_UI_SCENES, pSceneImpl, false, E_INVALID_STATE,
1626                                  "[%s] SceneManager is in an invalid state. scene is not valid.",
1627                                  GetErrorMessage(E_INVALID_STATE));
1628
1629         return pSceneImpl->OnSceneDeactivated(currentSceneId, nextSceneId);
1630 }
1631
1632 SceneId
1633 _SceneManagerImpl::CallStretegyGetNextScene(const SceneId& currentSceneId, const IList* pArgs)
1634 {
1635         SceneId nextScene(L"");
1636         if (__pPolicyProvider)
1637         {
1638                 nextScene = __pPolicyProvider->GetNextScene(currentSceneId, pArgs);
1639         }
1640         return nextScene;
1641 }
1642
1643 void
1644 _SceneManagerImpl::DestroySceneAsync(const SceneId& sceneId)
1645 {
1646         _SceneControlEventArg* pArg = new (std::nothrow) _SceneControlEventArg(
1647                                                                                                                 _SceneControlEventArg::SCENE_CONTROL_EVENT_TYPE_DESTROY, sceneId);
1648         SysTryReturnVoidResult(NID_UI_SCENES, pArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
1649                                                    GetErrorMessage(E_OUT_OF_MEMORY));
1650         __sceneControlEvent.FireAsync(*pArg);
1651 }
1652
1653 void
1654 _SceneManagerImpl::ReserveDestroyingScene(const SceneId& sceneId)
1655 {
1656         if (!__destroyReservedScene.IsEmpty())
1657         {
1658                 SysLog(NID_UI_SCENES, "Previous reserved sceneId=%ls", __destroyReservedScene.GetPointer());
1659         }
1660         __destroyReservedScene = sceneId;
1661 }
1662
1663 void
1664 _SceneManagerImpl::DestroyReservedScene(void)
1665 {
1666         if (!__destroyReservedScene.IsEmpty())
1667         {
1668                 DestroySceneAsync(__destroyReservedScene);
1669                 __destroyReservedScene.Clear();
1670         }
1671 }
1672
1673 void
1674 _SceneManagerImpl::DestroySiblingPanelScene(const SceneId& sceneId)
1675 {
1676         Scene* pScene = null;
1677         pScene = GetSceneFromContainer(sceneId);
1678         SysTryReturnVoidResult(NID_UI_SCENES, pScene != null, E_OBJ_NOT_FOUND, "[%s] Specified sceneId does not exist.",
1679                                                    GetErrorMessage(E_OBJ_NOT_FOUND));
1680
1681         Panel* pPanel = pScene->GetPanel();
1682         if (pPanel)
1683         {
1684                 int panelCount = 0;
1685                 result r = __formToPanelMultiMap.GetCount(pScene->GetFormId(), panelCount);
1686                 SysTryReturnVoidResult(NID_UI_SCENES, !IsFailed(r), E_SYSTEM,
1687                                                            "[%s] A system error has been occurred. Form(SceneId:%ls) not valid.",
1688                                                            GetErrorMessage(E_SYSTEM), sceneId.GetPointer());
1689                 if (panelCount <= 1)
1690                 {
1691                         return;
1692                 }
1693
1694                 ArrayListT<Scene*> destroyList;
1695                 std::unique_ptr<IEnumeratorT<Scene*> > pSceneEnum(__formToPanelMultiMap.GetValuesN(pScene->GetFormId()));
1696                 SysTryReturnVoidResult(NID_UI_SCENES, pSceneEnum != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
1697                                                            GetErrorMessage(E_OUT_OF_MEMORY));
1698                 while (pSceneEnum->MoveNext() == E_SUCCESS)
1699                 {
1700                         Scene* pCurrentScene = null;
1701                         pSceneEnum->GetCurrent(pCurrentScene);
1702                         SysTryReturnVoidResult(NID_UI_SCENES, pCurrentScene != null, E_SYSTEM,
1703                                                                    "[%s] A system error has been occurred. Current scene is not valid.",
1704                                                                    GetErrorMessage(E_SYSTEM));
1705                         if (pCurrentScene->GetPanel() != pPanel)
1706                         {
1707                                 destroyList.Add(pCurrentScene);                 // DestroyScene modify __formToPanelMultiMap so can't destroy here.
1708                         }
1709                 }
1710
1711                 for (int i = 0; i < destroyList.GetCount(); i++)
1712                 {
1713                         Scene* pCurrentScene = null;
1714                         destroyList.GetAt(i, pCurrentScene);
1715                         if (pCurrentScene)
1716                         {
1717                                 DestroyScene(pCurrentScene->GetSceneId());
1718                         }
1719                 }
1720         }
1721 }
1722
1723 Frame*
1724 _SceneManagerImpl::GetFrame(void)
1725 {
1726         if (__pCorrespondFrame == null)
1727         {
1728                 SysLog(NID_UI_SCENES, "WARNING! - Initialize error!. First GetInstance must call after set a FrameWindow.");
1729                 UiApp* pUiApp = UiApp::GetInstance();
1730                 SysTryReturn(NID_UI_SCENES, pUiApp != null, null, E_SYSTEM,
1731                                          "[%s] A system error has been occurred. UiApp::GetInstance failed.", GetErrorMessage(E_SYSTEM));
1732                 Frame* pFrame = pUiApp->GetFrameAt(0);
1733                 SysTryReturn(NID_UI_SCENES, pFrame != null, null, E_SYSTEM,
1734                                          "[%s] A system error has been occurred. pUiApp->GetFrameAt(0) return null.", GetErrorMessage(E_SYSTEM));
1735                 __pCorrespondFrame = pFrame;
1736                 _ContainerImpl* pFrameWindowImpl = _ContainerImpl::GetInstance(*__pCorrespondFrame);
1737                 if (pFrameWindowImpl)
1738                 {
1739                         __correspondFrameControlHandle = pFrameWindowImpl->GetCore().GetHandle();
1740                 }
1741         }
1742         return __pCorrespondFrame;
1743 }
1744
1745 bool
1746 _SceneManagerImpl::IsAnimationCompleted(void)
1747 {
1748         Frame* pFrame = GetFrame();
1749         SysTryReturn(NID_UI_SCENES, pFrame != null, true, E_SYSTEM, "[%s] A system error has been occurred. Cannot get Frame.",
1750                                  GetErrorMessage(E_SYSTEM));
1751         FrameAnimator* pFrameAnimator = pFrame->GetFrameAnimator();
1752
1753         if (pFrameAnimator)
1754         {
1755                 bool completed = (pFrameAnimator->GetStatus() == ANIMATOR_STATUS_STOPPED) ? true : false;
1756                 return completed;
1757         }
1758         return true;
1759 }
1760
1761 result
1762 _SceneManagerImpl::SetInputEventEnableState(Tizen::Ui::Control& control, bool enableState)
1763 {
1764         _ControlImpl* pControlImpl = _ControlImpl::GetInstance(control);
1765         SysTryReturnResult(NID_UI_SCENES, pControlImpl != null, E_SYSTEM, "A system error has been occurred. Cannot get _ControlImpl.");
1766         _Control& controlCore = pControlImpl->GetCore();
1767
1768         if (enableState == false)
1769         {
1770                 controlCore.LockInputEvent();
1771         }
1772         else
1773         {
1774                 controlCore.UnlockInputEvent();
1775         }
1776         return E_SUCCESS;
1777 }
1778
1779 result
1780 _SceneManagerImpl::GetSceneTransition(const SceneTransitionId& transitionId, SceneTransition& sceneTransition) const
1781 {
1782         result r = E_SUCCESS;
1783         SysTryReturnResult(NID_UI_SCENES, !transitionId.IsEmpty(), E_INVALID_ARG,
1784                                            "Invalid argument is used. The transitionId is empty.");
1785
1786         SceneTransition* pSceneTransition = null;
1787         r = __transitionMap.GetValue(transitionId, pSceneTransition);
1788         SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
1789         sceneTransition = *pSceneTransition;
1790
1791         return r;
1792 }
1793
1794 result
1795 _SceneManagerImpl::RegisterScene(xmlNodePtr pNode)
1796 {
1797         static const char* pPropId = "Id";
1798         static const char* pPropFormId = "Form";
1799         static const char* pPropPanelId = "Panel";
1800         result r = E_SUCCESS;
1801         _SceneDescription* pSceneDescription = null;
1802
1803         SysTryReturn(NID_UI_SCENES, pNode != null, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. pNode is null.",
1804                                  GetErrorMessage(E_INVALID_ARG));
1805
1806         xmlChar* pSceneId = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropId));
1807         if (pSceneId)
1808         {
1809                 String strSceneId(reinterpret_cast<char*>(pSceneId));
1810                 xmlFree(pSceneId);
1811
1812                 xmlChar* pFormId = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropFormId));
1813                 if (pFormId)
1814                 {
1815                         String strFormId(reinterpret_cast<char*>(pFormId));
1816                         xmlFree(pFormId);
1817
1818                         String strPanelId;
1819                         xmlChar* pPanelId = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropPanelId));
1820                         if (pPanelId)
1821                         {
1822                                 strPanelId = reinterpret_cast<char*>(pPanelId);
1823                                 xmlFree(pPanelId);
1824                         }
1825
1826                         // Register a Scene item
1827                         bool isContains = false;
1828                         r = __sceneMap.ContainsKey(strSceneId, isContains);
1829                         SysTryReturn(NID_UI_SCENES, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
1830                         SysTryReturnResult(NID_UI_SCENES, !isContains, E_OBJ_ALREADY_EXIST, "Specified sceneId already exist.");
1831
1832                         pSceneDescription = new (std::nothrow) _SceneDescription(strFormId, strPanelId);
1833                         SysTryReturnResult(NID_UI_SCENES, pSceneDescription != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1834
1835                         r = __sceneMap.Add(strSceneId, pSceneDescription);
1836                         SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1837                 }
1838         }
1839         return r;
1840
1841 CATCH:
1842         delete pSceneDescription;
1843         return r;
1844 }
1845
1846 result
1847 _SceneManagerImpl::RegisterSceneTransition(xmlNodePtr pNode)
1848 {
1849         static const xmlChar* pPropId = reinterpret_cast<const xmlChar*>("Id");
1850         static const char* pPropDestinationSceneId = "TargetId";
1851         static const char* pPropDirectionType = "DirectionType";
1852         static const char* pPropAnimationType = "AnimationType";
1853         static const char* pPropHistoryOption = "HistoryOption";
1854         static const char* pPropDestroyOption = "DestroyOption";
1855
1856         static const String strValueDirectionForward(L"forward");
1857         static const String strValueDirectionBackward(L"backward");
1858         static const String strValueDirectionAdjacentBackward(L"adjacentBackward");
1859         static const String strValueAnimationType[] = {L"none", L"custom", L"left", L"right", L"fade_in_out",
1860                                                                                                    L"zoom_in", L"zoom_out", L"depth_in", "depth_out"};
1861         static const String strValueHistoryOptionNoHistory(L"no");
1862         static const String strValueDestroyOptionKeep(L"keep");
1863         static const String strValueDestroyOptionDestroy(L"destroy");
1864
1865         static const SceneTransitionAnimationType valueAnimation[] = {
1866                 SCENE_TRANSITION_ANIMATION_TYPE_NONE, SCENE_TRANSITION_ANIMATION_TYPE_CUSTOM,
1867                 SCENE_TRANSITION_ANIMATION_TYPE_LEFT, SCENE_TRANSITION_ANIMATION_TYPE_RIGHT,
1868                 SCENE_TRANSITION_ANIMATION_TYPE_FADE_IN_OUT, SCENE_TRANSITION_ANIMATION_TYPE_ZOOM_IN,
1869                 SCENE_TRANSITION_ANIMATION_TYPE_ZOOM_OUT, SCENE_TRANSITION_ANIMATION_TYPE_DEPTH_IN,
1870                 SCENE_TRANSITION_ANIMATION_TYPE_DEPTH_OUT };
1871
1872         SceneTransition* pSceneTransition = null;
1873         result r = E_SUCCESS;
1874         SysTryReturn(NID_UI_SCENES, pNode != null, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. pNode is null.",
1875                                  GetErrorMessage(E_INVALID_ARG));
1876
1877         xmlChar* pTransitionId = xmlGetProp(pNode, pPropId);
1878         if (pTransitionId)
1879         {
1880                 String strTransitionId(reinterpret_cast<char*>(pTransitionId));
1881                 xmlFree(pTransitionId);
1882                 if (strTransitionId.GetLength() > 0)
1883                 {
1884                         xmlChar* pDirectionType = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropDirectionType));
1885                         if (pDirectionType)
1886                         {
1887                                 String strDirectionType(reinterpret_cast<char*>(pDirectionType));
1888                                 xmlFree(pDirectionType);
1889
1890                                 // Mandatory item: transitionId, direction
1891                                 // forward: destinationSceneId(mandatory), animationType, historyOption, destroyOption
1892                                 // backward: destinationSceneId(mandatory), animationType, destroyOption [ Don't care: historyOption ]
1893                                 // adjacentBackward: animationType, destroyOption [ Don't care: destinationSceneId, historyOption]
1894                                 String strDestinationSceneId;
1895                                 String strAnimationType;
1896                                 String strHistoryOption;
1897                                 String strDestroyOption;
1898                                 SceneTransitionAnimationType animationType = SCENE_TRANSITION_ANIMATION_TYPE_NONE;
1899
1900                                 // Get animationType and destroyOption (common property)
1901                                 xmlChar* pAnimationType = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropAnimationType));
1902                                 if (pAnimationType)
1903                                 {
1904                                         strAnimationType = reinterpret_cast<char*>(pAnimationType);
1905                                         xmlFree(pAnimationType);
1906                                         if (strAnimationType.GetLength() > 0)
1907                                         {
1908                                                 for (unsigned int i = 0; i < sizeof(valueAnimation)/sizeof(valueAnimation[0]); i++)
1909                                                 {       // Consider to use map collection.
1910                                                         if (strAnimationType == strValueAnimationType[i])
1911                                                         {
1912                                                                 animationType = valueAnimation[i];
1913                                                                 break;
1914                                                         }
1915                                                 }
1916                                         }
1917                                 }
1918
1919                                 xmlChar* pDestroyOption = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropDestroyOption));
1920                                 if (pDestroyOption)
1921                                 {
1922                                         strDestroyOption = reinterpret_cast<char*>(pDestroyOption);
1923                                         xmlFree(pDestroyOption);
1924                                 }
1925
1926                                 // Compose SceneTransition
1927                                 if (strDirectionType == strValueDirectionAdjacentBackward)      // Adjacent backward
1928                                 {
1929                                         SceneDestroyOption destroyOption = SCENE_DESTROY_OPTION_DESTROY;        // Default is destroy
1930                                         if ((strDestroyOption.GetLength() > 0) && (strDestroyOption == strValueDestroyOptionKeep))
1931                                         {
1932                                                 destroyOption = SCENE_DESTROY_OPTION_KEEP;
1933                                         }
1934
1935                                         pSceneTransition = new (std::nothrow) BackwardSceneTransition(animationType, destroyOption);
1936                                         SysTryReturnResult(NID_UI_SCENES, pSceneTransition != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1937                                         r = __transitionMap.Add(strTransitionId, pSceneTransition);
1938                                         SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1939                                         return r;
1940                                 }
1941
1942                                 // Get destinationSceneId
1943                                 xmlChar* pDestinationSceneId = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropDestinationSceneId));
1944                                 if (pDestinationSceneId)
1945                                 {
1946                                         strDestinationSceneId = reinterpret_cast<char*>(pDestinationSceneId);
1947                                         xmlFree(pDestinationSceneId);
1948                                 }
1949                                 SysTryReturn(NID_UI_SCENES, strDestinationSceneId.GetLength() > 0, E_INVALID_ARG, E_INVALID_ARG,
1950                                                          "[%s] Invalid argument is used. strDestinationSceneId is empty.", GetErrorMessage(E_INVALID_ARG));
1951
1952                                 if (strDirectionType == strValueDirectionBackward)              // Backward
1953                                 {
1954                                         SceneDestroyOption destroyOption = SCENE_DESTROY_OPTION_DESTROY;        // Default is destroy
1955                                         if ((strDestroyOption.GetLength() > 0) && (strDestroyOption == strValueDestroyOptionKeep))
1956                                         {
1957                                                 destroyOption = SCENE_DESTROY_OPTION_KEEP;
1958                                         }
1959
1960                                         pSceneTransition =
1961                                                         new (std::nothrow) BackwardSceneTransition(strDestinationSceneId, animationType, destroyOption);
1962                                         SysTryReturnResult(NID_UI_SCENES, pSceneTransition != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1963                                         r = __transitionMap.Add(strTransitionId, pSceneTransition);
1964                                         SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1965                                         return r;
1966                                 }
1967
1968                                 if (strDirectionType == strValueDirectionForward)               // Forward
1969                                 {
1970                                         SceneDestroyOption destroyOption = SCENE_DESTROY_OPTION_KEEP;           // Default is keep
1971                                         if ((strDestroyOption.GetLength() > 0) && (strDestroyOption == strValueDestroyOptionDestroy))
1972                                         {
1973                                                 destroyOption = SCENE_DESTROY_OPTION_DESTROY;
1974                                         }
1975
1976                                         xmlChar* pHistoryOption = xmlGetProp(pNode, reinterpret_cast<const xmlChar*>(pPropHistoryOption));
1977                                         if (pHistoryOption)
1978                                         {
1979                                                 strHistoryOption = reinterpret_cast<char*>(pHistoryOption);
1980                                                 xmlFree(pHistoryOption);
1981                                         }
1982                                         SceneHistoryOption historyOption = SCENE_HISTORY_OPTION_ADD_HISTORY;    // Default is add to history
1983                                         if ((strHistoryOption.GetLength() > 0) && (strHistoryOption == strValueHistoryOptionNoHistory))
1984                                         {
1985                                                 historyOption = SCENE_HISTORY_OPTION_NO_HISTORY;
1986                                         }
1987
1988                                         pSceneTransition = new (std::nothrow) ForwardSceneTransition(strDestinationSceneId, animationType,
1989                                                                                                                                                                  historyOption, destroyOption);
1990                                         SysTryReturnResult(NID_UI_SCENES, pSceneTransition != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1991                                         r = __transitionMap.Add(strTransitionId, pSceneTransition);
1992                                         SysTryCatch(NID_UI_SCENES, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
1993                                         return r;
1994                                 }
1995                                 else
1996                                 {
1997                                         SysLog(NID_UI_SCENES, "Unknown direction type!");
1998                                 }
1999                         }
2000                 }
2001         }
2002         return r;
2003
2004 CATCH:
2005         delete pSceneTransition;
2006         return r;
2007 }
2008
2009 result
2010 _SceneManagerImpl::StopAllAnimations(void)
2011 {
2012         Frame* pFrame = GetFrame();
2013         SysTryReturnResult(NID_UI_SCENES, pFrame != null, E_SYSTEM, "A system error has been occurred. Cannot get Frame.");
2014         FrameAnimator* pFrameAnimator = pFrame->GetFrameAnimator();
2015         SysTryReturnResult(NID_UI_SCENES, pFrameAnimator != null, E_SYSTEM, "A system error has been occurred. Cannot get FrameAnimator.");
2016         pFrameAnimator->StopAllAnimations();
2017         if (!__destroyReservedScene.IsEmpty())
2018         {
2019                 DestroyScene(__destroyReservedScene);
2020                 __destroyReservedScene.Clear();
2021         }
2022         return E_SUCCESS;
2023 }
2024
2025 } } } // Tizen::Ui::Scenes