summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/jni/android_graphics_drawable_VectorDrawable.cpp6
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java63
-rw-r--r--graphics/java/android/graphics/drawable/VectorDrawable.java42
-rw-r--r--libs/hwui/VectorDrawable.cpp4
-rw-r--r--libs/hwui/VectorDrawable.h4
5 files changed, 64 insertions, 55 deletions
diff --git a/core/jni/android_graphics_drawable_VectorDrawable.cpp b/core/jni/android_graphics_drawable_VectorDrawable.cpp
index e88287644555..7314fbcd92d2 100644
--- a/core/jni/android_graphics_drawable_VectorDrawable.cpp
+++ b/core/jni/android_graphics_drawable_VectorDrawable.cpp
@@ -138,11 +138,6 @@ static jlong createGroup(JNIEnv*, jobject, jlong srcGroupPtr) {
return reinterpret_cast<jlong>(newGroup);
}
-static void deleteNode(JNIEnv*, jobject, jlong nodePtr) {
- VectorDrawable::Node* node = reinterpret_cast<VectorDrawable::Node*>(nodePtr);
- delete node;
-}
-
static void setNodeName(JNIEnv* env, jobject, jlong nodePtr, jstring nameStr) {
VectorDrawable::Node* node = reinterpret_cast<VectorDrawable::Node*>(nodePtr);
const char* nodeName = env->GetStringUTFChars(nameStr, NULL);
@@ -346,7 +341,6 @@ static const JNINativeMethod gMethods[] = {
{"nCreateClipPath", "!(J)J", (void*)createClipPath},
{"nCreateGroup", "!()J", (void*)createEmptyGroup},
{"nCreateGroup", "!(J)J", (void*)createGroup},
- {"nDestroy", "!(J)V", (void*)deleteNode},
{"nSetName", "(JLjava/lang/String;)V", (void*)setNodeName},
{"nUpdateGroupProperties", "!(JFFFFFFF)V", (void*)updateGroupProperties},
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 0a3e27e94c06..af8ccf5018b9 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -25,6 +25,8 @@ import android.animation.ValueAnimator;
import android.animation.ObjectAnimator;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.ActivityThread;
+import android.app.Application;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
@@ -35,6 +37,7 @@ import android.graphics.Insets;
import android.graphics.Outline;
import android.graphics.PorterDuff;
import android.graphics.Rect;
+import android.os.Build;
import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.Log;
@@ -200,6 +203,24 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
mMutated = false;
}
+ /**
+ * In order to avoid breaking old apps, we only throw exception on invalid VectorDrawable
+ * animations * for apps targeting N and later. For older apps, we ignore (i.e. quietly skip)
+ * these animations.
+ *
+ * @return whether invalid animations for vector drawable should be ignored.
+ */
+ private static boolean shouldIgnoreInvalidAnimation() {
+ Application app = ActivityThread.currentApplication();
+ if (app == null || app.getApplicationInfo() == null) {
+ return true;
+ }
+ if (app.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.N) {
+ return true;
+ }
+ return false;
+ }
+
@Override
public ConstantState getConstantState() {
mAnimatedVectorState.mChangingConfigurations = getChangingConfigurations();
@@ -763,6 +784,8 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
private boolean mInitialized = false;
private boolean mAnimationPending = false;
private boolean mIsReversible = false;
+ // This needs to be set before parsing starts.
+ private boolean mShouldIgnoreInvalidAnim;
// TODO: Consider using NativeAllocationRegistery to track native allocation
private final VirtualRefBasePtr mSetRefBasePtr;
private WeakReference<RenderNode> mTarget = null;
@@ -782,6 +805,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
throw new UnsupportedOperationException("VectorDrawableAnimator cannot be " +
"re-initialized");
}
+ mShouldIgnoreInvalidAnim = shouldIgnoreInvalidAnimation();
parseAnimatorSet(set, 0);
mInitialized = true;
@@ -841,7 +865,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
} else if (target instanceof VectorDrawable.VFullPath) {
createRTAnimatorForFullPath(animator, (VectorDrawable.VFullPath) target,
startTime);
- } else {
+ } else if (!mShouldIgnoreInvalidAnim) {
throw new IllegalArgumentException("ClipPath only supports PathData " +
"property");
}
@@ -850,10 +874,11 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
} else if (target instanceof VectorDrawable.VectorDrawableState) {
createRTAnimatorForRootGroup(values, animator,
(VectorDrawable.VectorDrawableState) target, startTime);
- } else {
+ } else if (!mShouldIgnoreInvalidAnim) {
// Should never get here
throw new UnsupportedOperationException("Target should be either VGroup, VPath, " +
- "or ConstantState, " + target.getClass() + " is not supported");
+ "or ConstantState, " + target == null ? "Null target" : target.getClass() +
+ " is not supported");
}
}
@@ -912,8 +937,12 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
long nativePtr = target.getNativePtr();
if (mTmpValues.type == Float.class || mTmpValues.type == float.class) {
if (propertyId < 0) {
- throw new IllegalArgumentException("Property: " + mTmpValues
- .propertyName + " is not supported for FullPath");
+ if (mShouldIgnoreInvalidAnim) {
+ return;
+ } else {
+ throw new IllegalArgumentException("Property: " + mTmpValues.propertyName
+ + " is not supported for FullPath");
+ }
}
propertyPtr = nCreatePathPropertyHolder(nativePtr, propertyId,
(Float) mTmpValues.startValue, (Float) mTmpValues.endValue);
@@ -922,9 +951,13 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
propertyPtr = nCreatePathColorPropertyHolder(nativePtr, propertyId,
(Integer) mTmpValues.startValue, (Integer) mTmpValues.endValue);
} else {
- throw new UnsupportedOperationException("Unsupported type: " +
- mTmpValues.type + ". Only float, int or PathData value is " +
- "supported for Paths.");
+ if (mShouldIgnoreInvalidAnim) {
+ return;
+ } else {
+ throw new UnsupportedOperationException("Unsupported type: " +
+ mTmpValues.type + ". Only float, int or PathData value is " +
+ "supported for Paths.");
+ }
}
if (mTmpValues.dataSource != null) {
float[] dataPoints = createDataPoints(mTmpValues.dataSource, animator
@@ -939,8 +972,12 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
long startTime) {
long nativePtr = target.getNativeRenderer();
if (!animator.getPropertyName().equals("alpha")) {
- throw new UnsupportedOperationException("Only alpha is supported for root " +
- "group");
+ if (mShouldIgnoreInvalidAnim) {
+ return;
+ } else {
+ throw new UnsupportedOperationException("Only alpha is supported for root "
+ + "group");
+ }
}
Float startValue = null;
Float endValue = null;
@@ -953,7 +990,11 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
}
}
if (startValue == null && endValue == null) {
- throw new UnsupportedOperationException("No alpha values are specified");
+ if (mShouldIgnoreInvalidAnim) {
+ return;
+ } else {
+ throw new UnsupportedOperationException("No alpha values are specified");
+ }
}
long propertyPtr = nCreateRootAlphaPropertyHolder(nativePtr, startValue, endValue);
createNativeChildAnimator(propertyPtr, startTime, animator);
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index f4bbc8c43d08..bdbf3c04b000 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -924,8 +924,11 @@ public class VectorDrawable extends Drawable {
private int mChangingConfigurations;
private int[] mThemeAttrs;
private String mGroupName = null;
- private long mNativePtr = 0;
+ // The native object will be created in the constructor and will be destroyed in native
+ // when the neither java nor native has ref to the tree. This pointer should be valid
+ // throughout this VGroup Java object's life.
+ private final long mNativePtr;
public VGroup(VGroup copy, ArrayMap<String, Object> targetsMap) {
mIsStateful = copy.mIsStateful;
@@ -1065,16 +1068,6 @@ public class VectorDrawable extends Drawable {
}
@Override
- protected void finalize() throws Throwable {
- if (mNativePtr != 0) {
- nDestroy(mNativePtr);
- mNativePtr = 0;
- }
- super.finalize();
- }
-
-
- @Override
public void applyTheme(Theme t) {
if (mThemeAttrs != null) {
final TypedArray a = t.resolveAttributes(mThemeAttrs,
@@ -1208,10 +1201,10 @@ public class VectorDrawable extends Drawable {
* Clip path, which only has name and pathData.
*/
private static class VClipPath extends VPath {
- long mNativePtr = 0;
+ private final long mNativePtr;
+
public VClipPath() {
mNativePtr = nCreateClipPath();
- // Empty constructor.
}
public VClipPath(VClipPath copy) {
@@ -1225,14 +1218,6 @@ public class VectorDrawable extends Drawable {
}
@Override
- protected void finalize() throws Throwable {
- if (mNativePtr != 0) {
- nDestroy(mNativePtr);
- mNativePtr = 0;
- }
- super.finalize();
- }
- @Override
public void inflate(Resources r, AttributeSet attrs, Theme theme) {
final TypedArray a = obtainAttributes(r, theme, attrs,
R.styleable.VectorDrawableClipPath);
@@ -1317,10 +1302,9 @@ public class VectorDrawable extends Drawable {
ComplexColor mStrokeColors = null;
ComplexColor mFillColors = null;
- private long mNativePtr = 0;
+ private final long mNativePtr;
public VFullPath() {
- // Empty constructor.
mNativePtr = nCreateFullPath();
}
@@ -1384,15 +1368,6 @@ public class VectorDrawable extends Drawable {
a.recycle();
}
- @Override
- protected void finalize() throws Throwable {
- if (mNativePtr != 0) {
- nDestroy(mNativePtr);
- mNativePtr = 0;
- }
- super.finalize();
- }
-
private void updateStateFromTypedArray(TypedArray a) {
int byteCount = TOTAL_PROPERTY_COUNT * 4;
if (mPropertyData == null) {
@@ -1647,7 +1622,7 @@ public class VectorDrawable extends Drawable {
private static native void nDraw(long rendererPtr, long canvasWrapperPtr,
long colorFilterPtr, Rect bounds, boolean needsMirroring, boolean canReuseCache);
private static native long nCreateFullPath();
- private static native long nCreateFullPath(long mNativeFullPathPtr);
+ private static native long nCreateFullPath(long nativeFullPathPtr);
private static native boolean nGetFullPathProperties(long pathPtr, byte[] properties,
int length);
@@ -1663,7 +1638,6 @@ public class VectorDrawable extends Drawable {
private static native long nCreateGroup();
private static native long nCreateGroup(long groupPtr);
- private static native void nDestroy(long nodePtr);
private static native void nSetName(long nodePtr, String name);
private static native boolean nGetGroupProperties(long groupPtr, float[] properties,
int length);
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index 541c799f0149..2e3856fafb60 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -324,7 +324,7 @@ void Group::draw(SkCanvas* outCanvas, const SkMatrix& currentMatrix, float scale
// Save the current clip information, which is local to this group.
outCanvas->save();
// Draw the group tree in the same order as the XML file.
- for (Node* child : mChildren) {
+ for (auto& child : mChildren) {
child->draw(outCanvas, stackedMatrix, scaleX, scaleY);
}
// Restore the previous clip information.
@@ -361,7 +361,7 @@ void Group::getLocalMatrix(SkMatrix* outMatrix) {
}
void Group::addChild(Node* child) {
- mChildren.push_back(child);
+ mChildren.emplace_back(child);
}
bool Group::getProperties(float* outProperties, int length) {
diff --git a/libs/hwui/VectorDrawable.h b/libs/hwui/VectorDrawable.h
index f8f1ea62a624..36a8aebeaa33 100644
--- a/libs/hwui/VectorDrawable.h
+++ b/libs/hwui/VectorDrawable.h
@@ -316,7 +316,7 @@ private:
// Count of the properties, must be at the end.
Count,
};
- std::vector<Node*> mChildren;
+ std::vector< std::unique_ptr<Node> > mChildren;
Properties mProperties;
};
@@ -360,7 +360,7 @@ private:
float mViewportHeight = 0;
float mRootAlpha = 1.0f;
- Group* mRootNode;
+ std::unique_ptr<Group> mRootNode;
SkRect mBounds;
SkMatrix mCanvasMatrix;
SkPaint mPaint;