Deals with android:rotation attribute in layoutlib

The way Android views deal with their rotation xml attribute is through
native code called for hardware accelerated rendering. So layoutlib
has to bypass that in order to take those attributes into account.

Bug: http://b.android.com/73300
Change-Id: Ieb5bf0567a25a9021491ebf3250cedd0752f7863
diff --git a/bridge/src/android/view/RenderNode_Delegate.java b/bridge/src/android/view/RenderNode_Delegate.java
index 6c949d9..d62d4e1 100644
--- a/bridge/src/android/view/RenderNode_Delegate.java
+++ b/bridge/src/android/view/RenderNode_Delegate.java
@@ -19,6 +19,8 @@
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 
+import android.graphics.Matrix;
+
 /**
  * Delegate implementing the native methods of {@link RenderNode}
  * <p/>
@@ -36,6 +38,14 @@
 
 
     private float mLift;
+    private float mRotation;
+    private float mPivotX;
+    private float mPivotY;
+    private boolean mPivotExplicitelySet;
+    private int mLeft;
+    private int mRight;
+    private int mTop;
+    private int mBottom;
     @SuppressWarnings("UnusedDeclaration")
     private String mName;
 
@@ -69,4 +79,144 @@
         }
         return 0f;
     }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetRotation(long renderNode, float rotation) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mRotation != rotation) {
+            delegate.mRotation = rotation;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float nGetRotation(long renderNode) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null) {
+            return delegate.mRotation;
+        }
+        return 0f;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void getMatrix(RenderNode renderNode, Matrix outMatrix) {
+        outMatrix.reset();
+        if (renderNode != null) {
+            outMatrix.preRotate(renderNode.getRotation(), renderNode.getPivotX(),
+                    renderNode.getPivotY());
+        }
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetLeft(long renderNode, int left) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mLeft != left) {
+            delegate.mLeft = left;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetTop(long renderNode, int top) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mTop != top) {
+            delegate.mTop = top;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetRight(long renderNode, int right) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mRight != right) {
+            delegate.mRight = right;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetBottom(long renderNode, int bottom) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mBottom != bottom) {
+            delegate.mBottom = bottom;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetLeftTopRightBottom(long renderNode, int left, int top, int right,
+            int bottom) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && (delegate.mLeft != left || delegate.mTop != top || delegate
+                .mRight != right || delegate.mBottom != bottom)) {
+            delegate.mLeft = left;
+            delegate.mTop = top;
+            delegate.mRight = right;
+            delegate.mBottom = bottom;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nIsPivotExplicitlySet(long renderNode) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null) {
+            return delegate.mPivotExplicitelySet;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetPivotX(long renderNode, float pivotX) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mPivotX != pivotX) {
+            delegate.mPivotX = pivotX;
+            delegate.mPivotExplicitelySet = true;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float nGetPivotX(long renderNode) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null) {
+            if (delegate.mPivotExplicitelySet) {
+                return delegate.mPivotX;
+            } else {
+                return (delegate.mRight - delegate.mLeft) / 2.0f;
+            }
+        }
+        return 0f;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetPivotY(long renderNode, float pivotY) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mPivotY != pivotY) {
+            delegate.mPivotY = pivotY;
+            delegate.mPivotExplicitelySet = true;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float nGetPivotY(long renderNode) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null) {
+            if (delegate.mPivotExplicitelySet) {
+                return delegate.mPivotY;
+            } else {
+                return (delegate.mBottom - delegate.mTop) / 2.0f;
+            }
+        }
+        return 0f;
+    }
 }