From 686d972e1294eecaeb15db37a34c521cba0ac5a0 Mon Sep 17 00:00:00 2001 From: Chris Craik Date: Fri, 6 Jan 2017 16:11:45 -0800 Subject: [PATCH] Fix NPE in RenderNodeAnimator ALPHA when used outside ViewPropertyAnimator Bug: 33797688 Test: new RenderNodeAnimatorTest passes Other clients use RenderNodeAnimator now, so call ensureTransformationInfo to be safe. Change-Id: I837d6f5b00bb368d2bbf77b94d4c19a8426b9927 --- .../java/android/view/RenderNodeAnimator.java | 3 +- core/java/android/view/View.java | 3 +- core/tests/coretests/AndroidManifest.xml | 7 +++ .../android/view/RenderNodeAnimatorTest.java | 59 +++++++++++++++++++ 4 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 core/tests/coretests/src/android/view/RenderNodeAnimatorTest.java diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java index 7747580892f1b..95150409514db 100644 --- a/core/java/android/view/RenderNodeAnimator.java +++ b/core/java/android/view/RenderNodeAnimator.java @@ -200,8 +200,7 @@ public class RenderNodeAnimator extends Animator { // in mTransformationInfo instead of in RenderNode, so we need to update // it with the final value here. if (mRenderProperty == RenderNodeAnimator.ALPHA) { - // Don't need null check because ViewPropertyAnimator's - // ctor calls ensureTransformationInfo() + mViewTarget.ensureTransformationInfo(); mViewTarget.mTransformationInfo.mAlpha = mFinalValue; } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index aa941b8fcfb4a..aad7e0a123986 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -3394,7 +3394,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, float mTransitionAlpha = 1f; } - TransformationInfo mTransformationInfo; + /** @hide */ + public TransformationInfo mTransformationInfo; /** * Current clip bounds. to which all drawing of this view are constrained. diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml index cd419878bb501..e3a85b5620683 100644 --- a/core/tests/coretests/AndroidManifest.xml +++ b/core/tests/coretests/AndroidManifest.xml @@ -1107,6 +1107,13 @@ + + + + + + + diff --git a/core/tests/coretests/src/android/view/RenderNodeAnimatorTest.java b/core/tests/coretests/src/android/view/RenderNodeAnimatorTest.java new file mode 100644 index 0000000000000..b52d98c906c47 --- /dev/null +++ b/core/tests/coretests/src/android/view/RenderNodeAnimatorTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import android.app.Activity; +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.annotation.UiThreadTest; +import android.support.test.filters.MediumTest; +import android.support.test.rule.ActivityTestRule; + +import org.junit.Rule; +import org.junit.Test; + +@MediumTest +public class RenderNodeAnimatorTest { + @Rule + public ActivityTestRule mActivityRule = new ActivityTestRule<>(Activity.class); + + private Context getContext() { + return InstrumentationRegistry.getTargetContext(); + } + + private Activity getActivity() { + return mActivityRule.getActivity(); + } + + @UiThreadTest + @Test + public void testAlphaTransformationInfo() throws Throwable { + View view = new View(getContext()); + + // attach the view, since otherwise the RenderNodeAnimator won't accept view as target + getActivity().setContentView(view); + + RenderNodeAnimator anim = new RenderNodeAnimator(RenderNodeAnimator.ALPHA, 0.5f); + anim.setTarget(view); + assertNull(view.mTransformationInfo); + anim.start(); // should initialize mTransformationInfo + assertNotNull(view.mTransformationInfo); + } +}