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

Commit 5b5b1c0c authored by Xavier Ducrohet's avatar Xavier Ducrohet Committed by Android (Google) Code Review
Browse files

Merge "Animated vector drawable support" into nyc-dev

parents 53185a50 8a9a824c
Loading
Loading
Loading
Loading
+284 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.graphics.drawable;

import com.android.ide.common.rendering.api.LayoutLog;
import com.android.internal.view.animation.NativeInterpolatorFactoryHelper_Delegate;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.impl.DelegateManager;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.drawable.AnimatedVectorDrawable.VectorDrawableAnimatorRT;
import android.graphics.drawable.VectorDrawable_Delegate.VFullPath_Delegate;
import android.graphics.drawable.VectorDrawable_Delegate.VGroup_Delegate;
import android.graphics.drawable.VectorDrawable_Delegate.VNativeObject;
import android.graphics.drawable.VectorDrawable_Delegate.VPathRenderer_Delegate;

import java.util.ArrayList;
import java.util.function.Consumer;

/**
 * Delegate used to provide new implementation of a select few methods of {@link
 * AnimatedVectorDrawable}
 * <p>
 * Through the layoutlib_create tool, the original  methods of AnimatedVectorDrawable have been
 * replaced by calls to methods of the same name in this delegate class.
 */
@SuppressWarnings("unused")
public class AnimatedVectorDrawable_Delegate {
    private static DelegateManager<AnimatorSetHolder> sAnimatorSets = new
            DelegateManager<>(AnimatorSetHolder.class);
    private static DelegateManager<PropertySetter> sHolders = new
            DelegateManager<>(PropertySetter.class);


    @LayoutlibDelegate
    /*package*/ static long nCreateAnimatorSet() {
        return sAnimatorSets.addNewDelegate(new AnimatorSetHolder());
    }

    @LayoutlibDelegate
    /*package*/ static void nAddAnimator(long setPtr, long propertyValuesHolder,
            long nativeInterpolator, long startDelay, long duration, int repeatCount) {
        PropertySetter holder = sHolders.getDelegate(propertyValuesHolder);
        if (holder == null || holder.getValues() == null) {
            return;
        }

        ObjectAnimator animator = new ObjectAnimator();
        animator.setValues(holder.getValues());
        animator.setInterpolator(
                NativeInterpolatorFactoryHelper_Delegate.getDelegate(nativeInterpolator));
        animator.setStartDelay(startDelay);
        animator.setDuration(duration);
        animator.setRepeatCount(repeatCount);
        animator.setTarget(holder);
        animator.setPropertyName(holder.getValues().getPropertyName());

        AnimatorSetHolder set = sAnimatorSets.getDelegate(setPtr);
        assert set != null;
        set.addAnimator(animator);
    }

    @LayoutlibDelegate
    /*package*/ static long nCreateGroupPropertyHolder(long nativePtr, int propertyId,
            float startValue, float endValue) {
        VGroup_Delegate group = VNativeObject.getDelegate(nativePtr);
        Consumer<Float> setter = group.getPropertySetter(propertyId);

        return sHolders.addNewDelegate(FloatPropertySetter.of(setter, startValue,
                endValue));
    }

