[NUI] Fix memory leak 92/169592/1
authorhuiyu,eun <huiyu.eun@samsung.com>
Thu, 8 Feb 2018 00:40:02 +0000 (09:40 +0900)
committerhuiyu,eun <huiyu.eun@samsung.com>
Thu, 8 Feb 2018 00:40:02 +0000 (09:40 +0900)
Change-Id: I66981fc7f94992da9c466e9294c4f469aed77a10
Signed-off-by: huiyu,eun <huiyu.eun@samsung.com>
13 files changed:
src/Tizen.NUI/src/internal/FrameBuffer.cs
src/Tizen.NUI/src/internal/ViewWrapperImpl.cs
src/Tizen.NUI/src/public/Animation.cs
src/Tizen.NUI/src/public/BaseComponents/TableView.cs
src/Tizen.NUI/src/public/BaseComponents/View.cs
src/Tizen.NUI/src/public/FocusManager.cs
src/Tizen.NUI/src/public/NUIConstants.cs
src/Tizen.NUI/src/public/Renderer.cs
src/Tizen.NUI/src/public/TextureSet.cs
src/Tizen.NUI/src/public/Touch.cs
src/Tizen.NUI/src/public/UIComponents/Popup.cs
src/Tizen.NUI/src/public/VisualMaps.cs
test/NUITestSample/NUITestSample/examples/ref-cnt-error-memory-leak-2.cs [new file with mode: 0755]

