Merge "Add a command to get the minimum battery voltage required for flashing"
diff --git a/audio/core/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp b/audio/core/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
index bb1d26f..a08a2d6 100644
--- a/audio/core/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
@@ -661,8 +661,8 @@
         code;                                          \
     }
 
-TEST_IO_STREAM(GetFrameCount, "Check that the stream frame count == the one it was opened with",
-               ASSERT_EQ(audioConfig.frameCount, extract(stream->getFrameCount())))
+TEST_IO_STREAM(GetFrameCount, "Check that getting stream frame count does not crash the HAL.",
+               ASSERT_TRUE(stream->getFrameCount().isOk()))
 
 TEST_IO_STREAM(GetSampleRate, "Check that the stream sample rate == the one it was opened with",
                ASSERT_EQ(audioConfig.sampleRateHz, extract(stream->getSampleRate())))
diff --git a/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp b/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp
index 3a7c284..f1e0b21 100644
--- a/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp
@@ -823,8 +823,8 @@
         code;                                          \
     }
 
-TEST_IO_STREAM(GetFrameCount, "Check that the stream frame count == the one it was opened with",
-               ASSERT_EQ(audioConfig.frameCount, extract(stream->getFrameCount())))
+TEST_IO_STREAM(GetFrameCount, "Check that getting stream frame count does not crash the HAL.",
+               ASSERT_TRUE(stream->getFrameCount().isOk()))
 
 TEST_IO_STREAM(GetSampleRate, "Check that the stream sample rate == the one it was opened with",
                ASSERT_EQ(audioConfig.sampleRateHz, extract(stream->getSampleRate())))
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index f2a7836..fd9396c 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -1172,6 +1172,14 @@
     }
     ASSERT_GT(firstApiLevel, 0); // first_api_level must exist
 