    @LayoutlibDelegate
    /*package*/ static long nCreatePathDataPropertyHolder(long nativePtr, long startValuePtr,
            long endValuePtr) {
        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, "AnimatedVectorDrawable path " +
                "animations are not supported.", null, null);
        return 0;
    }

    @LayoutlibDelegate
    /*package*/ static long nCreatePathColorPropertyHolder(long nativePtr, int propertyId,
            int startValue, int endValue) {
        VFullPath_Delegate path = VNativeObject.getDelegate(nativePtr);
        Consumer<Integer> setter = path.getIntPropertySetter(propertyId);

        return sHolders.addNewDelegate(IntPropertySetter.of(setter, startValue,
                endValue));
    }

    @LayoutlibDelegate
    /*package*/ static long nCreatePathPropertyHolder(long nativePtr, int propertyId,
            float startValue, float endValue) {
        VFullPath_Delegate path = VNativeObject.getDelegate(nativePtr);
        Consumer<Float> setter = path.getFloatPropertySetter(propertyId);

        return sHolders.addNewDelegate(FloatPropertySetter.of(setter, startValue,
                endValue));
    }

    @LayoutlibDelegate
    /*package*/ static long nCreateRootAlphaPropertyHolder(long nativePtr, float startValue,
            float endValue) {
        VPathRenderer_Delegate renderer = VNativeObject.getDelegate(nativePtr);

        return sHolders.addNewDelegate(FloatPropertySetter.of(renderer::setRootAlpha,
                startValue,
                endValue));
    }

    @LayoutlibDelegate
    /*package*/ static void nSetPropertyHolderData(long nativePtr, float[] data, int length) {
        PropertySetter setter = sHolders.getDelegate(nativePtr);
        assert setter != null;

        setter.setValues(data);
    }

    @LayoutlibDelegate
    /*package*/ static void nStart(long animatorSetPtr, VectorDrawableAnimatorRT set, int id) {
        AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr);
        assert animatorSet != null;

        animatorSet.start();
    }

    @LayoutlibDelegate
    /*package*/ static void nReverse(long animatorSetPtr, VectorDrawableAnimatorRT set, int id) {
        AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr);
        assert animatorSet != null;

        animatorSet.reverse();
    }

    @LayoutlibDelegate
    /*package*/ static void nEnd(long animatorSetPtr) {
        AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr);
        assert animatorSet != null;

        animatorSet.end();
    }

    @LayoutlibDelegate
    /*package*/ static void nReset(long animatorSetPtr) {
        AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr);
        assert animatorSet != null;

        animatorSet.end();
        animatorSet.start();
    }

    private static class AnimatorSetHolder {
        private ArrayList<Animator> mAnimators = new ArrayList<>();
        private AnimatorSet mAnimatorSet = null;

        private void addAnimator(@NonNull Animator animator) {
            mAnimators.add(animator);
        }

        private void ensureAnimatorSet() {
            if (mAnimatorSet == null) {
                mAnimatorSet = new AnimatorSet();
                mAnimatorSet.playTogether(mAnimators);
            }
        }

        private void start() {
            ensureAnimatorSet();

            mAnimatorSet.start();
        }

        private void end() {
            mAnimatorSet.end();
        }

        private void reset() {
            end();
            start();
        }

        private void reverse() {
            mAnimatorSet.reverse();
        }
    }

    /**
     * Class that allows setting a value and holds the range of values for the given property.
     *
     * @param <T> the type of the property
     */
    private static class PropertySetter<T> {
        final Consumer<T> mValueSetter;
        private PropertyValuesHolder mValues;

        private PropertySetter(@NonNull Consumer<T> valueSetter) {
            mValueSetter = valueSetter;
        }

        /**
         * Method to set an {@link Integer} value for this property. The default implementation of
         * this method doesn't do anything. This method is accessed via reflection by the
         * PropertyValuesHolder.
         */
        public void setIntValue(Integer value) {
        }

        /**
         * Method to set an {@link Integer} value for this property. The default implementation of
         * this method doesn't do anything. This method is accessed via reflection by the
         * PropertyValuesHolder.
         */
        public void setFloatValue(Float value) {
        }

        void setValues(float... values) {
            mValues = PropertyValuesHolder.ofFloat("floatValue", values);
        }

        @Nullable
        PropertyValuesHolder getValues() {
            return mValues;
        }

        void setValues(int... values) {
            mValues = PropertyValuesHolder.ofInt("intValue", values);
        }
    }

    private static class IntPropertySetter extends PropertySetter<Integer> {
        private IntPropertySetter(Consumer<Integer> valueSetter) {
            super(valueSetter);
        }

        private static PropertySetter of(Consumer<Integer> valueSetter, int... values) {
            PropertySetter setter = new IntPropertySetter(valueSetter);
            setter.setValues(values);

            return setter;
        }

        public void setIntValue(Integer value) {
            mValueSetter.accept(value);
        }
    }

    private static class FloatPropertySetter extends PropertySetter<Float> {
        private FloatPropertySetter(Consumer<Float> valueSetter) {
            super(valueSetter);
        }

        private static PropertySetter of(Consumer<Float> valueSetter, float... values) {
            PropertySetter setter = new FloatPropertySetter(valueSetter);
            setter.setValues(values);

            return setter;
        }

        public void setFloatValue(Float value) {
            mValueSetter.accept(value);
        }

    }
}
+28 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.graphics.drawable;

import com.android.tools.layoutlib.annotations.LayoutlibDelegate;

import android.graphics.drawable.AnimatedVectorDrawable.VectorDrawableAnimatorRT;

public class AnimatedVectorDrawable_VectorDrawableAnimatorRT_Delegate {
    @LayoutlibDelegate
    /*package*/ static boolean useLastSeenTarget(VectorDrawableAnimatorRT thisDrawableAnimator) {
        return true;
    }
}
+117 −61

File changed.

Preview size limit exceeded, changes collapsed.

+128 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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 com.android.internal.view.animation;

import com.android.layoutlib.bridge.impl.DelegateManager;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;

