Specify light and shadow properties in theme

BUG: 15859361
Change-Id: I65c9aa8c7ad7a709504c879d96158efba040d3ce
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index be677ea..f2f363a 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -248,24 +248,8 @@
     abstract void detachSurfaceTexture(long hardwareLayer);
 
     /**
-     * Setup the hardware renderer for drawing. This is called whenever the size
-     * of the target surface changes or when the surface is first created.
-     *
-     * @param width Width of the drawing surface.
-     * @param height Height of the drawing surface.
-     * @param surfaceInsets Insets between the drawing surface and actual
-     *            surface bounds.
-     * @param lightX X position of the shadow casting light
-     * @param lightY Y position of the shadow casting light
-     * @param lightZ Z position of the shadow casting light
-     * @param lightRadius radius of the shadow casting light
-     */
-    abstract void setup(int width, int height, Rect surfaceInsets, float lightX, float lightY,
-            float lightZ, float lightRadius);
-
-    /**
      * Gets the current width of the surface. This is the width that the surface
-     * was last set to in a call to {@link #setup(int, int, Rect, float, float, float, float)}.
+     * was last set to in a call to {@link #setup(int, int, Rect)}.
      *
      * @return the current width of the surface
      */
@@ -273,7 +257,7 @@
 
     /**
      * Gets the current height of the surface. This is the height that the surface
-     * was last set to in a call to {@link #setup(int, int, Rect, float, float, float, float)}.
+     * was last set to in a call to {@link #setup(int, int, Rect)}.
      *
      * @return the current width of the surface
      */
@@ -371,19 +355,18 @@
      * @param width The width of the drawing surface.
      * @param height The height of the drawing surface.
      * @param surface The surface to hardware accelerate
-     * @param metrics The display metrics used to draw the output.
      * @param surfaceInsets The drawing surface insets to apply
      *
      * @return true if the surface was initialized, false otherwise. Returning
      *         false might mean that the surface was already initialized.
      */