+    // all devices with first API level == 28 and <= 1GB of RAM must set low_ram
+    // and thus be allowed to continue using HAL1
+    if ((firstApiLevel == HAL1_PHASE_OUT_API_LEVEL) &&
+        (property_get_bool("ro.config.low_ram", /*default*/ false))) {
+        ALOGI("Hal1 allowed for low ram device");
+        return;
+    }
+
     if (firstApiLevel >= HAL1_PHASE_OUT_API_LEVEL) {
         hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
         for (const auto& name : cameraDeviceNames) {
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
index 91318bc..db4c914 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
@@ -44,6 +44,12 @@
 using V2_1::Layer;
 using V2_1::vts::TestCommandReader;
 
+static const IComposerClient::Color BLACK = {0, 0, 0, 0xff};
+static const IComposerClient::Color RED = {0xff, 0, 0, 0xff};
+static const IComposerClient::Color TRANSLUCENT_RED = {0xff, 0, 0, 0x33};
+static const IComposerClient::Color GREEN = {0, 0xff, 0, 0xff};
+static const IComposerClient::Color BLUE = {0, 0, 0xff, 0xff};
+
 // Test environment for graphics.composer
 class GraphicsComposerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
    public:
@@ -61,106 +67,57 @@
 
 class TestLayer {
    public:
-    TestLayer(std::shared_ptr<ComposerClient> const client, Display display)
-        : mLayer(client->createLayer(display, kBufferSlotCount)),
-          mComposerClient(client),
-          mDisplay(display) {}
+    TestLayer(const std::shared_ptr<ComposerClient>& client, Display display)
+        : mLayer(client->createLayer(display, kBufferSlotCount)), mComposerClient(client) {}
 
-    virtual ~TestLayer() { mComposerClient->destroyLayer(mDisplay, mLayer); }
+    // ComposerClient will take care of destroying layers, no need to explicitly
+    // call destroyLayers here
+    virtual ~TestLayer(){};
 
-    virtual void write(std::shared_ptr<CommandWriterBase> writer) {
+    virtual void write(const std::shared_ptr<CommandWriterBase>& writer) {
         writer->selectLayer(mLayer);
         writer->setLayerDisplayFrame(mDisplayFrame);
+        writer->setLayerSourceCrop(mSourceCrop);
         writer->setLayerZOrder(mZOrder);
+        writer->setLayerSurfaceDamage(mSurfaceDamage);
+        writer->setLayerTransform(mTransform);
+        writer->setLayerPlaneAlpha(mAlpha);
+        writer->setLayerBlendMode(mBlendMode);
     }
 
     void setDisplayFrame(IComposerClient::Rect frame) { mDisplayFrame = frame; }
+    void setSourceCrop(IComposerClient::FRect crop) { mSourceCrop = crop; }
     void setZOrder(uint32_t z) { mZOrder = z; }
 
+    void setSurfaceDamage(std::vector<IComposerClient::Rect> surfaceDamage) {
+        mSurfaceDamage = surfaceDamage;
+    }
+
+    void setTransform(Transform transform) { mTransform = transform; }
+    void setAlpha(float alpha) { mAlpha = alpha; }
+    void setBlendMode(IComposerClient::BlendMode blendMode) { mBlendMode = blendMode; }
+
+    static constexpr uint32_t kBufferSlotCount = 64;
+
+    IComposerClient::Rect mDisplayFrame = {0, 0, 0, 0};
+    uint32_t mZOrder = 0;
+    std::vector<IComposerClient::Rect> mSurfaceDamage;
+    Transform mTransform = static_cast<Transform>(0);
+    IComposerClient::FRect mSourceCrop = {0, 0, 0, 0};
+    float mAlpha = 1.0;
+    IComposerClient::BlendMode mBlendMode = IComposerClient::BlendMode::NONE;
+
    protected:
     Layer mLayer;
-    IComposerClient::Rect mDisplayFrame = {0, 0, 0, 0};
-    uint32_t mZOrder = 0;
 
    private:
     std::shared_ptr<ComposerClient> const mComposerClient;
-    const Display mDisplay;
-    static constexpr uint32_t kBufferSlotCount = 64;
-};
-
-class TestColorLayer : public TestLayer {
-   public:
-    TestColorLayer(std::shared_ptr<ComposerClient> const client, Display display)
-        : TestLayer{client, display} {}
-
-    void write(std::shared_ptr<CommandWriterBase> writer) override {
-        TestLayer::write(writer);
-        writer->setLayerCompositionType(IComposerClient::Composition::SOLID_COLOR);
-        writer->setLayerColor(mColor);
-    }
-
-    void setColor(IComposerClient::Color color) { mColor = color; }
-
-   private:
-    IComposerClient::Color mColor = {0xff, 0xff, 0xff, 0xff};
 };
 
 class GraphicsComposerReadbackTest : public ::testing::VtsHalHidlTargetTestBase {
-   protected:
-    using PowerMode = V2_1::IComposerClient::PowerMode;
-    void SetUp() override {
-        ASSERT_NO_FATAL_FAILURE(
-            mComposer = std::make_unique<Composer>(
-                GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
-        ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient());
-        mComposerCallback = new V2_1::vts::GraphicsComposerCallback;
-        mComposerClient->registerCallback(mComposerCallback);
-
-        // assume the first display is primary and is never removed
-        mPrimaryDisplay = waitForFirstDisplay();
-        Config activeConfig = mComposerClient->getActiveConfig(mPrimaryDisplay);
-        mDisplayWidth = mComposerClient->getDisplayAttribute(mPrimaryDisplay, activeConfig,
-                                                             IComposerClient::Attribute::WIDTH);
-        mDisplayHeight = mComposerClient->getDisplayAttribute(mPrimaryDisplay, activeConfig,
-                                                              IComposerClient::Attribute::HEIGHT);
-
-        // explicitly disable vsync
-        mComposerClient->setVsyncEnabled(mPrimaryDisplay, false);
-        mComposerCallback->setVsyncAllowed(false);
-
-        // set up command writer/reader and gralloc
-        mWriter = std::make_shared<CommandWriterBase>(1024);
-        mReader = std::make_unique<TestCommandReader>();
-        mGralloc = std::make_unique<Gralloc>();
-
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-            mPrimaryDisplay, [&](const auto& tmpError, const auto&, const auto&) {
-                mHasReadbackBuffer = tmpError == Error::NONE;
-            });
-    }
-
-    ~GraphicsComposerReadbackTest() override {
-        if (mComposerCallback != nullptr) {
-            EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
-            EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
-            EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
-        }
-    }
-
-    void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
-
-    void render(const std::vector<std::shared_ptr<TestLayer>>& layers) {
-        for (auto layer : layers) {
-            layer->write(mWriter);
-        }
-        execute();
-        mWriter->validateDisplay();
-        mWriter->presentDisplay();
-        execute();
-    }
-
-    int32_t GetBytesPerPixel(PixelFormat format) {
-        switch (format) {
+   public:
+    static int32_t GetBytesPerPixel(PixelFormat pixelFormat) {
+        switch (pixelFormat) {
             case PixelFormat::RGBA_8888:
                 return 4;
             case PixelFormat::RGB_888:
@@ -170,9 +127,120 @@
         }
     }
 
+    static void fillBuffer(int32_t width, int32_t height, uint32_t stride, void* bufferData,
+                           PixelFormat pixelFormat,
+                           std::vector<IComposerClient::Color> desiredPixelColors) {
+        ASSERT_TRUE(pixelFormat == PixelFormat::RGB_888 || pixelFormat == PixelFormat::RGBA_8888);
+        int32_t bytesPerPixel = GetBytesPerPixel(pixelFormat);
+        ASSERT_NE(-1, bytesPerPixel);
+        for (int row = 0; row < height; row++) {
+            for (int col = 0; col < width; col++) {
+                int pixel = row * width + col;
+                IComposerClient::Color srcColor = desiredPixelColors[pixel];
+
+                int offset = (row * stride + col) * bytesPerPixel;
+                uint8_t* pixelColor = (uint8_t*)bufferData + offset;
+                pixelColor[0] = srcColor.r;
+                pixelColor[1] = srcColor.g;
+                pixelColor[2] = srcColor.b;
+
+                if (bytesPerPixel == 4) {
+                    pixelColor[3] = srcColor.a;
+                }
+            }
+        }
+    }
+
+   protected:
+    using PowerMode = V2_1::IComposerClient::PowerMode;
+    void SetUp() override {
+        VtsHalHidlTargetTestBase::SetUp();
+        ASSERT_NO_FATAL_FAILURE(
+            mComposer = std::make_unique<Composer>(
+                GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
+        ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient());
+        mComposerCallback = new V2_1::vts::GraphicsComposerCallback;
+        mComposerClient->registerCallback(mComposerCallback);
+
+        // assume the first display is primary and is never removed
+        mPrimaryDisplay = waitForFirstDisplay();
+        Config activeConfig;
+        ASSERT_NO_FATAL_FAILURE(activeConfig = mComposerClient->getActiveConfig(mPrimaryDisplay));
+        ASSERT_NO_FATAL_FAILURE(
+            mDisplayWidth = mComposerClient->getDisplayAttribute(
+                mPrimaryDisplay, activeConfig, IComposerClient::Attribute::WIDTH));
+        ASSERT_NO_FATAL_FAILURE(
+            mDisplayHeight = mComposerClient->getDisplayAttribute(
+                mPrimaryDisplay, activeConfig, IComposerClient::Attribute::HEIGHT));
+
+        // explicitly disable vsync
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->setVsyncEnabled(mPrimaryDisplay, false));
+        mComposerCallback->setVsyncAllowed(false);
+
+        // set up command writer/reader and gralloc
+        mWriter = std::make_shared<CommandWriterBase>(1024);
+        mReader = std::make_unique<TestCommandReader>();
+        mGralloc = std::make_shared<Gralloc>();
+
+        mComposerClient->getRaw()->getReadbackBufferAttributes(
+            mPrimaryDisplay,
+            [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
+                mHasReadbackBuffer = readbackSupported(tmpPixelFormat, tmpDataspace, tmpError);
+                mPixelFormat = tmpPixelFormat;
+                mDataspace = tmpDataspace;
+            });
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON));
+    }
+
+    void TearDown() override {
+        mWriter->validateDisplay();
+        mWriter->presentDisplay();
+        execute();
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::OFF));
+        EXPECT_EQ(0, mReader->mErrors.size());
+        EXPECT_EQ(0, mReader->mCompositionChanges.size());
+        if (mComposerCallback != nullptr) {
+            EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
+        }
+        VtsHalHidlTargetTestBase::TearDown();
+    }
+
+    void execute() {
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->execute(mReader.get(), mWriter.get()));
+    }
+
+    void writeLayers(const std::vector<std::shared_ptr<TestLayer>>& layers) {
+        for (auto layer : layers) {
+            layer->write(mWriter);
+        }
+        execute();
+    }
+
+    void clearColors(std::vector<IComposerClient::Color>& expectedColors, int32_t width,
+                     int32_t height) {
+        for (int row = 0; row < height; row++) {
+            for (int col = 0; col < width; col++) {
+                int pixel = row * mDisplayWidth + col;
+                expectedColors[pixel] = BLACK;
+            }
+        }
+    }
+
+    void fillColorsArea(std::vector<IComposerClient::Color>& expectedColors, int32_t stride,
+                        IComposerClient::Rect area, IComposerClient::Color color) {
+        for (int row = area.top; row < area.bottom; row++) {
+            for (int col = area.left; col < area.right; col++) {
+                int pixel = row * stride + col;
+                expectedColors[pixel] = color;
+            }
+        }
+    }
+
     bool readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace,
                            const Error error) {
-        if (error == Error::UNSUPPORTED) {
+        if (error != Error::NONE) {
             return false;
         }
         // TODO: add support for RGBA_1010102
@@ -185,33 +253,6 @@
         return true;
     }
 
-    void getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
-                                     Dataspace* outDataspace) {
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-            display, [&](const auto&, const auto& tmpOutPixelFormat, const auto& tmpOutDataspace) {
-                *outPixelFormat = tmpOutPixelFormat;
-                *outDataspace = tmpOutDataspace;
-            });
-    }
-
-    void checkReadbackBuffer(IMapper::BufferDescriptorInfo info, uint32_t stride, void* bufferData,
-                             std::vector<IComposerClient::Color> expectedColors) {
-        int32_t bytesPerPixel = GetBytesPerPixel(info.format);
-        ASSERT_NE(-1, bytesPerPixel)
-            << "unexpected pixel format " << static_cast<int32_t>(info.format)
-            << "(expected RGBA_8888 or RGB_888)";
-        for (int row = 0; row < mDisplayHeight; row++) {
-            for (int col = 0; col < mDisplayWidth; col++) {
-                int pixel = row * mDisplayWidth + col;
-                int offset = (row * stride + col) * bytesPerPixel;
-                uint8_t* pixelColor = (uint8_t*)bufferData + offset;
-
-                EXPECT_EQ(expectedColors[pixel].r, pixelColor[0]);
-                EXPECT_EQ(expectedColors[pixel].g, pixelColor[1]);
-                EXPECT_EQ(expectedColors[pixel].b, pixelColor[2]);
-            }
-        }
-    }
 
     std::unique_ptr<Composer> mComposer;
     std::shared_ptr<ComposerClient> mComposerClient;
@@ -223,9 +264,13 @@
     int32_t mDisplayHeight;
     std::shared_ptr<CommandWriterBase> mWriter;
     std::unique_ptr<TestCommandReader> mReader;
-    std::unique_ptr<Gralloc> mGralloc;
+    std::shared_ptr<Gralloc> mGralloc;
 
     bool mHasReadbackBuffer;
+    PixelFormat mPixelFormat;
+    Dataspace mDataspace;
+
+    static constexpr uint32_t kClientTargetSlotCount = 64;
 
    private:
     Display waitForFirstDisplay() {
@@ -239,6 +284,178 @@
         }
     }
 };
