Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ee2dd2f authored by Doris Liu's avatar Doris Liu Committed by Android (Google) Code Review
Browse files

Merge "Check whether VD tree is still valid before calling native setter" into nyc-dev

parents a8d21a0f cdedc9a8
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -343,7 +343,7 @@ static void setTrimPathOffset(JNIEnv*, jobject, jlong fullPathPtr, jfloat trimPa
}
}


static const JNINativeMethod gMethods[] = {
static const JNINativeMethod gMethods[] = {
        {"nCreateRenderer", "!(J)J", (void*)createTree},
        {"nCreateTree", "!(J)J", (void*)createTree},
        {"nSetRendererViewportSize", "!(JFF)V", (void*)setTreeViewportSize},
        {"nSetRendererViewportSize", "!(JFF)V", (void*)setTreeViewportSize},
        {"nSetRootAlpha", "!(JF)Z", (void*)setRootAlpha},
        {"nSetRootAlpha", "!(JF)Z", (void*)setRootAlpha},
        {"nGetRootAlpha", "!(J)F", (void*)getRootAlpha},
        {"nGetRootAlpha", "!(J)F", (void*)getRootAlpha},
+106 −55
Original line number Original line Diff line number Diff line
@@ -534,13 +534,17 @@ public class VectorDrawable extends Drawable {
    public void inflate(@NonNull Resources r, @NonNull XmlPullParser parser,
    public void inflate(@NonNull Resources r, @NonNull XmlPullParser parser,
            @NonNull AttributeSet attrs, @Nullable Theme theme)
            @NonNull AttributeSet attrs, @Nullable Theme theme)
            throws XmlPullParserException, IOException {
            throws XmlPullParserException, IOException {
        if (mVectorState.mRootGroup != null || mVectorState.mNativeRendererRefBase != null) {
        if (mVectorState.mRootGroup != null || mVectorState.mNativeTree != null) {
            // This VD has been used to display other VD resource content, clean up.
            // This VD has been used to display other VD resource content, clean up.
            if (mVectorState.mRootGroup != null) {
                // Remove child nodes' reference to tree
                mVectorState.mRootGroup.setTree(null);
            }
            mVectorState.mRootGroup = new VGroup();
            mVectorState.mRootGroup = new VGroup();
            if (mVectorState.mNativeRendererRefBase != null) {
            if (mVectorState.mNativeTree != null) {
                mVectorState.mNativeRendererRefBase.release();
                mVectorState.mNativeTree.release();
            }
            }
            mVectorState.createNativeRenderer(mVectorState.mRootGroup.mNativePtr);
            mVectorState.createNativeTree(mVectorState.mRootGroup);
        }
        }
        final VectorDrawableState state = mVectorState;
        final VectorDrawableState state = mVectorState;
        state.setDensity(Drawable.resolveDensity(r, 0));
        state.setDensity(Drawable.resolveDensity(r, 0));
@@ -734,7 +738,7 @@ public class VectorDrawable extends Drawable {
        Insets mOpticalInsets = Insets.NONE;
        Insets mOpticalInsets = Insets.NONE;
        String mRootName = null;
        String mRootName = null;
        VGroup mRootGroup;
        VGroup mRootGroup;
        VirtualRefBasePtr mNativeRendererRefBase = null;
        VirtualRefBasePtr mNativeTree = null;


        int mDensity = DisplayMetrics.DENSITY_DEFAULT;
        int mDensity = DisplayMetrics.DENSITY_DEFAULT;
        final ArrayMap<String, Object> mVGTargetsMap = new ArrayMap<>();
        final ArrayMap<String, Object> mVGTargetsMap = new ArrayMap<>();
@@ -755,7 +759,7 @@ public class VectorDrawable extends Drawable {
                mTintMode = copy.mTintMode;
                mTintMode = copy.mTintMode;
                mAutoMirrored = copy.mAutoMirrored;
                mAutoMirrored = copy.mAutoMirrored;
                mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap);
                mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap);
                createNativeRenderer(mRootGroup.mNativePtr);
                createNativeTree(mRootGroup);


                mBaseWidth = copy.mBaseWidth;
                mBaseWidth = copy.mBaseWidth;
                mBaseHeight = copy.mBaseHeight;
                mBaseHeight = copy.mBaseHeight;
@@ -770,15 +774,16 @@ public class VectorDrawable extends Drawable {
            }
            }
        }
        }


        private void createNativeRenderer(long rootGroupPtr) {
        private void createNativeTree(VGroup rootGroup) {
            mNativeRendererRefBase = new VirtualRefBasePtr(nCreateRenderer(rootGroupPtr));
            mNativeTree = new VirtualRefBasePtr(nCreateTree(rootGroup.mNativePtr));
            mRootGroup.setTree(mNativeTree);
        }
        }


        long getNativeRenderer() {
        long getNativeRenderer() {
            if (mNativeRendererRefBase == null) {
            if (mNativeTree == null) {
                return 0;
                return 0;
            }
            }
            return mNativeRendererRefBase.get();
            return mNativeTree.get();
        }
        }


        public boolean canReuseCache() {
        public boolean canReuseCache() {
@@ -817,7 +822,7 @@ public class VectorDrawable extends Drawable {


        public VectorDrawableState() {
        public VectorDrawableState() {
            mRootGroup = new VGroup();
            mRootGroup = new VGroup();
            createNativeRenderer(mRootGroup.mNativePtr);
            createNativeTree(mRootGroup);
        }
        }


        @Override
        @Override
@@ -881,16 +886,16 @@ public class VectorDrawable extends Drawable {
         * has changed.
         * has changed.
         */
         */
        public boolean setAlpha(float alpha) {
        public boolean setAlpha(float alpha) {
            return nSetRootAlpha(mNativeRendererRefBase.get(), alpha);
            return nSetRootAlpha(mNativeTree.get(), alpha);
        }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        public float getAlpha() {
        public float getAlpha() {
            return nGetRootAlpha(mNativeRendererRefBase.get());
            return nGetRootAlpha(mNativeTree.get());
        }
        }
    }
    }


    static class VGroup implements VObject {
    static class VGroup extends VObject {
        private static final int ROTATE_INDEX = 0;
        private static final int ROTATE_INDEX = 0;
        private static final int PIVOT_X_INDEX = 1;
        private static final int PIVOT_X_INDEX = 1;
        private static final int PIVOT_Y_INDEX = 2;
        private static final int PIVOT_Y_INDEX = 2;
@@ -984,10 +989,17 @@ public class VectorDrawable extends Drawable {
        public void addChild(VObject child) {
        public void addChild(VObject child) {
            nAddChild(mNativePtr, child.getNativePtr());
            nAddChild(mNativePtr, child.getNativePtr());
            mChildren.add(child);
            mChildren.add(child);

            mIsStateful |= child.isStateful();
            mIsStateful |= child.isStateful();
        }
        }


        @Override
        public void setTree(VirtualRefBasePtr treeRoot) {
            super.setTree(treeRoot);
            for (int i = 0; i < mChildren.size(); i++) {
                mChildren.get(i).setTree(treeRoot);
            }
        }

        @Override
        @Override
        public long getNativePtr() {
        public long getNativePtr() {
            return mNativePtr;
            return mNativePtr;
@@ -1101,79 +1113,93 @@ public class VectorDrawable extends Drawable {
        /* Setters and Getters, used by animator from AnimatedVectorDrawable. */
        /* Setters and Getters, used by animator from AnimatedVectorDrawable. */
        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        public float getRotation() {
        public float getRotation() {
            return nGetRotation(mNativePtr);
            return isTreeValid() ? nGetRotation(mNativePtr) : 0;
        }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        public void setRotation(float rotation) {
        public void setRotation(float rotation) {
            if (isTreeValid()) {
                nSetRotation(mNativePtr, rotation);
                nSetRotation(mNativePtr, rotation);
            }
            }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        public float getPivotX() {
        public float getPivotX() {
            return nGetPivotX(mNativePtr);
            return isTreeValid() ? nGetPivotX(mNativePtr) : 0;
        }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        public void setPivotX(float pivotX) {
        public void setPivotX(float pivotX) {
            if (isTreeValid()) {
                nSetPivotX(mNativePtr, pivotX);
                nSetPivotX(mNativePtr, pivotX);
            }
            }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        public float getPivotY() {
        public float getPivotY() {
            return nGetPivotY(mNativePtr);
            return isTreeValid() ? nGetPivotY(mNativePtr) : 0;
        }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        public void setPivotY(float pivotY) {
        public void setPivotY(float pivotY) {
            if (isTreeValid()) {
                nSetPivotY(mNativePtr, pivotY);
                nSetPivotY(mNativePtr, pivotY);
            }
            }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        public float getScaleX() {
        public float getScaleX() {
            return nGetScaleX(mNativePtr);
            return isTreeValid() ? nGetScaleX(mNativePtr) : 0;
        }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        public void setScaleX(float scaleX) {
        public void setScaleX(float scaleX) {
            if (isTreeValid()) {
                nSetScaleX(mNativePtr, scaleX);
                nSetScaleX(mNativePtr, scaleX);
            }
            }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        public float getScaleY() {
        public float getScaleY() {
            return nGetScaleY(mNativePtr);
            return isTreeValid() ? nGetScaleY(mNativePtr) : 0;
        }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        public void setScaleY(float scaleY) {
        public void setScaleY(float scaleY) {
            if (isTreeValid()) {
                nSetScaleY(mNativePtr, scaleY);
                nSetScaleY(mNativePtr, scaleY);
            }
            }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        public float getTranslateX() {
        public float getTranslateX() {
            return nGetTranslateX(mNativePtr);
            return isTreeValid() ? nGetTranslateX(mNativePtr) : 0;
        }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        public void setTranslateX(float translateX) {
        public void setTranslateX(float translateX) {
            if (isTreeValid()) {
                nSetTranslateX(mNativePtr, translateX);
                nSetTranslateX(mNativePtr, translateX);
            }
            }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        public float getTranslateY() {
        public float getTranslateY() {
            return nGetTranslateY(mNativePtr);
            return isTreeValid() ? nGetTranslateY(mNativePtr) : 0;
        }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        public void setTranslateY(float translateY) {
        public void setTranslateY(float translateY) {
            if (isTreeValid()) {
                nSetTranslateY(mNativePtr, translateY);
                nSetTranslateY(mNativePtr, translateY);
            }
            }
        }
        }
    }


    /**
    /**
     * Common Path information for clip path and normal path.
     * Common Path information for clip path and normal path.
     */
     */
    static abstract class VPath implements VObject {
    static abstract class VPath extends VObject {
        protected PathParser.PathData mPathData = null;
        protected PathParser.PathData mPathData = null;


        String mPathName;
        String mPathName;
@@ -1203,9 +1229,11 @@ public class VectorDrawable extends Drawable {
        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        public void setPathData(PathParser.PathData pathData) {
        public void setPathData(PathParser.PathData pathData) {
            mPathData.setPathData(pathData);
            mPathData.setPathData(pathData);
            if (isTreeValid()) {
                nSetPathData(getNativePtr(), mPathData.getNativePtr());
                nSetPathData(getNativePtr(), mPathData.getNativePtr());
            }
            }
        }
        }
    }


    /**
    /**
     * Clip path, which only has name and pathData.
     * Clip path, which only has name and pathData.
@@ -1549,97 +1577,120 @@ public class VectorDrawable extends Drawable {
        /* Setters and Getters, used by animator from AnimatedVectorDrawable. */
        /* Setters and Getters, used by animator from AnimatedVectorDrawable. */
        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        int getStrokeColor() {
        int getStrokeColor() {
            return nGetStrokeColor(mNativePtr);
            return isTreeValid() ? nGetStrokeColor(mNativePtr) : 0;
        }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        void setStrokeColor(int strokeColor) {
        void setStrokeColor(int strokeColor) {
            mStrokeColors = null;
            mStrokeColors = null;
            if (isTreeValid()) {
                nSetStrokeColor(mNativePtr, strokeColor);
                nSetStrokeColor(mNativePtr, strokeColor);
            }
            }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        float getStrokeWidth() {
        float getStrokeWidth() {
            return nGetStrokeWidth(mNativePtr);
            return isTreeValid() ? nGetStrokeWidth(mNativePtr) : 0;
        }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        void setStrokeWidth(float strokeWidth) {
        void setStrokeWidth(float strokeWidth) {
            if (isTreeValid()) {
                nSetStrokeWidth(mNativePtr, strokeWidth);
                nSetStrokeWidth(mNativePtr, strokeWidth);
            }
            }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        float getStrokeAlpha() {
        float getStrokeAlpha() {
            return nGetStrokeAlpha(mNativePtr);
            return isTreeValid() ? nGetStrokeAlpha(mNativePtr) : 0;
        }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        void setStrokeAlpha(float strokeAlpha) {
        void setStrokeAlpha(float strokeAlpha) {
            if (isTreeValid()) {
                nSetStrokeAlpha(mNativePtr, strokeAlpha);
                nSetStrokeAlpha(mNativePtr, strokeAlpha);
            }
            }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        int getFillColor() {
        int getFillColor() {
            return nGetFillColor(mNativePtr);
            return isTreeValid() ? nGetFillColor(mNativePtr) : 0;
        }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        void setFillColor(int fillColor) {
        void setFillColor(int fillColor) {
            mFillColors = null;
            mFillColors = null;
            if (isTreeValid()) {
                nSetFillColor(mNativePtr, fillColor);
                nSetFillColor(mNativePtr, fillColor);
            }
            }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        float getFillAlpha() {
        float getFillAlpha() {
            return nGetFillAlpha(mNativePtr);
            return isTreeValid() ? nGetFillAlpha(mNativePtr) : 0;
        }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        void setFillAlpha(float fillAlpha) {
        void setFillAlpha(float fillAlpha) {
            if (isTreeValid()) {
                nSetFillAlpha(mNativePtr, fillAlpha);
                nSetFillAlpha(mNativePtr, fillAlpha);
            }
            }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        float getTrimPathStart() {
        float getTrimPathStart() {
            return nGetTrimPathStart(mNativePtr);
            return isTreeValid() ? nGetTrimPathStart(mNativePtr) : 0;
        }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        void setTrimPathStart(float trimPathStart) {
        void setTrimPathStart(float trimPathStart) {
            if (isTreeValid()) {
                nSetTrimPathStart(mNativePtr, trimPathStart);
                nSetTrimPathStart(mNativePtr, trimPathStart);
            }
            }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        float getTrimPathEnd() {
        float getTrimPathEnd() {
            return nGetTrimPathEnd(mNativePtr);
            return isTreeValid() ? nGetTrimPathEnd(mNativePtr) : 0;
        }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        void setTrimPathEnd(float trimPathEnd) {
        void setTrimPathEnd(float trimPathEnd) {
            if (isTreeValid()) {
                nSetTrimPathEnd(mNativePtr, trimPathEnd);
                nSetTrimPathEnd(mNativePtr, trimPathEnd);
            }
            }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        float getTrimPathOffset() {
        float getTrimPathOffset() {
            return nGetTrimPathOffset(mNativePtr);
            return isTreeValid() ? nGetTrimPathOffset(mNativePtr) : 0;
        }
        }


        @SuppressWarnings("unused")
        @SuppressWarnings("unused")
        void setTrimPathOffset(float trimPathOffset) {
        void setTrimPathOffset(float trimPathOffset) {
            if (isTreeValid()) {
                nSetTrimPathOffset(mNativePtr, trimPathOffset);
                nSetTrimPathOffset(mNativePtr, trimPathOffset);
            }
            }
        }
        }
    }


    interface VObject {
    abstract static class VObject {
        long getNativePtr();
        VirtualRefBasePtr mTreePtr = null;
        void inflate(Resources r, AttributeSet attrs, Theme theme);
        boolean isTreeValid() {
        boolean canApplyTheme();
            return mTreePtr != null && mTreePtr.get() != 0;
        void applyTheme(Theme t);
        }
        boolean onStateChange(int[] state);
        void setTree(VirtualRefBasePtr ptr) {
        boolean isStateful();
            mTreePtr = ptr;
        }
        abstract long getNativePtr();
        abstract void inflate(Resources r, AttributeSet attrs, Theme theme);
        abstract boolean canApplyTheme();
        abstract void applyTheme(Theme t);
        abstract boolean onStateChange(int[] state);
        abstract boolean isStateful();
    }
    }


    private static native long nCreateRenderer(long rootGroupPtr);
    private static native long nCreateTree(long rootGroupPtr);
    private static native void nSetRendererViewportSize(long rendererPtr, float viewportWidth,
    private static native void nSetRendererViewportSize(long rendererPtr, float viewportWidth,
            float viewportHeight);
            float viewportHeight);
    private static native boolean nSetRootAlpha(long rendererPtr, float alpha);
    private static native boolean nSetRootAlpha(long rendererPtr, float alpha);