Copy native tree's property when mutate vector drawable

When mutating vector drawables, we need to not only copy over
the VD tree structure, but also the properties of the VD tree,
such as alpha.

Bug: 28974071
Change-Id: If793f5f2b6e116472a1c6da0fb60d8278a78b03f
diff --git a/core/jni/android_graphics_drawable_VectorDrawable.cpp b/core/jni/android_graphics_drawable_VectorDrawable.cpp
index 9e69f79..045f127 100644
--- a/core/jni/android_graphics_drawable_VectorDrawable.cpp
+++ b/core/jni/android_graphics_drawable_VectorDrawable.cpp
@@ -36,6 +36,13 @@
     return reinterpret_cast<jlong>(tree);
 }
 
+static jlong createTreeFromCopy(JNIEnv*, jobject, jlong treePtr, jlong groupPtr) {
+    VectorDrawable::Group* rootGroup = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
+    VectorDrawable::Tree* treeToCopy = reinterpret_cast<VectorDrawable::Tree*>(treePtr);
+    VectorDrawable::Tree* tree = new VectorDrawable::Tree(treeToCopy, rootGroup);
+    return reinterpret_cast<jlong>(tree);
+}
+
 static jlong createEmptyFullPath(JNIEnv*, jobject) {
     VectorDrawable::FullPath* newPath = new VectorDrawable::FullPath();
     return reinterpret_cast<jlong>(newPath);
@@ -344,6 +351,7 @@
 
 static const JNINativeMethod gMethods[] = {
         {"nCreateTree", "!(J)J", (void*)createTree},
+        {"nCreateTreeFromCopy", "!(JJ)J", (void*)createTreeFromCopy},
         {"nSetRendererViewportSize", "!(JFF)V", (void*)setTreeViewportSize},
         {"nSetRootAlpha", "!(JF)Z", (void*)setRootAlpha},
         {"nGetRootAlpha", "!(J)F", (void*)getRootAlpha},
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index 47bafe3..a8c8737 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -834,7 +834,7 @@
                 mTintMode = copy.mTintMode;
                 mAutoMirrored = copy.mAutoMirrored;
                 mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap);
-                createNativeTree(mRootGroup);
+                createNativeTreeFromCopy(copy, mRootGroup);
 
                 mBaseWidth = copy.mBaseWidth;
                 mBaseHeight = copy.mBaseHeight;
@@ -856,6 +856,16 @@
             VMRuntime.getRuntime().registerNativeAllocation(NATIVE_ALLOCATION_SIZE);
         }
 
+        // Create a new native tree with the given root group, and copy the properties from the
+        // given VectorDrawableState's native tree.
+        private void createNativeTreeFromCopy(VectorDrawableState copy, VGroup rootGroup) {
+            mNativeTree = new VirtualRefBasePtr(nCreateTreeFromCopy(
+                    copy.mNativeTree.get(), rootGroup.mNativePtr));
+            // Register tree size
+            VMRuntime.getRuntime().registerNativeAllocation(NATIVE_ALLOCATION_SIZE);
+        }
+
+
         void onTreeConstructionFinished() {
             mRootGroup.setTree(mNativeTree);
             mAllocationOfAllNodes = mRootGroup.getNativeSize();
@@ -2074,6 +2084,7 @@
     }
 
     private static native long nCreateTree(long rootGroupPtr);
+    private static native long nCreateTreeFromCopy(long treeToCopy, long rootGroupPtr);
     private static native void nSetRendererViewportSize(long rendererPtr, float viewportWidth,
             float viewportHeight);
     private static native boolean nSetRootAlpha(long rendererPtr, float alpha);
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index f0348e4..2b79941 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -530,7 +530,7 @@
     if (prop->getRootAlpha() == 1.0f && prop->getColorFilter() == nullptr) {
         return nullptr;
     } else {
-        outPaint->setColorFilter(mStagingProperties.getColorFilter());
+        outPaint->setColorFilter(prop->getColorFilter());
         outPaint->setFilterQuality(kLow_SkFilterQuality);
         outPaint->setAlpha(prop->getRootAlpha() * 255);
         return outPaint;
diff --git a/libs/hwui/VectorDrawable.h b/libs/hwui/VectorDrawable.h
index 1a1f49f..940b1ca 100644
--- a/libs/hwui/VectorDrawable.h
+++ b/libs/hwui/VectorDrawable.h
@@ -549,6 +549,12 @@
     Tree(Group* rootNode) : mRootNode(rootNode) {
         mRootNode->setPropertyChangedListener(&mPropertyChangedListener);
     }
+
+    // Copy properties from the tree and use the give node as the root node
+    Tree(const Tree* copy, Group* rootNode) : Tree(rootNode) {
+        mStagingProperties.syncAnimatableProperties(*copy->stagingProperties());
+        mStagingProperties.syncNonAnimatableProperties(*copy->stagingProperties());
+    }
     // Draws the VD onto a bitmap cache, then the bitmap cache will be rendered onto the input
     // canvas. Returns the number of pixels needed for the bitmap cache.
     int draw(Canvas* outCanvas, SkColorFilter* colorFilter,
@@ -673,7 +679,7 @@
     };
     void onPropertyChanged(TreeProperties* prop);
     TreeProperties* mutateStagingProperties() { return &mStagingProperties; }
-    const TreeProperties* stagingProperties() { return &mStagingProperties; }
+    const TreeProperties* stagingProperties() const { return &mStagingProperties; }
 
     // This should only be called from animations on RT
     TreeProperties* mutateProperties() { return &mProperties; }