+class ReadbackBuffer {
+   public:
+    ReadbackBuffer(Display display, const std::shared_ptr<ComposerClient>& client,
+                   const std::shared_ptr<Gralloc>& gralloc, uint32_t width, uint32_t height,
+                   PixelFormat pixelFormat, Dataspace dataspace) {
+        mDisplay = display;
+
+        mComposerClient = client;
+        mGralloc = gralloc;
+
+        mPixelFormat = pixelFormat;
+        mDataspace = dataspace;
+
+        mInfo.width = width;
+        mInfo.height = height;
+        mInfo.layerCount = 1;
+        mInfo.format = mPixelFormat;
+        mInfo.usage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::GPU_TEXTURE);
+
+        mAccessRegion.top = 0;
+        mAccessRegion.left = 0;
+        mAccessRegion.width = width;
+        mAccessRegion.height = height;
+    };
+
+    ~ReadbackBuffer() {
+        if (mBufferHandle != nullptr) {
+            mGralloc->freeBuffer(mBufferHandle);
+        }
+    }
+
+    void setReadbackBuffer() {
+        if (mBufferHandle != nullptr) {
+            mGralloc->freeBuffer(mBufferHandle);
+            mBufferHandle = nullptr;
+        }
+        mBufferHandle = mGralloc->allocate(mInfo, /*import*/ true, &mStride);
+        ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle, mInfo, mStride));
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->setReadbackBuffer(mDisplay, mBufferHandle, -1));
+    }
+
+    void checkReadbackBuffer(std::vector<IComposerClient::Color> expectedColors) {
+        // lock buffer for reading
+        int32_t fenceHandle;
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->getReadbackBufferFence(mDisplay, &fenceHandle));
+
+        void* bufData = mGralloc->lock(mBufferHandle, mInfo.usage, mAccessRegion, fenceHandle);
+        ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
+        int32_t bytesPerPixel = GraphicsComposerReadbackTest::GetBytesPerPixel(mPixelFormat);
+        ASSERT_NE(-1, bytesPerPixel);
+        for (int row = 0; row < mInfo.height; row++) {
+            for (int col = 0; col < mInfo.width; col++) {
+                int pixel = row * mInfo.width + col;
+                int offset = (row * mStride + col) * bytesPerPixel;
+                uint8_t* pixelColor = (uint8_t*)bufData + offset;
+
+                ASSERT_EQ(expectedColors[pixel].r, pixelColor[0]);
+                ASSERT_EQ(expectedColors[pixel].g, pixelColor[1]);
+                ASSERT_EQ(expectedColors[pixel].b, pixelColor[2]);
+            }
+        }
+        int32_t unlockFence = mGralloc->unlock(mBufferHandle);
+        if (unlockFence != -1) {
+            sync_wait(unlockFence, -1);
+            close(unlockFence);
+        }
+    }
+
+   protected:
+    IMapper::BufferDescriptorInfo mInfo;
+    IMapper::Rect mAccessRegion;
+    uint32_t mStride;
+    const native_handle_t* mBufferHandle = nullptr;
+    PixelFormat mPixelFormat;
+    Dataspace mDataspace;
+    Display mDisplay;
+    std::shared_ptr<Gralloc> mGralloc;
+    std::shared_ptr<ComposerClient> mComposerClient;
+};
+
+class TestColorLayer : public TestLayer {
+   public:
+    TestColorLayer(const std::shared_ptr<ComposerClient>& client, Display display)
+        : TestLayer{client, display} {}
+
+    void write(const std::shared_ptr<CommandWriterBase>& writer) override {
+        TestLayer::write(writer);
+        writer->setLayerCompositionType(IComposerClient::Composition::SOLID_COLOR);
+        writer->setLayerColor(mColor);
+    }
+
+    void setColor(IComposerClient::Color color) { mColor = color; }
+
+   private:
+    IComposerClient::Color mColor = {0xff, 0xff, 0xff, 0xff};
+};
+
+class TestBufferLayer : public TestLayer {
+   public:
+    TestBufferLayer(const std::shared_ptr<ComposerClient>& client,
+                    const std::shared_ptr<Gralloc>& gralloc, Display display, int32_t width,
+                    int32_t height, PixelFormat format,
+                    IComposerClient::Composition composition = IComposerClient::Composition::DEVICE)
+        : TestLayer{client, display} {
+        mGralloc = gralloc;
+        mComposition = composition;
+        mInfo.width = width;
+        mInfo.height = height;
+        mInfo.layerCount = 1;
+        mInfo.format = format;
+        mInfo.usage =
+            static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
+                                  BufferUsage::COMPOSER_OVERLAY);
+
+        mAccessRegion.top = 0;
+        mAccessRegion.left = 0;
+        mAccessRegion.width = width;
+        mAccessRegion.height = height;
+
+        setSourceCrop({0, 0, (float)width, (float)height});
+    }
+
+    ~TestBufferLayer() {
+        if (mBufferHandle != nullptr) {
+            mGralloc->freeBuffer(mBufferHandle);
+        }
+    }
+
+    void write(const std::shared_ptr<CommandWriterBase>& writer) override {
+        TestLayer::write(writer);
+        writer->setLayerCompositionType(mComposition);
+        writer->setLayerDataspace(Dataspace::UNKNOWN);
+        writer->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, mDisplayFrame));
+        if (mBufferHandle != nullptr) writer->setLayerBuffer(0, mBufferHandle, mFillFence);
+    }
+
+    void fillBuffer(std::vector<IComposerClient::Color> expectedColors) {
+        void* bufData = mGralloc->lock(mBufferHandle, mInfo.usage, mAccessRegion, -1);
+        ASSERT_NO_FATAL_FAILURE(GraphicsComposerReadbackTest::fillBuffer(
+            mInfo.width, mInfo.height, mStride, bufData, mInfo.format, expectedColors));
+        mFillFence = mGralloc->unlock(mBufferHandle);
+        if (mFillFence != -1) {
+            sync_wait(mFillFence, -1);
+            close(mFillFence);
+        }
+    }
+    void setBuffer(std::vector<IComposerClient::Color> colors) {
+        if (mBufferHandle != nullptr) {
+            mGralloc->freeBuffer(mBufferHandle);
+            mBufferHandle = nullptr;
+        }
+        mBufferHandle = mGralloc->allocate(mInfo, /*import*/ true, &mStride);
+        ASSERT_NE(nullptr, mBufferHandle);
+        ASSERT_NO_FATAL_FAILURE(fillBuffer(colors));
+        ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle, mInfo, mStride));
+    }
+
+    void setToClientComposition(const std::shared_ptr<CommandWriterBase>& writer) {
+        writer->selectLayer(mLayer);
+        writer->setLayerCompositionType(IComposerClient::Composition::CLIENT);
+    }
+
+    IMapper::BufferDescriptorInfo mInfo;
+    IMapper::Rect mAccessRegion;
+    uint32_t mStride;
+
+   protected:
+    IComposerClient::Composition mComposition;
+    std::shared_ptr<Gralloc> mGralloc;
+    int32_t mFillFence;
+    const native_handle_t* mBufferHandle = nullptr;
+};
 
 TEST_F(GraphicsComposerReadbackTest, SingleSolidColorLayer) {
     if (!mHasReadbackBuffer) {
@@ -246,13 +463,12 @@
         return;
     }
     mWriter->selectDisplay(mPrimaryDisplay);
-    mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON);
-    mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB, RenderIntent::COLORIMETRIC);
+    ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB,
+                                                          RenderIntent::COLORIMETRIC));
 
     auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
-    IComposerClient::Color color({0, 0, 0xff, 0xff});
-    IComposerClient::Rect coloredSquare({100, 100, 500, 500});
-    layer->setColor(color);
+    IComposerClient::Rect coloredSquare({0, 0, mDisplayWidth, mDisplayHeight});
+    layer->setColor(BLUE);
     layer->setDisplayFrame(coloredSquare);
     layer->setZOrder(10);
 