import android.util.MathUtils;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AnticipateInterpolator;
import android.view.animation.AnticipateOvershootInterpolator;
import android.view.animation.BaseInterpolator;
import android.view.animation.BounceInterpolator;
import android.view.animation.CycleInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.OvershootInterpolator;

/**
 * Delegate used to provide new implementation of a select few methods of {@link
 * NativeInterpolatorFactoryHelper}
 * <p>
 * Through the layoutlib_create tool, the original  methods of NativeInterpolatorFactoryHelper have
 * been replaced by calls to methods of the same name in this delegate class.
 */
@SuppressWarnings("unused")
public class NativeInterpolatorFactoryHelper_Delegate {
    private static final DelegateManager<Interpolator> sManager = new DelegateManager<>
            (Interpolator.class);

    public static Interpolator getDelegate(long nativePtr) {
        return sManager.getDelegate(nativePtr);
    }

    @LayoutlibDelegate
    /*package*/ static long createAccelerateDecelerateInterpolator() {
        return sManager.addNewDelegate(new AccelerateDecelerateInterpolator());
    }

    @LayoutlibDelegate
    /*package*/ static long createAccelerateInterpolator(float factor) {
        return sManager.addNewDelegate(new AccelerateInterpolator(factor));
    }

    @LayoutlibDelegate
    /*package*/ static long createAnticipateInterpolator(float tension) {
        return sManager.addNewDelegate(new AnticipateInterpolator(tension));
    }

    @LayoutlibDelegate
    /*package*/ static long createAnticipateOvershootInterpolator(float tension) {
        return sManager.addNewDelegate(new AnticipateOvershootInterpolator(tension));
    }

    @LayoutlibDelegate
    /*package*/ static long createBounceInterpolator() {
        return sManager.addNewDelegate(new BounceInterpolator());
    }

    @LayoutlibDelegate
    /*package*/ static long createCycleInterpolator(float cycles) {
        return sManager.addNewDelegate(new CycleInterpolator(cycles));
    }

    @LayoutlibDelegate
    /*package*/ static long createDecelerateInterpolator(float factor) {
        return sManager.addNewDelegate(new DecelerateInterpolator(factor));
    }

    @LayoutlibDelegate
    /*package*/ static long createLinearInterpolator() {
        return sManager.addNewDelegate(new LinearInterpolator());
    }

    @LayoutlibDelegate
    /*package*/ static long createOvershootInterpolator(float tension) {
        return sManager.addNewDelegate(new OvershootInterpolator(tension));
    }

    private static class LutInterpolator extends BaseInterpolator {
        private final float[] mValues;
        private final int mSize;

        private LutInterpolator(float[] values) {
            mValues = values;
            mSize = mValues.length;
        }

        @Override
        public float getInterpolation(float input) {
            float lutpos = input * mSize;
            if (lutpos >= (mSize - 1)) {
                return mValues[mSize - 1];
            }

            int ipart = (int) lutpos;
            float weight = lutpos - ipart;

            int i1 = ipart;
            int i2 = Math.min(i1 + 1, mSize - 1);

            assert i1 >= 0 && i2 >= 0 : "Negatives in the interpolation";

            return MathUtils.lerp(mValues[i1], mValues[i2], weight);
        }
    }

    @LayoutlibDelegate
    /*package*/ static long createLutInterpolator(float[] values) {
        return sManager.addNewDelegate(new LutInterpolator(values));
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -164,6 +164,7 @@ public final class CreateInfo implements ICreateInfo {
        "android.content.res.TypedArray#obtain",
        "android.graphics.BitmapFactory#finishDecode",
        "android.graphics.BitmapFactory#setDensityFromOptions",
        "android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT#useLastSeenTarget",
        "android.graphics.drawable.GradientDrawable#buildRing",
        "android.graphics.Typeface#getSystemFontConfigLocation",
        "android.graphics.Typeface#makeFamilyFromParsed",
@@ -269,6 +270,7 @@ public final class CreateInfo implements ICreateInfo {
        "android.graphics.SweepGradient",
        "android.graphics.Typeface",
        "android.graphics.Xfermode",
        "android.graphics.drawable.AnimatedVectorDrawable",
        "android.graphics.drawable.VectorDrawable",
        "android.os.SystemClock",
        "android.os.SystemProperties",
@@ -276,6 +278,7 @@ public final class CreateInfo implements ICreateInfo {
        "android.text.StaticLayout",
        "android.util.PathParser",
        "android.view.Display",
        "com.android.internal.view.animation.NativeInterpolatorFactoryHelper",
        "libcore.icu.ICU",
    };