/*
 * Copyright (C) 2010 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;

import android.annotation.BytesLong;
import android.annotation.ColorInt;
import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.view.NativeVectorDrawableAnimator;
import android.view.RenderNodeAnimator;
import android.view.Surface;
import android.view.View;

import com.android.internal.util.ArrayUtils;

import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.FastNative;

import libcore.util.NativeAllocationRegistry;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * <p>RenderNode is used to build hardware accelerated rendering hierarchies. Each RenderNode
 * contains both a display list as well as a set of properties that affect the rendering of the
 * display list. RenderNodes are used internally for all Views by default and are not typically
 * used directly.</p>
 *
 * <p>RenderNodes are used to divide up the rendering content of a complex scene into smaller
 * pieces that can then be updated individually more cheaply. Updating part of the scene only needs
 * to update the display list or properties of a small number of RenderNode instead of redrawing
 * everything from scratch. A RenderNode only needs its display list re-recorded when its content
 * alone should be changed. RenderNodes can also be transformed without re-recording the display
 * list through the transform properties.</p>
 *
 * <p>A text editor might for instance store each paragraph into its own RenderNode.
 * Thus when the user inserts or removes characters, only the display list of the
 * affected paragraph needs to be recorded again.</p>
 *
 * <h3>Hardware acceleration</h3>
 * <p>RenderNodes can be drawn using a {@link RecordingCanvas}. They are not
 * supported in software. Always make sure that the {@link android.graphics.Canvas}
 * you are using to render a display list is hardware accelerated using
 * {@link android.graphics.Canvas#isHardwareAccelerated()}.</p>
 *
 * <h3>Creating a RenderNode</h3>
 * <pre class="prettyprint">
 *     RenderNode renderNode = new RenderNode("myRenderNode");
 *     renderNode.setLeftTopRightBottom(0, 0, 50, 50); // Set the size to 50x50
 *     RecordingCanvas canvas = renderNode.beginRecording();
 *     try {
 *         // Draw with the canvas
 *         canvas.drawRect(...);
 *     } finally {
 *         renderNode.endRecording();
 *     }</pre>
 *
 * <h3>Drawing a RenderNode in a View</h3>
 * <pre class="prettyprint">
 *     protected void onDraw(Canvas canvas) {
 *         if (canvas.isHardwareAccelerated()) {
 *             // Check that the RenderNode has a display list, re-recording it if it does not.
 *             if (!myRenderNode.hasDisplayList()) {
 *                 updateDisplayList(myRenderNode);
 *             }
 *             // Draw the RenderNode into this canvas.
 *             canvas.drawRenderNode(myRenderNode);
 *         }
 *     }</pre>
 *
 * <h3>Releasing resources</h3>
 * <p>This step is not mandatory but recommended if you want to release resources
 * held by a display list as soon as possible. Most significantly any bitmaps it may contain.</p>
 * <pre class="prettyprint">
 *     // Discards the display list content allowing for any held resources to be released.
 *     // After calling this
 *     renderNode.discardDisplayList();</pre>
 *
 *
 * <h3>Properties</h3>
 * <p>In addition, a RenderNode offers several properties, such as
 * {@link #setScaleX(float)} or {@link #setTranslationX(float)}, that can be used to affect all
 * the drawing commands recorded within. For instance, these properties can be used
 * to move around a large number of images without re-issuing all the individual
 * <code>canvas.drawBitmap()</code> calls.</p>
 *
 * <pre class="prettyprint">
 *     private void createDisplayList() {
 *         mRenderNode = new RenderNode("MyRenderNode");
 *         mRenderNode.setLeftTopRightBottom(0, 0, width, height);
 *         RecordingCanvas canvas = mRenderNode.beginRecording();
 *         try {
 *             for (Bitmap b : mBitmaps) {
 *                 canvas.drawBitmap(b, 0.0f, 0.0f, null);
 *                 canvas.translate(0.0f, b.getHeight());
 *             }
 *         } finally {
 *             mRenderNode.endRecording();
 *         }
 *     }
 *
 *     protected void onDraw(Canvas canvas) {
 *         if (canvas.isHardwareAccelerated())
 *             canvas.drawRenderNode(mRenderNode);
 *         }
 *     }
 *
 *     private void moveContentBy(int x) {
 *          // This will move all the bitmaps recorded inside the display list
 *          // by x pixels to the right and redraw this view. All the commands
 *          // recorded in createDisplayList() won't be re-issued, only onDraw()
 *          // will be invoked and will execute very quickly
 *          mRenderNode.offsetLeftAndRight(x);
 *          invalidate();
 *     }</pre>
 *
 * <p>A few of the properties may at first appear redundant, such as {@link #setElevation(float)}
 * and {@link #setTranslationZ(float)}. The reason for these duplicates are to allow for a
 * separation between static & transient usages. For example consider a button that raises from 2dp
 * to 8dp when pressed. To achieve that an application may decide to setElevation(2dip), and then
 * on press to animate setTranslationZ to 6dip. Combined this achieves the final desired 8dip
 * value, but the animation need only concern itself with animating the lift from press without
 * needing to know the initial starting value. {@link #setTranslationX(float)} and
 * {@link #setTranslationY(float)} are similarly provided for animation uses despite the functional
 * overlap with {@link #setPosition(Rect)}.
 *
 * <p>The RenderNode's transform matrix is computed at render time as follows:
 * <pre class="prettyprint">
 *     Matrix transform = new Matrix();
 *     transform.setTranslate(renderNode.getTranslationX(), renderNode.getTranslationY());
 *     transform.preRotate(renderNode.getRotationZ(),
 *             renderNode.getPivotX(), renderNode.getPivotY());
 *     transform.preScale(renderNode.getScaleX(), renderNode.getScaleY(),
 *             renderNode.getPivotX(), renderNode.getPivotY());</pre>
 * The current canvas transform matrix, which is translated to the RenderNode's position,
 * is then multiplied by the RenderNode's transform matrix. Therefore the ordering of calling
 * property setters does not affect the result. That is to say that:
 *
 * <pre class="prettyprint">
 *     renderNode.setTranslationX(100);
 *     renderNode.setScaleX(100);</pre>
 *
 * is equivalent to:
 *
 * <pre class="prettyprint">
 *     renderNode.setScaleX(100);
 *     renderNode.setTranslationX(100);</pre>
 *
 * <h3>Threading</h3>
 * <p>RenderNode may be created and used on any thread but they are not thread-safe. Only
 * a single thread may interact with a RenderNode at any given time. It is critical
 * that the RenderNode is only used on the same thread it is drawn with. For example when using
 * RenderNode with a custom View, then that RenderNode must only be used from the UI thread.</p>
 *
 * <h3>When to re-render</h3>
 * <p>Many of the RenderNode mutation methods, such as {@link #setTranslationX(float)}, return
 * a boolean indicating if the value actually changed or not. This is useful in detecting
 * if a new frame should be rendered or not. A typical usage would look like:
 * <pre class="prettyprint">
 *     public void translateTo(int x, int y) {
 *         boolean needsUpdate = myRenderNode.setTranslationX(x);
 *         needsUpdate |= myRenderNode.setTranslationY(y);
 *         if (needsUpdate) {
 *             myOwningView.invalidate();
 *         }
 *     }</pre>
 * This is marginally faster than doing a more explicit up-front check if the value changed by
 * comparing the desired value against {@link #getTranslationX()} as it minimizes JNI transitions.
 * The actual mechanism of requesting a new frame to be rendered will depend on how this
 * RenderNode is being drawn. If it's drawn to a containing View, as in the above snippet,
 * then simply invalidating that View works. If instead the RenderNode is being drawn to a Canvas
 * directly such as with {@link Surface#lockHardwareCanvas()} then a new frame needs to be drawn
 * by calling {@link Surface#lockHardwareCanvas()}, re-drawing the root RenderNode or whatever
 * top-level content is desired, and finally calling {@link Surface#unlockCanvasAndPost(Canvas)}.
 * </p>
 */