@@ -260,58 +476,831 @@
 
     // expected color for each pixel
     std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
-    for (int row = 0; row < mDisplayHeight; row++) {
-        for (int col = 0; col < mDisplayWidth; col++) {
-            int pixel = row * mDisplayWidth + col;
-            if (row >= coloredSquare.top && row < coloredSquare.bottom &&
-                col >= coloredSquare.left && col < coloredSquare.right) {
-                expectedColors[pixel] = color;
-            } else {
-                expectedColors[pixel] = {0, 0, 0, 0xff};
+    fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE);
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    writeLayers(layers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    // if hwc cannot handle and asks for composition change,
+    // just succeed the test
+    if (mReader->mCompositionChanges.size() != 0) {
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_F(GraphicsComposerReadbackTest, SetLayerBuffer) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight / 2}, GREEN);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE);
+
+    auto layer =
+        std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth,
+                                          mDisplayHeight, PixelFormat::RGBA_8888);
+    layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+    layer->setZOrder(10);
+    ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
+
+    std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+    writeLayers(layers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+
+    if (mReader->mCompositionChanges.size() != 0) {
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    mWriter->presentDisplay();
+    execute();
+
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_F(GraphicsComposerReadbackTest, SetLayerBufferNoEffect) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+    ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB,
+                                                          RenderIntent::COLORIMETRIC));
+
+    auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+    IComposerClient::Rect coloredSquare({0, 0, mDisplayWidth, mDisplayHeight});
+    layer->setColor(BLUE);
+    layer->setDisplayFrame(coloredSquare);
+    layer->setZOrder(10);
+    layer->write(mWriter);
+
+    // This following buffer call should have no effect
+    IMapper::BufferDescriptorInfo bufferInfo{};
+    bufferInfo.width = mDisplayWidth;
+    bufferInfo.height = mDisplayHeight;
+    bufferInfo.layerCount = 1;
+    bufferInfo.format = PixelFormat::RGBA_8888;
+    bufferInfo.usage =
+        static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN);
+    const native_handle_t* bufferHandle = mGralloc->allocate(bufferInfo);
+    mWriter->setLayerBuffer(0, bufferHandle, -1);
+
+    // expected color for each pixel
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE);
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    mWriter->validateDisplay();
+    execute();
+
+    if (mReader->mCompositionChanges.size() != 0) {
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_F(GraphicsComposerReadbackTest, ClientComposition) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight / 2}, GREEN);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE);
+
+    auto layer =
+        std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth,
+                                          mDisplayHeight, PixelFormat::RGBA_FP16);
+    layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+    layer->setZOrder(10);
+
+    std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+    writeLayers(layers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+
+    if (mReader->mCompositionChanges.size() != 0) {
+        ASSERT_EQ(1, mReader->mCompositionChanges.size());
+        ASSERT_EQ(1, mReader->mCompositionChanges[0].second);
+
+        ASSERT_NO_FATAL_FAILURE(
+            mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount));
+
+        // create client target buffer
+        uint32_t clientStride;
+        IMapper::BufferDescriptorInfo clientInfo;
+        clientInfo.width = layer->mInfo.width;
+        clientInfo.height = layer->mInfo.height;
+        clientInfo.layerCount = layer->mInfo.layerCount;
+        clientInfo.format = PixelFormat::RGBA_8888;
+        clientInfo.usage =
+            static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
+                                  BufferUsage::COMPOSER_CLIENT_TARGET);
+        const native_handle_t* clientBufferHandle =
+            mGralloc->allocate(clientInfo, /*import*/ true, &clientStride);
+        ASSERT_NE(nullptr, clientBufferHandle);
+
+        void* clientBufData =
+            mGralloc->lock(clientBufferHandle, clientInfo.usage, layer->mAccessRegion, -1);
+
+        ASSERT_NO_FATAL_FAILURE(fillBuffer(clientInfo.width, clientInfo.height, clientStride,
+                                           clientBufData, clientInfo.format, expectedColors));
+        int clientFence = mGralloc->unlock(clientBufferHandle);
+        if (clientFence != -1) {
+            sync_wait(clientFence, -1);
+            close(clientFence);
+        }
+
+        IComposerClient::Rect damage{0, 0, mDisplayWidth, mDisplayHeight};
+        mWriter->setClientTarget(0, clientBufferHandle, clientFence, Dataspace::UNKNOWN,
+                                 std::vector<IComposerClient::Rect>(1, damage));
+
+        layer->setToClientComposition(mWriter);
+        mWriter->validateDisplay();
+        execute();
+        ASSERT_EQ(0, mReader->mCompositionChanges.size());
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    mWriter->presentDisplay();
+    execute();
+
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_F(GraphicsComposerReadbackTest, DeviceAndClientComposition) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+    ASSERT_NO_FATAL_FAILURE(
+        mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount));
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, {0, 0, mDisplayWidth, mDisplayHeight / 2}, GREEN);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, RED);
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    auto deviceLayer =
+        std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth,
+                                          mDisplayHeight / 2, PixelFormat::RGBA_8888);
+    std::vector<IComposerClient::Color> deviceColors(deviceLayer->mInfo.width *
+                                                     deviceLayer->mInfo.height);
+    fillColorsArea(deviceColors, deviceLayer->mInfo.width,
+                   {0, 0, static_cast<int32_t>(deviceLayer->mInfo.width),
+                    static_cast<int32_t>(deviceLayer->mInfo.height)},
+                   GREEN);
+    deviceLayer->setDisplayFrame({0, 0, static_cast<int32_t>(deviceLayer->mInfo.width),
+                                  static_cast<int32_t>(deviceLayer->mInfo.height)});
+    deviceLayer->setZOrder(10);
+    ASSERT_NO_FATAL_FAILURE(deviceLayer->setBuffer(deviceColors));
+    deviceLayer->write(mWriter);
+
+    auto clientLayer = std::make_shared<TestBufferLayer>(
+        mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth, mDisplayHeight / 2,
+        PixelFormat::RGBA_8888, IComposerClient::Composition::CLIENT);
+    IComposerClient::Rect clientFrame = {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight};
+    clientLayer->setDisplayFrame(clientFrame);
+    clientLayer->setZOrder(0);
+    clientLayer->write(mWriter);
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    IMapper::BufferDescriptorInfo clientInfo;
+    clientInfo.width = mDisplayWidth;
+    clientInfo.height = mDisplayHeight;
+    clientInfo.layerCount = 1;
+    clientInfo.format = PixelFormat::RGBA_8888;
+    clientInfo.usage =
+        static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
+                              BufferUsage::COMPOSER_CLIENT_TARGET);
+
+    uint32_t clientStride;
+    const native_handle_t* clientBufferHandle =
+        mGralloc->allocate(clientInfo, /*import*/ true, &clientStride);
+    ASSERT_NE(nullptr, clientBufferHandle);
+
+    IMapper::Rect clientAccessRegion;
+    clientAccessRegion.left = 0;
+    clientAccessRegion.top = 0;
+    clientAccessRegion.width = mDisplayWidth;
+    clientAccessRegion.height = mDisplayHeight;
+    void* clientData = mGralloc->lock(clientBufferHandle, clientInfo.usage, clientAccessRegion, -1);
+    std::vector<IComposerClient::Color> clientColors(clientInfo.width * clientInfo.height);
+    fillColorsArea(clientColors, clientInfo.width, clientFrame, RED);
+    ASSERT_NO_FATAL_FAILURE(fillBuffer(clientInfo.width, clientInfo.height, clientStride,
+                                       clientData, clientInfo.format, clientColors));
+    int clientFence = mGralloc->unlock(clientBufferHandle);
+    if (clientFence != -1) {
+        sync_wait(clientFence, -1);
+        close(clientFence);
+    }
+
+    mWriter->setClientTarget(0, clientBufferHandle, clientFence, Dataspace::UNKNOWN,
+                             std::vector<IComposerClient::Rect>(1, clientFrame));
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_F(GraphicsComposerReadbackTest, SetLayerDamage) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelformat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+
+    IComposerClient::Rect redRect = {0, 0, mDisplayWidth / 4, mDisplayHeight / 4};
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+
+    auto layer =
+        std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth,
+                                          mDisplayHeight, PixelFormat::RGBA_8888);
+    layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+    layer->setZOrder(10);
+    ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
+
+    std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    writeLayers(layers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+
+    // update surface damage and recheck
+    redRect = {mDisplayWidth / 4, mDisplayHeight / 4, mDisplayWidth / 2, mDisplayHeight / 2};
+    clearColors(expectedColors, mDisplayWidth, mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+
+    ASSERT_NO_FATAL_FAILURE(layer->fillBuffer(expectedColors));
+    layer->setSurfaceDamage(
+        std::vector<IComposerClient::Rect>(1, {0, 0, mDisplayWidth / 2, mDisplayWidth / 2}));
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    writeLayers(layers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+    ASSERT_EQ(0, mReader->mCompositionChanges.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_F(GraphicsComposerReadbackTest, SetLayerPlaneAlpha) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+    ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB,
+                                                          RenderIntent::COLORIMETRIC));
+
+    auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+    layer->setColor(RED);
+    layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+    layer->setZOrder(10);
+    layer->setAlpha(0);
+    layer->setBlendMode(IComposerClient::BlendMode::PREMULTIPLIED);
+
+    std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    writeLayers(layers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_F(GraphicsComposerReadbackTest, SetLayerSourceCrop) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE);
+
+    auto layer =
+        std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth,
+                                          mDisplayHeight, PixelFormat::RGBA_8888);
+    layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+    layer->setZOrder(10);
+    layer->setSourceCrop({0, static_cast<float>(mDisplayHeight / 2),
+                          static_cast<float>(mDisplayWidth), static_cast<float>(mDisplayHeight)});
+    ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
+
+    std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+    // update expected colors to match crop
+    fillColorsArea(expectedColors, mDisplayWidth, {0, 0, mDisplayWidth, mDisplayHeight}, BLUE);
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+    writeLayers(layers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_F(GraphicsComposerReadbackTest, SetLayerZOrder) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+    ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB,
+                                                          RenderIntent::COLORIMETRIC));
+
+    IComposerClient::Rect redRect = {0, 0, mDisplayWidth, mDisplayHeight / 2};
+    IComposerClient::Rect blueRect = {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight};
+    auto redLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+    redLayer->setColor(RED);
+    redLayer->setDisplayFrame(redRect);
+
+    auto blueLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+    blueLayer->setColor(BLUE);
+    blueLayer->setDisplayFrame(blueRect);
+    blueLayer->setZOrder(5);
+
+    std::vector<std::shared_ptr<TestLayer>> layers = {redLayer, blueLayer};
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+
+    // red in front of blue
+    redLayer->setZOrder(10);
+
+    // fill blue first so that red will overwrite on overlap
+    fillColorsArea(expectedColors, mDisplayWidth, blueRect, BLUE);
+    fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    writeLayers(layers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        GTEST_SUCCEED();
+        return;
+    }
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+
+    redLayer->setZOrder(1);
+    clearColors(expectedColors, mDisplayWidth, mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+    fillColorsArea(expectedColors, mDisplayWidth, blueRect, BLUE);
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    writeLayers(layers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mCompositionChanges.size());
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+class GraphicsComposerBlendModeReadbackTest : public GraphicsComposerReadbackTest,
+                                              public ::testing::WithParamInterface<float> {
+   public:
+    void SetUp() override {
+        GraphicsComposerReadbackTest::SetUp();
+        mBackgroundColor = BLACK;
+        mTopLayerColor = RED;
+    }
+
+    void TearDown() override { GraphicsComposerReadbackTest::TearDown(); }
+
+    void setBackgroundColor(IComposerClient::Color color) { mBackgroundColor = color; }
+
+    void setTopLayerColor(IComposerClient::Color color) { mTopLayerColor = color; }
+
+    void setUpLayers(IComposerClient::BlendMode blendMode) {
+        mLayers.clear();
+        std::vector<IComposerClient::Color> topLayerPixelColors(mDisplayWidth * mDisplayHeight);
+        fillColorsArea(topLayerPixelColors, mDisplayWidth, {0, 0, mDisplayWidth, mDisplayHeight},
+                       mTopLayerColor);
+
+        auto backgroundLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+        backgroundLayer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+        backgroundLayer->setZOrder(0);
+        backgroundLayer->setColor(mBackgroundColor);
+
+        auto layer = std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay,
+                                                       mDisplayWidth, mDisplayHeight,
+                                                       PixelFormat::RGBA_8888);
+        layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+        layer->setZOrder(10);
+        ASSERT_NO_FATAL_FAILURE(layer->setBuffer(topLayerPixelColors));
+
+        layer->setBlendMode(blendMode);
+        layer->setAlpha(GetParam());
+
+        mLayers.push_back(backgroundLayer);
+        mLayers.push_back(layer);
+    }
+
+    void setExpectedColors(std::vector<IComposerClient::Color>& expectedColors) {
+        ASSERT_EQ(2, mLayers.size());
+        clearColors(expectedColors, mDisplayWidth, mDisplayHeight);
+
+        auto layer = mLayers[1];
+        IComposerClient::BlendMode blendMode = layer->mBlendMode;
+        float alpha = mTopLayerColor.a / 255.0 * layer->mAlpha;
+        if (blendMode == IComposerClient::BlendMode::NONE) {
+            for (int i = 0; i < expectedColors.size(); i++) {
+                expectedColors[i].r = mTopLayerColor.r * layer->mAlpha;
+                expectedColors[i].g = mTopLayerColor.g * layer->mAlpha;
+                expectedColors[i].b = mTopLayerColor.b * layer->mAlpha;
+                expectedColors[i].a = alpha * 255.0;
+            }
+        } else if (blendMode == IComposerClient::BlendMode::PREMULTIPLIED) {
+            for (int i = 0; i < expectedColors.size(); i++) {
+                expectedColors[i].r =
+                    mTopLayerColor.r * layer->mAlpha + mBackgroundColor.r * (1.0 - alpha);
+                expectedColors[i].g =
+                    mTopLayerColor.g * layer->mAlpha + mBackgroundColor.g * (1.0 - alpha);
+                expectedColors[i].b =
+                    mTopLayerColor.b * layer->mAlpha + mBackgroundColor.b * (1.0 - alpha);
+                expectedColors[i].a = alpha + mBackgroundColor.a * (1.0 - alpha);
+            }
+        } else if (blendMode == IComposerClient::BlendMode::COVERAGE) {
+            for (int i = 0; i < expectedColors.size(); i++) {
+                expectedColors[i].r = mTopLayerColor.r * alpha + mBackgroundColor.r * (1.0 - alpha);
+                expectedColors[i].g = mTopLayerColor.g * alpha + mBackgroundColor.g * (1.0 - alpha);
+                expectedColors[i].b = mTopLayerColor.b * alpha + mBackgroundColor.b * (1.0 - alpha);
+                expectedColors[i].a = mTopLayerColor.a * alpha + mBackgroundColor.a * (1.0 - alpha);
             }
         }
     }
 
-    PixelFormat pixelFormat;
-    Dataspace dataspace;
+   protected:
+    std::vector<std::shared_ptr<TestLayer>> mLayers;
+    IComposerClient::Color mBackgroundColor;
+    IComposerClient::Color mTopLayerColor;
+};
 
