1e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck/* 2e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * Copyright (C) 2014 The Android Open Source Project 3e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * 4e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * Licensed under the Apache License, Version 2.0 (the "License"); 5e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * you may not use this file except in compliance with the License. 6e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * You may obtain a copy of the License at 7e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * 8e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * http://www.apache.org/licenses/LICENSE-2.0 9e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * 10e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * Unless required by applicable law or agreed to in writing, software 11e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * distributed under the License is distributed on an "AS IS" BASIS, 12e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * See the License for the specific language governing permissions and 14e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * limitations under the License. 15e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck */ 16e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 17e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckpackage android.view; 18e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 19ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viveretteimport android.animation.Animator; 20315c329544d7c593d1072b071cbb92d9afe74021John Reckimport android.animation.TimeInterpolator; 218d8af3c1b768d590754d657a7d1242dcb462454bJohn Reckimport android.animation.ValueAnimator; 221c058e96b3fb5075c34b89cf22773373811abf7aJohn Reckimport android.graphics.Canvas; 2352244fff29042926e21fa897ef5ab11148e35299John Reckimport android.graphics.CanvasProperty; 2452244fff29042926e21fa897ef5ab11148e35299John Reckimport android.graphics.Paint; 25e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckimport android.util.SparseIntArray; 26e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 279fa4071c4768c63902c6a74a4b480b51a8b95d43John Reckimport com.android.internal.util.VirtualRefBasePtr; 28315c329544d7c593d1072b071cbb92d9afe74021John Reckimport com.android.internal.view.animation.FallbackLUTInterpolator; 29315c329544d7c593d1072b071cbb92d9afe74021John Reckimport com.android.internal.view.animation.HasNativeInterpolator; 30315c329544d7c593d1072b071cbb92d9afe74021John Reckimport com.android.internal.view.animation.NativeInterpolatorFactory; 319fa4071c4768c63902c6a74a4b480b51a8b95d43John Reck 32ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viveretteimport java.util.ArrayList; 33e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 34e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck/** 35e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * @hide 36e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck */ 378d8af3c1b768d590754d657a7d1242dcb462454bJohn Reckpublic class RenderNodeAnimator extends Animator { 38e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck // Keep in sync with enum RenderProperty in Animator.h 3952244fff29042926e21fa897ef5ab11148e35299John Reck public static final int TRANSLATION_X = 0; 4052244fff29042926e21fa897ef5ab11148e35299John Reck public static final int TRANSLATION_Y = 1; 4152244fff29042926e21fa897ef5ab11148e35299John Reck public static final int TRANSLATION_Z = 2; 4252244fff29042926e21fa897ef5ab11148e35299John Reck public static final int SCALE_X = 3; 4352244fff29042926e21fa897ef5ab11148e35299John Reck public static final int SCALE_Y = 4; 4452244fff29042926e21fa897ef5ab11148e35299John Reck public static final int ROTATION = 5; 4552244fff29042926e21fa897ef5ab11148e35299John Reck public static final int ROTATION_X = 6; 4652244fff29042926e21fa897ef5ab11148e35299John Reck public static final int ROTATION_Y = 7; 4752244fff29042926e21fa897ef5ab11148e35299John Reck public static final int X = 8; 4852244fff29042926e21fa897ef5ab11148e35299John Reck public static final int Y = 9; 4952244fff29042926e21fa897ef5ab11148e35299John Reck public static final int Z = 10; 5052244fff29042926e21fa897ef5ab11148e35299John Reck public static final int ALPHA = 11; 51918988c1ce5af002d41c7ac37f3fa490558b0c90John Reck // The last value in the enum, used for array size initialization 52918988c1ce5af002d41c7ac37f3fa490558b0c90John Reck public static final int LAST_VALUE = ALPHA; 5352244fff29042926e21fa897ef5ab11148e35299John Reck 5452244fff29042926e21fa897ef5ab11148e35299John Reck // Keep in sync with enum PaintFields in Animator.h 5552244fff29042926e21fa897ef5ab11148e35299John Reck public static final int PAINT_STROKE_WIDTH = 0; 56ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette 57ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette /** 58ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette * Field for the Paint alpha channel, which should be specified as a value 59ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette * between 0 and 255. 60ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette */ 6152244fff29042926e21fa897ef5ab11148e35299John Reck public static final int PAINT_ALPHA = 1; 62e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 63e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck // ViewPropertyAnimator uses a mask for its values, we need to remap them 64e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck // to the enum values here. RenderPropertyAnimator can't use the mask values 65e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck // directly as internally it uses a lookup table so it needs the values to 66e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck // be sequential starting from 0 67e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck private static final SparseIntArray sViewPropertyAnimatorMap = new SparseIntArray(15) {{ 68e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck put(ViewPropertyAnimator.TRANSLATION_X, TRANSLATION_X); 69e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck put(ViewPropertyAnimator.TRANSLATION_Y, TRANSLATION_Y); 70e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck put(ViewPropertyAnimator.TRANSLATION_Z, TRANSLATION_Z); 71e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck put(ViewPropertyAnimator.SCALE_X, SCALE_X); 72e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck put(ViewPropertyAnimator.SCALE_Y, SCALE_Y); 73e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck put(ViewPropertyAnimator.ROTATION, ROTATION); 74e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck put(ViewPropertyAnimator.ROTATION_X, ROTATION_X); 75e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck put(ViewPropertyAnimator.ROTATION_Y, ROTATION_Y); 76e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck put(ViewPropertyAnimator.X, X); 77e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck put(ViewPropertyAnimator.Y, Y); 78e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck put(ViewPropertyAnimator.Z, Z); 79e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck put(ViewPropertyAnimator.ALPHA, ALPHA); 80e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck }}; 81e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 829fa4071c4768c63902c6a74a4b480b51a8b95d43John Reck private VirtualRefBasePtr mNativePtr; 83e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 84315c329544d7c593d1072b071cbb92d9afe74021John Reck private RenderNode mTarget; 85ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette private View mViewTarget; 868d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck private int mRenderProperty = -1; 878d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck private float mFinalValue; 88315c329544d7c593d1072b071cbb92d9afe74021John Reck private TimeInterpolator mInterpolator; 89ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette 904d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck private static final int STATE_PREPARE = 0; 914d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck private static final int STATE_DELAYED = 1; 924d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck private static final int STATE_RUNNING = 2; 934d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck private static final int STATE_FINISHED = 3; 944d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck private int mState = STATE_PREPARE; 95315c329544d7c593d1072b071cbb92d9afe74021John Reck 968d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck private long mUnscaledDuration = 300; 978d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck private long mUnscaledStartDelay = 0; 98291161ac3815fb853fd6af21055d60f57a869608John Reck // If this is true, we will run any start delays on the UI thread. This is 99291161ac3815fb853fd6af21055d60f57a869608John Reck // the safe default, and is necessary to ensure start listeners fire at 100291161ac3815fb853fd6af21055d60f57a869608John Reck // the correct time. Animators created by RippleDrawable (the 101291161ac3815fb853fd6af21055d60f57a869608John Reck // CanvasProperty<> ones) do not have this expectation, and as such will 102291161ac3815fb853fd6af21055d60f57a869608John Reck // set this to false so that the renderthread handles the startdelay instead 103291161ac3815fb853fd6af21055d60f57a869608John Reck private final boolean mUiThreadHandlesDelay; 104291161ac3815fb853fd6af21055d60f57a869608John Reck private long mStartDelay = 0; 105291161ac3815fb853fd6af21055d60f57a869608John Reck private long mStartTime; 1068d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck 107918988c1ce5af002d41c7ac37f3fa490558b0c90John Reck public static int mapViewPropertyToRenderProperty(int viewProperty) { 108e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck return sViewPropertyAnimatorMap.get(viewProperty); 109e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck } 110e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 111ff941dcd815021bb20d6504eb486acb1e50592c3John Reck public RenderNodeAnimator(int property, float finalValue) { 1128d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck mRenderProperty = property; 1138d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck mFinalValue = finalValue; 114291161ac3815fb853fd6af21055d60f57a869608John Reck mUiThreadHandlesDelay = true; 115119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck init(nCreateAnimator(property, finalValue)); 116e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck } 117e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 118ff941dcd815021bb20d6504eb486acb1e50592c3John Reck public RenderNodeAnimator(CanvasProperty<Float> property, float finalValue) { 1199fa4071c4768c63902c6a74a4b480b51a8b95d43John Reck init(nCreateCanvasPropertyFloatAnimator( 120ff941dcd815021bb20d6504eb486acb1e50592c3John Reck property.getNativeContainer(), finalValue)); 121291161ac3815fb853fd6af21055d60f57a869608John Reck mUiThreadHandlesDelay = false; 12252244fff29042926e21fa897ef5ab11148e35299John Reck } 12352244fff29042926e21fa897ef5ab11148e35299John Reck 124ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette /** 125ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette * Creates a new render node animator for a field on a Paint property. 126ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette * 127ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette * @param property The paint property to target 128ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette * @param paintField Paint field to animate, one of {@link #PAINT_ALPHA} or 129ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette * {@link #PAINT_STROKE_WIDTH} 130ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette * @param finalValue The target value for the property 131ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette */ 132ff941dcd815021bb20d6504eb486acb1e50592c3John Reck public RenderNodeAnimator(CanvasProperty<Paint> property, int paintField, float finalValue) { 1339fa4071c4768c63902c6a74a4b480b51a8b95d43John Reck init(nCreateCanvasPropertyPaintAnimator( 134ff941dcd815021bb20d6504eb486acb1e50592c3John Reck property.getNativeContainer(), paintField, finalValue)); 135291161ac3815fb853fd6af21055d60f57a869608John Reck mUiThreadHandlesDelay = false; 1369fa4071c4768c63902c6a74a4b480b51a8b95d43John Reck } 1379fa4071c4768c63902c6a74a4b480b51a8b95d43John Reck 138af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik public RenderNodeAnimator(int x, int y, float startRadius, float endRadius) { 139119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck init(nCreateRevealAnimator(x, y, startRadius, endRadius)); 140291161ac3815fb853fd6af21055d60f57a869608John Reck mUiThreadHandlesDelay = true; 141d3de42cae84fadfa1befd082a2cf1bf72f9ad82aJohn Reck } 142d3de42cae84fadfa1befd082a2cf1bf72f9ad82aJohn Reck 1439fa4071c4768c63902c6a74a4b480b51a8b95d43John Reck private void init(long ptr) { 1449fa4071c4768c63902c6a74a4b480b51a8b95d43John Reck mNativePtr = new VirtualRefBasePtr(ptr); 14552244fff29042926e21fa897ef5ab11148e35299John Reck } 14652244fff29042926e21fa897ef5ab11148e35299John Reck 147315c329544d7c593d1072b071cbb92d9afe74021John Reck private void checkMutable() { 1484d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck if (mState != STATE_PREPARE) { 149315c329544d7c593d1072b071cbb92d9afe74021John Reck throw new IllegalStateException("Animator has already started, cannot change it now!"); 150315c329544d7c593d1072b071cbb92d9afe74021John Reck } 151c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck if (mNativePtr == null) { 152c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck throw new IllegalStateException("Animator's target has been destroyed " 153c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck + "(trying to modify an animation after activity destroy?)"); 154c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck } 155315c329544d7c593d1072b071cbb92d9afe74021John Reck } 156315c329544d7c593d1072b071cbb92d9afe74021John Reck 157918988c1ce5af002d41c7ac37f3fa490558b0c90John Reck static boolean isNativeInterpolator(TimeInterpolator interpolator) { 158918988c1ce5af002d41c7ac37f3fa490558b0c90John Reck return interpolator.getClass().isAnnotationPresent(HasNativeInterpolator.class); 159918988c1ce5af002d41c7ac37f3fa490558b0c90John Reck } 160918988c1ce5af002d41c7ac37f3fa490558b0c90John Reck 161315c329544d7c593d1072b071cbb92d9afe74021John Reck private void applyInterpolator() { 162315c329544d7c593d1072b071cbb92d9afe74021John Reck if (mInterpolator == null) return; 163315c329544d7c593d1072b071cbb92d9afe74021John Reck 164315c329544d7c593d1072b071cbb92d9afe74021John Reck long ni; 165918988c1ce5af002d41c7ac37f3fa490558b0c90John Reck if (isNativeInterpolator(mInterpolator)) { 166315c329544d7c593d1072b071cbb92d9afe74021John Reck ni = ((NativeInterpolatorFactory)mInterpolator).createNativeInterpolator(); 167315c329544d7c593d1072b071cbb92d9afe74021John Reck } else { 168ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette long duration = nGetDuration(mNativePtr.get()); 169315c329544d7c593d1072b071cbb92d9afe74021John Reck ni = FallbackLUTInterpolator.createNativeInterpolator(mInterpolator, duration); 170315c329544d7c593d1072b071cbb92d9afe74021John Reck } 171315c329544d7c593d1072b071cbb92d9afe74021John Reck nSetInterpolator(mNativePtr.get(), ni); 172315c329544d7c593d1072b071cbb92d9afe74021John Reck } 173315c329544d7c593d1072b071cbb92d9afe74021John Reck 174ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette @Override 175ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette public void start() { 176ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette if (mTarget == null) { 177ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette throw new IllegalStateException("Missing target!"); 178ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette } 179ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette 1804d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck if (mState != STATE_PREPARE) { 181315c329544d7c593d1072b071cbb92d9afe74021John Reck throw new IllegalStateException("Already started!"); 182315c329544d7c593d1072b071cbb92d9afe74021John Reck } 183ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette 1844d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck mState = STATE_DELAYED; 185315c329544d7c593d1072b071cbb92d9afe74021John Reck applyInterpolator(); 186291161ac3815fb853fd6af21055d60f57a869608John Reck 187c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck if (mNativePtr == null) { 188c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck // It's dead, immediately cancel 189c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck cancel(); 190c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck } else if (mStartDelay <= 0 || !mUiThreadHandlesDelay) { 191291161ac3815fb853fd6af21055d60f57a869608John Reck nSetStartDelay(mNativePtr.get(), mStartDelay); 192291161ac3815fb853fd6af21055d60f57a869608John Reck doStart(); 193291161ac3815fb853fd6af21055d60f57a869608John Reck } else { 194291161ac3815fb853fd6af21055d60f57a869608John Reck getHelper().addDelayedAnimation(this); 195291161ac3815fb853fd6af21055d60f57a869608John Reck } 196291161ac3815fb853fd6af21055d60f57a869608John Reck } 197291161ac3815fb853fd6af21055d60f57a869608John Reck 198291161ac3815fb853fd6af21055d60f57a869608John Reck private void doStart() { 1998d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck // Alpha is a special snowflake that has the canonical value stored 2008d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck // in mTransformationInfo instead of in RenderNode, so we need to update 2018d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck // it with the final value here. 2028d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck if (mRenderProperty == RenderNodeAnimator.ALPHA) { 2038d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck // Don't need null check because ViewPropertyAnimator's 2048d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck // ctor calls ensureTransformationInfo() 2058d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck mViewTarget.mTransformationInfo.mAlpha = mFinalValue; 2068d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck } 207ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette 20872d6e4facb1abd81809fdaddbe42f41ad885189cJohn Reck moveToRunningState(); 209ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette 210ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette if (mViewTarget != null) { 211ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette // Kick off a frame to start the process 212ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette mViewTarget.invalidateViewProperty(true, false); 213ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette } 214ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette } 215ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette 21672d6e4facb1abd81809fdaddbe42f41ad885189cJohn Reck private void moveToRunningState() { 21772d6e4facb1abd81809fdaddbe42f41ad885189cJohn Reck mState = STATE_RUNNING; 218c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck if (mNativePtr != null) { 219c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck nStart(mNativePtr.get()); 220c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck } 22172d6e4facb1abd81809fdaddbe42f41ad885189cJohn Reck notifyStartListeners(); 22272d6e4facb1abd81809fdaddbe42f41ad885189cJohn Reck } 22372d6e4facb1abd81809fdaddbe42f41ad885189cJohn Reck 2244d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck private void notifyStartListeners() { 2254d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck final ArrayList<AnimatorListener> listeners = cloneListeners(); 2264d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck final int numListeners = listeners == null ? 0 : listeners.size(); 2274d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck for (int i = 0; i < numListeners; i++) { 2284d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck listeners.get(i).onAnimationStart(this); 2294d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck } 2304d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck } 2314d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck 232ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette @Override 233ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette public void cancel() { 23455b46eff394e23cde692e8acdfd7b42676a3f198John Reck if (mState != STATE_PREPARE && mState != STATE_FINISHED) { 2354d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck if (mState == STATE_DELAYED) { 2364d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck getHelper().removeDelayedAnimation(this); 23772d6e4facb1abd81809fdaddbe42f41ad885189cJohn Reck moveToRunningState(); 2384d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck } 23968bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 2403b27e59e1ea3b9928d2ddd0d37c0a13d83ae834bJohn Reck final ArrayList<AnimatorListener> listeners = cloneListeners(); 24168bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck final int numListeners = listeners == null ? 0 : listeners.size(); 24268bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck for (int i = 0; i < numListeners; i++) { 24368bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck listeners.get(i).onAnimationCancel(this); 24468bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck } 2454d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck 246c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck end(); 247ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette } 248ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette } 249ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette 250ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette @Override 251ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette public void end() { 2524d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck if (mState != STATE_FINISHED) { 25372d6e4facb1abd81809fdaddbe42f41ad885189cJohn Reck if (mState < STATE_RUNNING) { 25472d6e4facb1abd81809fdaddbe42f41ad885189cJohn Reck getHelper().removeDelayedAnimation(this); 25572d6e4facb1abd81809fdaddbe42f41ad885189cJohn Reck doStart(); 25672d6e4facb1abd81809fdaddbe42f41ad885189cJohn Reck } 257c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck if (mNativePtr != null) { 258c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck nEnd(mNativePtr.get()); 259c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck if (mViewTarget != null) { 260c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck // Kick off a frame to flush the state change 261c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck mViewTarget.invalidateViewProperty(true, false); 262c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck } 263c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck } else { 264c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck // It's already dead, jump to onFinish 265c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck onFinished(); 26672d6e4facb1abd81809fdaddbe42f41ad885189cJohn Reck } 267d3de42cae84fadfa1befd082a2cf1bf72f9ad82aJohn Reck } 268ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette } 269ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette 270ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette @Override 271ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette public void pause() { 272ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette throw new UnsupportedOperationException(); 273ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette } 274ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette 275ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette @Override 276ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette public void resume() { 277ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette throw new UnsupportedOperationException(); 278315c329544d7c593d1072b071cbb92d9afe74021John Reck } 279315c329544d7c593d1072b071cbb92d9afe74021John Reck 280ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette public void setTarget(View view) { 281ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette mViewTarget = view; 282119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck setTarget(mViewTarget.mRenderNode); 283e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck } 284e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 285ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette public void setTarget(Canvas canvas) { 286c9070ebd13263a341511cf779087a46750021196Chris Craik if (!(canvas instanceof DisplayListCanvas)) { 2871c058e96b3fb5075c34b89cf22773373811abf7aJohn Reck throw new IllegalArgumentException("Not a GLES20RecordingCanvas"); 2881c058e96b3fb5075c34b89cf22773373811abf7aJohn Reck } 289c9070ebd13263a341511cf779087a46750021196Chris Craik final DisplayListCanvas recordingCanvas = (DisplayListCanvas) canvas; 290ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette setTarget(recordingCanvas.mNode); 2911c058e96b3fb5075c34b89cf22773373811abf7aJohn Reck } 2921c058e96b3fb5075c34b89cf22773373811abf7aJohn Reck 293119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck private void setTarget(RenderNode node) { 294c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck checkMutable(); 2958d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck if (mTarget != null) { 2968d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck throw new IllegalStateException("Target already set!"); 2978d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck } 298c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck nSetListener(mNativePtr.get(), this); 299ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette mTarget = node; 3008d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck mTarget.addAnimator(this); 301e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck } 302e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 303c6b3264e16f1d2b72e7f9508559981ce9970157cJohn Reck public void setStartValue(float startValue) { 304c6b3264e16f1d2b72e7f9508559981ce9970157cJohn Reck checkMutable(); 305c6b3264e16f1d2b72e7f9508559981ce9970157cJohn Reck nSetStartValue(mNativePtr.get(), startValue); 306c6b3264e16f1d2b72e7f9508559981ce9970157cJohn Reck } 307c6b3264e16f1d2b72e7f9508559981ce9970157cJohn Reck 308ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette @Override 309ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette public void setStartDelay(long startDelay) { 310ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette checkMutable(); 31168bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck if (startDelay < 0) { 31268bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck throw new IllegalArgumentException("startDelay must be positive; " + startDelay); 31368bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck } 3148d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck mUnscaledStartDelay = startDelay; 315291161ac3815fb853fd6af21055d60f57a869608John Reck mStartDelay = (long) (ValueAnimator.getDurationScale() * startDelay); 316ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette } 317ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette 318ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette @Override 319ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette public long getStartDelay() { 3208d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck return mUnscaledStartDelay; 321ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette } 322ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette 323ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette @Override 324ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette public RenderNodeAnimator setDuration(long duration) { 325315c329544d7c593d1072b071cbb92d9afe74021John Reck checkMutable(); 32668bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck if (duration < 0) { 32768bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck throw new IllegalArgumentException("duration must be positive; " + duration); 32868bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck } 3298d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck mUnscaledDuration = duration; 3308d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck nSetDuration(mNativePtr.get(), (long) (duration * ValueAnimator.getDurationScale())); 331ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette return this; 332e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck } 333e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 334ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette @Override 335ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette public long getDuration() { 3368d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck return mUnscaledDuration; 337ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette } 338ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette 3391309914ebf21e705fc59d7d44014124d8a21a2d2Doris Liu @Override 3401309914ebf21e705fc59d7d44014124d8a21a2d2Doris Liu public long getTotalDuration() { 3411309914ebf21e705fc59d7d44014124d8a21a2d2Doris Liu return mUnscaledDuration + mUnscaledStartDelay; 3421309914ebf21e705fc59d7d44014124d8a21a2d2Doris Liu } 3431309914ebf21e705fc59d7d44014124d8a21a2d2Doris Liu 344ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette @Override 345ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette public boolean isRunning() { 3464d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck return mState == STATE_DELAYED || mState == STATE_RUNNING; 347ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette } 348ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette 349ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette @Override 350d3de42cae84fadfa1befd082a2cf1bf72f9ad82aJohn Reck public boolean isStarted() { 3514d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck return mState != STATE_PREPARE; 352d3de42cae84fadfa1befd082a2cf1bf72f9ad82aJohn Reck } 353d3de42cae84fadfa1befd082a2cf1bf72f9ad82aJohn Reck 354d3de42cae84fadfa1befd082a2cf1bf72f9ad82aJohn Reck @Override 355315c329544d7c593d1072b071cbb92d9afe74021John Reck public void setInterpolator(TimeInterpolator interpolator) { 356315c329544d7c593d1072b071cbb92d9afe74021John Reck checkMutable(); 357315c329544d7c593d1072b071cbb92d9afe74021John Reck mInterpolator = interpolator; 358315c329544d7c593d1072b071cbb92d9afe74021John Reck } 359315c329544d7c593d1072b071cbb92d9afe74021John Reck 360ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette @Override 361ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette public TimeInterpolator getInterpolator() { 362ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette return mInterpolator; 363e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck } 364e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 365291161ac3815fb853fd6af21055d60f57a869608John Reck protected void onFinished() { 366c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck if (mState == STATE_PREPARE) { 367c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck // Unlikely but possible, the native side has been destroyed 368c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck // before we have started. 369c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck releaseNativePtr(); 370c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck return; 371c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck } 3724d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck if (mState == STATE_DELAYED) { 3734d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck getHelper().removeDelayedAnimation(this); 3744d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck notifyStartListeners(); 3754d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck } 3764d2c47206a8e1706e5f89ef73c0e50e7321bf862John Reck mState = STATE_FINISHED; 377ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette 3783b27e59e1ea3b9928d2ddd0d37c0a13d83ae834bJohn Reck final ArrayList<AnimatorListener> listeners = cloneListeners(); 379ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette final int numListeners = listeners == null ? 0 : listeners.size(); 380ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette for (int i = 0; i < numListeners; i++) { 381ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette listeners.get(i).onAnimationEnd(this); 382ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette } 383119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck 384119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck // Release the native object, as it has a global reference to us. This 385119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck // breaks the cyclic reference chain, and allows this object to be 386119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck // GC'd 387c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck releaseNativePtr(); 388c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck } 389c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck 390c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck private void releaseNativePtr() { 391c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck if (mNativePtr != null) { 392c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck mNativePtr.release(); 393c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck mNativePtr = null; 394c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck } 395ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette } 396ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette 3973b27e59e1ea3b9928d2ddd0d37c0a13d83ae834bJohn Reck @SuppressWarnings("unchecked") 3983b27e59e1ea3b9928d2ddd0d37c0a13d83ae834bJohn Reck private ArrayList<AnimatorListener> cloneListeners() { 3993b27e59e1ea3b9928d2ddd0d37c0a13d83ae834bJohn Reck ArrayList<AnimatorListener> listeners = getListeners(); 4003b27e59e1ea3b9928d2ddd0d37c0a13d83ae834bJohn Reck if (listeners != null) { 4013b27e59e1ea3b9928d2ddd0d37c0a13d83ae834bJohn Reck listeners = (ArrayList<AnimatorListener>) listeners.clone(); 4023b27e59e1ea3b9928d2ddd0d37c0a13d83ae834bJohn Reck } 4033b27e59e1ea3b9928d2ddd0d37c0a13d83ae834bJohn Reck return listeners; 4043b27e59e1ea3b9928d2ddd0d37c0a13d83ae834bJohn Reck } 4053b27e59e1ea3b9928d2ddd0d37c0a13d83ae834bJohn Reck 406ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette long getNativeAnimator() { 407ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette return mNativePtr.get(); 408e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck } 409e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 410291161ac3815fb853fd6af21055d60f57a869608John Reck /** 411291161ac3815fb853fd6af21055d60f57a869608John Reck * @return true if the animator was started, false if still delayed 412291161ac3815fb853fd6af21055d60f57a869608John Reck */ 413291161ac3815fb853fd6af21055d60f57a869608John Reck private boolean processDelayed(long frameTimeMs) { 414291161ac3815fb853fd6af21055d60f57a869608John Reck if (mStartTime == 0) { 415291161ac3815fb853fd6af21055d60f57a869608John Reck mStartTime = frameTimeMs; 416291161ac3815fb853fd6af21055d60f57a869608John Reck } else if ((frameTimeMs - mStartTime) >= mStartDelay) { 417291161ac3815fb853fd6af21055d60f57a869608John Reck doStart(); 418291161ac3815fb853fd6af21055d60f57a869608John Reck return true; 419291161ac3815fb853fd6af21055d60f57a869608John Reck } 420291161ac3815fb853fd6af21055d60f57a869608John Reck return false; 421291161ac3815fb853fd6af21055d60f57a869608John Reck } 422291161ac3815fb853fd6af21055d60f57a869608John Reck 423291161ac3815fb853fd6af21055d60f57a869608John Reck private static DelayedAnimationHelper getHelper() { 424291161ac3815fb853fd6af21055d60f57a869608John Reck DelayedAnimationHelper helper = sAnimationHelper.get(); 425291161ac3815fb853fd6af21055d60f57a869608John Reck if (helper == null) { 426291161ac3815fb853fd6af21055d60f57a869608John Reck helper = new DelayedAnimationHelper(); 427291161ac3815fb853fd6af21055d60f57a869608John Reck sAnimationHelper.set(helper); 428291161ac3815fb853fd6af21055d60f57a869608John Reck } 429291161ac3815fb853fd6af21055d60f57a869608John Reck return helper; 430291161ac3815fb853fd6af21055d60f57a869608John Reck } 431291161ac3815fb853fd6af21055d60f57a869608John Reck 432291161ac3815fb853fd6af21055d60f57a869608John Reck private static ThreadLocal<DelayedAnimationHelper> sAnimationHelper = 433291161ac3815fb853fd6af21055d60f57a869608John Reck new ThreadLocal<DelayedAnimationHelper>(); 434291161ac3815fb853fd6af21055d60f57a869608John Reck 435291161ac3815fb853fd6af21055d60f57a869608John Reck private static class DelayedAnimationHelper implements Runnable { 436291161ac3815fb853fd6af21055d60f57a869608John Reck 437291161ac3815fb853fd6af21055d60f57a869608John Reck private ArrayList<RenderNodeAnimator> mDelayedAnims = new ArrayList<RenderNodeAnimator>(); 438291161ac3815fb853fd6af21055d60f57a869608John Reck private final Choreographer mChoreographer; 439291161ac3815fb853fd6af21055d60f57a869608John Reck private boolean mCallbackScheduled; 440291161ac3815fb853fd6af21055d60f57a869608John Reck 441291161ac3815fb853fd6af21055d60f57a869608John Reck public DelayedAnimationHelper() { 442291161ac3815fb853fd6af21055d60f57a869608John Reck mChoreographer = Choreographer.getInstance(); 443291161ac3815fb853fd6af21055d60f57a869608John Reck } 444291161ac3815fb853fd6af21055d60f57a869608John Reck 445291161ac3815fb853fd6af21055d60f57a869608John Reck public void addDelayedAnimation(RenderNodeAnimator animator) { 446291161ac3815fb853fd6af21055d60f57a869608John Reck mDelayedAnims.add(animator); 447291161ac3815fb853fd6af21055d60f57a869608John Reck scheduleCallback(); 448291161ac3815fb853fd6af21055d60f57a869608John Reck } 449291161ac3815fb853fd6af21055d60f57a869608John Reck 450291161ac3815fb853fd6af21055d60f57a869608John Reck public void removeDelayedAnimation(RenderNodeAnimator animator) { 451291161ac3815fb853fd6af21055d60f57a869608John Reck mDelayedAnims.remove(animator); 452291161ac3815fb853fd6af21055d60f57a869608John Reck } 453291161ac3815fb853fd6af21055d60f57a869608John Reck 454291161ac3815fb853fd6af21055d60f57a869608John Reck private void scheduleCallback() { 455291161ac3815fb853fd6af21055d60f57a869608John Reck if (!mCallbackScheduled) { 456291161ac3815fb853fd6af21055d60f57a869608John Reck mCallbackScheduled = true; 457291161ac3815fb853fd6af21055d60f57a869608John Reck mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, this, null); 458291161ac3815fb853fd6af21055d60f57a869608John Reck } 459291161ac3815fb853fd6af21055d60f57a869608John Reck } 460291161ac3815fb853fd6af21055d60f57a869608John Reck 461291161ac3815fb853fd6af21055d60f57a869608John Reck @Override 462291161ac3815fb853fd6af21055d60f57a869608John Reck public void run() { 463291161ac3815fb853fd6af21055d60f57a869608John Reck long frameTimeMs = mChoreographer.getFrameTime(); 464291161ac3815fb853fd6af21055d60f57a869608John Reck mCallbackScheduled = false; 465291161ac3815fb853fd6af21055d60f57a869608John Reck 466291161ac3815fb853fd6af21055d60f57a869608John Reck int end = 0; 467291161ac3815fb853fd6af21055d60f57a869608John Reck for (int i = 0; i < mDelayedAnims.size(); i++) { 468291161ac3815fb853fd6af21055d60f57a869608John Reck RenderNodeAnimator animator = mDelayedAnims.get(i); 469291161ac3815fb853fd6af21055d60f57a869608John Reck if (!animator.processDelayed(frameTimeMs)) { 470291161ac3815fb853fd6af21055d60f57a869608John Reck if (end != i) { 471291161ac3815fb853fd6af21055d60f57a869608John Reck mDelayedAnims.set(end, animator); 472291161ac3815fb853fd6af21055d60f57a869608John Reck } 473291161ac3815fb853fd6af21055d60f57a869608John Reck end++; 474291161ac3815fb853fd6af21055d60f57a869608John Reck } 475291161ac3815fb853fd6af21055d60f57a869608John Reck } 476291161ac3815fb853fd6af21055d60f57a869608John Reck while (mDelayedAnims.size() > end) { 477291161ac3815fb853fd6af21055d60f57a869608John Reck mDelayedAnims.remove(mDelayedAnims.size() - 1); 478291161ac3815fb853fd6af21055d60f57a869608John Reck } 479291161ac3815fb853fd6af21055d60f57a869608John Reck 480291161ac3815fb853fd6af21055d60f57a869608John Reck if (mDelayedAnims.size() > 0) { 481291161ac3815fb853fd6af21055d60f57a869608John Reck scheduleCallback(); 482291161ac3815fb853fd6af21055d60f57a869608John Reck } 483291161ac3815fb853fd6af21055d60f57a869608John Reck } 484291161ac3815fb853fd6af21055d60f57a869608John Reck } 485291161ac3815fb853fd6af21055d60f57a869608John Reck 486e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck // Called by native 487119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck private static void callOnFinished(RenderNodeAnimator animator) { 488119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck animator.onFinished(); 489e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck } 490e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 491291161ac3815fb853fd6af21055d60f57a869608John Reck @Override 492291161ac3815fb853fd6af21055d60f57a869608John Reck public Animator clone() { 493291161ac3815fb853fd6af21055d60f57a869608John Reck throw new IllegalStateException("Cannot clone this animator"); 494291161ac3815fb853fd6af21055d60f57a869608John Reck } 495291161ac3815fb853fd6af21055d60f57a869608John Reck 496f5945a0c8bb868f978d9d0d22043a8b44464a86eJohn Reck @Override 497f5945a0c8bb868f978d9d0d22043a8b44464a86eJohn Reck public void setAllowRunningAsynchronously(boolean mayRunAsync) { 498f5945a0c8bb868f978d9d0d22043a8b44464a86eJohn Reck checkMutable(); 499f5945a0c8bb868f978d9d0d22043a8b44464a86eJohn Reck nSetAllowRunningAsync(mNativePtr.get(), mayRunAsync); 500f5945a0c8bb868f978d9d0d22043a8b44464a86eJohn Reck } 501f5945a0c8bb868f978d9d0d22043a8b44464a86eJohn Reck 502119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck private static native long nCreateAnimator(int property, float finalValue); 503119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck private static native long nCreateCanvasPropertyFloatAnimator( 504c6b3264e16f1d2b72e7f9508559981ce9970157cJohn Reck long canvasProperty, float finalValue); 505119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck private static native long nCreateCanvasPropertyPaintAnimator( 506c6b3264e16f1d2b72e7f9508559981ce9970157cJohn Reck long canvasProperty, int paintField, float finalValue); 507119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck private static native long nCreateRevealAnimator( 508af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik int x, int y, float startRadius, float endRadius); 50968bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 510c6b3264e16f1d2b72e7f9508559981ce9970157cJohn Reck private static native void nSetStartValue(long nativePtr, float startValue); 511ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette private static native void nSetDuration(long nativePtr, long duration); 512ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette private static native long nGetDuration(long nativePtr); 513ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette private static native void nSetStartDelay(long nativePtr, long startDelay); 514315c329544d7c593d1072b071cbb92d9afe74021John Reck private static native void nSetInterpolator(long animPtr, long interpolatorPtr); 515f5945a0c8bb868f978d9d0d22043a8b44464a86eJohn Reck private static native void nSetAllowRunningAsync(long animPtr, boolean mayRunAsync); 516c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck private static native void nSetListener(long animPtr, RenderNodeAnimator listener); 51768bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 518c47c98be04d602f331e0ea9704d2c11f8c53852dJohn Reck private static native void nStart(long animPtr); 519d3de42cae84fadfa1befd082a2cf1bf72f9ad82aJohn Reck private static native void nEnd(long animPtr); 520e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck} 521