Fix leak in VPathRenderer

The pointer to the root group in the VPathRenderer is not freed anywhere
in the Java side so we need to take care of it on the "native" side.

Change-Id: I2ca60b1f0e975a0b5d29799c5f6f31b5f8d42b9d
(cherry picked from commit ffdb1b241d9458196403c8f16264aa7053487323)
diff --git a/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java b/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
index 1dfd305..2903e3a 100644
--- a/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
+++ b/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
@@ -91,16 +91,14 @@
 
     @LayoutlibDelegate
     static long nCreateTree(long rootGroupPtr) {
-        VGroup_Delegate rootGroup = VNativeObject.getDelegate(rootGroupPtr);
-        return sPathManager.addNewDelegate(new VPathRenderer_Delegate(rootGroup));
+        return sPathManager.addNewDelegate(new VPathRenderer_Delegate(rootGroupPtr));
     }
 
     @LayoutlibDelegate
     static long nCreateTreeFromCopy(long rendererToCopyPtr, long rootGroupPtr) {
-        VGroup_Delegate rootGroup = VNativeObject.getDelegate(rootGroupPtr);
         VPathRenderer_Delegate rendererToCopy = VNativeObject.getDelegate(rendererToCopyPtr);
         return sPathManager.addNewDelegate(new VPathRenderer_Delegate(rendererToCopy,
-                rootGroup));
+                rootGroupPtr));
     }
 
     @LayoutlibDelegate
@@ -163,7 +161,6 @@
     @LayoutlibDelegate
     static long nCreateFullPath(long nativeFullPathPtr) {
         VFullPath_Delegate original = VNativeObject.getDelegate(nativeFullPathPtr);
-
         return sPathManager.addNewDelegate(new VFullPath_Delegate(original));
     }
 
@@ -247,8 +244,7 @@
     @LayoutlibDelegate
     static long nCreateGroup(long groupPtr) {
         VGroup_Delegate original = VNativeObject.getDelegate(groupPtr);
-        return sPathManager.addNewDelegate(
-                new VGroup_Delegate(original, new ArrayMap<String, Object>()));
+        return sPathManager.addNewDelegate(new VGroup_Delegate(original, new ArrayMap<>()));
     }
 
     @LayoutlibDelegate
@@ -1029,7 +1025,7 @@
         private final Path mPath;
         private final Path mRenderPath;
         private final Matrix mFinalPathMatrix = new Matrix();
-        private final VGroup_Delegate mRootGroup;
+        private final long mRootGroupPtr;
         private float mViewportWidth = 0;
         private float mViewportHeight = 0;
         private float mRootAlpha = 1.0f;
@@ -1037,15 +1033,15 @@
         private Paint mFillPaint;
         private PathMeasure mPathMeasure;
 
-        private VPathRenderer_Delegate(VGroup_Delegate rootGroup) {
-            mRootGroup = rootGroup;
+        private VPathRenderer_Delegate(long rootGroupPtr) {
+            mRootGroupPtr = rootGroupPtr;
             mPath = new Path();
             mRenderPath = new Path();
         }
 
         private VPathRenderer_Delegate(VPathRenderer_Delegate rendererToCopy,
-                VGroup_Delegate rootGroup) {
-            this(rootGroup);
+                long rootGroupPtr) {
+            this(rootGroupPtr);
             mViewportWidth = rendererToCopy.mViewportWidth;
             mViewportHeight = rendererToCopy.mViewportHeight;
             mRootAlpha = rendererToCopy.mRootAlpha;
@@ -1087,7 +1083,7 @@
 
         public void draw(long canvasPtr, long filterPtr, int w, int h) {
             // Traverse the tree in pre-order to draw.
-            drawGroupTree(mRootGroup, Matrix.IDENTITY_MATRIX, canvasPtr, w, h, filterPtr);
+            drawGroupTree(VNativeObject.getDelegate(mRootGroupPtr), Matrix.IDENTITY_MATRIX, canvasPtr, w, h, filterPtr);
         }
 
         private void drawPath(VGroup_Delegate VGroup, VPath_Delegate VPath, long canvasPtr,
@@ -1227,5 +1223,14 @@
         @Override
         public void setName(String name) {
         }
+
+        @Override
+        protected void finalize() throws Throwable {
+            super.finalize();
+
+            // The mRootGroupPtr is not explicitly freed by anything in the VectorDrawable so we
+            // need to free it here.
+            sPathManager.removeJavaReferenceFor(mRootGroupPtr);
+        }
     }
 }
diff --git a/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java b/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
index 0c39026..ea40ba7 100644
--- a/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
+++ b/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
@@ -165,5 +165,6 @@
             int idx = sDelegates.indexOfValue(reference);
             out.printf("[%d] %s\n", sDelegates.keyAt(idx), reference.getClass().getSimpleName());
         }
+        out.printf("\nTotal number of objects: %d\n", sJavaReferences.size());
     }
 }
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
index ba687fe..d160268 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
+++ b/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
@@ -349,7 +349,11 @@
         obj = null;
         while(ref.get() != null) {
             System.gc();
+            System.runFinalization();
         }
+
+        System.gc();
+        System.runFinalization();
     }
 
     @AfterClass