Add getClientTargetProperty API entry.

getClientTargetProperty will give hardware composer the ability to request some
properties of the client target that hardware composer wants. Prior to this
API, the client will does its best to produce the client target of which the
properties are pretty much fixed.

BUG: b/145968912
Test: mmma -j32 hardware/interfaces/graphics/composer/2.4/
Change-Id: I055f46b1eeba1d3e20d6a92a9d50a83e0f1ee694
diff --git a/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h b/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h
index 64ed4f3..499d3b9 100644
--- a/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h
+++ b/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h
@@ -626,9 +626,15 @@
     }
 
    protected:
+     template <typename T>
+     bool beginCommand(T* outCommand, uint16_t* outLength) {
+         return beginCommandBase(reinterpret_cast<IComposerClient::Command*>(outCommand),
+                                 outLength);
+     }
+
     bool isEmpty() const { return (mDataRead >= mDataSize); }
 
-    bool beginCommand(IComposerClient::Command* outCommand, uint16_t* outLength) {
+    bool beginCommandBase(IComposerClient::Command* outCommand, uint16_t* outLength) {
         if (mCommandEnd) {
             LOG_FATAL("endCommand was not called for last command");
         }
diff --git a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerCommandEngine.h b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerCommandEngine.h
index b173e2e..ab67eb1 100644
--- a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerCommandEngine.h
+++ b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerCommandEngine.h
@@ -146,6 +146,25 @@
         return std::make_unique<CommandWriterBase>(writerInitialSize);
     }
 
+    virtual Error executeValidateDisplayInternal() {
+        std::vector<Layer> changedLayers;
+        std::vector<IComposerClient::Composition> compositionTypes;
+        uint32_t displayRequestMask = 0x0;
+        std::vector<Layer> requestedLayers;
+        std::vector<uint32_t> requestMasks;
+
+        auto err = mHal->validateDisplay(mCurrentDisplay, &changedLayers, &compositionTypes,
+                                         &displayRequestMask, &requestedLayers, &requestMasks);
+        mResources->setDisplayMustValidateState(mCurrentDisplay, false);
+        if (err == Error::NONE) {
+            mWriter->setChangedCompositionTypes(changedLayers, compositionTypes);
+            mWriter->setDisplayRequests(displayRequestMask, requestedLayers, requestMasks);
+        } else {
+            mWriter->setError(getCommandLoc(), err);
+        }
+        return err;
+    }
+
     bool executeSelectDisplay(uint16_t length) {
         if (length != CommandWriterBase::kSelectDisplayLength) {
             return false;
@@ -255,23 +274,7 @@
         if (length != CommandWriterBase::kValidateDisplayLength) {
             return false;
         }
-
-        std::vector<Layer> changedLayers;
-        std::vector<IComposerClient::Composition> compositionTypes;
-        uint32_t displayRequestMask = 0x0;
-        std::vector<Layer> requestedLayers;
-        std::vector<uint32_t> requestMasks;
-
-        auto err = mHal->validateDisplay(mCurrentDisplay, &changedLayers, &compositionTypes,
-                                         &displayRequestMask, &requestedLayers, &requestMasks);
-        mResources->setDisplayMustValidateState(mCurrentDisplay, false);
-        if (err == Error::NONE) {
-            mWriter->setChangedCompositionTypes(changedLayers, compositionTypes);
-            mWriter->setDisplayRequests(displayRequestMask, requestedLayers, requestMasks);
-        } else {
-            mWriter->setError(getCommandLoc(), err);
-        }
-
+        executeValidateDisplayInternal();
         return true;
     }
 
@@ -297,21 +300,9 @@
         }
 
         // Present has failed. We need to fallback to validate
-        std::vector<Layer> changedLayers;
-        std::vector<IComposerClient::Composition> compositionTypes;
-        uint32_t displayRequestMask = 0x0;
-        std::vector<Layer> requestedLayers;
-        std::vector<uint32_t> requestMasks;
-
-        auto err = mHal->validateDisplay(mCurrentDisplay, &changedLayers, &compositionTypes,
-                                         &displayRequestMask, &requestedLayers, &requestMasks);
-        mResources->setDisplayMustValidateState(mCurrentDisplay, false);
+        auto err = executeValidateDisplayInternal();
         if (err == Error::NONE) {
             mWriter->setPresentOrValidateResult(0);
-            mWriter->setChangedCompositionTypes(changedLayers, compositionTypes);
-            mWriter->setDisplayRequests(displayRequestMask, requestedLayers, requestMasks);
-        } else {
-            mWriter->setError(getCommandLoc(), err);
         }
 
         return true;
diff --git a/graphics/composer/2.4/IComposerClient.hal b/graphics/composer/2.4/IComposerClient.hal
index 1b8170b..7e0c33c 100644
--- a/graphics/composer/2.4/IComposerClient.hal
+++ b/graphics/composer/2.4/IComposerClient.hal
@@ -16,6 +16,9 @@
 
 package android.hardware.graphics.composer@2.4;
 
+import android.hardware.graphics.common@1.2::PixelFormat;
+import android.hardware.graphics.common@1.2::Dataspace;
+import android.hardware.graphics.composer@2.1::IComposerClient.Command;
 import IComposerCallback;
 import @2.1::Config;
 import @2.1::Display;
@@ -56,6 +59,20 @@
         AUTO_LOW_LATENCY_MODE = 5,
     };
 
