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