[Graphics] Introduce per display capability.

Previously, the capability of skipping client color transform is global that
will apply on all displays. However, some hardwares are not capable of managing
it for all displays. This patch introduced a per display capability.

BUG: 69911676
Test: Build with mmma hardware/interfaces
Change-Id: I4a143ea89d06bd30ad2bf3f5307c8af9b17f0890
diff --git a/graphics/composer/2.3/IComposerClient.hal b/graphics/composer/2.3/IComposerClient.hal
index 7856658..87002ec 100644
--- a/graphics/composer/2.3/IComposerClient.hal
+++ b/graphics/composer/2.3/IComposerClient.hal
@@ -27,6 +27,42 @@
 
 interface IComposerClient extends @2.2::IComposerClient {
 
+    // TODO: Move this enum to LLNDK after we decide where to put graphic types.
+    /**
+     * Required capabilities which are supported by the display. The
+     * particular set of supported capabilities for a given display may be
+     * retrieved using getDisplayCapabilities.
+     */
+    enum DisplayCapability : uint32_t {
+        INVALID = 0,
+
+        /**
+         * Specifies that the display must a color transform even when
+         * either the client or the device has chosen that all layers should
+         * be composed by the client. This prevents the client from applying
+         * the color transform during its composition step.
+         * If getDisplayCapabilities is supported, the global capability
+         * SKIP_CLIENT_COLOR_TRANSFORM is ignored.
+         * If getDisplayCapabilities is not supported, and the global capability
+         * SKIP_CLIENT_COLOR_TRANSFORM is returned by getCapabilities,
+         * then all displays must be treated as having
+         * SKIP_CLIENT_COLOR_TRANSFORM.
+         */
+        SKIP_CLIENT_COLOR_TRANSFORM = 1,
+
+        /**
+         * Specifies that the display supports PowerMode::DOZE and
+         * PowerMode::DOZE_SUSPEND. DOZE_SUSPEND may not provide any benefit
+         * over DOZE (see the definition of PowerMode for more information),
+         * but if both DOZE and DOZE_SUSPEND are no different from
+         * PowerMode::ON, the device must not claim support.
+         * Must be returned by getDisplayCapabilities when getDozeSupport
+         * indicates the display supports PowerMode::DOZE and
+         * PowerMode::DOZE_SUSPEND.
+         */
+        DOZE = 2,
+    };
+
     enum Command : @2.2::IComposerClient.Command {
         /**
          * SET_LAYER_COLOR_TRANSFORM has this pseudo prototype
@@ -350,4 +386,17 @@
      */
     setColorMode_2_3(Display display, ColorMode mode, RenderIntent intent)
           generates (Error error);
+
+    /**
+     * Provides a list of supported capabilities (as described in the
+     * definition of DisplayCapability above). This list must not change after
+     * initialization.
+     *
+     * @return error is NONE upon success. Otherwise,
+     *     BAD_DISPLAY when an invalid display handle was passed in.
+     * @return capabilities is a list of supported capabilities.
+     */
+    getDisplayCapabilities(Display display)
+              generates (Error error,
+                         vec<DisplayCapability> capabilities);
 };
diff --git a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h
index be0ef4c..69872d2 100644
--- a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h
+++ b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h
@@ -73,6 +73,14 @@
         return err;
     }
 
+    Return<void> getDisplayCapabilities(
+        Display display, IComposerClient::getDisplayCapabilities_cb hidl_cb) override {
+        hidl_vec<IComposerClient::DisplayCapability> capabilities;
+        Error error = mHal->getDisplayCapabilities(display, &capabilities);
+        hidl_cb(error, capabilities);
+        return Void();
+    }
+
     static std::unique_ptr<ComposerClientImpl> create(Hal* hal) {
         auto client = std::make_unique<ComposerClientImpl>(hal);
         return client->init() ? std::move(client) : nullptr;
diff --git a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h
index 8ca5d75..c7de848 100644
--- a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h
+++ b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerHal.h
@@ -84,6 +84,8 @@
                                             hidl_vec<uint64_t>& sampleComponent1,
                                             hidl_vec<uint64_t>& sampleComponent2,
                                             hidl_vec<uint64_t>& sampleComponent3) = 0;
+    virtual Error getDisplayCapabilities(
+        Display display, hidl_vec<IComposerClient::DisplayCapability>* outCapabilities) = 0;
 };
 
 }  // namespace hal
diff --git a/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h b/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h
index 8d444c8..f7ce7e8 100644
--- a/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h
+++ b/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h
@@ -163,6 +163,29 @@
         return static_cast<Error>(errorRaw);
     }
 