-    getReadbackBufferAttributes(mPrimaryDisplay, &pixelFormat, &dataspace);
-
-    IMapper::BufferDescriptorInfo info;
-    info.width = mDisplayWidth;
-    info.height = mDisplayHeight;
-    info.layerCount = 1;
-    info.format = pixelFormat;
-    info.usage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::GPU_TEXTURE);
-
-    uint32_t stride;
-    const native_handle_t* buffer = mGralloc->allocate(info, /*import*/ true, &stride);
-    mComposerClient->setReadbackBuffer(mPrimaryDisplay, buffer, -1);
-
-    render(layers);
-
-    int32_t fenceHandle;
-    mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fenceHandle);
-
-    // lock buffer
-    // Create Rect accessRegion to specify reading the entire buffer
-    IMapper::Rect accessRegion;
-    accessRegion.left = 0;
-    accessRegion.top = 0;
-    accessRegion.width = info.width;
-    accessRegion.height = info.height;
-
-    void* bufData = mGralloc->lock(buffer, info.usage, accessRegion, fenceHandle);
-    checkReadbackBuffer(info, stride, bufData, expectedColors);
-    int unlockFence = mGralloc->unlock(buffer);
-
-    if (unlockFence != -1) {
-        close(unlockFence);
+TEST_P(GraphicsComposerBlendModeReadbackTest, None) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
     }
 
