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);