+    enum Command : @2.3::IComposerClient.Command {
+        /**
+         * SET_CLIENT_TARGET_PROPERTY has this pseudo prototype
+         *
+         * This command has the following binary layout in bytes:
+         *
+         *     0 - 3: clientTargetProperty.pixelFormat
+         *     4 - 7: clientTargetProperty.dataspace
+         *
+         *   setClientTargetProperty(ClientTargetProperty clientTargetProperty);
+         */
+         SET_CLIENT_TARGET_PROPERTY = 0x105 << @2.1::IComposerClient.Command:OPCODE_SHIFT,
+    };
+
     /**
      * Supersedes {@link @2.1::IComposerClient.DisplayType}.
      */
@@ -99,6 +116,11 @@
         bool seamlessRequired;
     };
 
+    struct ClientTargetProperty {
+        PixelFormat pixelFormat;
+        Dataspace dataspace;
+    };
+
     /**
      * Provides a IComposerCallback object for the device to call.
      *
diff --git a/graphics/composer/2.4/utils/command-buffer/include/composer-command-buffer/2.4/ComposerCommandBuffer.h b/graphics/composer/2.4/utils/command-buffer/include/composer-command-buffer/2.4/ComposerCommandBuffer.h
index cb391be..e84779e 100644
--- a/graphics/composer/2.4/utils/command-buffer/include/composer-command-buffer/2.4/ComposerCommandBuffer.h
+++ b/graphics/composer/2.4/utils/command-buffer/include/composer-command-buffer/2.4/ComposerCommandBuffer.h
@@ -41,14 +41,25 @@
 // units of uint32_t's.
 class CommandWriterBase : public V2_3::CommandWriterBase {
   public:
+    static constexpr uint16_t kSetClientTargetPropertyLength = 2;
+
     CommandWriterBase(uint32_t initialMaxSize) : V2_3::CommandWriterBase(initialMaxSize) {}
+
+    void setClientTargetProperty(
+            const IComposerClient::ClientTargetProperty& clientTargetProperty) {
+        beginCommand(IComposerClient::Command::SET_CLIENT_TARGET_PROPERTY,
+                     kSetClientTargetPropertyLength);
+        writeSigned(static_cast<int32_t>(clientTargetProperty.pixelFormat));
+        writeSigned(static_cast<int32_t>(clientTargetProperty.dataspace));
+        endCommand();
+    }
 };
 
 // This class helps parse a command queue.  Note that all sizes/lengths are in
 // units of uint32_t's.
 class CommandReaderBase : public V2_3::CommandReaderBase {
   public:
-    CommandReaderBase() : V2_3::CommandReaderBase(){};
+    CommandReaderBase() : V2_3::CommandReaderBase() {}
 };
 
 }  // namespace V2_4
diff --git a/graphics/composer/2.4/utils/hal/Android.bp b/graphics/composer/2.4/utils/hal/Android.bp
index 3ee4e19..f4cdea4 100644
--- a/graphics/composer/2.4/utils/hal/Android.bp
+++ b/graphics/composer/2.4/utils/hal/Android.bp
@@ -26,11 +26,11 @@
     ],
     header_libs: [
         "android.hardware.graphics.composer@2.3-hal",
-        "android.hardware.graphics.composer@2.3-command-buffer",
+        "android.hardware.graphics.composer@2.4-command-buffer",
     ],
     export_header_lib_headers: [
         "android.hardware.graphics.composer@2.3-hal",
-        "android.hardware.graphics.composer@2.3-command-buffer",
+        "android.hardware.graphics.composer@2.4-command-buffer",
     ],
     export_include_dirs: ["include"],
 }
diff --git a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h
index d48a9e7..c864ce6 100644
--- a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h
+++ b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h
@@ -22,6 +22,7 @@
 
 #include <android/hardware/graphics/composer/2.4/IComposerCallback.h>
 #include <android/hardware/graphics/composer/2.4/IComposerClient.h>
+#include <composer-hal/2.4/ComposerCommandEngine.h>
 #include <composer-hal/2.4/ComposerHal.h>
 #include <composer-resources/2.1/ComposerResources.h>
 
@@ -168,12 +169,18 @@
         return client->init() ? std::move(client) : nullptr;
     }
 
+  protected:
+    std::unique_ptr<V2_1::hal::ComposerCommandEngine> createCommandEngine() override {
+        return std::make_unique<ComposerCommandEngine>(
+                mHal, static_cast<V2_2::hal::ComposerResources*>(mResources.get()));
+    }
+
   private:
     using BaseType2_3 = V2_3::hal::detail::ComposerClientImpl<Interface, Hal>;
     using BaseType2_1 = V2_1::hal::detail::ComposerClientImpl<Interface, Hal>;
     using BaseType2_1::mHal;
-    std::unique_ptr<HalEventCallback> mHalEventCallback_2_4;
     using BaseType2_1::mResources;
+    std::unique_ptr<HalEventCallback> mHalEventCallback_2_4;
 };
 
 }  // namespace detail
diff --git a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerCommandEngine.h b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerCommandEngine.h
new file mode 100644
index 0000000..e0153ce
--- /dev/null
+++ b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerCommandEngine.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2020 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.
+ */
+
+#pragma once
+
+#ifndef LOG_TAG
+#warning "ComposerCommandEngine.h included without LOG_TAG"
+#endif
+
+#include <composer-command-buffer/2.4/ComposerCommandBuffer.h>
+#include <composer-hal/2.1/ComposerCommandEngine.h>
+#include <composer-hal/2.3/ComposerCommandEngine.h>
+#include <composer-hal/2.4/ComposerHal.h>
+#include <composer-resources/2.2/ComposerResources.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_4 {
+namespace hal {
+
+class ComposerCommandEngine : public V2_3::hal::ComposerCommandEngine {
+  public:
+    ComposerCommandEngine(ComposerHal* hal, V2_2::hal::ComposerResources* resources)
+        : BaseType2_3(hal, resources), mHal(hal) {}
+
+  protected:
+    std::unique_ptr<V2_1::CommandWriterBase> createCommandWriter(
+            size_t writerInitialSize) override {
+        return std::make_unique<CommandWriterBase>(writerInitialSize);
+    }
+
+  private:
+    using BaseType2_1 = V2_1::hal::ComposerCommandEngine;
+    using BaseType2_3 = V2_3::hal::ComposerCommandEngine;
+    using BaseType2_1::mWriter;
+
+    V2_1::Error executeValidateDisplayInternal() override {
+        std::vector<Layer> changedLayers;
+        std::vector<IComposerClient::Composition> compositionTypes;
+        uint32_t displayRequestMask = 0x0;
+        std::vector<Layer> requestedLayers;
+        std::vector<uint32_t> requestMasks;
+        IComposerClient::ClientTargetProperty clientTargetProperty{PixelFormat::RGBA_8888,
+                                                                   Dataspace::UNKNOWN};
+
+        auto err = mHal->validateDisplay_2_4(mCurrentDisplay, &changedLayers, &compositionTypes,
+                                             &displayRequestMask, &requestedLayers, &requestMasks,
+                                             &clientTargetProperty);
+        mResources->setDisplayMustValidateState(mCurrentDisplay, false);
+        if (err == Error::NONE) {
+            mWriter->setChangedCompositionTypes(changedLayers, compositionTypes);
+            mWriter->setDisplayRequests(displayRequestMask, requestedLayers, requestMasks);
+            getWriter()->setClientTargetProperty(clientTargetProperty);
+        } else {
+            mWriter->setError(getCommandLoc(), static_cast<V2_1::Error>(err));
+        }
+        return static_cast<V2_1::Error>(err);
+    }
+
+    CommandWriterBase* getWriter() { return static_cast<CommandWriterBase*>(mWriter.get()); }
+
+    ComposerHal* mHal;
+};
+
+}  // namespace hal
+}  // namespace V2_4
+}  // namespace composer
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
diff --git a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h
index bbc5405..277055c 100644
--- a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h
+++ b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h
@@ -73,6 +73,12 @@
             Display display,
             std::vector<IComposerClient::ContentType>* outSupportedContentTypes) = 0;
     virtual Error setContentType(Display display, IComposerClient::ContentType contentType) = 0;