+    mWriter->selectDisplay(mPrimaryDisplay);
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+
+    setBackgroundColor(BLACK);
+    setTopLayerColor(TRANSLUCENT_RED);
+    setUpLayers(IComposerClient::BlendMode::NONE);
+    setExpectedColors(expectedColors);
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+    writeLayers(mLayers);
+    ASSERT_EQ(0, mReader->mErrors.size());
     mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
     mWriter->presentDisplay();
     execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+// TODO: bug 116865056: Readback returns (245, 0, 0) for layer plane
+// alpha of .2, expected 10.2
+TEST_P(GraphicsComposerBlendModeReadbackTest, DISABLED_Coverage) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+
+    setBackgroundColor(BLACK);
+    setTopLayerColor(TRANSLUCENT_RED);
+
+    setUpLayers(IComposerClient::BlendMode::COVERAGE);
+    setExpectedColors(expectedColors);
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+    writeLayers(mLayers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_P(GraphicsComposerBlendModeReadbackTest, Premultiplied) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+
+    setBackgroundColor(BLACK);
+    setTopLayerColor(TRANSLUCENT_RED);
+    setUpLayers(IComposerClient::BlendMode::PREMULTIPLIED);
+    setExpectedColors(expectedColors);
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+    writeLayers(mLayers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+INSTANTIATE_TEST_CASE_P(BlendModeTest, GraphicsComposerBlendModeReadbackTest,
+                        ::testing::Values(.2, 1.0));
+
+class GraphicsComposerTransformReadbackTest : public GraphicsComposerReadbackTest {
+   protected:
+    void SetUp() override {
+        GraphicsComposerReadbackTest::SetUp();
+        if (!mHasReadbackBuffer) {
+            GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+            return;
+        }
+
+        mWriter->selectDisplay(mPrimaryDisplay);
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB,
+                                                              RenderIntent::COLORIMETRIC));
+
+        auto backgroundLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+        backgroundLayer->setColor({0, 0, 0, 0});
+        backgroundLayer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+        backgroundLayer->setZOrder(0);
+
+        mSideLength = mDisplayWidth < mDisplayHeight ? mDisplayWidth : mDisplayHeight;
+        IComposerClient::Rect redRect = {0, 0, mSideLength / 2, mSideLength / 2};
+        IComposerClient::Rect blueRect = {mSideLength / 2, mSideLength / 2, mSideLength,
+                                          mSideLength};
+
+        mLayer =
+            std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay,
+                                              mSideLength, mSideLength, PixelFormat::RGBA_8888);
+        mLayer->setDisplayFrame({0, 0, mSideLength, mSideLength});
+        mLayer->setZOrder(10);
+
+        std::vector<IComposerClient::Color> baseColors(mSideLength * mSideLength);
+        fillColorsArea(baseColors, mSideLength, redRect, RED);
+        fillColorsArea(baseColors, mSideLength, blueRect, BLUE);
+        ASSERT_NO_FATAL_FAILURE(mLayer->setBuffer(baseColors));
+
+        mLayers = {backgroundLayer, mLayer};
+    }
+
+   protected:
+    std::shared_ptr<TestBufferLayer> mLayer;
+    std::vector<IComposerClient::Color> baseColors;
+    std::vector<std::shared_ptr<TestLayer>> mLayers;
+    int mSideLength;
+};
+
+TEST_F(GraphicsComposerTransformReadbackTest, FLIP_H) {
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+    mLayer->setTransform(Transform::FLIP_H);
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {mSideLength / 2, 0, mSideLength, mSideLength / 2}, RED);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mSideLength / 2, mSideLength / 2, mSideLength}, BLUE);
+
+    writeLayers(mLayers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_F(GraphicsComposerTransformReadbackTest, FLIP_V) {
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    mLayer->setTransform(Transform::FLIP_V);
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mSideLength / 2, mSideLength / 2, mSideLength}, RED);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {mSideLength / 2, 0, mSideLength, mSideLength / 2}, BLUE);
+
+    writeLayers(mLayers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+}
+
+TEST_F(GraphicsComposerTransformReadbackTest, ROT_180) {
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    mLayer->setTransform(Transform::ROT_180);
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {mSideLength / 2, mSideLength / 2, mSideLength, mSideLength}, RED);
+    fillColorsArea(expectedColors, mDisplayWidth, {0, 0, mSideLength / 2, mSideLength / 2}, BLUE);
+
+    writeLayers(mLayers);
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        GTEST_SUCCEED();
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
 }
 
 }  // anonymous namespace
diff --git a/health/2.0/default/Health.cpp b/health/2.0/default/Health.cpp
index e02bfa9..a2b81d1 100644
--- a/health/2.0/default/Health.cpp
+++ b/health/2.0/default/Health.cpp
@@ -46,7 +46,7 @@
     }
 
     {
-        std::lock_guard<std::mutex> _lock(callbacks_lock_);
+        std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
         callbacks_.push_back(callback);
         // unlock
     }
@@ -58,14 +58,14 @@
         // ignore the error
     }
 