-    boolean initializeIfNeeded(int width, int height, Surface surface, Rect surfaceInsets, DisplayMetrics metrics)
+    boolean initializeIfNeeded(int width, int height, Surface surface, Rect surfaceInsets)
             throws OutOfResourcesException {
         if (isRequested()) {
             // We lost the gl context, so recreate it.
             if (!isEnabled()) {
                 if (initialize(surface)) {
-                    setup(width, height, surfaceInsets, metrics);
+                    setup(width, height, surfaceInsets);
                     return true;
                 }
             }
@@ -391,13 +374,14 @@
         return false;
     }
 
-    void setup(int width, int height, Rect surfaceInsets, DisplayMetrics metrics) {
-        float lightX = width / 2.0f;
-        float lightY = -400 * metrics.density;
-        float lightZ = 800 * metrics.density;
-        float lightRadius = 800 * metrics.density;
-        setup(width, height, surfaceInsets, lightX, lightY, lightZ, lightRadius);
-    }
+    /**
+     * Sets up the renderer for drawing.
+     *
+     * @param width The width of the drawing surface.
+     * @param height The height of the drawing surface.
+     * @param surfaceInsets The drawing surface insets to apply
+     */
+    abstract void setup(int width, int height, Rect surfaceInsets);
 
     /**
      * Optional, sets the name of the renderer. Useful for debugging purposes.
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index acb2fe4..fb8ce15 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -16,8 +16,11 @@
 
 package android.view;
 
+import com.android.internal.R;
+
 import android.content.Context;
 import android.content.res.Resources;
+import android.content.res.TypedArray;
 import android.graphics.Bitmap;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
@@ -78,6 +81,13 @@
     // applied as translation when updating the root render node.
     private int mInsetTop, mInsetLeft;
 
+    // Light and shadow properties specified by the theme.
+    private final float mLightY;
+    private final float mLightZ;
+    private final float mLightRadius;
+    private final float mAmbientShadowAlpha;
+    private final float mSpotShadowAlpha;
+
     private long mNativeProxy;
     private boolean mInitialized = false;
     private RenderNode mRootNode;
@@ -85,6 +95,15 @@
     private boolean mProfilingEnabled;
 
     ThreadedRenderer(Context context, boolean translucent) {
+        final TypedArray a = context.obtainStyledAttributes(
+                null, R.styleable.Lighting, R.attr.lightingStyle, 0);
+        mLightY = a.getDimension(R.styleable.Lighting_lightY, 0);
+        mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
+        mLightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
+        mAmbientShadowAlpha = a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0);
+        mSpotShadowAlpha = a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0);
+        a.recycle();
+
         long rootNodePtr = nCreateRootRenderNode();
         mRootNode = RenderNode.adopt(rootNodePtr);
         mRootNode.setClipToBounds(false);
@@ -164,8 +183,8 @@
     }
 
     @Override
-    void setup(int width, int height, Rect surfaceInsets, float lightX, float lightY, float lightZ,
-            float lightRadius) {
+    void setup(int width, int height, Rect surfaceInsets) {
+        final float lightX = width / 2.0f;
         mWidth = width;
         mHeight = height;
         if (surfaceInsets != null) {
@@ -180,7 +199,7 @@
             mSurfaceHeight = height;
         }
         mRootNode.setLeftTopRightBottom(-mInsetLeft, -mInsetTop, mSurfaceWidth, mSurfaceHeight);
-        nSetup(mNativeProxy, mSurfaceWidth, mSurfaceHeight, lightX, lightY, lightZ, lightRadius);
+        nSetup(mNativeProxy, mSurfaceWidth, mSurfaceHeight, lightX, mLightY, mLightZ, mLightRadius);
     }
 
     @Override
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 9405299..7fab808 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1714,8 +1714,7 @@
                         mWidth != mAttachInfo.mHardwareRenderer.getWidth() ||
                         mHeight != mAttachInfo.mHardwareRenderer.getHeight()) {
                     final Rect shadowInsets = params != null ? params.shadowInsets : null;
-                    mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight, shadowInsets,
-                            mAttachInfo.mRootView.getResources().getDisplayMetrics());
+                    mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight, shadowInsets);
                     if (!hwInitialized) {
                         mAttachInfo.mHardwareRenderer.invalidate(mSurface);
                         mFullRedrawNeeded = true;
@@ -2459,8 +2458,7 @@
 
                     try {
                         attachInfo.mHardwareRenderer.initializeIfNeeded(
-                                mWidth, mHeight, mSurface, surfaceInsets,
-                                attachInfo.mRootView.getResources().getDisplayMetrics());
+                                mWidth, mHeight, mSurface, surfaceInsets);
                     } catch (OutOfResourcesException e) {
                         handleOutOfResourcesException(e);
                         return;
@@ -3159,8 +3157,7 @@
                                 final WindowManager.LayoutParams lp = mWindowAttributes;
                                 final Rect surfaceInsets = lp != null ? lp.shadowInsets : null;
                                 mAttachInfo.mHardwareRenderer.initializeIfNeeded(
-                                        mWidth, mHeight, mSurface, surfaceInsets,
-                                        mAttachInfo.mRootView.getResources().getDisplayMetrics());
+                                        mWidth, mHeight, mSurface, surfaceInsets);
                             } catch (OutOfResourcesException e) {
                                 Log.e(TAG, "OutOfResourcesException locking surface", e);
                                 try {
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 9438fcc..5fdadb7 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -985,6 +985,14 @@
 
         <!-- The color applied to framework buttons in their normal state. -->
         <attr name="colorButtonNormal" format="color" />
+
+        <!-- ================== -->
+        <!-- Hardware rendering -->
+        <!-- ================== -->
+        <eat-comment />
+
+        <!-- Reference to the Lighting style. -->
+        <attr name="lightingStyle" format="reference" />
     </declare-styleable>
 
     <!-- **************************************************************** -->
@@ -7141,4 +7149,13 @@
         <attr name="layout_ignoreOffset" format="boolean" />
         <attr name="layout_gravity" />
     </declare-styleable>
+
+    <!-- @hide -->
+    <declare-styleable name="Lighting">
+        <attr name="lightY" format="dimension" />
+        <attr name="lightZ" format="dimension" />
+        <attr name="lightRadius" format="dimension" />
+        <attr name="ambientShadowAlpha" format="float" />
+        <attr name="spotShadowAlpha" format="float" />
+    </declare-styleable>
 </resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 9e25913..0eceae6 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1362,4 +1362,12 @@
         <item name="padding">16dp</item>
     </style>
 
+    <style name="Lighting">
+        <item name="lightY">-200dp</item>
+        <item name="lightZ">800dp</item>
+        <item name="lightRadius">800dp</item>
+        <item name="ambientShadowAlpha">0.125</item>
+        <item name="spotShadowAlpha">0.25</item>
+    </style>
+
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 6d22536..cd7394a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1904,7 +1904,6 @@
   <java-symbol type="attr" name="seekBarPreferenceStyle" />
   <java-symbol type="style" name="Theme.DeviceDefault.Resolver" />
   <java-symbol type="attr" name="preferenceFragmentStyle" />
-
   <java-symbol type="bool" name="skipHoldBeforeMerge" />
   <java-symbol type="bool" name="useImsAlwaysForEmergencyCall" />
   <java-symbol type="attr" name="touchscreenBlocksFocus" />
@@ -1916,4 +1915,10 @@
   <java-symbol type="string" name="whichEditApplicationNamed" />
   <java-symbol type="string" name="whichSendApplication" />
   <java-symbol type="string" name="whichSendApplicationNamed" />
+  <java-symbol type="attr" name="lightingStyle" />
+  <java-symbol type="attr" name="lightY" />
+  <java-symbol type="attr" name="lightZ" />
+  <java-symbol type="attr" name="lightRadius" />
+  <java-symbol type="attr" name="ambientShadowAlpha" />
+  <java-symbol type="attr" name="spotShadowAlpha" />
 </resources>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index d61253f..6ada975 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -420,6 +420,9 @@
 
         <!-- Accessibility focused drawable. -->
         <item name="accessibilityFocusedDrawable">@drawable/view_accessibility_focused</item>
+
+        <!-- Lighting and shadow style. -->
+        <item name="lightingStyle">@style/Lighting</item>
     </style>
 
     <!-- Variant of {@link #Theme} with no title bar -->