public final class RenderNode {

    // Use a Holder to allow static initialization in the boot image.
    private static class NoImagePreloadHolder {
        public static final NativeAllocationRegistry sRegistry =
                NativeAllocationRegistry.createMalloced(
                RenderNode.class.getClassLoader(), nGetNativeFinalizer());
    }

    /**
     * Not for general use; use only if you are ThreadedRenderer or RecordingCanvas.
     *
     * @hide
     */
    public final long mNativeRenderNode;
    private final AnimationHost mAnimationHost;
    private RecordingCanvas mCurrentRecordingCanvas;

    // Will be null if not currently registered
    @Nullable
    private CompositePositionUpdateListener mCompositePositionUpdateListener;

    /**
     * Creates a new RenderNode that can be used to record batches of
     * drawing operations, and store / apply render properties when drawn.
     *
     * @param name The name of the RenderNode, used for debugging purpose. May be null.
     */
    public RenderNode(@Nullable String name) {
        this(name, null);
    }

    private RenderNode(String name, AnimationHost animationHost) {
        mNativeRenderNode = nCreate(name);
        NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode);
        mAnimationHost = animationHost;
    }

    /**
     * @see RenderNode#adopt(long)
     */
    private RenderNode(long nativePtr) {
        mNativeRenderNode = nativePtr;
        NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode);
        mAnimationHost = null;
    }

    /** @hide */
    public static RenderNode create(String name, @Nullable AnimationHost animationHost) {
        return new RenderNode(name, animationHost);
    }

    /**
     * Adopts an existing native render node.
     *
     * Note: This will *NOT* incRef() on the native object, however it will
     * decRef() when it is destroyed. The caller should have already incRef'd it
     *
     * @hide
     */
    public static RenderNode adopt(long nativePtr) {
        return new RenderNode(nativePtr);
    }

    /**
     * Listens for RenderNode position updates for synchronous window movement.
     *
     * This is not suitable for generic position listening, it is only designed & intended
     * for use by things which require external position events like SurfaceView, PopupWindow, etc..
     *
     * @hide
     */
    public interface PositionUpdateListener {

        /**
         * Called by native by a Rendering Worker thread to update window position
         *
         * @hide
         */
        void positionChanged(long frameNumber, int left, int top, int right, int bottom);

        /**
         * Called by native on RenderThread to notify that the view is no longer in the
         * draw tree. UI thread is blocked at this point.
         *
         * @hide
         */
        void positionLost(long frameNumber);

    }

    private static final class CompositePositionUpdateListener implements PositionUpdateListener {
        private final PositionUpdateListener[] mListeners;
        private static final PositionUpdateListener[] sEmpty = new PositionUpdateListener[0];

        CompositePositionUpdateListener(PositionUpdateListener... listeners) {
            mListeners = listeners != null ? listeners : sEmpty;
        }

        public CompositePositionUpdateListener with(PositionUpdateListener listener) {
            return new CompositePositionUpdateListener(
                    ArrayUtils.appendElement(PositionUpdateListener.class, mListeners, listener));
        }

        public CompositePositionUpdateListener without(PositionUpdateListener listener) {
            return new CompositePositionUpdateListener(
                    ArrayUtils.removeElement(PositionUpdateListener.class, mListeners, listener));
        }

        @Override
        public void positionChanged(long frameNumber, int left, int top, int right, int bottom) {
            for (PositionUpdateListener pul : mListeners) {
                pul.positionChanged(frameNumber, left, top, right, bottom);
            }
        }

        @Override
        public void positionLost(long frameNumber) {
            for (PositionUpdateListener pul : mListeners) {
                pul.positionLost(frameNumber);
            }
        }
    }

    /**
     * Enable callbacks for position changes. Call only from the UI thread or with
     * external synchronization.
     *
     * @hide
     */
    public void addPositionUpdateListener(@NonNull PositionUpdateListener listener) {
        CompositePositionUpdateListener comp = mCompositePositionUpdateListener;
        if (comp == null) {
            comp = new CompositePositionUpdateListener(listener);
        } else {
            comp = comp.with(listener);
        }
        mCompositePositionUpdateListener = comp;
        nRequestPositionUpdates(mNativeRenderNode, comp);
    }

    /**
     * Disable a callback for position changes. Call only from the UI thread or with
     * external synchronization.
     *
     * @param listener Callback to remove
     * @hide
     */
    public void removePositionUpdateListener(@NonNull PositionUpdateListener listener) {
        CompositePositionUpdateListener comp = mCompositePositionUpdateListener;
        if (comp != null) {
            comp = comp.without(listener);
            mCompositePositionUpdateListener = comp;
            nRequestPositionUpdates(mNativeRenderNode, comp);
        }
    }

    /**
     * Starts recording a display list for the render node. All
     * operations performed on the returned canvas are recorded and
     * stored in this display list.
     *
     * {@link #endRecording()} must be called when the recording is finished in order to apply
     * the updated display list. Failing to call {@link #endRecording()} will result in an
     * {@link IllegalStateException} if {@link #beginRecording(int, int)} is called again.
     *
     * @param width  The width of the recording viewport. This will not alter the width of the
     *               RenderNode itself, that must be set with {@link #setPosition(Rect)}.
     * @param height The height of the recording viewport. This will not alter the height of the
     *               RenderNode itself, that must be set with {@link #setPosition(Rect)}.
     * @return A canvas to record drawing operations.
     * @throws IllegalStateException If a recording is already in progress. That is, the previous
     * call to {@link #beginRecording(int, int)} did not call {@link #endRecording()}.
     * @see #endRecording()
     * @see #hasDisplayList()
     */
    public @NonNull RecordingCanvas beginRecording(int width, int height) {
        if (mCurrentRecordingCanvas != null) {
            throw new IllegalStateException(
                    "Recording currently in progress - missing #endRecording() call?");
        }
        mCurrentRecordingCanvas = RecordingCanvas.obtain(this, width, height);
        return mCurrentRecordingCanvas;
    }

    /**
     * Same as {@link #beginRecording(int, int)} with the width & height set
     * to the RenderNode's own width & height. The RenderNode's width & height may be set
     * with {@link #setPosition(int, int, int, int)}.
     *
     * @return A canvas to record drawing operations.
     * @throws IllegalStateException If a recording is already in progress. That is, the previous
     * call to {@link #beginRecording(int, int)} did not call {@link #endRecording()}.
     * @see #endRecording()
     * @see #hasDisplayList()
     */
    public @NonNull RecordingCanvas beginRecording() {
        return beginRecording(nGetWidth(mNativeRenderNode), nGetHeight(mNativeRenderNode));
    }

    /**
     * `
     * Ends the recording for this display list. Calling this method marks
     * the display list valid and {@link #hasDisplayList()} will return true.
     *
     * @see #beginRecording(int, int)
     * @see #hasDisplayList()
     */
    public void endRecording() {
        if (mCurrentRecordingCanvas == null) {
            throw new IllegalStateException(
                    "No recording in progress, forgot to call #beginRecording()?");
        }
        RecordingCanvas canvas = mCurrentRecordingCanvas;
        mCurrentRecordingCanvas = null;
        long displayList = canvas.finishRecording();
        nSetDisplayList(mNativeRenderNode, displayList);
        canvas.recycle();
    }

    /**
     * @hide
     * @deprecated use {@link #beginRecording(int, int)} instead
     */
    @Deprecated
    public RecordingCanvas start(int width, int height) {
        return beginRecording(width, height);
    }

    /**
     * @hide
     * @deprecated use {@link #endRecording()} instead
     */
    @Deprecated
    public void end(RecordingCanvas canvas) {
        if (canvas != mCurrentRecordingCanvas) {
            throw new IllegalArgumentException("Wrong canvas");
        }
        endRecording();
    }

    /**
     * Reset native resources. This is called when cleaning up the state of display lists
     * during destruction of hardware resources, to ensure that we do not hold onto
     * obsolete resources after related resources are gone.
     */
    public void discardDisplayList() {
        nSetDisplayList(mNativeRenderNode, 0);
    }

    /**
     * Returns whether the RenderNode has a display list. If this returns false, the RenderNode
     * should be re-recorded with {@link #beginRecording()} and {@link #endRecording()}.
     *
     * A RenderNode without a display list may still be drawn, however it will have no impact
     * on the rendering content until its display list is updated.
     *
     * When a RenderNode is no longer drawn by anything the system may automatically
     * invoke {@link #discardDisplayList()}. It is therefore important to ensure that
     * {@link #hasDisplayList()} is true on a RenderNode prior to drawing it.
     *
     * See {@link #discardDisplayList()}
     *
     * @return boolean true if this RenderNode has a display list, false otherwise.
     */
    public boolean hasDisplayList() {
        return nIsValid(mNativeRenderNode);
    }

    ///////////////////////////////////////////////////////////////////////////
    // Matrix manipulation
    ///////////////////////////////////////////////////////////////////////////

    /**
     * Whether or not the RenderNode has an identity transform. This is a faster
     * way to do the otherwise equivalent {@link #getMatrix(Matrix)} {@link Matrix#isIdentity()}
     * as it doesn't require copying the Matrix first, thus minimizing overhead.
     *
     * @return true if the RenderNode has an identity transform, false otherwise
     */
    public boolean hasIdentityMatrix() {
        return nHasIdentityMatrix(mNativeRenderNode);
    }

    /**
     * Gets the current transform matrix
     *
     * @param outMatrix The matrix to store the transform of the RenderNode
     */
    public void getMatrix(@NonNull Matrix outMatrix) {
        nGetTransformMatrix(mNativeRenderNode, outMatrix.native_instance);
    }

    /**
     * Gets the current transform inverted. This is a faster way to do the otherwise
     * equivalent {@link #getMatrix(Matrix)} followed by {@link Matrix#invert(Matrix)}
     *
     * @param outMatrix The matrix to store the inverse transform of the RenderNode
     */
    public void getInverseMatrix(@NonNull Matrix outMatrix) {
        nGetInverseTransformMatrix(mNativeRenderNode, outMatrix.native_instance);
    }

    ///////////////////////////////////////////////////////////////////////////
    // RenderProperty Setters
    ///////////////////////////////////////////////////////////////////////////

    /**
     * @hide
     * @deprecated use {@link #setUseCompositingLayer(boolean, Paint)} instead
     */
    @Deprecated
    public boolean setLayerType(int layerType) {
        return nSetLayerType(mNativeRenderNode, layerType);
    }

    /**
     * @hide
     * @deprecated use {@link #setUseCompositingLayer(boolean, Paint)} instead
     */
    @Deprecated
    public boolean setLayerPaint(@Nullable Paint paint) {
        return nSetLayerPaint(mNativeRenderNode, paint != null ? paint.getNativeInstance() : 0);
    }

    /**
     * Controls whether or not to force this RenderNode to render to an intermediate buffer.
     * Internally RenderNode will already promote itself to a composition layer if it's useful
     * for performance or required for the current combination of {@link #setAlpha(float)} and
     * {@link #setHasOverlappingRendering(boolean)}.
     *
     * <p>The usage of this is instead to allow for either overriding of the internal behavior
     * if it's measured to be necessary for the particular rendering content in question or, more
     * usefully, to add a composition effect to the RenderNode via the optional paint parameter.
     *
     * <p>Note: When a RenderNode is using a compositing layer it will also result in
     * clipToBounds=true behavior.
     *
     * @param forceToLayer if true this forces the RenderNode to use an intermediate buffer.
     *                     Default & generally recommended value is false.
     * @param paint        The blend mode, alpha, and ColorFilter to apply to the compositing layer.
     *                     Only applies if forceToLayer is true. The paint's alpha is multiplied
     *                     with {@link #getAlpha()} to resolve the final alpha of the RenderNode.
     *                     If null then no additional composition effects are applied on top of the
     *                     composition layer.
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setUseCompositingLayer(boolean forceToLayer, @Nullable Paint paint) {
        boolean didChange = nSetLayerType(mNativeRenderNode, forceToLayer ? 2 : 0);
        didChange |= nSetLayerPaint(mNativeRenderNode,
                paint != null ? paint.getNativeInstance() : 0);
        return didChange;
    }

    /**
     * Gets whether or not a compositing layer is forced to be used. The default & recommended
     * is false, as it is typically faster to avoid using compositing layers.
     * See {@link #setUseCompositingLayer(boolean, Paint)}.
     *
     * @return true if a compositing layer is forced, false otherwise
     */
    public boolean getUseCompositingLayer() {
        return nGetLayerType(mNativeRenderNode) != 0;
    }

    /**
     * Sets an additional clip on the RenderNode. If null, the extra clip is removed from the
     * RenderNode. If non-null, the RenderNode will be clipped to this rect. In addition  if
     * {@link #setClipToBounds(boolean)} is true, then the RenderNode will be clipped to the
     * intersection of this rectangle and the bounds of the render node, which is set with
     * {@link #setPosition(Rect)}.
     *
     * <p>This is equivalent to do a {@link Canvas#clipRect(Rect)} at the start of this
     * RenderNode's display list. However, as this is a property of the RenderNode instead
     * of part of the display list it can be more easily animated for transient additional
     * clipping. An example usage of this would be the {@link android.transition.ChangeBounds}
     * transition animation with the resizeClip=true option.
     *
     * @param rect the bounds to clip to. If null, the additional clip is removed.
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setClipRect(@Nullable Rect rect) {
        if (rect == null) {
            return nSetClipBoundsEmpty(mNativeRenderNode);
        } else {
            return nSetClipBounds(mNativeRenderNode, rect.left, rect.top, rect.right, rect.bottom);
        }
    }

    /**
     * Set whether the Render node should clip itself to its bounds. This defaults to true,
     * and is useful to the renderer in enable quick-rejection of chunks of the tree as well as
     * better partial invalidation support. Clipping can be further restricted or controlled
     * through the combination of this property as well as {@link #setClipRect(Rect)}, which
     * allows for a different clipping rectangle to be used in addition to or instead of the
     * {@link #setPosition(int, int, int, int)} or the RenderNode.
     *
     * @param clipToBounds true if the display list should clip to its bounds, false otherwise.
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setClipToBounds(boolean clipToBounds) {
        return nSetClipToBounds(mNativeRenderNode, clipToBounds);
    }

    /**
     * Returns whether or not the RenderNode is clipping to its bounds. See
     * {@link #setClipToBounds(boolean)} and {@link #setPosition(int, int, int, int)}
     *
     * @return true if the render node clips to its bounds, false otherwise.
     */
    public boolean getClipToBounds() {
        return nGetClipToBounds(mNativeRenderNode);
    }

    /**
     * <p>Sets whether the RenderNode should be drawn immediately after the
     * closest ancestor RenderNode containing a projection receiver.
     *
     * <p>The default is false, and the rendering of this node happens in the typical draw order.
     *
     * <p>If true, then at rendering time this rendernode will not be drawn in order with the
     * {@link Canvas#drawRenderNode(RenderNode)} command that drew this RenderNode, but instead
     * it will be re-positioned in the RenderNode tree to be drawn on the closet ancestor with a
     * child rendernode that has {@link #setProjectionReceiver(boolean)} as true.
     *
     * <p>The typical usage of this is to allow a child RenderNode to draw on a parent's background,
     * such as the platform's usage with {@link android.graphics.drawable.RippleDrawable}. Consider
     * the following structure, built out of which RenderNode called drawRenderNode on a different
     * RenderNode:
     *
     * <pre>
     *        +-------------+
     *        |RenderNode: P|
     *        +-+----------++
     *          |          |
     *          v          v
     *  +-------+-----+  +-+--------------+
     *  |RenderNode: C|  |RenderNode: P'BG|
     *  +-------+-----+  +----------------+
     *          |
     *          |
     * +--------+-------+
     * |RenderNode: C'BG|
     * +----------------+
     * </pre>
     *
     * If P'BG is a projection receiver, and C'BG is set to project backwards then C'BG will
     * behave as if it was drawn directly by P'BG instead of by C. This includes inheriting P'BG's
     * clip instead of C's clip.
     *
     * @param shouldProject true if the display list should be projected onto a
     *                      containing volume. Default is false.
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setProjectBackwards(boolean shouldProject) {
        return nSetProjectBackwards(mNativeRenderNode, shouldProject);
    }

    /**
     * Sets whether the RenderNode is a projection receiver. If true then this RenderNode's parent
     * should draw any descendant RenderNodes with ProjectBackwards=true directly on top of it.
     * Default value is false. See
     * {@link #setProjectBackwards(boolean)} for a description of what this entails.
     *
     * @param shouldRecieve True if this RenderNode is a projection receiver, false otherwise.
     *                      Default is false.
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setProjectionReceiver(boolean shouldRecieve) {
        return nSetProjectionReceiver(mNativeRenderNode, shouldRecieve);
    }

    /**
     * Sets the outline, defining the shape that casts a shadow, and the path to
     * be clipped if setClipToOutline is set.
     *
     * This will make a copy of the provided {@link Outline}, so any future modifications
     * to the outline will need to call {@link #setOutline(Outline)} with the modified
     * outline for those changes to be applied.
     *
     * @param outline The outline to use for this RenderNode.
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setOutline(@Nullable Outline outline) {
        if (outline == null) {
            return nSetOutlineNone(mNativeRenderNode);
        }

        switch (outline.mMode) {
            case Outline.MODE_EMPTY:
                return nSetOutlineEmpty(mNativeRenderNode);
            case Outline.MODE_ROUND_RECT:
                return nSetOutlineRoundRect(mNativeRenderNode,
                        outline.mRect.left, outline.mRect.top,
                        outline.mRect.right, outline.mRect.bottom,
                        outline.mRadius, outline.mAlpha);
            case Outline.MODE_CONVEX_PATH:
                return nSetOutlineConvexPath(mNativeRenderNode, outline.mPath.mNativePath,
                        outline.mAlpha);
        }

        throw new IllegalArgumentException("Unrecognized outline?");
    }

    /**
     * Checks if the RenderNode has a shadow. That is, if the combination of {@link #getElevation()}
     * and {@link #getTranslationZ()} is greater than zero, there is an {@link Outline} set with
     * a valid shadow caster path, and the provided outline has a non-zero
     * {@link Outline#getAlpha()}.
     *
     * @return True if this RenderNode has a shadow, false otherwise
     */
    public boolean hasShadow() {
        return nHasShadow(mNativeRenderNode);
    }

    /**
     * Sets the color of the spot shadow that is drawn when the RenderNode has a positive Z or
     * elevation value and is drawn inside of a {@link Canvas#enableZ()} section.
     * <p>
     * By default the shadow color is black. Generally, this color will be opaque so the intensity
     * of the shadow is consistent between different RenderNodes with different colors.
     * <p>
     * The opacity of the final spot shadow is a function of the shadow caster height, the
     * alpha channel of the outlineSpotShadowColor (typically opaque), and the
     * {@link android.R.attr#spotShadowAlpha} theme attribute
     *
     * @param color The color this RenderNode will cast for its elevation spot shadow.
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setSpotShadowColor(@ColorInt int color) {
        return nSetSpotShadowColor(mNativeRenderNode, color);
    }

    /**
     * @return The shadow color set by {@link #setSpotShadowColor(int)}, or black if nothing
     * was set
     */
    public @ColorInt int getSpotShadowColor() {
        return nGetSpotShadowColor(mNativeRenderNode);
    }

    /**
     * Sets the color of the ambient shadow that is drawn when the RenderNode has a positive Z or
     * elevation value and is drawn inside of a {@link Canvas#enableZ()} section.
     * <p>
     * By default the shadow color is black. Generally, this color will be opaque so the intensity
     * of the shadow is consistent between different RenderNodes with different colors.
     * <p>
     * The opacity of the final ambient shadow is a function of the shadow caster height, the
     * alpha channel of the outlineAmbientShadowColor (typically opaque), and the
     * {@link android.R.attr#ambientShadowAlpha} theme attribute.
     *
     * @param color The color this RenderNode will cast for its elevation shadow.
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setAmbientShadowColor(@ColorInt int color) {
        return nSetAmbientShadowColor(mNativeRenderNode, color);
    }

    /**
     * @return The shadow color set by {@link #setAmbientShadowColor(int)}, or black if
     * nothing was set
     */
    public @ColorInt int getAmbientShadowColor() {
        return nGetAmbientShadowColor(mNativeRenderNode);
    }

    /**
     * Enables or disables clipping to the outline.
     *
     * @param clipToOutline true if clipping to the outline.
     * @return True if the clipToOutline value changed, false if previous value matched the new
     *         value.
     */
    public boolean setClipToOutline(boolean clipToOutline) {
        return nSetClipToOutline(mNativeRenderNode, clipToOutline);
    }

    /**
     * See {@link #setClipToOutline(boolean)}
     *
     * @return True if this RenderNode clips to its outline, false otherwise
     */
    public boolean getClipToOutline() {
        return nGetClipToOutline(mNativeRenderNode);
    }

    /**
     * Controls the RenderNode's circular reveal clip.
     *
     * @hide
     */
    public boolean setRevealClip(boolean shouldClip,
            float x, float y, float radius) {
        return nSetRevealClip(mNativeRenderNode, shouldClip, x, y, radius);
    }

    /**
     * Set the static matrix on the display list. The specified matrix is combined with other
     * transforms (such as {@link #setScaleX(float)}, {@link #setRotationZ(float)}, etc.)
     *
     * @param matrix A transform matrix to apply to this display list
     * @hide TODO Do we want this?
     */
    public boolean setStaticMatrix(Matrix matrix) {
        return nSetStaticMatrix(mNativeRenderNode, matrix.native_instance);
    }

    /**
     * Set the Animation matrix on the display list. This matrix exists if an Animation is
     * currently playing on a View, and is set on the display list during at draw() time. When
     * the Animation finishes, the matrix should be cleared by sending <code>null</code>
     * for the matrix parameter.
     *
     * @param matrix The matrix, null indicates that the matrix should be cleared.
     * @see #getAnimationMatrix()
     *
     * @hide TODO Do we want this?
     */
    public boolean setAnimationMatrix(@Nullable Matrix matrix) {
        return nSetAnimationMatrix(mNativeRenderNode,
                (matrix != null) ? matrix.native_instance : 0);
    }

    /**
     * Returns the previously set Animation matrix. This matrix exists if an Animation is
     * currently playing on a View, and is set on the display list during at draw() time.
     * Returns <code>null</code> when there is no transformation provided by
     * {@link #setAnimationMatrix(Matrix)}.
     *
     * @return the current Animation matrix.
     * @see #setAnimationMatrix(Matrix)
     *
     * @hide
     */
    @Nullable
    public Matrix getAnimationMatrix() {
        Matrix output = new Matrix();
        if (nGetAnimationMatrix(mNativeRenderNode, output.native_instance)) {
            return output;
        } else {
            return null;
        }
    }

    /**
     * Sets the translucency level for the display list.
     *
     * @param alpha The translucency of the display list, must be a value between 0.0f and 1.0f
     * @see View#setAlpha(float)
     * @see #getAlpha()
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setAlpha(float alpha) {
        return nSetAlpha(mNativeRenderNode, alpha);
    }

    /**
     * Returns the translucency level of this display list.
     *
     * @return A value between 0.0f and 1.0f
     * @see #setAlpha(float)
     */
    public float getAlpha() {
        return nGetAlpha(mNativeRenderNode);
    }

    /**
     * Sets whether the display list renders content which overlaps. Non-overlapping rendering
     * can use a fast path for alpha that avoids rendering to an offscreen buffer. By default
     * display lists consider they do not have overlapping content.
     *
     * @param hasOverlappingRendering False if the content is guaranteed to be non-overlapping,
     *                                true otherwise.
     * @see android.view.View#hasOverlappingRendering()
     * @see #hasOverlappingRendering()
     */
    public boolean setHasOverlappingRendering(boolean hasOverlappingRendering) {
        return nSetHasOverlappingRendering(mNativeRenderNode, hasOverlappingRendering);
    }

    /** @hide */
    @IntDef({USAGE_BACKGROUND})
    @Retention(RetentionPolicy.SOURCE)
    public @interface UsageHint {
    }

    /**
     * The default usage hint
     *
     * @hide
     */
    public static final int USAGE_UNKNOWN = 0;

    /**
     * Usage is background content
     *
     * @hide
     */
    public static final int USAGE_BACKGROUND = 1;

    /**
     * Provides a hint on what this RenderNode's display list content contains. This hint is used
     * for automatic content transforms to improve accessibility or similar.
     *
     * @hide
     */
    public void setUsageHint(@UsageHint int usageHint) {
        nSetUsageHint(mNativeRenderNode, usageHint);
    }

    /**
     * Indicates whether the content of this display list overlaps.
     *
     * @return True if this display list renders content which overlaps, false otherwise.
     * @see #setHasOverlappingRendering(boolean)
     */
    public boolean hasOverlappingRendering() {
        return nHasOverlappingRendering(mNativeRenderNode);
    }

    /**
     * Sets the base elevation of this RenderNode in pixels
     *
     * @param lift the elevation in pixels
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setElevation(float lift) {
        return nSetElevation(mNativeRenderNode, lift);
    }

    /**
     * See {@link #setElevation(float)}
     *
     * @return The RenderNode's current elevation
     */
    public float getElevation() {
        return nGetElevation(mNativeRenderNode);
    }

    /**
     * Sets the translation value for the display list on the X axis.
     *
     * @param translationX The X axis translation value of the display list, in pixels
     * @see View#setTranslationX(float)
     * @see #getTranslationX()
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setTranslationX(float translationX) {
        return nSetTranslationX(mNativeRenderNode, translationX);
    }

    /**
     * Returns the translation value for this display list on the X axis, in pixels.
     *
     * @see #setTranslationX(float)
     */
    public float getTranslationX() {
        return nGetTranslationX(mNativeRenderNode);
    }

    /**
     * Sets the translation value for the display list on the Y axis.
     *
     * @param translationY The Y axis translation value of the display list, in pixels
     * @see View#setTranslationY(float)
     * @see #getTranslationY()
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setTranslationY(float translationY) {
        return nSetTranslationY(mNativeRenderNode, translationY);
    }

    /**
     * Returns the translation value for this display list on the Y axis, in pixels.
     *
     * @see #setTranslationY(float)
     */
    public float getTranslationY() {
        return nGetTranslationY(mNativeRenderNode);
    }

    /**
     * Sets the translation value for the display list on the Z axis.
     *
     * @see View#setTranslationZ(float)
     * @see #getTranslationZ()
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setTranslationZ(float translationZ) {
        return nSetTranslationZ(mNativeRenderNode, translationZ);
    }

    /**
     * Returns the translation value for this display list on the Z axis.
     *
     * @see #setTranslationZ(float)
     */
    public float getTranslationZ() {
        return nGetTranslationZ(mNativeRenderNode);
    }

    /**
     * Sets the rotation value for the display list around the Z axis.
     *
     * @param rotation The rotation value of the display list, in degrees
     * @see View#setRotationZ(float)
     * @see #getRotationZ()
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setRotationZ(float rotation) {
        return nSetRotation(mNativeRenderNode, rotation);
    }

    /**
     * Returns the rotation value for this display list around the Z axis, in degrees.
     *
     * @see #setRotationZ(float)
     */
    public float getRotationZ() {
        return nGetRotation(mNativeRenderNode);
    }

    /**
     * Sets the rotation value for the display list around the X axis.
     *
     * @param rotationX The rotation value of the display list, in degrees
     * @see View#setRotationX(float)
     * @see #getRotationX()
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setRotationX(float rotationX) {
        return nSetRotationX(mNativeRenderNode, rotationX);
    }

    /**
     * Returns the rotation value for this display list around the X axis, in degrees.
     *
     * @see #setRotationX(float)
     */
    public float getRotationX() {
        return nGetRotationX(mNativeRenderNode);
    }

    /**
     * Sets the rotation value for the display list around the Y axis.
     *
     * @param rotationY The rotation value of the display list, in degrees
     * @see View#setRotationY(float)
     * @see #getRotationY()
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setRotationY(float rotationY) {
        return nSetRotationY(mNativeRenderNode, rotationY);
    }

    /**
     * Returns the rotation value for this display list around the Y axis, in degrees.
     *
     * @see #setRotationY(float)
     */
    public float getRotationY() {
        return nGetRotationY(mNativeRenderNode);
    }

    /**
     * Sets the scale value for the display list on the X axis.
     *
     * @param scaleX The scale value of the display list
     * @see View#setScaleX(float)
     * @see #getScaleX()
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setScaleX(float scaleX) {
        return nSetScaleX(mNativeRenderNode, scaleX);
    }

    /**
     * Returns the scale value for this display list on the X axis.
     *
     * @see #setScaleX(float)
     */
    public float getScaleX() {
        return nGetScaleX(mNativeRenderNode);
    }

    /**
     * Sets the scale value for the display list on the Y axis.
     *
     * @param scaleY The scale value of the display list
     * @see View#setScaleY(float)
     * @see #getScaleY()
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setScaleY(float scaleY) {
        return nSetScaleY(mNativeRenderNode, scaleY);
    }

    /**
     * Returns the scale value for this display list on the Y axis.
     *
     * @see #setScaleY(float)
     */
    public float getScaleY() {
        return nGetScaleY(mNativeRenderNode);
    }

    /**
     * Sets the pivot value for the display list on the X axis
     *
     * @param pivotX The pivot value of the display list on the X axis, in pixels
     * @see View#setPivotX(float)
     * @see #getPivotX()
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setPivotX(float pivotX) {
        return nSetPivotX(mNativeRenderNode, pivotX);
    }

    /**
     * Returns the pivot value for this display list on the X axis, in pixels.
     *
     * @see #setPivotX(float)
     */
    public float getPivotX() {
        return nGetPivotX(mNativeRenderNode);
    }

    /**
     * Sets the pivot value for the display list on the Y axis
     *
     * @param pivotY The pivot value of the display list on the Y axis, in pixels
     * @see View#setPivotY(float)
     * @see #getPivotY()
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setPivotY(float pivotY) {
        return nSetPivotY(mNativeRenderNode, pivotY);
    }

    /**
     * Returns the pivot value for this display list on the Y axis, in pixels.
     *
     * @see #setPivotY(float)
     */
    public float getPivotY() {
        return nGetPivotY(mNativeRenderNode);
    }

    /**
     * @return Whether or not a pivot was explicitly set with {@link #setPivotX(float)} or
     * {@link #setPivotY(float)}. If no pivot has been set then the pivot will be the center
     * of the RenderNode.
     */
    public boolean isPivotExplicitlySet() {
        return nIsPivotExplicitlySet(mNativeRenderNode);
    }

    /**
     * Clears any pivot previously set by a call to  {@link #setPivotX(float)} or
     * {@link #setPivotY(float)}. After calling this {@link #isPivotExplicitlySet()} will be false
     * and the pivot used for rotation will return to default of being centered on the view.
     *
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean resetPivot() {
        return nResetPivot(mNativeRenderNode);
    }

    /**
     * <p>Sets the distance along the Z axis (orthogonal to the X/Y plane on which
     * RenderNodes are drawn) from the camera to this RenderNode. The camera's distance
     * affects 3D transformations, for instance rotations around the X and Y
     * axis. If the rotationX or rotationY properties are changed and this view is
     * large (more than half the size of the screen), it is recommended to always
     * use a camera distance that's greater than the height (X axis rotation) or
     * the width (Y axis rotation) of this view.</p>
     *
     * <p>The distance of the camera from the drawing plane can have an affect on the
     * perspective distortion of the RenderNode when it is rotated around the x or y axis.
     * For example, a large distance will result in a large viewing angle, and there
     * will not be much perspective distortion of the view as it rotates. A short
     * distance may cause much more perspective distortion upon rotation, and can
     * also result in some drawing artifacts if the rotated view ends up partially
     * behind the camera (which is why the recommendation is to use a distance at
     * least as far as the size of the view, if the view is to be rotated.)</p>
     *
     * <p>The distance is expressed in pixels and must always be positive</p>
     *
     * @param distance The distance in pixels, must always be positive
     * @see #setRotationX(float)
     * @see #setRotationY(float)
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setCameraDistance(
            @FloatRange(from = 0.0f, to = Float.MAX_VALUE) float distance) {
        if (!Float.isFinite(distance) || distance < 0.0f) {
            throw new IllegalArgumentException("distance must be finite & positive, given="
                    + distance);
        }
        // Native actually wants this to be negative not positive, so we flip it.
        return nSetCameraDistance(mNativeRenderNode, -distance);
    }

    /**
     * Returns the distance in Z of the camera for this RenderNode
     *
     * @return the distance along the Z axis in pixels.
     * @see #setCameraDistance(float)
     */
    public @FloatRange(from = 0.0f, to = Float.MAX_VALUE) float getCameraDistance() {
        return -nGetCameraDistance(mNativeRenderNode);
    }

    /**
     * Sets the left position for the RenderNode.
     *
     * @param left The left position, in pixels, of the RenderNode
     * @return true if the value changed, false otherwise
     * @hide
     */
    public boolean setLeft(int left) {
        return nSetLeft(mNativeRenderNode, left);
    }

    /**
     * Sets the top position for the RenderNode.
     *
     * @param top The top position, in pixels, of the RenderNode
     * @return true if the value changed, false otherwise.
     * @hide
     */
    public boolean setTop(int top) {
        return nSetTop(mNativeRenderNode, top);
    }

    /**
     * Sets the right position for the RenderNode.
     *
     * @param right The right position, in pixels, of the RenderNode
     * @return true if the value changed, false otherwise.
     * @hide
     */
    public boolean setRight(int right) {
        return nSetRight(mNativeRenderNode, right);
    }

    /**
     * Sets the bottom position for the RenderNode.
     *
     * @param bottom The bottom position, in pixels, of the RenderNode
     * @return true if the value changed, false otherwise.
     * @hide
     */
    public boolean setBottom(int bottom) {
        return nSetBottom(mNativeRenderNode, bottom);
    }

    /**
     * Gets the left position for the RenderNode.
     *
     * @return the left position in pixels
     */
    public int getLeft() {
        return nGetLeft(mNativeRenderNode);
    }

    /**
     * Gets the top position for the RenderNode.
     *
     * @return the top position in pixels
     */
    public int getTop() {
        return nGetTop(mNativeRenderNode);
    }

    /**
     * Gets the right position for the RenderNode.
     *
     * @return the right position in pixels
     */
    public int getRight() {
        return nGetRight(mNativeRenderNode);
    }

    /**
     * Gets the bottom position for the RenderNode.
     *
     * @return the bottom position in pixels
     */
    public int getBottom() {
        return nGetBottom(mNativeRenderNode);
    }

    /**
     * Gets the width of the RenderNode, which is the right - left.
     *
     * @return the width of the RenderNode
     */
    public int getWidth() {
        return nGetWidth(mNativeRenderNode);
    }

    /**
     * Gets the height of the RenderNode, which is the bottom - top.
     *
     * @return the height of the RenderNode
     */
    public int getHeight() {
        return nGetHeight(mNativeRenderNode);
    }

    /**
     * Sets the left, top, right, and bottom of the RenderNode.
     *
     * @param left   The left position of the RenderNode, in pixels
     * @param top    The top position of the RenderNode, in pixels
     * @param right  The right position of the RenderNode, in pixels
     * @param bottom The bottom position of the RenderNode, in pixels
     * @return true if any values changed, false otherwise.
     * @hide
     */
    public boolean setLeftTopRightBottom(int left, int top, int right, int bottom) {
        return nSetLeftTopRightBottom(mNativeRenderNode, left, top, right, bottom);
    }

    /**
     * Sets the position of the RenderNode.
     *
     * @param left   The left position of the RenderNode, in pixels
     * @param top    The top position of the RenderNode, in pixels
     * @param right  The right position of the RenderNode, in pixels
     * @param bottom The bottom position of the RenderNode, in pixels
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setPosition(int left, int top, int right, int bottom) {
        return nSetLeftTopRightBottom(mNativeRenderNode, left, top, right, bottom);
    }

    /**
     * Sets the position of the RenderNode.
     *
     * @param position The position rectangle in pixels
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setPosition(@NonNull Rect position) {
        return nSetLeftTopRightBottom(mNativeRenderNode,
                position.left, position.top, position.right, position.bottom);
    }

    /**
     * Offsets the left and right positions for the RenderNode
     *
     * @param offset The amount that the left and right positions are offset in pixels
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean offsetLeftAndRight(int offset) {
        return nOffsetLeftAndRight(mNativeRenderNode, offset);
    }

    /**
     * Offsets the top and bottom values for the RenderNode
     *
     * @param offset The amount that the left and right positions are offset in pixels
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean offsetTopAndBottom(int offset) {
        return nOffsetTopAndBottom(mNativeRenderNode, offset);
    }

    /**
     * Outputs the RenderNode to the log. This method exists for use by
     * tools to output display lists for selected nodes to the log.
     *
     * @hide TODO: Expose? Should the shape of this be different than forced dump to logcat?
     */
    public void output() {
        nOutput(mNativeRenderNode);
    }

    /**
     * Gets the approximate memory usage of the RenderNode for debug purposes. Does not include
     * the memory usage of any child RenderNodes nor any bitmaps, only the memory usage of
     * this RenderNode and any data it owns.
     *
     * @return Approximate memory usage in bytes.
     */
    public @BytesLong long computeApproximateMemoryUsage() {
        return nGetDebugSize(mNativeRenderNode);
    }

    /**
     * Sets whether or not to allow force dark to apply to this RenderNode.
     *
     * Setting this to false will disable the auto-dark feature on everything this RenderNode
     * draws, including any descendants.
     *
     * Setting this to true will allow this RenderNode to be automatically made dark, however
     * a value of 'true' will not override any 'false' value in its parent chain nor will
     * it prevent any 'false' in any of its children.
     *
     * @param allow Whether or not to allow force dark.
     * @return True if the value changed, false if the new value was the same as the previous value.
     */
    public boolean setForceDarkAllowed(boolean allow) {
        return nSetAllowForceDark(mNativeRenderNode, allow);
    }

    /**
     * See {@link #setForceDarkAllowed(boolean)}
     *
     * @return true if force dark is allowed (default), false if it is disabled
     */
    public boolean isForceDarkAllowed() {
        return nGetAllowForceDark(mNativeRenderNode);
    }

    /**
     * Returns the unique ID that identifies this RenderNode. This ID is unique for the
     * lifetime of the process. IDs are reset on process death, and are unique only within
     * the process.
     *
     * This ID is intended to be used with debugging tools to associate a particular
     * RenderNode across different debug dumping & inspection tools. For example
     * a View layout inspector should include the unique ID for any RenderNodes that it owns
     * to associate the drawing content with the layout content.
     *
     * @return the unique ID for this RenderNode
     */
    public long getUniqueId() {
        return nGetUniqueId(mNativeRenderNode);
    }

    ///////////////////////////////////////////////////////////////////////////
    // Animations
    ///////////////////////////////////////////////////////////////////////////

    /**
     * TODO: Figure out if this can be eliminated/refactored away
     *
     * For now this interface exists to de-couple RenderNode from anything View-specific in a
     * bit of a kludge.
     *
     * @hide
     */
    public interface AnimationHost {
        /** @hide */
        void registerAnimatingRenderNode(RenderNode animator);

        /** @hide */
        void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator);

        /** @hide */
        boolean isAttached();
    }

    /** @hide */
    public void addAnimator(RenderNodeAnimator animator) {
        if (!isAttached()) {
            throw new IllegalStateException("Cannot start this animator on a detached view!");
        }
        nAddAnimator(mNativeRenderNode, animator.getNativeAnimator());
        mAnimationHost.registerAnimatingRenderNode(this);
    }

    /** @hide */
    public boolean isAttached() {
        return mAnimationHost != null && mAnimationHost.isAttached();
    }

    /** @hide */
    public void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animatorSet) {
        if (!isAttached()) {
            throw new IllegalStateException("Cannot start this animator on a detached view!");
        }
        mAnimationHost.registerVectorDrawableAnimator(animatorSet);
    }

    /** @hide */
    public void endAllAnimators() {
        nEndAllAnimators(mNativeRenderNode);
    }

    ///////////////////////////////////////////////////////////////////////////
    // Regular JNI methods
    ///////////////////////////////////////////////////////////////////////////

    private static native long nCreate(String name);

    private static native long nGetNativeFinalizer();

    private static native void nOutput(long renderNode);

    private static native int nGetDebugSize(long renderNode);

    private static native void nRequestPositionUpdates(long renderNode,
            PositionUpdateListener callback);

    // Animations

    private static native void nAddAnimator(long renderNode, long animatorPtr);

    private static native void nEndAllAnimators(long renderNode);


    ///////////////////////////////////////////////////////////////////////////
    // @FastNative methods
    ///////////////////////////////////////////////////////////////////////////

    @FastNative
    private static native void nSetDisplayList(long renderNode, long newData);


    ///////////////////////////////////////////////////////////////////////////
    // @CriticalNative methods
    ///////////////////////////////////////////////////////////////////////////

    @CriticalNative
    private static native boolean nIsValid(long renderNode);

    // Matrix

    @CriticalNative
    private static native void nGetTransformMatrix(long renderNode, long nativeMatrix);

    @CriticalNative
    private static native void nGetInverseTransformMatrix(long renderNode, long nativeMatrix);

    @CriticalNative
    private static native boolean nHasIdentityMatrix(long renderNode);

    // Properties

    @CriticalNative
    private static native boolean nOffsetTopAndBottom(long renderNode, int offset);

    @CriticalNative
    private static native boolean nOffsetLeftAndRight(long renderNode, int offset);

    @CriticalNative
    private static native boolean nSetLeftTopRightBottom(long renderNode, int left, int top,
            int right, int bottom);

    @CriticalNative
    private static native boolean nSetLeft(long renderNode, int left);

    @CriticalNative
    private static native boolean nSetTop(long renderNode, int top);

    @CriticalNative
    private static native boolean nSetRight(long renderNode, int right);

    @CriticalNative
    private static native boolean nSetBottom(long renderNode, int bottom);

    @CriticalNative
    private static native int nGetLeft(long renderNode);

    @CriticalNative
    private static native int nGetTop(long renderNode);

    @CriticalNative
    private static native int nGetRight(long renderNode);

    @CriticalNative
    private static native int nGetBottom(long renderNode);

    @CriticalNative
    private static native boolean nSetCameraDistance(long renderNode, float distance);

    @CriticalNative
    private static native boolean nSetPivotY(long renderNode, float pivotY);

    @CriticalNative
    private static native boolean nSetPivotX(long renderNode, float pivotX);

    @CriticalNative
    private static native boolean nResetPivot(long renderNode);

    @CriticalNative
    private static native boolean nSetLayerType(long renderNode, int layerType);

    @CriticalNative
    private static native int nGetLayerType(long renderNode);

    @CriticalNative
    private static native boolean nSetLayerPaint(long renderNode, long paint);

    @CriticalNative
    private static native boolean nSetClipToBounds(long renderNode, boolean clipToBounds);

    @CriticalNative
    private static native boolean nGetClipToBounds(long renderNode);

    @CriticalNative
    private static native boolean nSetClipBounds(long renderNode, int left, int top,
            int right, int bottom);

    @CriticalNative
    private static native boolean nSetClipBoundsEmpty(long renderNode);

    @CriticalNative
    private static native boolean nSetProjectBackwards(long renderNode, boolean shouldProject);

    @CriticalNative
    private static native boolean nSetProjectionReceiver(long renderNode, boolean shouldRecieve);

    @CriticalNative
    private static native boolean nSetOutlineRoundRect(long renderNode, int left, int top,
            int right, int bottom, float radius, float alpha);

    @CriticalNative
    private static native boolean nSetOutlineConvexPath(long renderNode, long nativePath,
            float alpha);

    @CriticalNative
    private static native boolean nSetOutlineEmpty(long renderNode);

    @CriticalNative
    private static native boolean nSetOutlineNone(long renderNode);

    @CriticalNative
    private static native boolean nHasShadow(long renderNode);

    @CriticalNative
    private static native boolean nSetSpotShadowColor(long renderNode, int color);

    @CriticalNative
    private static native boolean nSetAmbientShadowColor(long renderNode, int color);

    @CriticalNative
    private static native int nGetSpotShadowColor(long renderNode);

    @CriticalNative
    private static native int nGetAmbientShadowColor(long renderNode);

    @CriticalNative
    private static native boolean nSetClipToOutline(long renderNode, boolean clipToOutline);

    @CriticalNative
    private static native boolean nSetRevealClip(long renderNode,
            boolean shouldClip, float x, float y, float radius);

    @CriticalNative
    private static native boolean nSetAlpha(long renderNode, float alpha);

    @CriticalNative
    private static native boolean nSetHasOverlappingRendering(long renderNode,
            boolean hasOverlappingRendering);

    @CriticalNative
    private static native void nSetUsageHint(long renderNode, int usageHint);

    @CriticalNative
    private static native boolean nSetElevation(long renderNode, float lift);

    @CriticalNative
    private static native boolean nSetTranslationX(long renderNode, float translationX);

    @CriticalNative
    private static native boolean nSetTranslationY(long renderNode, float translationY);

    @CriticalNative
    private static native boolean nSetTranslationZ(long renderNode, float translationZ);

    @CriticalNative
    private static native boolean nSetRotation(long renderNode, float rotation);

    @CriticalNative
    private static native boolean nSetRotationX(long renderNode, float rotationX);

    @CriticalNative
    private static native boolean nSetRotationY(long renderNode, float rotationY);

    @CriticalNative
    private static native boolean nSetScaleX(long renderNode, float scaleX);

    @CriticalNative
    private static native boolean nSetScaleY(long renderNode, float scaleY);

    @CriticalNative
    private static native boolean nSetStaticMatrix(long renderNode, long nativeMatrix);

    @CriticalNative
    private static native boolean nSetAnimationMatrix(long renderNode, long animationMatrix);

    @CriticalNative
    private static native boolean nHasOverlappingRendering(long renderNode);

    @CriticalNative
    private static native boolean nGetAnimationMatrix(long renderNode, long animationMatrix);

    @CriticalNative
    private static native boolean nGetClipToOutline(long renderNode);

    @CriticalNative
    private static native float nGetAlpha(long renderNode);

    @CriticalNative
    private static native float nGetCameraDistance(long renderNode);

    @CriticalNative
    private static native float nGetScaleX(long renderNode);

    @CriticalNative
    private static native float nGetScaleY(long renderNode);

    @CriticalNative
    private static native float nGetElevation(long renderNode);

    @CriticalNative
    private static native float nGetTranslationX(long renderNode);

    @CriticalNative
    private static native float nGetTranslationY(long renderNode);

    @CriticalNative
    private static native float nGetTranslationZ(long renderNode);

    @CriticalNative
    private static native float nGetRotation(long renderNode);

    @CriticalNative
    private static native float nGetRotationX(long renderNode);

    @CriticalNative
    private static native float nGetRotationY(long renderNode);

    @CriticalNative
    private static native boolean nIsPivotExplicitlySet(long renderNode);

    @CriticalNative
    private static native float nGetPivotX(long renderNode);

    @CriticalNative
    private static native float nGetPivotY(long renderNode);

    @CriticalNative
    private static native int nGetWidth(long renderNode);

    @CriticalNative
    private static native int nGetHeight(long renderNode);

    @CriticalNative
    private static native boolean nSetAllowForceDark(long renderNode, boolean allowForceDark);

    @CriticalNative
    private static native boolean nGetAllowForceDark(long renderNode);

    @CriticalNative
    private static native long nGetUniqueId(long renderNode);
}