-    return update();
+    return updateAndNotify(callback);
 }
 
 bool Health::unregisterCallbackInternal(const sp<IBase>& callback) {
     if (callback == nullptr) return false;
 
     bool removed = false;
-    std::lock_guard<std::mutex> _lock(callbacks_lock_);
+    std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
     for (auto it = callbacks_.begin(); it != callbacks_.end();) {
         if (interfacesEqual(*it, callback)) {
             it = callbacks_.erase(it);
@@ -156,6 +156,18 @@
     return Result::SUCCESS;
 }
 
+Return<Result> Health::updateAndNotify(const sp<IHealthInfoCallback>& callback) {
+    std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
+    std::vector<sp<IHealthInfoCallback>> storedCallbacks{std::move(callbacks_)};
+    callbacks_.clear();
+    if (callback != nullptr) {
+        callbacks_.push_back(callback);
+    }
+    Return<Result> result = update();
+    callbacks_ = std::move(storedCallbacks);
+    return result;
+}
+
 void Health::notifyListeners(HealthInfo* healthInfo) {
     std::vector<StorageInfo> info;
     get_storage_info(info);
@@ -175,7 +187,7 @@
     healthInfo->diskStats = stats;
     healthInfo->storageInfos = info;
 
-    std::lock_guard<std::mutex> _lock(callbacks_lock_);
+    std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
     for (auto it = callbacks_.begin(); it != callbacks_.end();) {
         auto ret = (*it)->healthInfoChanged(*healthInfo);
         if (!ret.isOk() && ret.isDeadObject()) {
@@ -233,7 +245,7 @@
 Return<void> Health::getHealthInfo(getHealthInfo_cb _hidl_cb) {
     using android::hardware::health::V1_0::hal_conversion::convertToHealthInfo;
 
-    update();
+    updateAndNotify(nullptr);
     struct android::BatteryProperties p = getBatteryProperties(battery_monitor_.get());
 
     V1_0::HealthInfo batteryInfo;
diff --git a/health/2.0/default/include/health2/Health.h b/health/2.0/default/include/health2/Health.h
index 134cdc6..6410474 100644
--- a/health/2.0/default/include/health2/Health.h
+++ b/health/2.0/default/include/health2/Health.h
@@ -31,12 +31,10 @@
     // Should only be called by implementation itself (-impl, -service).
     // Clients should not call this function. Instead, initInstance() initializes and returns the
     // global instance that has fewer functions.
-    // TODO(b/62229583): clean up and hide these functions after update() logic is simplified.
     static sp<Health> getImplementation();
 
     Health(struct healthd_config* c);
 
-    // TODO(b/62229583): clean up and hide these functions after update() logic is simplified.
     void notifyListeners(HealthInfo* info);
 
     // Methods from IHealth follow.
@@ -61,11 +59,15 @@
    private:
     static sp<Health> instance_;
 
-    std::mutex callbacks_lock_;
+    std::recursive_mutex callbacks_lock_;
     std::vector<sp<IHealthInfoCallback>> callbacks_;
     std::unique_ptr<BatteryMonitor> battery_monitor_;
 
     bool unregisterCallbackInternal(const sp<IBase>& cb);
+
+    // update() and only notify the given callback, but none of the other callbacks.
+    // If cb is null, do not notify any callback at all.
+    Return<Result> updateAndNotify(const sp<IHealthInfoCallback>& cb);
 };
 
 }  // namespace implementation
diff --git a/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp b/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp
index bba4661..f895aec 100644
--- a/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp
+++ b/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp
@@ -222,38 +222,83 @@
 }
 
 /*
- * Tests the values returned by getChargeCounter(),
- * getCurrentNow(), getCurrentAverage(), getCapacity(), getEnergyCounter(),
- * getChargeStatus(), getStorageInfo(), getDiskStats() and getHealthInfo() from
- * interface IHealth.
+ * Tests the values returned by getChargeCounter() from interface IHealth.
  */
-TEST_F(HealthHidlTest, Properties) {
+TEST_F(HealthHidlTest, getChargeCounter) {
     EXPECT_OK(mHealth->getChargeCounter([](auto result, auto value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), value > 0);
     }));
+}
+
+/*
+ * Tests the values returned by getCurrentNow() from interface IHealth.
+ */
+TEST_F(HealthHidlTest, getCurrentNow) {
     EXPECT_OK(mHealth->getCurrentNow([](auto result, auto value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), value != INT32_MIN);
     }));
+}
+
+/*
+ * Tests the values returned by getCurrentAverage() from interface IHealth.
+ */
+TEST_F(HealthHidlTest, getCurrentAverage) {
     EXPECT_OK(mHealth->getCurrentAverage([](auto result, auto value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), value != INT32_MIN);
     }));
+}
+
+/*
+ * Tests the values returned by getCapacity() from interface IHealth.
+ */
+TEST_F(HealthHidlTest, getCapacity) {
     EXPECT_OK(mHealth->getCapacity([](auto result, auto value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), 0 <= value && value <= 100);
     }));
+}
+
+/*
+ * Tests the values returned by getEnergyCounter() from interface IHealth.
+ */
+TEST_F(HealthHidlTest, getEnergyCounter) {
     EXPECT_OK(mHealth->getEnergyCounter([](auto result, auto value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), value != INT64_MIN);
     }));
+}
+
+/*
+ * Tests the values returned by getChargeStatus() from interface IHealth.
+ */
+TEST_F(HealthHidlTest, getChargeStatus) {
     EXPECT_OK(mHealth->getChargeStatus([](auto result, auto value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(
             result, toString(value),
             value != BatteryStatus::UNKNOWN && verifyEnum<BatteryStatus>(value));
     }));
+}
+
+/*
+ * Tests the values returned by getStorageInfo() from interface IHealth.
+ */
+TEST_F(HealthHidlTest, getStorageInfo) {
     EXPECT_OK(mHealth->getStorageInfo([](auto result, auto& value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, toString(value), verifyStorageInfo(value));
     }));
+}
+
+/*
+ * Tests the values returned by getDiskStats() from interface IHealth.
+ */
+TEST_F(HealthHidlTest, getDiskStats) {
     EXPECT_OK(mHealth->getDiskStats([](auto result, auto& value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, toString(value), true);
     }));
+}
+
+/*
+ * Tests the values returned by getHealthInfo() from interface IHealth.
+ */
+TEST_F(HealthHidlTest, getHealthInfo) {
     EXPECT_OK(mHealth->getHealthInfo([](auto result, auto& value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, toString(value), verifyHealthInfo(value));
     }));
diff --git a/radio/1.3/Android.bp b/radio/1.3/Android.bp
index 5ac38cd..9424a85 100644
--- a/radio/1.3/Android.bp
+++ b/radio/1.3/Android.bp
@@ -22,6 +22,7 @@
         "AccessNetwork",
         "DataRegStateResult",
         "EmergencyNumber",
+        "EmergencyNumberSource",
         "EmergencyServiceCategory",
         "LteVopsInfo",
     ],