index 648d0c2af0612824a402478c6c7a553bf3cf3d30..085bdb1ee748917def4fd9ca60f7a359f84ecdac 100755 (executable)
@@ -99,8 +99,12 @@ namespace Tizen.NUI
 
         public Texture GetColorTexture()
         {
+            //to fix memory leak issue, match the handle count with native side.
             global::System.IntPtr cPtr = NDalicPINVOKE.FrameBuffer_GetColorTexture(swigCPtr);
-            Texture ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Texture;
+            HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
+            Texture ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as Texture;
+            NDalicPINVOKE.delete_BaseHandle(CPtr);
+            CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
 
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
             return ret;
index d145ce6d963e0075df5c0bb0d3886e545cf865d3..3c009a666dacb3032d38d9af5515048c0e525cfb 100755 (executable)
@@ -252,8 +252,12 @@ namespace Tizen.NUI
 
         public VisualBase GetVisual(int index)
         {
+            //to fix memory leak issue, match the handle count with native side.
             System.IntPtr cPtr = NDalicManualPINVOKE.ViewWrapperImpl_GetVisual(swigCPtr, index);
-            VisualBase ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as VisualBase;
+            HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
+            VisualBase ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as VisualBase;
+            NDalicPINVOKE.delete_BaseHandle(CPtr);
+            CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
 
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
             return ret;
index 6bd8eee717dce52faf48b7d5441b4d7e4c9cc151..54e2be7ac3d93ddf17c616acde6887840af4decf 100755 (executable)
@@ -83,7 +83,10 @@ namespace Tizen.NUI
 
             }
 
-            this?.Clear();
+            if (this != null)
+            {
+                this.Clear();
+            }
 
             //Release your own unmanaged resources here.
             //You should not access any managed member here except static instance.
index 8743ae12dfda78895657654670f4cab3ea18a6b2..be2115c559bf5e3dea38cc33e7d176f4be5f020a 100755 (executable)
@@ -379,8 +379,12 @@ namespace Tizen.NUI.BaseComponents
         /// <since_tizen> 3 </since_tizen>
         public View GetChildAt(TableView.CellPosition position)
         {
+            //to fix memory leak issue, match the handle count with native side.
             IntPtr cPtr = NDalicPINVOKE.TableView_GetChildAt(swigCPtr, TableView.CellPosition.getCPtr(position));
-            View ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as View;
+            HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
+            View ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as View;
+            NDalicPINVOKE.delete_BaseHandle(CPtr);
+            CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
 
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
             return ret;
@@ -394,8 +398,12 @@ namespace Tizen.NUI.BaseComponents
         /// <since_tizen> 3 </since_tizen>
         public View RemoveChildAt(TableView.CellPosition position)
         {
+            //to fix memory leak issue, match the handle count with native side.
             IntPtr cPtr = NDalicPINVOKE.TableView_RemoveChildAt(swigCPtr, TableView.CellPosition.getCPtr(position));
-            View ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as View;
+            HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
+            View ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as View;
+            NDalicPINVOKE.delete_BaseHandle(CPtr);
+            CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
 
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
             return ret;
index 4b3f3d833c29f897423fabb3793a9b27d283a38a..45a55d4b7549f4ddd390a3a48911c7e2157d401c 100755 (executable)
@@ -4338,10 +4338,10 @@ namespace Tizen.NUI.BaseComponents
                 else
                 {
                     ret = basehandle as View;
-                    NDalicPINVOKE.delete_BaseHandle(CPtr);
-                    CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
                 }
 
+                NDalicPINVOKE.delete_BaseHandle(CPtr);
+                CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
 
                 if (NDalicPINVOKE.SWIGPendingException.Pending)
                     throw NDalicPINVOKE.SWIGPendingException.Retrieve();
index 1982994d780f288df4c733ce2012de7f6dd3f582..f8fd384d39d5436589d8da0e629b04b1e5f34035 100755 (executable)
@@ -449,8 +449,12 @@ namespace Tizen.NUI
         /// <since_tizen> 3 </since_tizen>
         public View GetCurrentFocusView()
         {
+            //to fix memory leak issue, match the handle count with native side.
             IntPtr cPtr = NDalicManualPINVOKE.FocusManager_GetCurrentFocusActor(swigCPtr);
-            View ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as View;
+            HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
+            View ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as View;
+            NDalicPINVOKE.delete_BaseHandle(CPtr);
+            CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
 
             return ret;
         }
@@ -553,8 +557,12 @@ namespace Tizen.NUI
         /// <since_tizen> 3 </since_tizen>
         public View GetFocusGroup(View view)
         {
+            //to fix memory leak issue, match the handle count with native side.
             IntPtr cPtr = NDalicManualPINVOKE.FocusManager_GetFocusGroup(swigCPtr, View.getCPtr(view));
-            View ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as View;
+            HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
+            View ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as View;
+            NDalicPINVOKE.delete_BaseHandle(CPtr);
+            CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
 
             return ret;
         }
@@ -584,8 +592,12 @@ namespace Tizen.NUI
 
         internal View GetFocusIndicatorView()
         {
+            //to fix memory leak issue, match the handle count with native side.
             IntPtr cPtr = NDalicManualPINVOKE.FocusManager_GetFocusIndicatorActor(swigCPtr);
-            View ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as View;
+            HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
+            View ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as View;
+            NDalicPINVOKE.delete_BaseHandle(CPtr);
+            CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
 
             return ret;
         }
index c513bc8b72f9a322c8821933b52b3a39578d284a..6a5fae0614f0be08268cfe10a5857afab6950cf8 100755 (executable)
@@ -1261,7 +1261,7 @@ namespace Tizen.NUI
         public static readonly int FrameDelay = NDalic.IMAGE_VISUAL_FRAME_DELAY;
         /// <summary>
         /// The number of times the AnimatedImageVisual will be looped
-        /// Default -1. if &lt; 0, loop unlimited. else, loop loopCount times.
+        /// Default -1. if < 0, loop unlimited. else, loop loopCount times.
         /// </summary>
         /// <since_tizen> 4 </since_tizen>
         public static readonly int LoopCount = NDalic.IMAGE_VISUAL_LOOP_COUNT;
index 4e0320ea99d575041a2d3734af7bdeced334bea8..e345ddd712dd8f0d9baf859c4b5a68a7840a2555 100755 (executable)
@@ -231,8 +231,12 @@ namespace Tizen.NUI
         /// <since_tizen> 3 </since_tizen>
         public Geometry GetGeometry()
         {
+            //to fix memory leak issue, match the handle count with native side.
             System.IntPtr cPtr = NDalicPINVOKE.Renderer_GetGeometry(swigCPtr);
-            Geometry ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Geometry;
+            HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
+            Geometry ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as Geometry;
+            NDalicPINVOKE.delete_BaseHandle(CPtr);
+            CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
 
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
             return ret;
@@ -268,8 +272,12 @@ namespace Tizen.NUI
         /// <since_tizen> 3 </since_tizen>
         public TextureSet GetTextures()
         {
+            //to fix memory leak issue, match the handle count with native side.
             System.IntPtr cPtr = NDalicPINVOKE.Renderer_GetTextures(swigCPtr);
-            TextureSet ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as TextureSet;
+            HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
+            TextureSet ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as TextureSet;
+            NDalicPINVOKE.delete_BaseHandle(CPtr);
+            CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
 
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
             return ret;
@@ -293,8 +301,12 @@ namespace Tizen.NUI
         /// <since_tizen> 3 </since_tizen>
         public Shader GetShader()
         {
+            //to fix memory leak issue, match the handle count with native side.
             System.IntPtr cPtr = NDalicPINVOKE.Renderer_GetShader(swigCPtr);
-            Shader ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Shader;
+            HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
+            Shader ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as Shader;
+            NDalicPINVOKE.delete_BaseHandle(CPtr);
+            CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
 
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
             return ret;
index 91b6de623db8ef16b06becde6546dfb29cc5b08b..949dece421356fee6106b5dd6cd337186556857d 100755 (executable)
@@ -104,8 +104,12 @@ namespace Tizen.NUI
         /// <since_tizen> 3 </since_tizen>
         public Texture GetTexture(uint index)
         {
+            //to fix memory leak issue, match the handle count with native side.
             System.IntPtr cPtr = NDalicPINVOKE.TextureSet_GetTexture(swigCPtr, index);
-            Texture ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Texture;
+            HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
+            Texture ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as Texture;
+            NDalicPINVOKE.delete_BaseHandle(CPtr);
+            CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
 
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
             return ret;
@@ -131,8 +135,12 @@ namespace Tizen.NUI
         /// <since_tizen> 3 </since_tizen>
         public Sampler GetSampler(uint index)
         {
+            //to fix memory leak issue, match the handle count with native side.
             System.IntPtr cPtr = NDalicPINVOKE.TextureSet_GetSampler(swigCPtr, index);
-            Sampler ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Sampler;
+            HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
+            Sampler ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as Sampler;
+            NDalicPINVOKE.delete_BaseHandle(CPtr);
+            CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
 
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
             return ret;
index 49e933d8a90a5d54e223284cbe9f42dd7701dbf9..635c6798caabddb780779852e09d94ec56a68739 100755 (executable)
@@ -165,8 +165,12 @@ namespace Tizen.NUI
         /// <since_tizen> 3 </since_tizen>
         public View GetHitView(uint point)
         {
+            //to fix memory leak issue, match the handle count with native side.
             global::System.IntPtr cPtr = NDalicPINVOKE.Touch_GetHitActor(swigCPtr, point);
-            View ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as View;
+            HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
+            View ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as View;
+            NDalicPINVOKE.delete_BaseHandle(CPtr);
+            CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
 
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
             return ret;
index 0b81c5a0de0a47f8b40f360b7eb03fe741cda94e..1a557ee1968d654a016bc267960307c6fbbf46ca 100755 (executable)
@@ -405,8 +405,12 @@ namespace Tizen.NUI.UIComponents
 
         internal View GetTitle()
         {
+            //to fix memory leak issue, match the handle count with native side.
             IntPtr cPtr = NDalicPINVOKE.Popup_GetTitle(swigCPtr);
-            View ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as View;
+            HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
+            View ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as View;
+            NDalicPINVOKE.delete_BaseHandle(CPtr);
+            CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
 
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
             return ret;
@@ -425,8 +429,12 @@ namespace Tizen.NUI.UIComponents
 
         internal View GetContent()
         {
+            //to fix memory leak issue, match the handle count with native side.
             IntPtr cPtr = NDalicPINVOKE.Popup_GetContent(swigCPtr);
-            View ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as View;
+            HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
+            View ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as View;
+            NDalicPINVOKE.delete_BaseHandle(CPtr);
+            CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
 
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
             return ret;
@@ -445,8 +453,12 @@ namespace Tizen.NUI.UIComponents
 
         internal View GetFooter()
         {
+            //to fix memory leak issue, match the handle count with native side.
             IntPtr cPtr = NDalicPINVOKE.Popup_GetFooter(swigCPtr);
-            View ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as View;
+            HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
+            View ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as View;
+            NDalicPINVOKE.delete_BaseHandle(CPtr);
+            CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
 
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
             return ret;
index 1008473f155d5d13d191a40274ba60fa949b8b31..4c4191e9d0d9f53aadbbc8989dc459d1dc1f0030 100755 (executable)
@@ -2425,7 +2425,7 @@ namespace Tizen.NUI
 
         /// <summary>
         /// Gets and Sets the number of times the AnimatedImageVisual will be looped.
-        /// Default -1. if &lt; 0, loop unlimited. else, loop loopCount times.
+        /// Default -1. if < 0, loop unlimited. else, loop loopCount times.
         /// </summary>
         /// <since_tizen> 4 </since_tizen>
         public float LoopCount
diff --git a/test/NUITestSample/NUITestSample/examples/ref-cnt-error-memory-leak-2.cs b/test/NUITestSample/NUITestSample/examples/ref-cnt-error-memory-leak-2.cs
new file mode 100755 (executable)
index 0000000..972c3c5
--- /dev/null
@@ -0,0 +1,210 @@
+using System;
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.UIComponents;
+
+namespace RefCountMemoryLeakTest2
+{
+    class Program : NUIApplication
+    {
+        const string X = "NUI1";
+        protected override void OnCreate()
+        {
+            base.OnCreate();
+            Initialize();
+        }
+
+        View parent1, child1, child2;
+        
+        void Initialize()
+        {
+            Window.Instance.KeyEvent += OnKeyEvent;
+            Window.Instance.BackgroundColor = Color.Green;
+        }
+
+        public void OnKeyEvent(object sender, Window.KeyEventArgs e)
+        {
+            if (e.Key.State == Key.StateType.Down && (e.Key.KeyPressedName == "XF86Back" || e.Key.KeyPressedName == "Escape"))
+            {
+                Exit();
+            }
+            else if (e.Key.State == Key.StateType.Down && e.Key.KeyPressedName == "Return")
+            {
+            }
+            else if (e.Key.State == Key.StateType.Down && e.Key.KeyPressedName == "Left")
+            {
+            }
+            else if (e.Key.State == Key.StateType.Down && e.Key.KeyPressedName == "Up")
+            {
+            }
+            else if (e.Key.State == Key.StateType.Down && e.Key.KeyPressedName == "Right")
+            {
+            }
+            ////////////////////////////////////////////////////////////////////////
+            else if (e.Key.State == Key.StateType.Down && e.Key.KeyPressedName == "1")
+            {
+                Tizen.Log.Fatal(X, $"########## 1 pressed! ################");
+                Tizen.Log.Fatal(X, $"View.Parent property test!");
+                Tizen.Log.Fatal(X, $"parent is a View and child is View");
+                Tizen.Log.Fatal(X, $"####################################");
+
+                Layer layer = Window.Instance.GetDefaultLayer();
+                parent1 = new View();
+                parent1.BackgroundColor = Color.Blue;
+                parent1.Size2D = new Size2D(200, 200);
+                layer.Add(parent1);
+
+                View child = new View();
+                child.BackgroundColor = Color.Blue;
+                child.Size2D = new Size2D(200, 200);
+                parent1.Add(child);
+
+                Tizen.Log.Fatal(X, $"[Before test] layer(DefaultLayer) refcnt={layer?.GetObjectPtr()?.ReferenceCount()}");
+                Tizen.Log.Fatal(X, $"[Before test] parent1 id={parent1.ID} refcnt={parent1?.GetObjectPtr()?.ReferenceCount()}");
+                Tizen.Log.Fatal(X, $"[Before test] child id={child.ID} refcnt={child?.GetObjectPtr()?.ReferenceCount()}");
+
+                View parent = child.Parent;
+
+                Tizen.Log.Fatal(X, $"[After test] layer(DefaultLayer) refcnt={layer?.GetObjectPtr()?.ReferenceCount()}");
+                Tizen.Log.Fatal(X, $"[After test] parent id={parent.ID} refcnt={parent?.GetObjectPtr()?.ReferenceCount()}");
+                Tizen.Log.Fatal(X, $"[After test] child id={child.ID} refcnt={child?.GetObjectPtr()?.ReferenceCount()}");
+
+                Tizen.Log.Fatal(X, $"############### END! #####################");
+            }
+            ////////////////////////////////////////////////////////////////////////
+            else if (e.Key.State == Key.StateType.Down && e.Key.KeyPressedName == "2")
+            {
+                Tizen.Log.Fatal(X, $"########## 2 pressed! ################");
+                Tizen.Log.Fatal(X, $"View.Parent property test!");
+                Tizen.Log.Fatal(X, $"parent is DefaultLayer and child is View");
+                Tizen.Log.Fatal(X, $"####################################");
+
+                Layer layer = Window.Instance.GetDefaultLayer();
+                View child = new View();
+                child.BackgroundColor = Color.Blue;
+                child.Size2D = new Size2D(200, 200);
+                layer.Add(child);
+
+                Tizen.Log.Fatal(X, $"[Before test] layer(DefaultLayer) refcnt={layer?.GetObjectPtr()?.ReferenceCount()}");
+                Tizen.Log.Fatal(X, $"[Before test] child id={child.ID} refcnt={child?.GetObjectPtr()?.ReferenceCount()}");
+
+                View parent = child.Parent;
+
+                Tizen.Log.Fatal(X, $"[After test] parent(DefaultLayer) refcnt={parent?.GetObjectPtr()?.ReferenceCount()}");
+                Tizen.Log.Fatal(X, $"[After test] child id={child.ID} refcnt={child?.GetObjectPtr()?.ReferenceCount()}");
+
+                Tizen.Log.Fatal(X, $"############### END! #####################");
+            }
+            ////////////////////////////////////////////////////////////////////////
+            else if (e.Key.State == Key.StateType.Down && e.Key.KeyPressedName == "3")
+            {
+                Tizen.Log.Fatal(X, $"########## 3 pressed! ################");
+                Tizen.Log.Fatal(X, $"View.GetParent() test!");
+                Tizen.Log.Fatal(X, $"parent is DefaultLayer and child is View");
+                Tizen.Log.Fatal(X, $"####################################");
+
+                Layer layer = Window.Instance.GetDefaultLayer();
+                View child = new View();
+                child.BackgroundColor = Color.Blue;
+                child.Size2D = new Size2D(200, 200);
+                layer.Add(child);
+
+                Tizen.Log.Fatal(X, $"[Before test] layer(DefaultLayer) refcnt={layer?.GetObjectPtr()?.ReferenceCount()}");
+                Tizen.Log.Fatal(X, $"[Before test] child id={child.ID} refcnt={child?.GetObjectPtr()?.ReferenceCount()}");
+
+                Layer parent = child.GetParent() as Layer;
+
+                Tizen.Log.Fatal(X, $"[After test] parent(DefaultLayer) refcnt={parent?.GetObjectPtr()?.ReferenceCount()}");
+                Tizen.Log.Fatal(X, $"[After test] child id={child.ID} refcnt={child?.GetObjectPtr()?.ReferenceCount()}");
+
+                Tizen.Log.Fatal(X, $"############### END! #####################");
+            }
+            ////////////////////////////////////////////////////////////////////////
+            else if (e.Key.State == Key.StateType.Down && e.Key.KeyPressedName == "4")
+            {
+                Tizen.Log.Fatal(X, $"########## 4 pressed! ################");
+                Tizen.Log.Fatal(X, $"FocusManager.GetCurrentFocusView() test!");
+                Tizen.Log.Fatal(X, $"parent1 is a View and there are 2 children");
+                Tizen.Log.Fatal(X, $"####################################");
+
+                Layer layer = Window.Instance.GetDefaultLayer();
+                parent1 = new View();
+                parent1.BackgroundColor = Color.Yellow;
+                parent1.Size2D = new Size2D(500, 500);
+                parent1.Position2D = new Position2D(100, 100);
+                layer.Add(parent1);
+
+                child1 = new View();
+                child1.BackgroundColor = Color.Red;
+                child1.Size2D = new Size2D(100, 100);
+                child1.Position2D = new Position2D(150, 150);
+                child1.Focusable = true;
+                parent1.Add(child1);
+
+                child2 = new View();
+                child2.BackgroundColor = Color.Red;
+                child2.Size2D = new Size2D(100, 100);
+                child2.Position2D = new Position2D(300, 150);
+                child2.Focusable = true;
+                parent1.Add(child2);
+
+                child1.RightFocusableView = child2;
+                child2.LeftFocusableView = child1;
+
+                Tizen.Log.Fatal(X, $"[Before test] child1 id={child1.ID} refcnt={child1?.GetObjectPtr()?.ReferenceCount()}");
+                Tizen.Log.Fatal(X, $"[Before test] child2 id={child2.ID} refcnt={child2?.GetObjectPtr()?.ReferenceCount()}");
+                Tizen.Log.Fatal(X, $"[Before test] parent1 id={parent1.ID} refcnt={parent1?.GetObjectPtr()?.ReferenceCount()}");
+
+                FocusManager.Instance.SetCurrentFocusView(child1);
+
+                Tizen.Log.Fatal(X, $"please push Right, Left key on remocon");
+                Tizen.Log.Fatal(X, $"and check the values with 8 key!");
+
+                View currentFocused = FocusManager.Instance.GetCurrentFocusView();
+                Tizen.Log.Fatal(X, $"[After test] currentFocused id={currentFocused.ID} refcnt={currentFocused?.GetObjectPtr()?.ReferenceCount()}");
+            }
+            else if (e.Key.State == Key.StateType.Down && e.Key.KeyPressedName == "5")
+            {
+                Tizen.Log.Fatal(X, $"########## 5 pressed! ################");
+                Tizen.Log.Fatal(X, $"FocusManager.GetCurrentFocusView() test!");
+                Tizen.Log.Fatal(X, $"this is After test!!!");
+                Tizen.Log.Fatal(X, $"####################################");
+
+                View currentFocused = FocusManager.Instance.GetCurrentFocusView();
+                Tizen.Log.Fatal(X, $"[After test] currentFocused id={currentFocused.ID} refcnt={currentFocused?.GetObjectPtr()?.ReferenceCount()}");
+                Tizen.Log.Fatal(X, $"[After test] parent1 id={parent1.ID} refcnt={parent1?.GetObjectPtr()?.ReferenceCount()}");
+            }
+            ////////////////////////////////////////////////////////////////////////
+            else if (e.Key.State == Key.StateType.Down && e.Key.KeyPressedName == "6")
+            {
+                Tizen.Log.Fatal(X, $"########## 6 pressed! ################");
+                Tizen.Log.Fatal(X, $"Parent TCT crash test! should not be crashed");
+                Tizen.Log.Fatal(X, $"####################################");
+
+                /* TEST CODE */
+                View view = new View();
+                View leftView = new View();
+                Window.Instance.GetDefaultLayer().Add(view);
+                Window.Instance.GetDefaultLayer().Add(leftView);
+                view.LeftFocusableView = leftView;
+                if(leftView == view.LeftFocusableView)
+                {
+                    Tizen.Log.Fatal(X, $"view and LeftView is same => good!");
+                }
+                else
+                {
+                    Tizen.Log.Fatal(X, $"view and LeftView is different => NG!");
+                }
+            }
+
+
+        }
+
+        static void _Main(string[] args)
+        {
+            var app = new Program();
+            app.Run(args);
+        }
+    }
+}
+