Merge "Add missing union members to ASensorEvent" into sc-dev
diff --git a/libs/binder/include/binder/AppOpsManager.h b/libs/binder/include/binder/AppOpsManager.h
index f1085cf..0386d66 100644
--- a/libs/binder/include/binder/AppOpsManager.h
+++ b/libs/binder/include/binder/AppOpsManager.h
@@ -138,7 +138,11 @@
         OP_RECORD_AUDIO_HOTWORD = 102,
         // Ops 103-105 are currently unused in native, and intentionally omitted
         OP_RECORD_AUDIO_OUTPUT = 106,
-        _NUM_OP = 107
+        OP_SCHEDULE_EXACT_ALARM = 107,
+        OP_FINE_LOCATION_SOURCE = 108,
+        OP_COARSE_LOCATION_SOURCE = 109,
+        OP_MANAGE_MEDIA = 110,
+        _NUM_OP = 111
     };
 
     AppOpsManager();
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 989abd9..bb8124b 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -935,7 +935,8 @@
         return NO_ERROR;
     }
 
-    status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) override {
+    status_t setDisplayBrightness(const sp<IBinder>& displayToken,
+                                  const gui::DisplayBrightness& brightness) override {
         Parcel data, reply;
         status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (error != NO_ERROR) {
@@ -947,7 +948,7 @@
             ALOGE("setDisplayBrightness: failed to write display token: %d", error);
             return error;
         }
-        error = data.writeFloat(brightness);
+        error = data.writeParcelable(brightness);
         if (error != NO_ERROR) {
             ALOGE("setDisplayBrightness: failed to write brightness: %d", error);
             return error;
@@ -1832,8 +1833,8 @@
                 ALOGE("setDisplayBrightness: failed to read display token: %d", error);
                 return error;
             }
-            float brightness = -1.0f;
-            error = data.readFloat(&brightness);
+            gui::DisplayBrightness brightness;
+            error = data.readParcelable(&brightness);
             if (error != NO_ERROR) {
                 ALOGE("setDisplayBrightness: failed to read brightness: %d", error);
                 return error;
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index f565789..c16a98f 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1984,7 +1984,7 @@
 }
 
 status_t SurfaceComposerClient::setDisplayBrightness(const sp<IBinder>& displayToken,
-                                                     float brightness) {
+                                                     const gui::DisplayBrightness& brightness) {
     return ComposerService::getComposerService()->setDisplayBrightness(displayToken, brightness);
 }
 
diff --git a/libs/gui/aidl/android/gui/DisplayBrightness.aidl b/libs/gui/aidl/android/gui/DisplayBrightness.aidl
new file mode 100644
index 0000000..bdb8c63
--- /dev/null
+++ b/libs/gui/aidl/android/gui/DisplayBrightness.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2021 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.
+ */
+
+package android.gui;
+
+/** @hide */
+parcelable DisplayBrightness {
+    // Range 0-1f, the desired sdr white point brightness
+    float sdrWhitePoint = 0f;
+
+    // The SDR white point in nits. -1 if unknown
+    float sdrWhitePointNits = -1f;
+
+    // Range 0-1f, the desired brightness of the display itself. -1f to turn the backlight off
+    float displayBrightness = 0f;
+
+    // The desired brightness of the display in nits. -1 if unknown
+    float displayBrightnessNits = -1f;
+}
\ No newline at end of file
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 88cfe4b..2a9e3f7 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -16,6 +16,7 @@
 
 #pragma once
 
+#include <android/gui/DisplayBrightness.h>
 #include <android/gui/IFpsListener.h>
 #include <android/gui/IScreenCaptureListener.h>
 #include <android/gui/ITransactionTraceListener.h>
@@ -415,15 +416,15 @@
      * displayToken
      *      The token of the display whose brightness is set.
      * brightness
-     *      A number between 0.0f (minimum brightness) and 1.0 (maximum brightness), or -1.0f to
-     *      turn the backlight off.
+     *      The DisplayBrightness info to set on the desired display.
      *
      * Returns NO_ERROR upon success. Otherwise,
      *      NAME_NOT_FOUND    if the display is invalid, or
      *      BAD_VALUE         if the brightness is invalid, or
      *      INVALID_OPERATION if brightness operations are not supported.
      */
-    virtual status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) = 0;
+    virtual status_t setDisplayBrightness(const sp<IBinder>& displayToken,
+                                          const gui::DisplayBrightness& brightness) = 0;
 
     /*
      * Sends a power boost to the composer. This function is asynchronous.
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 40c4135..88484c0 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -209,7 +209,8 @@
      *      BAD_VALUE         if the brightness value is invalid, or
      *      INVALID_OPERATION if brightness operaetions are not supported.
      */
-    static status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness);
+    static status_t setDisplayBrightness(const sp<IBinder>& displayToken,
+                                         const gui::DisplayBrightness& brightness);
 
     /*
      * Sends a power boost to the composer. This function is asynchronous.
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index e8fb71d..8d7f8c9 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -811,7 +811,7 @@
         return NO_ERROR;
     }
     status_t setDisplayBrightness(const sp<IBinder>& /*displayToken*/,