+    Error getDisplayCapabilities(
+        Display display, hidl_vec<IComposerClient::DisplayCapability>* outCapabilities) override {
+        if (!mDispatch.getDisplayCapabilities) {
+            return Error::UNSUPPORTED;
+        }
+
+        uint32_t count = 0;
+        int32_t error = mDispatch.getDisplayCapabilities(mDevice, display, &count, nullptr);
+        if (error != HWC2_ERROR_NONE) {
+            return static_cast<Error>(error);
+        }
+        outCapabilities->resize(count);
+        error = mDispatch.getDisplayCapabilities(
+            mDevice, display, &count,
+            reinterpret_cast<std::underlying_type<IComposerClient::DisplayCapability>::type*>(
+                outCapabilities->data()));
+        if (error != HWC2_ERROR_NONE) {
+            *outCapabilities = hidl_vec<IComposerClient::DisplayCapability>();
+            return static_cast<Error>(error);
+        }
+        return Error::NONE;
+    }
+
    protected:
     bool initDispatch() override {
         if (!BaseType2_2::initDispatch()) {
@@ -179,6 +202,8 @@
                                    &mDispatch.setDisplayedContentSamplingEnabled);
         this->initOptionalDispatch(HWC2_FUNCTION_GET_DISPLAYED_CONTENT_SAMPLE,
                                    &mDispatch.getDisplayedContentSample);
+        this->initOptionalDispatch(HWC2_FUNCTION_GET_DISPLAY_CAPABILITIES,
+                                   &mDispatch.getDisplayCapabilities);
         return true;
     }
 
@@ -189,6 +214,7 @@
         HWC2_PFN_GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES getDisplayedContentSamplingAttributes;
         HWC2_PFN_SET_DISPLAYED_CONTENT_SAMPLING_ENABLED setDisplayedContentSamplingEnabled;
         HWC2_PFN_GET_DISPLAYED_CONTENT_SAMPLE getDisplayedContentSample;
+        HWC2_PFN_GET_DISPLAY_CAPABILITIES getDisplayCapabilities;
     } mDispatch = {};
 
     using BaseType2_2 = V2_2::passthrough::detail::HwcHalImpl<Hal>;
diff --git a/graphics/composer/2.3/utils/vts/ComposerVts.cpp b/graphics/composer/2.3/utils/vts/ComposerVts.cpp
index 9304992..c631c50 100644
--- a/graphics/composer/2.3/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.3/utils/vts/ComposerVts.cpp
@@ -150,6 +150,15 @@
     return error;
 }
 
+std::vector<IComposerClient::DisplayCapability> ComposerClient::getDisplayCapabilities(
+    Display display) {
+    std::vector<IComposerClient::DisplayCapability> capabilities;
+    mClient->getDisplayCapabilities(
+        display, [&](const auto&, const auto& tmpCapabilities) { capabilities = tmpCapabilities; });
+
+    return capabilities;
+}
+
 }  // namespace vts
 }  // namespace V2_3
 }  // namespace composer
diff --git a/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h b/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
index 4b9c955..d3aa779 100644
--- a/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
+++ b/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
@@ -91,6 +91,7 @@
 
     bool getClientTargetSupport_2_3(Display display, uint32_t width, uint32_t height,
                                     PixelFormat format, Dataspace dataspace);
+    std::vector<IComposerClient::DisplayCapability> getDisplayCapabilities(Display display);
 
    private:
     const sp<IComposerClient> mClient;
diff --git a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
index a294825..6c5cb5d 100644
--- a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
+++ b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
@@ -427,6 +427,23 @@
     }
 }
 
+/*
+ * getDisplayCapabilities is required in composer 2.3
+ * Test some constraints.
+ */
+TEST_F(GraphicsComposerHidlTest, getDisplayCapabilitiesBasic) {
+    auto capabilities = mComposerClient->getDisplayCapabilities(mPrimaryDisplay);
+    bool hasDozeSupport = std::find(capabilities.begin(), capabilities.end(),
+                                    IComposerClient::DisplayCapability::DOZE) != capabilities.end();
+    EXPECT_EQ(mComposerClient->getDozeSupport(mPrimaryDisplay), hasDozeSupport);
+}
+
+TEST_F(GraphicsComposerHidlTest, getDisplayCapabilitiesBadDisplay) {
+    mComposerClient->getRaw()->getDisplayCapabilities(
+        mInvalidDisplayId,
+        [&](const auto& tmpError, const auto&) { EXPECT_EQ(Error::BAD_DISPLAY, tmpError); });
+}
+
 }  // namespace
 }  // namespace vts
 }  // namespace V2_3