[Shadows] Add api to set global shadow settings (4/n)

Bug: 136561771
Test: go/wm-smoke
Change-Id: Icdb9e2f2b79ac5d461a9a2a323792962da3d3e26
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 5805797..b9597db 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -978,6 +978,35 @@
         }
         return NO_ERROR;
     }
+
+    virtual status_t setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor,
+                                             float lightPosY, float lightPosZ, float lightRadius) {
+        Parcel data, reply;
+        status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        if (error != NO_ERROR) {
+            ALOGE("setGlobalShadowSettings: failed to write interface token: %d", error);
+            return error;
+        }
+
+        std::vector<float> shadowConfig = {ambientColor.r, ambientColor.g, ambientColor.b,
+                                           ambientColor.a, spotColor.r,    spotColor.g,
+                                           spotColor.b,    spotColor.a,    lightPosY,
+                                           lightPosZ,      lightRadius};
+
+        error = data.writeFloatVector(shadowConfig);
+        if (error != NO_ERROR) {
+            ALOGE("setGlobalShadowSettings: failed to write shadowConfig: %d", error);
+            return error;
+        }
+
+        error = remote()->transact(BnSurfaceComposer::SET_GLOBAL_SHADOW_SETTINGS, data, &reply,
+                                   IBinder::FLAG_ONEWAY);
+        if (error != NO_ERROR) {
+            ALOGE("setGlobalShadowSettings: failed to transact: %d", error);
+            return error;
+        }
+        return NO_ERROR;
+    }
 };
 
 // Out-of-line virtual method definition to trigger vtable emission in this
@@ -1593,6 +1622,25 @@
             }
             return notifyPowerHint(hintId);
         }
+        case SET_GLOBAL_SHADOW_SETTINGS: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+
+            std::vector<float> shadowConfig;
+            status_t error = data.readFloatVector(&shadowConfig);
+            if (error != NO_ERROR || shadowConfig.size() != 11) {
+                ALOGE("setGlobalShadowSettings: failed to read shadowConfig: %d", error);
+                return error;
+            }
+
+            half4 ambientColor = {shadowConfig[0], shadowConfig[1], shadowConfig[2],
+                                  shadowConfig[3]};
+            half4 spotColor = {shadowConfig[4], shadowConfig[5], shadowConfig[6], shadowConfig[7]};
+            float lightPosY = shadowConfig[8];
+            float lightPosZ = shadowConfig[9];
+            float lightRadius = shadowConfig[10];
+            return setGlobalShadowSettings(ambientColor, spotColor, lightPosY, lightPosZ,
+                                           lightRadius);
+        }
         default: {
             return BBinder::onTransact(code, data, reply, flags);
         }
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index a538e14..2ab4d8a 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1726,6 +1726,14 @@
     return ComposerService::getComposerService()->notifyPowerHint(hintId);
 }
 
+status_t SurfaceComposerClient::setGlobalShadowSettings(const half4& ambientColor,
+                                                        const half4& spotColor, float lightPosY,
+                                                        float lightPosZ, float lightRadius) {
+    return ComposerService::getComposerService()->setGlobalShadowSettings(ambientColor, spotColor,
+                                                                          lightPosY, lightPosZ,
+                                                                          lightRadius);
+}
+
 // ----------------------------------------------------------------------------
 
 status_t ScreenshotClient::capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace,
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index f2bae98..514dfe2 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -25,6 +25,8 @@
 
 #include <gui/ITransactionCompletedListener.h>
 
+#include <math/vec4.h>
+
 #include <ui/ConfigStoreTypes.h>
 #include <ui/DisplayedFrameStats.h>
 #include <ui/FrameStats.h>
@@ -439,6 +441,28 @@
      * Returns NO_ERROR upon success.
      */
     virtual status_t notifyPowerHint(int32_t hintId) = 0;
+
+    /*
+     * Sets the global configuration for all the shadows drawn by SurfaceFlinger. Shadow follows
+     * material design guidelines.
+     *
+     * ambientColor
+     *      Color to the ambient shadow. The alpha is premultiplied.
+     *
+     * spotColor
+     *      Color to the spot shadow. The alpha is premultiplied. The position of the spot shadow
+     *      depends on the light position.
+     *
+     * lightPosY/lightPosZ
+     *      Position of the light used to cast the spot shadow. The X value is always the display
+     *      width / 2.
+     *
+     * lightRadius
+     *      Radius of the light casting the shadow.
+     */
+    virtual status_t setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor,
+                                             float lightPosY, float lightPosZ,
+                                             float lightRadius) = 0;
 };
 
 // ----------------------------------------------------------------------------
@@ -492,6 +516,7 @@
         SET_DISPLAY_BRIGHTNESS,
         CAPTURE_SCREEN_BY_ID,
         NOTIFY_POWER_HINT,
+        SET_GLOBAL_SHADOW_SETTINGS,
         // Always append new enum to the end.
     };
 
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 37387ac..d218356 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -214,6 +214,27 @@
      */
     static status_t notifyPowerHint(int32_t hintId);
 
+    /*
+     * Sets the global configuration for all the shadows drawn by SurfaceFlinger. Shadow follows
+     * material design guidelines.
+     *
+     * ambientColor
+     *      Color to the ambient shadow. The alpha is premultiplied.
+     *
+     * spotColor
+     *      Color to the spot shadow. The alpha is premultiplied. The position of the spot shadow
+     *      depends on the light position.
+     *
+     * lightPosY/lightPosZ
+     *      Position of the light used to cast the spot shadow. The X value is always the display
+     *      width / 2.
+     *
+     * lightRadius
+     *      Radius of the light casting the shadow.
+     */
+    static status_t setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor,
+                                            float lightPosY, float lightPosZ, float lightRadius);
+
     // ------------------------------------------------------------------------
     // surface creation / destruction
 
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index a4fdb35..c4f35ae 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -833,6 +833,12 @@
     }
     status_t notifyPowerHint(int32_t /*hintId*/) override { return NO_ERROR; }
 
+    status_t setGlobalShadowSettings(const half4& /*ambientColor*/, const half4& /*spotColor*/,
+                                     float /*lightPosY*/, float /*lightPosZ*/,
+                                     float /*lightRadius*/) override {
+        return NO_ERROR;
+    }
+
 protected:
     IBinder* onAsBinder() override { return nullptr; }