-                                  float /*brightness*/) override {
+                                  const gui::DisplayBrightness& /*brightness*/) override {
         return NO_ERROR;
     }
 
diff --git a/libs/input/tests/Flags_test.cpp b/libs/input/tests/Flags_test.cpp
index 0dbb4cf..6de030f 100644
--- a/libs/input/tests/Flags_test.cpp
+++ b/libs/input/tests/Flags_test.cpp
@@ -148,6 +148,11 @@
     ASSERT_NE(flags1, flags2);
 }
 
+TEST(Flags, GetValue) {
+    Flags<TestFlags> flags = TestFlags::ONE | TestFlags::TWO;
+    ASSERT_EQ(flags.get(), 0x3);
+}
+
 TEST(Flags, String_NoFlags) {
     Flags<TestFlags> flags;
     ASSERT_EQ(flags.string(), "0x0");
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index 66efb09..f76bfa2 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -651,9 +651,8 @@
     if (mBlurFilter) {
         bool requiresCompositionLayer = false;
         for (const auto& layer : layers) {
-            if (layer->backgroundBlurRadius > 0) {
-                // when skbug.com/11208 and b/176903027 are resolved we can add the additional
-                // restriction for layer->backgroundBlurRadius < BlurFilter::kMaxCrossFadeRadius
+            if (layer->backgroundBlurRadius > 0 &&
+                layer->backgroundBlurRadius < BlurFilter::kMaxCrossFadeRadius) {
                 requiresCompositionLayer = true;
             }
             for (auto region : layer->blurRegions) {
diff --git a/services/inputflinger/reader/Android.bp b/services/inputflinger/reader/Android.bp
index 8a2828c..1af70a4 100644
--- a/services/inputflinger/reader/Android.bp
+++ b/services/inputflinger/reader/Android.bp
@@ -68,6 +68,7 @@
         "libcutils",
         "libinput",
         "liblog",
+        "libstatslog",
         "libui",
         "libutils",
     ],
diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp
index 1a7fcd5..07011f5 100644
--- a/services/inputflinger/reader/EventHub.cpp
+++ b/services/inputflinger/reader/EventHub.cpp
@@ -37,13 +37,14 @@
 
 // #define LOG_NDEBUG 0
 #include <android-base/file.h>
-#include <android-base/strings.h>
 #include <android-base/stringprintf.h>
+#include <android-base/strings.h>
 #include <cutils/properties.h>
 #include <input/KeyCharacterMap.h>
 #include <input/KeyLayoutMap.h>
 #include <input/VirtualKeyMap.h>
 #include <openssl/sha.h>
+#include <statslog.h>
 #include <utils/Errors.h>
 #include <utils/Log.h>
 #include <utils/Timers.h>
@@ -1461,7 +1462,7 @@
             for (auto it = mUnattachedVideoDevices.begin(); it != mUnattachedVideoDevices.end();
                  it++) {
                 std::unique_ptr<TouchVideoDevice>& videoDevice = *it;
-                if (tryAddVideoDevice(*device, videoDevice)) {
+                if (tryAddVideoDeviceLocked(*device, videoDevice)) {
                     // videoDevice was transferred to 'device'
                     it = mUnattachedVideoDevices.erase(it);
                     break;
@@ -1771,6 +1772,13 @@
     }
 }
 
+void EventHub::reportDeviceAddedForStatisticsLocked(const InputDeviceIdentifier& identifier,
+                                                    Flags<InputDeviceClass> classes) {
+    android::util::stats_write(android::util::INPUTDEVICE_REGISTERED, identifier.name.c_str(),
+                               identifier.vendor, identifier.product, identifier.version,
+                               identifier.bus, identifier.uniqueId.c_str(), classes.get());
+}
+
 void EventHub::openDeviceLocked(const std::string& devicePath) {
     // If an input device happens to register around the time when EventHub's constructor runs, it
     // is possible that the same input event node (for example, /dev/input/event3) will be noticed
@@ -2076,7 +2084,7 @@
     }
     // Transfer ownership of this video device to a matching input device
     for (const auto& [id, device] : mDevices) {
-        if (tryAddVideoDevice(*device, videoDevice)) {
+        if (tryAddVideoDeviceLocked(*device, videoDevice)) {
             return; // 'device' now owns 'videoDevice'
         }
     }
@@ -2088,8 +2096,8 @@
     mUnattachedVideoDevices.push_back(std::move(videoDevice));
 }
 
-bool EventHub::tryAddVideoDevice(EventHub::Device& device,
-                                 std::unique_ptr<TouchVideoDevice>& videoDevice) {
+bool EventHub::tryAddVideoDeviceLocked(EventHub::Device& device,
+                                       std::unique_ptr<TouchVideoDevice>& videoDevice) {
     if (videoDevice->getName() != device.identifier.name) {
         return false;
     }
@@ -2163,6 +2171,7 @@
 }
 
 void EventHub::addDeviceLocked(std::unique_ptr<Device> device) {
+    reportDeviceAddedForStatisticsLocked(device->identifier, device->classes);
     mOpeningDevices.push_back(std::move(device));
 }
 
diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h
index 5e5f85e..2afaa85 100644
--- a/services/inputflinger/reader/include/EventHub.h
+++ b/services/inputflinger/reader/include/EventHub.h
@@ -570,8 +570,8 @@
     /**
      * Create a new device for the provided path.
      */
-    void openDeviceLocked(const std::string& devicePath);
-    void openVideoDeviceLocked(const std::string& devicePath);
+    void openDeviceLocked(const std::string& devicePath) REQUIRES(mLock);
+    void openVideoDeviceLocked(const std::string& devicePath) REQUIRES(mLock);
     /**
      * Try to associate a video device with an input device. If the association succeeds,
      * the videoDevice is moved into the input device. 'videoDevice' will become null if this
@@ -579,39 +579,42 @@
      * Return true if the association succeeds.
      * Return false otherwise.
      */
-    bool tryAddVideoDevice(Device& device, std::unique_ptr<TouchVideoDevice>& videoDevice);
-    void createVirtualKeyboardLocked();
-    void addDeviceLocked(std::unique_ptr<Device> device);
-    void assignDescriptorLocked(InputDeviceIdentifier& identifier);
+    bool tryAddVideoDeviceLocked(Device& device, std::unique_ptr<TouchVideoDevice>& videoDevice)
+            REQUIRES(mLock);
+    void createVirtualKeyboardLocked() REQUIRES(mLock);
+    void addDeviceLocked(std::unique_ptr<Device> device) REQUIRES(mLock);
+    void assignDescriptorLocked(InputDeviceIdentifier& identifier) REQUIRES(mLock);
 
-    void closeDeviceByPathLocked(const std::string& devicePath);
-    void closeVideoDeviceByPathLocked(const std::string& devicePath);
-    void closeDeviceLocked(Device& device);
-    void closeAllDevicesLocked();
+    void closeDeviceByPathLocked(const std::string& devicePath) REQUIRES(mLock);
+    void closeVideoDeviceByPathLocked(const std::string& devicePath) REQUIRES(mLock);
+    void closeDeviceLocked(Device& device) REQUIRES(mLock);
+    void closeAllDevicesLocked() REQUIRES(mLock);
 
     status_t registerFdForEpoll(int fd);
     status_t unregisterFdFromEpoll(int fd);
-    status_t registerDeviceForEpollLocked(Device& device);
-    void registerVideoDeviceForEpollLocked(const TouchVideoDevice& videoDevice);
-    status_t unregisterDeviceFromEpollLocked(Device& device);
-    void unregisterVideoDeviceFromEpollLocked(const TouchVideoDevice& videoDevice);
+    status_t registerDeviceForEpollLocked(Device& device) REQUIRES(mLock);
+    void registerVideoDeviceForEpollLocked(const TouchVideoDevice& videoDevice) REQUIRES(mLock);
+    status_t unregisterDeviceFromEpollLocked(Device& device) REQUIRES(mLock);
+    void unregisterVideoDeviceFromEpollLocked(const TouchVideoDevice& videoDevice) REQUIRES(mLock);
 
-    status_t scanDirLocked(const std::string& dirname);
-    status_t scanVideoDirLocked(const std::string& dirname);
-    void scanDevicesLocked();
-    status_t readNotifyLocked();
+    status_t scanDirLocked(const std::string& dirname) REQUIRES(mLock);
+    status_t scanVideoDirLocked(const std::string& dirname) REQUIRES(mLock);
+    void scanDevicesLocked() REQUIRES(mLock);
+    status_t readNotifyLocked() REQUIRES(mLock);
 
-    Device* getDeviceByDescriptorLocked(const std::string& descriptor) const;
-    Device* getDeviceLocked(int32_t deviceId) const;
-    Device* getDeviceByPathLocked(const std::string& devicePath) const;
+    Device* getDeviceByDescriptorLocked(const std::string& descriptor) const REQUIRES(mLock);
+    Device* getDeviceLocked(int32_t deviceId) const REQUIRES(mLock);
+    Device* getDeviceByPathLocked(const std::string& devicePath) const REQUIRES(mLock);
     /**
      * Look through all available fd's (both for input devices and for video devices),
      * and return the device pointer.
      */
-    Device* getDeviceByFdLocked(int fd) const;
+    Device* getDeviceByFdLocked(int fd) const REQUIRES(mLock);
 
-    int32_t getNextControllerNumberLocked(const std::string& name);
-    void releaseControllerNumberLocked(int32_t num);
+    int32_t getNextControllerNumberLocked(const std::string& name) REQUIRES(mLock);
+    void releaseControllerNumberLocked(int32_t num) REQUIRES(mLock);
+    void reportDeviceAddedForStatisticsLocked(const InputDeviceIdentifier& identifier,
+                                              Flags<InputDeviceClass> classes) REQUIRES(mLock);
 
     // Protect all internal state.
     mutable std::mutex mLock;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
index 5f834be..a3e84e2 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
@@ -89,6 +89,7 @@
         sp<GraphicBuffer> buffer = nullptr;
         sp<Fence> acquireFence = nullptr;
         Rect displayFrame = {};
+        ui::Dataspace dataspace{ui::Dataspace::UNKNOWN};
     } overrideInfo;
 
     /*
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h
index fa87fb8..b0e42b7 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h
@@ -62,6 +62,7 @@
     size_t getAge() const { return mAge; }
     const sp<GraphicBuffer>& getBuffer() const { return mTexture.getBuffer(); }
     const sp<Fence>& getDrawFence() const { return mDrawFence; }
+    ui::Dataspace getOutputDataspace() const { return mOutputDataspace; }
 
     NonBufferHash getNonBufferHash() const;
 
@@ -80,6 +81,7 @@
     void setLastUpdate(std::chrono::steady_clock::time_point now) { mLastUpdate = now; }
     void append(const CachedSet& other) {
         mTexture.setBuffer(nullptr, nullptr);
+        mOutputDataspace = ui::Dataspace::UNKNOWN;
         mDrawFence = nullptr;
 
         mLayers.insert(mLayers.end(), other.mLayers.cbegin(), other.mLayers.cend());
@@ -90,7 +92,8 @@
     }
     void incrementAge() { ++mAge; }
 
-    void render(renderengine::RenderEngine&);
+    // Renders the cached set with the supplied output dataspace.
+    void render(renderengine::RenderEngine&, ui::Dataspace outputDataspace);
 
     void dump(std::string& result) const;
 
@@ -129,6 +132,7 @@
 
     Texture mTexture;
     sp<Fence> mDrawFence;
+    ui::Dataspace mOutputDataspace;
 
     static const bool sDebugHighlighLayers;
 };
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h
index 582723d..5b9a9f0 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h
@@ -42,7 +42,8 @@
     NonBufferHash flattenLayers(const std::vector<const LayerState*>& layers, NonBufferHash,
                                 std::chrono::steady_clock::time_point now);
 
-    void renderCachedSets(renderengine::RenderEngine&);
+    // Renders the newest cached sets with the supplied output dataspace
+    void renderCachedSets(renderengine::RenderEngine&, ui::Dataspace outputDataspace);
 
     void reset();
 
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
index 7f8cb4e..a3beadc 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
@@ -278,8 +278,8 @@
                            }};
 
     using DataspaceState = OutputLayerState<ui::Dataspace, LayerStateField::Dataspace>;
-    DataspaceState mDataspace{[](auto layer) { return layer->getState().dataspace; },
-                              DataspaceState::getHalToStrings()};
+    DataspaceState mOutputDataspace{[](auto layer) { return layer->getState().dataspace; },
+                                    DataspaceState::getHalToStrings()};
 
     // TODO(b/180638831): Buffer format
 
@@ -341,7 +341,7 @@
     std::array<const StateInterface*, 13> getNonUniqueFields() const {
         return {
                 &mDisplayFrame,   &mSourceCrop,      &mZOrder,         &mBufferTransform,
-                &mBlendMode,      &mAlpha,           &mVisibleRegion,  &mDataspace,
+                &mBlendMode,      &mAlpha,           &mVisibleRegion,  &mOutputDataspace,
                 &mColorTransform, &mCompositionType, &mSidebandStream, &mBuffer,
                 &mSolidColor,
         };
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Planner.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Planner.h
index e96abb7..89de34d 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Planner.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Planner.h
@@ -59,7 +59,7 @@
             compositionengine::Output::OutputLayersEnumerator<compositionengine::Output>&& layers);
 
     // The planner will call to the Flattener to render any pending cached set
-    void renderCachedSets(renderengine::RenderEngine&);
+    void renderCachedSets(renderengine::RenderEngine&, ui::Dataspace outputDataspace);
 
     void dump(const Vector<String16>& args, std::string&);
 
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index dc1aacc..ded2dcc 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -1252,7 +1252,7 @@
 
 void Output::renderCachedSets() {
     if (mPlanner) {
-        mPlanner->renderCachedSets(getCompositionEngine().getRenderEngine());
+        mPlanner->renderCachedSets(getCompositionEngine().getRenderEngine(), getState().dataspace);
     }
 }
 
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index 54784a2..b364649 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -681,6 +681,7 @@
                                               .buffer = getState().overrideInfo.buffer,
                                               .fence = getState().overrideInfo.acquireFence,
                                       }};
+    settings.sourceDataspace = getState().overrideInfo.dataspace;
     settings.alpha = 1.0f;
 
     return {static_cast<LayerFE::LayerSettings>(settings)};
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
index ba03655..137697b 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
@@ -79,10 +79,11 @@
         return mFingerprint;
     }
 
-    // TODO(b/181192080): Add all fields which contribute to geometry of override layer (e.g.,
-    // dataspace)
+    // TODO(b/182614524): We sometimes match this with LayerState hashes. Determine if that is
+    // necessary (and therefore we need to match implementations).
     size_t hash = 0;
     android::hashCombineSingle(hash, mBounds);
+    android::hashCombineSingle(hash, mOutputDataspace);
     return hash;
 }
 
@@ -148,10 +149,11 @@
     }
 }
 
-void CachedSet::render(renderengine::RenderEngine& renderEngine) {
+void CachedSet::render(renderengine::RenderEngine& renderEngine, ui::Dataspace outputDataspace) {
     renderengine::DisplaySettings displaySettings{
             .physicalDisplay = Rect(0, 0, mBounds.getWidth(), mBounds.getHeight()),
             .clip = mBounds,
+            .outputDataspace = outputDataspace,
     };
 
     Region clearRegion = Region::INVALID_REGION;
@@ -163,8 +165,7 @@
             .supportsProtectedContent = false,
             .clearRegion = clearRegion,
             .viewport = viewport,
-            // TODO(181192086): Propagate the Output's dataspace instead of using UNKNOWN
-            .dataspace = ui::Dataspace::UNKNOWN,
+            .dataspace = outputDataspace,
             .realContentIsVisible = true,
             .clearContent = false,
             .disableBlurs = false,
@@ -216,6 +217,7 @@
     if (result == NO_ERROR) {
         mTexture.setBuffer(buffer, &renderEngine);
         mDrawFence = new Fence(drawFence.release());
+        mOutputDataspace = outputDataspace;
     }
 }
 
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp
index d304c9f..30b5761 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp
@@ -51,12 +51,13 @@
     return hash;
 }
 
-void Flattener::renderCachedSets(renderengine::RenderEngine& renderEngine) {
+void Flattener::renderCachedSets(renderengine::RenderEngine& renderEngine,
+                                 ui::Dataspace outputDataspace) {
     if (!mNewCachedSet) {
         return;
     }
 
-    mNewCachedSet->render(renderEngine);
+    mNewCachedSet->render(renderEngine, outputDataspace);
 }
 
 void Flattener::reset() {
@@ -223,6 +224,7 @@
                                 .buffer = mNewCachedSet->getBuffer(),
                                 .acquireFence = mNewCachedSet->getDrawFence(),
                                 .displayFrame = mNewCachedSet->getBounds(),
+                                .dataspace = mNewCachedSet->getOutputDataspace(),
                         };
                         ++incomingLayerIter;
                     }
@@ -253,6 +255,7 @@
                         .buffer = currentLayerIter->getBuffer(),
                         .acquireFence = currentLayerIter->getDrawFence(),
                         .displayFrame = currentLayerIter->getBounds(),
+                        .dataspace = currentLayerIter->getOutputDataspace(),
                 };
                 ++incomingLayerIter;
             }
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp b/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp
index f3746de..222b2be 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp
@@ -158,7 +158,8 @@
             lhs.mSourceCrop == rhs.mSourceCrop && lhs.mZOrder == rhs.mZOrder &&
             lhs.mBufferTransform == rhs.mBufferTransform && lhs.mBlendMode == rhs.mBlendMode &&
             lhs.mAlpha == rhs.mAlpha && lhs.mVisibleRegion == rhs.mVisibleRegion &&
-            lhs.mDataspace == rhs.mDataspace && lhs.mColorTransform == rhs.mColorTransform &&
+            lhs.mOutputDataspace == rhs.mOutputDataspace &&
+            lhs.mColorTransform == rhs.mColorTransform &&
             lhs.mCompositionType == rhs.mCompositionType &&
             lhs.mSidebandStream == rhs.mSidebandStream && lhs.mBuffer == rhs.mBuffer &&
             (lhs.mCompositionType.get() != hal::Composition::SOLID_COLOR ||
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
index 4570253..87721c7 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
@@ -133,8 +133,9 @@
                             finalPlan);
 }
 
-void Planner::renderCachedSets(renderengine::RenderEngine& renderEngine) {
-    mFlattener.renderCachedSets(renderEngine);
+void Planner::renderCachedSets(renderengine::RenderEngine& renderEngine,
+                               ui::Dataspace outputDataspace) {
+    mFlattener.renderCachedSets(renderEngine, outputDataspace);
 }
 
 void Planner::dump(const Vector<String16>& args, std::string& result) {
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
index c33828f..377f817 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
@@ -303,6 +303,7 @@
         EXPECT_EQ(Rect(0, 0, 2, 2), displaySettings.clip);
         EXPECT_EQ(0.5f, layers[0]->alpha);
         EXPECT_EQ(0.75f, layers[1]->alpha);
+        EXPECT_EQ(ui::Dataspace::SRGB, displaySettings.outputDataspace);
 
         return NO_ERROR;
     };
@@ -311,7 +312,7 @@
     EXPECT_CALL(*layerFE2, prepareClientCompositionList(_)).WillOnce(Return(clientCompList2));
     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Invoke(drawLayers));
     EXPECT_CALL(mRenderEngine, cacheExternalTextureBuffer(_));
-    cachedSet.render(mRenderEngine);
+    cachedSet.render(mRenderEngine, ui::Dataspace::SRGB);
     expectReadyBuffer(cachedSet);
 
     // Now check that appending a new cached set properly cleans up RenderEngine resources.
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp
index c4bd5b3..bd77559 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp
@@ -134,13 +134,13 @@
     initializeOverrideBuffer(layers);
     EXPECT_EQ(getNonBufferHash(layers),
               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
-    mFlattener->renderCachedSets(mRenderEngine);
+    mFlattener->renderCachedSets(mRenderEngine, ui::Dataspace::SRGB);
 
     // same geometry, update the internal layer stack
     initializeOverrideBuffer(layers);
     EXPECT_EQ(getNonBufferHash(layers),
               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
-    mFlattener->renderCachedSets(mRenderEngine);
+    mFlattener->renderCachedSets(mRenderEngine, ui::Dataspace::SRGB);
 }
 
 void FlattenerTest::expectAllLayersFlattened(const std::vector<const LayerState*>& layers) {
@@ -150,7 +150,7 @@
     initializeOverrideBuffer(layers);
     EXPECT_EQ(getNonBufferHash(layers),
               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
-    mFlattener->renderCachedSets(mRenderEngine);
+    mFlattener->renderCachedSets(mRenderEngine, ui::Dataspace::SRGB);
 
     for (const auto layer : layers) {
         EXPECT_EQ(nullptr, layer->getOutputLayer()->getState().overrideInfo.buffer);
@@ -160,7 +160,7 @@
     initializeOverrideBuffer(layers);
     EXPECT_NE(getNonBufferHash(layers),
               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
-    mFlattener->renderCachedSets(mRenderEngine);
+    mFlattener->renderCachedSets(mRenderEngine, ui::Dataspace::SRGB);
 
     const auto buffer = layers[0]->getOutputLayer()->getState().overrideInfo.buffer;
     EXPECT_NE(nullptr, buffer);
@@ -195,7 +195,7 @@
     initializeOverrideBuffer(layers);
     EXPECT_EQ(getNonBufferHash(layers),
               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
-    mFlattener->renderCachedSets(mRenderEngine);
+    mFlattener->renderCachedSets(mRenderEngine, ui::Dataspace::SRGB);
 }
 
 TEST_F(FlattenerTest, flattenLayers_basicFlatten) {
@@ -241,7 +241,7 @@
     initializeOverrideBuffer(layers);
     EXPECT_NE(getNonBufferHash(layers),
               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
-    mFlattener->renderCachedSets(mRenderEngine);
+    mFlattener->renderCachedSets(mRenderEngine, ui::Dataspace::SRGB);
 
     EXPECT_NE(nullptr, overrideBuffer1);
     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
@@ -276,7 +276,7 @@
     initializeOverrideBuffer(layers);
     EXPECT_EQ(getNonBufferHash(layers),
               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
-    mFlattener->renderCachedSets(mRenderEngine);
+    mFlattener->renderCachedSets(mRenderEngine, ui::Dataspace::SRGB);
 
     EXPECT_EQ(nullptr, overrideBuffer1);
     EXPECT_EQ(nullptr, overrideBuffer2);
@@ -313,7 +313,7 @@
     initializeOverrideBuffer(layers);
     EXPECT_EQ(getNonBufferHash(layers),
               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
-    mFlattener->renderCachedSets(mRenderEngine);
+    mFlattener->renderCachedSets(mRenderEngine, ui::Dataspace::SRGB);
 
     EXPECT_EQ(nullptr, overrideBuffer1);
     EXPECT_EQ(nullptr, overrideBuffer2);
@@ -322,7 +322,7 @@
     initializeOverrideBuffer(layers);
     EXPECT_NE(getNonBufferHash(layers),
               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
-    mFlattener->renderCachedSets(mRenderEngine);
+    mFlattener->renderCachedSets(mRenderEngine, ui::Dataspace::SRGB);
 
     EXPECT_EQ(nullptr, overrideBuffer1);
     EXPECT_NE(nullptr, overrideBuffer2);
@@ -335,7 +335,7 @@
     initializeOverrideBuffer(layers);
     EXPECT_NE(getNonBufferHash(layers),
               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
-    mFlattener->renderCachedSets(mRenderEngine);
+    mFlattener->renderCachedSets(mRenderEngine, ui::Dataspace::SRGB);
 
     EXPECT_EQ(nullptr, overrideBuffer1);
     EXPECT_NE(nullptr, overrideBuffer2);
@@ -344,7 +344,7 @@
     initializeOverrideBuffer(layers);
     EXPECT_NE(getNonBufferHash(layers),
               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
-    mFlattener->renderCachedSets(mRenderEngine);
+    mFlattener->renderCachedSets(mRenderEngine, ui::Dataspace::SRGB);
 
     EXPECT_NE(nullptr, overrideBuffer1);
     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
@@ -386,7 +386,7 @@
     initializeOverrideBuffer(layers);
     EXPECT_EQ(getNonBufferHash(layers),
               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
-    mFlattener->renderCachedSets(mRenderEngine);
+    mFlattener->renderCachedSets(mRenderEngine, ui::Dataspace::SRGB);
 
     EXPECT_EQ(nullptr, overrideBuffer1);
     EXPECT_EQ(nullptr, overrideBuffer2);
@@ -399,7 +399,7 @@
     initializeOverrideBuffer(layers);
     EXPECT_NE(getNonBufferHash(layers),
               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
-    mFlattener->renderCachedSets(mRenderEngine);
+    mFlattener->renderCachedSets(mRenderEngine, ui::Dataspace::SRGB);
 
     EXPECT_NE(nullptr, overrideBuffer1);
     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
@@ -411,7 +411,7 @@
     initializeOverrideBuffer(layers);
     EXPECT_NE(getNonBufferHash(layers),
               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
-    mFlattener->renderCachedSets(mRenderEngine);
+    mFlattener->renderCachedSets(mRenderEngine, ui::Dataspace::SRGB);
 
     EXPECT_NE(nullptr, overrideBuffer1);
     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
@@ -426,7 +426,7 @@
     initializeOverrideBuffer(layers);
     EXPECT_NE(getNonBufferHash(layers),
               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
-    mFlattener->renderCachedSets(mRenderEngine);
+    mFlattener->renderCachedSets(mRenderEngine, ui::Dataspace::SRGB);
 
     EXPECT_NE(nullptr, overrideBuffer1);
     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
@@ -437,7 +437,7 @@
     initializeOverrideBuffer(layers);
     EXPECT_NE(getNonBufferHash(layers),
               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
-    mFlattener->renderCachedSets(mRenderEngine);
+    mFlattener->renderCachedSets(mRenderEngine, ui::Dataspace::SRGB);
 
     EXPECT_NE(nullptr, overrideBuffer1);
     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 9da9483..d048380 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1462,14 +1462,16 @@
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) {
+status_t SurfaceFlinger::setDisplayBrightness(const sp<IBinder>& displayToken,
+                                              const gui::DisplayBrightness& brightness) {
     if (!displayToken) {
         return BAD_VALUE;
     }
 
     return ftl::chain(schedule([=]() MAIN_THREAD {
                if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
-                   return getHwComposer().setDisplayBrightness(*displayId, brightness);
+                   return getHwComposer().setDisplayBrightness(*displayId,
+                                                               brightness.displayBrightness);
                } else {
                    ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
                    return ftl::yield<status_t>(NAME_NOT_FOUND);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 3787b9d..a5b06df 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -680,7 +680,8 @@
                                         float* outAppRequestRefreshRateMax) override;
     status_t getDisplayBrightnessSupport(const sp<IBinder>& displayToken,
                                          bool* outSupport) const override;
-    status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) override;
+    status_t setDisplayBrightness(const sp<IBinder>& displayToken,
+                                  const gui::DisplayBrightness& brightness) override;
     status_t notifyPowerBoost(int32_t boostId) override;
     status_t setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor,
                                      float lightPosY, float lightPosZ, float lightRadius) override;
diff --git a/vulkan/vkjson/vkjson.cc b/vulkan/vkjson/vkjson.cc
index a513239..438e5dd 100644
--- a/vulkan/vkjson/vkjson.cc
+++ b/vulkan/vkjson/vkjson.cc
@@ -842,6 +842,8 @@
   bool ret = true;
   switch (device->properties.apiVersion ^
           VK_VERSION_PATCH(device->properties.apiVersion)) {
+    case VK_API_VERSION_1_2:
+      FALLTHROUGH_INTENDED;
     case VK_API_VERSION_1_1:
       ret &=
           visitor->Visit("subgroupProperties", &device->subgroup_properties) &&
@@ -896,6 +898,8 @@
 inline bool Iterate(Visitor* visitor, VkJsonInstance* instance) {
   bool ret = true;
   switch (instance->api_version ^ VK_VERSION_PATCH(instance->api_version)) {
+    case VK_API_VERSION_1_2:
+      FALLTHROUGH_INTENDED;
     case VK_API_VERSION_1_1:
       ret &= visitor->Visit("deviceGroups", &instance->device_groups);
       FALLTHROUGH_INTENDED;