1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License") {} 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.graphics.drawable; 18 19 import com.android.ide.common.rendering.api.LayoutLog; 20 import com.android.layoutlib.bridge.Bridge; 21 import com.android.layoutlib.bridge.impl.DelegateManager; 22 import com.android.tools.layoutlib.annotations.LayoutlibDelegate; 23 24 import android.animation.Animator; 25 import android.animation.AnimatorSet; 26 import android.animation.ObjectAnimator; 27 import android.animation.PropertyValuesHolder; 28 import android.annotation.NonNull; 29 import android.annotation.Nullable; 30 import android.graphics.animation.NativeInterpolatorFactory_Delegate; 31 import android.graphics.drawable.AnimatedVectorDrawable.VectorDrawableAnimatorRT; 32 import android.graphics.drawable.VectorDrawable_Delegate.VFullPath_Delegate; 33 import android.graphics.drawable.VectorDrawable_Delegate.VGroup_Delegate; 34 import android.graphics.drawable.VectorDrawable_Delegate.VNativeObject; 35 import android.graphics.drawable.VectorDrawable_Delegate.VPathRenderer_Delegate; 36 37 import java.util.ArrayList; 38 import java.util.function.Consumer; 39 40 /** 41 * Delegate used to provide new implementation of a select few methods of {@link 42 * AnimatedVectorDrawable} 43 * <p> 44 * Through the layoutlib_create tool, the original methods of AnimatedVectorDrawable have been 45 * replaced by calls to methods of the same name in this delegate class. 46 */ 47 @SuppressWarnings("unused") 48 public class AnimatedVectorDrawable_Delegate { 49 private static DelegateManager<AnimatorSetHolder> sAnimatorSets = new 50 DelegateManager<>(AnimatorSetHolder.class); 51 private static DelegateManager<PropertySetter> sHolders = new 52 DelegateManager<>(PropertySetter.class); 53 54 55 @LayoutlibDelegate nCreateAnimatorSet()56 /*package*/ static long nCreateAnimatorSet() { 57 return sAnimatorSets.addNewDelegate(new AnimatorSetHolder()); 58 } 59 60 @LayoutlibDelegate nSetVectorDrawableTarget(long animatorPtr, long vectorDrawablePtr)61 /*package*/ static void nSetVectorDrawableTarget(long animatorPtr, long vectorDrawablePtr) { 62 // TODO: implement 63 } 64 @LayoutlibDelegate nAddAnimator(long setPtr, long propertyValuesHolder, long nativeInterpolator, long startDelay, long duration, int repeatCount, int repeatMode)65 /*package*/ static void nAddAnimator(long setPtr, long propertyValuesHolder, 66 long nativeInterpolator, long startDelay, long duration, int repeatCount, 67 int repeatMode) { 68 PropertySetter holder = sHolders.getDelegate(propertyValuesHolder); 69 if (holder == null || holder.getValues() == null) { 70 return; 71 } 72 73 ObjectAnimator animator = new ObjectAnimator(); 74 animator.setValues(holder.getValues()); 75 animator.setInterpolator( 76 NativeInterpolatorFactory_Delegate.getDelegate(nativeInterpolator)); 77 animator.setStartDelay(startDelay); 78 animator.setDuration(duration); 79 animator.setRepeatCount(repeatCount); 80 animator.setRepeatMode(repeatMode); 81 animator.setTarget(holder); 82 animator.setPropertyName(holder.getValues().getPropertyName()); 83 84 AnimatorSetHolder set = sAnimatorSets.getDelegate(setPtr); 85 assert set != null; 86 set.addAnimator(animator); 87 } 88 89 @LayoutlibDelegate nCreateGroupPropertyHolder(long nativePtr, int propertyId, float startValue, float endValue)90 /*package*/ static long nCreateGroupPropertyHolder(long nativePtr, int propertyId, 91 float startValue, float endValue) { 92 VGroup_Delegate group = VNativeObject.getDelegate(nativePtr); 93 Consumer<Float> setter = group.getPropertySetter(propertyId); 94 95 return sHolders.addNewDelegate(FloatPropertySetter.of(setter, startValue, 96 endValue)); 97 } 98 99 @LayoutlibDelegate nCreatePathDataPropertyHolder(long nativePtr, long startValuePtr, long endValuePtr)100 /*package*/ static long nCreatePathDataPropertyHolder(long nativePtr, long startValuePtr, 101 long endValuePtr) { 102 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, "AnimatedVectorDrawable path " + 103 "animations are not supported.", null, null, null); 104 return 0; 105 } 106 107 @LayoutlibDelegate nCreatePathColorPropertyHolder(long nativePtr, int propertyId, int startValue, int endValue)108 /*package*/ static long nCreatePathColorPropertyHolder(long nativePtr, int propertyId, 109 int startValue, int endValue) { 110 VFullPath_Delegate path = VNativeObject.getDelegate(nativePtr); 111 Consumer<Integer> setter = path.getIntPropertySetter(propertyId); 112 113 return sHolders.addNewDelegate(IntPropertySetter.of(setter, startValue, 114 endValue)); 115 } 116 117 @LayoutlibDelegate nCreatePathPropertyHolder(long nativePtr, int propertyId, float startValue, float endValue)118 /*package*/ static long nCreatePathPropertyHolder(long nativePtr, int propertyId, 119 float startValue, float endValue) { 120 VFullPath_Delegate path = VNativeObject.getDelegate(nativePtr); 121 Consumer<Float> setter = path.getFloatPropertySetter(propertyId); 122 123 return sHolders.addNewDelegate(FloatPropertySetter.of(setter, startValue, 124 endValue)); 125 } 126 127 @LayoutlibDelegate nCreateRootAlphaPropertyHolder(long nativePtr, float startValue, float endValue)128 /*package*/ static long nCreateRootAlphaPropertyHolder(long nativePtr, float startValue, 129 float endValue) { 130 VPathRenderer_Delegate renderer = VNativeObject.getDelegate(nativePtr); 131 132 return sHolders.addNewDelegate(FloatPropertySetter.of(renderer::setRootAlpha, 133 startValue, 134 endValue)); 135 } 136 137 @LayoutlibDelegate nSetPropertyHolderData(long nativePtr, float[] data, int length)138 /*package*/ static void nSetPropertyHolderData(long nativePtr, float[] data, int length) { 139 PropertySetter setter = sHolders.getDelegate(nativePtr); 140 assert setter != null; 141 142 setter.setValues(data); 143 } 144 145 @LayoutlibDelegate nSetPropertyHolderData(long nativePtr, int[] data, int length)146 /*package*/ static void nSetPropertyHolderData(long nativePtr, int[] data, int length) { 147 PropertySetter setter = sHolders.getDelegate(nativePtr); 148 assert setter != null; 149 150 setter.setValues(data); 151 } 152 153 @LayoutlibDelegate nStart(long animatorSetPtr, VectorDrawableAnimatorRT set, int id)154 /*package*/ static void nStart(long animatorSetPtr, VectorDrawableAnimatorRT set, int id) { 155 AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr); 156 assert animatorSet != null; 157 158 animatorSet.start(); 159 } 160 161 @LayoutlibDelegate nReverse(long animatorSetPtr, VectorDrawableAnimatorRT set, int id)162 /*package*/ static void nReverse(long animatorSetPtr, VectorDrawableAnimatorRT set, int id) { 163 AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr); 164 assert animatorSet != null; 165 166 animatorSet.reverse(); 167 } 168 169 @LayoutlibDelegate nEnd(long animatorSetPtr)170 /*package*/ static void nEnd(long animatorSetPtr) { 171 AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr); 172 assert animatorSet != null; 173 174 animatorSet.end(); 175 } 176 177 @LayoutlibDelegate nReset(long animatorSetPtr)178 /*package*/ static void nReset(long animatorSetPtr) { 179 AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr); 180 assert animatorSet != null; 181 182 animatorSet.end(); 183 animatorSet.start(); 184 } 185 186 private static class AnimatorSetHolder { 187 private ArrayList<Animator> mAnimators = new ArrayList<>(); 188 private AnimatorSet mAnimatorSet = null; 189 addAnimator(@onNull Animator animator)190 private void addAnimator(@NonNull Animator animator) { 191 mAnimators.add(animator); 192 } 193 ensureAnimatorSet()194 private void ensureAnimatorSet() { 195 if (mAnimatorSet == null) { 196 mAnimatorSet = new AnimatorSet(); 197 mAnimatorSet.playTogether(mAnimators); 198 } 199 } 200 start()201 private void start() { 202 ensureAnimatorSet(); 203 204 mAnimatorSet.start(); 205 } 206 end()207 private void end() { 208 mAnimatorSet.end(); 209 } 210 reset()211 private void reset() { 212 end(); 213 start(); 214 } 215 reverse()216 private void reverse() { 217 mAnimatorSet.reverse(); 218 } 219 } 220 221 /** 222 * Class that allows setting a value and holds the range of values for the given property. 223 * 224 * @param <T> the type of the property 225 */ 226 private static class PropertySetter<T> { 227 final Consumer<T> mValueSetter; 228 private PropertyValuesHolder mValues; 229 PropertySetter(@onNull Consumer<T> valueSetter)230 private PropertySetter(@NonNull Consumer<T> valueSetter) { 231 mValueSetter = valueSetter; 232 } 233 234 /** 235 * Method to set an {@link Integer} value for this property. The default implementation of 236 * this method doesn't do anything. This method is accessed via reflection by the 237 * PropertyValuesHolder. 238 */ setIntValue(Integer value)239 public void setIntValue(Integer value) { 240 } 241 242 /** 243 * Method to set an {@link Integer} value for this property. The default implementation of 244 * this method doesn't do anything. This method is accessed via reflection by the 245 * PropertyValuesHolder. 246 */ setFloatValue(Float value)247 public void setFloatValue(Float value) { 248 } 249 setValues(float... values)250 void setValues(float... values) { 251 mValues = PropertyValuesHolder.ofFloat("floatValue", values); 252 } 253 254 @Nullable getValues()255 PropertyValuesHolder getValues() { 256 return mValues; 257 } 258 setValues(int... values)259 void setValues(int... values) { 260 mValues = PropertyValuesHolder.ofInt("intValue", values); 261 } 262 } 263 264 private static class IntPropertySetter extends PropertySetter<Integer> { IntPropertySetter(Consumer<Integer> valueSetter)265 private IntPropertySetter(Consumer<Integer> valueSetter) { 266 super(valueSetter); 267 } 268 of(Consumer<Integer> valueSetter, int... values)269 private static PropertySetter of(Consumer<Integer> valueSetter, int... values) { 270 PropertySetter setter = new IntPropertySetter(valueSetter); 271 setter.setValues(values); 272 273 return setter; 274 } 275 setIntValue(Integer value)276 public void setIntValue(Integer value) { 277 mValueSetter.accept(value); 278 } 279 } 280 281 private static class FloatPropertySetter extends PropertySetter<Float> { FloatPropertySetter(Consumer<Float> valueSetter)282 private FloatPropertySetter(Consumer<Float> valueSetter) { 283 super(valueSetter); 284 } 285 of(Consumer<Float> valueSetter, float... values)286 private static PropertySetter of(Consumer<Float> valueSetter, float... values) { 287 PropertySetter setter = new FloatPropertySetter(valueSetter); 288 setter.setValues(values); 289 290 return setter; 291 } 292 setFloatValue(Float value)293 public void setFloatValue(Float value) { 294 mValueSetter.accept(value); 295 } 296 297 } 298 } 299