[NUI] Fix memory leak (#112) 5.0.0-preview1-00457
authordongsug-song <35130733+dongsug-song@users.noreply.github.com>
Tue, 6 Feb 2018 05:31:27 +0000 (14:31 +0900)
committerGitHub <noreply@github.com>
Tue, 6 Feb 2018 05:31:27 +0000 (14:31 +0900)
src/Tizen.NUI/src/public/Animation.cs
src/Tizen.NUI/src/public/BaseComponents/View.cs [changed mode: 0644->0755]
test/NUITestSample/NUITestSample/examples/ref-cnt-error-memory-leak-2.cs [new file with mode: 0755]

index 6bd8eee..54e2be7 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.
old mode 100644 (file)
new mode 100755 (executable)
index 6a73ab0..fc11d95
@@ -1196,10 +1196,9 @@ namespace Tizen.NUI.BaseComponents
         private View ConvertIdToView(uint id)
         {
             View view = null;
-
-            if (Parent is View)
+            if (GetParent() is View)
             {
-                View parentView = Parent as View;
+                View parentView = GetParent() as View;
                 view = parentView.FindChildById(id);
             }
 
@@ -4328,18 +4327,20 @@ namespace Tizen.NUI.BaseComponents
                 IntPtr cPtr = NDalicPINVOKE.Actor_GetParent(swigCPtr);
                 HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
                 BaseHandle basehandle = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle);
-                NDalicPINVOKE.delete_BaseHandle(CPtr);
-                CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
 
                 if (basehandle is Layer)
                 {
                     ret = new View(cPtr, false);
+                    NUILog.Error("This Parent property is deprecated, shoud do not be used");
                 }
                 else
                 {
                     ret = basehandle 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;
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);
+        }
+    }
+}
+