diff --git a/radio/1.3/IRadio.hal b/radio/1.3/IRadio.hal
index 480a61f..2b14488 100644
--- a/radio/1.3/IRadio.hal
+++ b/radio/1.3/IRadio.hal
@@ -86,36 +86,19 @@
             bool isRoaming, DataRequestReason reason, vec<string> addresses, vec<string> dnses);
 
     /**
-     * Request the current emergency number list.
-     *
-     * Each emergency number (@1.3::EmergencyNumber) in the emergency number list contains a
-     * dialing number, one or more service category(s), and mobile country code.
-     *
-     * Radio must collect all sources of the emergency number to build the response.
-     * For example, network operator signals, sim card information, modem configuration, OEM
-     * configuration (for example, OEM system properties), always-available emergency numbers and
-     * sim-absence emergency numbers, etc.
-     *
-     * 112, 911 are always available. Besides, 000, 08, 110, 999, 118 and 119 should be available
-     * when sim is not present.
-     *
-     * Please refer the document of @1.3::EmergencyNumber to construct each emergency number to be
-     * returned.
-     *
-     * Reference: 3GPP TS 22.101 version 9.1.0 Release 9
-     *
-     * @param serial Serial number of request.
-     *
-     * Response function is IRadioResponse.getCurrentEmergencyNumberListResponse()
-     */
-    oneway getCurrentEmergencyNumberList(int32_t serial);
-
-    /**
-     * Initiate emergency voice call, with one or more emergency service category(s).
+     * Initiate emergency voice call, with zero or more emergency service category(s).
      *
      * Note this API is the same as IRadio.dial except using the
      * @1.3::EmergencyServiceCategory as the input param.
      *
+     * If the dialed emergency number does not have a specified emergency service category, the
+     * 'categories' field is set to @1.3::EmergencyServiceCategory#UNSPECIFIED; iff either the
+     * 'categories' field is set to @1.3::EmergencyServiceCategory#UNSPECIFIED or the underlying
+     * technology used to request emergency services does not support the emergency service
+     * category, the interpretation of the categories is defined by implementation.
+     *
+     * Reference: 3gpp TS 22.101, Section 10 - Emergency Calls
+     *
      * @param serial Serial number of request.
      * @param dialInfo the same @1.0::Dial information used by @1.0::IRadio.dial.
      * @param categories bitfield<@1.3::EmergencyServiceCategory> the Emergency Service Category(s)
diff --git a/radio/1.3/IRadioIndication.hal b/radio/1.3/IRadioIndication.hal
index c80e762..509eef8 100644
--- a/radio/1.3/IRadioIndication.hal
+++ b/radio/1.3/IRadioIndication.hal
@@ -24,29 +24,28 @@
  */
 interface IRadioIndication extends @1.2::IRadioIndication {
     /**
-     * Indicate and update all of the current Emergency Number information known to the radio,
-     * when any of the Emergency Number sources (For example, network operator signals, sim card
-     * information, modem configuration, OEM configuration or system properties, etc.) change the
-     * list of emergency numbers.
+     * Report the current list of emergency numbers
      *
-     * 112, 911 are always available. Besides, 000, 08, 110, 999, 118 and 119 should be available
-     * when sim is not present.
+     * Each emergency number (@1.3::EmergencyNumber) in the emergency number list contains a
+     * dialing number, zero or more service category(s), mobile country code, and source(s) that
+     * indicate where it comes from.
      *
-     * This should be the same information as returned by getCurrentEmergencyNumberList() in
-     * 1.3::IRadio.
+     * Radio must report all the valid emergency numbers with known mobile country code and
+     * emergency service categories from all available sources including network signaling, sim,
+     * modem/oem configuration, and default configuration (112 and 911 must be always available;
+     * additionally, 000, 08, 110, 999, 118 and 119 must be available when sim is not present).
+     * Radio shall not report emergency numbers that are invalid in the current locale. The
+     * reported emergency number list must not have duplicate @1.3::EmergencyNumber entries. Please
+     * refer the documentation of @1.3::EmergencyNumber to construct each emergency number to
+     * report.
      *
-     * The indicated list of emergency numbers should not have duplicate @1.3::EmergencyNumber.
-     * Please refer the document of @1.3::EmergencyNumber to construct each emergency number to be
-     * returned.
+     * Radio must report the complete list of emergency numbers whenever the emergency numbers in
+     * the list are changed or whenever the client and the radio server are connected.
      *
-     * Reference: 3GPP TS 22.101 version 9.1.0 Release 9
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
      *
      * @param type Type of radio indication
-     * @param emergencyNumberList List of current Emergency Number information
-     *     (@1.3::EmergencyNumber) known to radio. Radio must collect all sources of the emergency
-     *     numbers to build the indication. For example, network operator signals, sim card
-     *     information, modem configuration, OEM configuration (for example, OEM specific system
-     *     properties), always-available emergency numbers and sim-absence emergency numbers, etc.
+     * @param emergencyNumberList Current list of emergency numbers known to radio.
      */
     oneway currentEmergencyNumberList(RadioIndicationType type,
             vec<EmergencyNumber> emergencyNumberList);
diff --git a/radio/1.3/IRadioResponse.hal b/radio/1.3/IRadioResponse.hal
index 3604953..10e7d63 100644
--- a/radio/1.3/IRadioResponse.hal
+++ b/radio/1.3/IRadioResponse.hal
@@ -25,30 +25,6 @@
 interface IRadioResponse extends @1.2::IRadioResponse {
     /**
      * @param info Response info struct containing response type, serial no. and error
-     * @param emergencyNumberList List of current Emergency Number information known to radio.
-     *
-     * Radio must collect all sources of the emergency number to build the response. For example,
-     * network operator signals, sim card information, modem configuration, OEM configuration (for
-     * example, OEM system properties), always-available emergency numbers and sim-absence
-     * emergency numbers, etc.
-     *
-     * The returned list of emergency numbers must not have duplicate @1.3::EmergencyNumber. Please
-     * refer the document of @1.3::EmergencyNumber to construct each emergency number to be
-     * returned.
-     *
-     * Reference: 3GPP TS 22.101 version 9.1.0 Release 9
-     *
-     * Valid errors returned:
-     *   RadioError:NONE
-     *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:NO_MEMORY
-     *   RadioError:MODEM_ERR
-     */
-    oneway getCurrentEmergencyNumberListResponse(RadioResponseInfo info,
-            vec<EmergencyNumber> emergencyNumberList);
-
-    /**
-     * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
      *   RadioError:NONE
diff --git a/radio/1.3/types.hal b/radio/1.3/types.hal
index d472ca7..09202a5 100644
--- a/radio/1.3/types.hal
+++ b/radio/1.3/types.hal
@@ -29,14 +29,14 @@
 };
 
 /**
- * Emergency number contains information of number, one or more service category(s), and mobile
- * country code (mcc).
+ * Emergency number contains information of number, one or more service category(s), mobile country
+ * code (mcc), and source(s) that indicate where it comes from.
  *
  * If the source of the emergency number is associated with country, field ‘mcc’ must be
  * provided; otherwise the field ‘mcc’ must be an empty string.
  *
- * A unique EmergencyNumber has a unique combination of ‘number’ and ‘mcc’ fields.
- * Multiple @1.3::EmergencyServiceCategory should be merged into the bitfield for the same
+ * A unique EmergencyNumber has a unique combination of ‘number’, ‘mcc’ and 'categories' fields.
+ * Multiple @1.3::EmergencyNumberSource should be merged into the bitfield for the same
  * EmergencyNumber.
  *
  * Reference: 3GPP TS 22.101 version 9.1.0 Release 9
@@ -56,6 +56,11 @@
      * the value of each bit.
      */
     bitfield<EmergencyServiceCategory> categories;
+    /**
+     * The bitfield of @1.3::EmergencyNumberSource(s). See @1.3::EmergencyNumberSource for the
+     * value of each bit.
+     */
+    bitfield<EmergencyNumberSource> sources;
 };
 
 /**
@@ -69,20 +74,55 @@
  * - Manually Initiated eCall (MIeC);
  * - Automatically Initiated eCall (AIeC);
  *
- * Type GENERIC (General emergency call, all categories) is considered to use if the reported type
- * is not any of the other specific types.
+ * Category UNSPECIFIED (General emergency call, all categories) indicates that no specific
+ * services are associated with this emergency number.
  *
- * Reference: 3GPP TS 22.101 version 9.1.0 Release 9
+ * Reference: 3gpp 22.101, Section 10 - Emergency Calls
  */
 enum EmergencyServiceCategory : int32_t {
-    GENERIC = 0, // General emergency call, all categories
+    /**
+     * General emergency call, all categories
+     */
+    UNSPECIFIED = 0,
     POLICE = 1 << 0,
     AMBULANCE = 1 << 1,
     FIRE_BRIGADE = 1 << 2,
     MARINE_GUARD = 1 << 3,
     MOUNTAIN_RESCUE = 1 << 4,
-    MIEC = 1 << 5, // Manually Initiated eCall (MIeC)
-    AIEC = 1 << 6, // Automatically Initiated eCall (AIeC)
+    /**
+     * Manually Initiated eCall (MIeC)
+     */
+    MIEC = 1 << 5,
+    /**
+     * Automatically Initiated eCall (AIeC)
+     */
+    AIEC = 1 << 6,
+};
+
+/**
+ * The source to tell where the corresponding @1.3::EmergencyNumber comes from.
+ *
+ * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+ */
+enum EmergencyNumberSource : int32_t {
+    /**
+     * Indicates the number is from the network signal.
+     */
+    NETWORK_SIGNALING = 1 << 0,
+    /**
+     * Indicates the number is from the sim card.
+     */
+    SIM = 1 << 1,
+    /**
+     * Indicates the number is from the modem config.
+     */
+    MODEM_CONFIG = 1 << 2,
+    /**
+     * Indicates the number is available as default. Per the reference, 112, 911 must always be
+     * available; additionally, 000, 08, 110, 999, 118 and 119 must be available when sim is not
+     * present.
+     */
+    DEFAULT = 1 << 3,
 };
 
 /**
diff --git a/sensors/2.0/ISensors.hal b/sensors/2.0/ISensors.hal
index 2a57251..939bf73 100644
--- a/sensors/2.0/ISensors.hal
+++ b/sensors/2.0/ISensors.hal
@@ -27,6 +27,13 @@
 interface ISensors {
     /**
      * Enumerate all available (static) sensors.
+     *
+     * The SensorInfo for each sensor returned by getSensorsList must be stable
+     * from the initial call to getSensorsList after a device boot until the
+     * entire system restarts. The SensorInfo for each sensor must not change
+     * between subsequent calls to getSensorsList, even across restarts of the
+     * HAL and its dependencies (for example, the sensor handle for a given
+     * sensor must not change across HAL restarts).
      */
     getSensorsList() generates (vec<SensorInfo> list);