+    virtual Error validateDisplay_2_4(
+            Display display, std::vector<Layer>* outChangedLayers,
+            std::vector<IComposerClient::Composition>* outCompositionTypes,
+            uint32_t* outDisplayRequestMask, std::vector<Layer>* outRequestedLayers,
+            std::vector<uint32_t>* outRequestMasks,
+            IComposerClient::ClientTargetProperty* outClientTargetProperty) = 0;
 };
 
 }  // namespace hal
diff --git a/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h b/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h
index 07d8607..616852a 100644
--- a/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h
+++ b/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h
@@ -43,6 +43,7 @@
 using common::V1_2::PixelFormat;
 using V2_1::Config;
 using V2_1::Display;
+using V2_1::Layer;
 using V2_4::Error;
 
 // HwcHalImpl implements V2_*::hal::ComposerHal on top of hwcomposer2
@@ -218,6 +219,32 @@
         return Error::NONE;
     }
 
+    Error validateDisplay_2_4(
+            Display display, std::vector<Layer>* outChangedLayers,
+            std::vector<IComposerClient::Composition>* outCompositionTypes,
+            uint32_t* outDisplayRequestMask, std::vector<Layer>* outRequestedLayers,
+            std::vector<uint32_t>* outRequestMasks,
+            IComposerClient::ClientTargetProperty* outClientTargetProperty) override {
+        auto err = static_cast<Error>(BaseType2_1::validateDisplay(
+                display, outChangedLayers, outCompositionTypes, outDisplayRequestMask,
+                outRequestedLayers, outRequestMasks));
+        if (err != Error::NONE) {
+            return err;
+        }
+
+        if (mDispatch.getClientTargetProperty) {
+            hwc_client_target_property_t clientTargetProperty;
+            err = static_cast<Error>(
+                    mDispatch.getClientTargetProperty(mDevice, display, &clientTargetProperty));
+            outClientTargetProperty->pixelFormat =
+                    static_cast<PixelFormat>(clientTargetProperty.pixelFormat);
+            outClientTargetProperty->dataspace =
+                    static_cast<Dataspace>(clientTargetProperty.dataspace);
+        }
+
+        return err;
+    }
+
   protected:
     bool initDispatch() override {
         if (!BaseType2_3::initDispatch()) {
@@ -238,6 +265,8 @@
         this->initOptionalDispatch(HWC2_FUNCTION_GET_SUPPORTED_CONTENT_TYPES,
                                    &mDispatch.getSupportedContentTypes);
         this->initOptionalDispatch(HWC2_FUNCTION_SET_CONTENT_TYPE, &mDispatch.setContentType);
+        this->initOptionalDispatch(HWC2_FUNCTION_GET_CLIENT_TARGET_PROPERTY,
+                                   &mDispatch.getClientTargetProperty);
         return true;
     }
 
@@ -289,6 +318,7 @@
         HWC2_PFN_SET_AUTO_LOW_LATENCY_MODE setAutoLowLatencyMode;
         HWC2_PFN_GET_SUPPORTED_CONTENT_TYPES getSupportedContentTypes;
         HWC2_PFN_SET_CONTENT_TYPE setContentType;
+        HWC2_PFN_GET_CLIENT_TARGET_PROPERTY getClientTargetProperty;
     } mDispatch = {};
 
     hal::ComposerHal::EventCallback_2_4* mEventCallback_2_4 = nullptr;