1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "[email protected]"
18 
19 #include <android-base/logging.h>
20 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
21 #include <composer-vts/2.1/GraphicsComposerCallback.h>
22 #include <composer-vts/2.1/TestCommandReader.h>
23 #include <composer-vts/2.2/ComposerVts.h>
24 #include <gtest/gtest.h>
25 #include <hidl/GtestPrinter.h>
26 #include <hidl/ServiceManagement.h>
27 #include <mapper-vts/2.0/MapperVts.h>
28 
29 namespace android {
30 namespace hardware {
31 namespace graphics {
32 namespace composer {
33 namespace V2_2 {
34 namespace vts {
35 namespace {
36 
37 using common::V1_0::BufferUsage;
38 using common::V1_0::ColorTransform;
39 using common::V1_0::Transform;
40 using common::V1_1::ColorMode;
41 using common::V1_1::Dataspace;
42 using common::V1_1::PixelFormat;
43 using common::V1_1::RenderIntent;
44 using mapper::V2_0::IMapper;
45 
46 class GraphicsComposerHidlTest : public ::testing::TestWithParam<std::string> {
47   protected:
SetUp()48     void SetUp() override {
49         ASSERT_NO_FATAL_FAILURE(
50                 mComposer = std::make_unique<Composer>(IComposer::getService(GetParam())));
51         ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient());
52 
53         mComposerCallback = new V2_1::vts::GraphicsComposerCallback;
54         mComposerClient->registerCallback(mComposerCallback);
55 
56         // assume the first display is primary and is never removed
57         mPrimaryDisplay = waitForFirstDisplay();
58 
59         Config config = mComposerClient->getActiveConfig(mPrimaryDisplay);
60         mDisplayWidth = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
61                                                              IComposerClient::Attribute::WIDTH);
62         mDisplayHeight = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
63                                                               IComposerClient::Attribute::HEIGHT);
64 
65         // explicitly disable vsync
66         mComposerClient->setVsyncEnabled(mPrimaryDisplay, false);
67         mComposerCallback->setVsyncAllowed(false);
68 
69         mComposerClient->getRaw()->getReadbackBufferAttributes(
70             mPrimaryDisplay,
71             [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
72                 mHasReadbackBuffer = tmpError == Error::NONE;
73                 if (mHasReadbackBuffer) {
74                     mReadbackPixelFormat = tmpPixelFormat;
75                     mReadbackDataspace = tmpDataspace;
76                     ASSERT_LT(static_cast<PixelFormat>(0), mReadbackPixelFormat);
77                     ASSERT_NE(Dataspace::UNKNOWN, mReadbackDataspace);
78                 }
79             });
80 
81         mInvalidDisplayId = GetInvalidDisplayId();
82     }
83 
TearDown()84     void TearDown() override {
85         if (mComposerCallback != nullptr) {
86             EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
87             EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
88             EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
89         }
90     }
91 
92     // returns an invalid display id (one that has not been registered to a
93     // display.  Currently assuming that a device will never have close to
94     // std::numeric_limit<uint64_t>::max() displays registered while running tests
GetInvalidDisplayId()95     Display GetInvalidDisplayId() {
96         std::vector<Display> validDisplays = mComposerCallback->getDisplays();
97         uint64_t id = std::numeric_limits<uint64_t>::max();
98         while (id > 0) {
99             if (std::find(validDisplays.begin(), validDisplays.end(), id) == validDisplays.end()) {
100                 return id;
101             }
102             id--;
103         }
104 
105         return 0;
106     }
107 
108     // use the slot count usually set by SF
109     static constexpr uint32_t kBufferSlotCount = 64;
110 
111     std::unique_ptr<Composer> mComposer;
112     std::unique_ptr<ComposerClient> mComposerClient;
113     sp<V2_1::vts::GraphicsComposerCallback> mComposerCallback;
114     // the first display and is assumed never to be removed
115     Display mPrimaryDisplay;
116     int32_t mDisplayWidth;
117     int32_t mDisplayHeight;
118 
119     bool mHasReadbackBuffer;
120 
121     uint64_t mInvalidDisplayId;
122     PixelFormat mReadbackPixelFormat;
123     Dataspace mReadbackDataspace;
124 
125    private:
waitForFirstDisplay()126     Display waitForFirstDisplay() {
127         while (true) {
128             std::vector<Display> displays = mComposerCallback->getDisplays();
129             if (displays.empty()) {
130                 usleep(5 * 1000);
131                 continue;
132             }
133 
134             return displays[0];
135         }
136     }
137 };
138 
139 // Tests for IComposerClient::Command.
140 class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest {
141    protected:
SetUp()142     void SetUp() override {
143         ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::SetUp());
144 
145         ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>());
146 
147         mWriter = std::make_unique<CommandWriterBase>(1024);
148         mReader = std::make_unique<V2_1::vts::TestCommandReader>();
149     }
150 
TearDown()151     void TearDown() override {
152         ASSERT_EQ(0, mReader->mErrors.size());
153         ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown());
154     }
155 
allocate()156     const native_handle_t* allocate() {
157         uint64_t usage =
158                 static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
159         return mGralloc->allocate(/*width*/ 64, /*height*/ 64, /*layerCount*/ 1,
160                                   PixelFormat::RGBA_8888, usage);
161     }
162 
execute()163     void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
164 
165     std::unique_ptr<CommandWriterBase> mWriter;
166     std::unique_ptr<V2_1::vts::TestCommandReader> mReader;
167 
168    private:
169     std::unique_ptr<Gralloc> mGralloc;
170 };
171 
172 /**
173  * Test IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA.
174  */
TEST_P(GraphicsComposerHidlCommandTest,SET_LAYER_PER_FRAME_METADATA)175 TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_PER_FRAME_METADATA) {
176     Layer layer;
177     ASSERT_NO_FATAL_FAILURE(layer =
178                                 mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
179 
180     mWriter->selectDisplay(mPrimaryDisplay);
181     mWriter->selectLayer(layer);
182 
183     /**
184      * DISPLAY_P3 is a color space that uses the DCI_P3 primaries,
185      * the D65 white point and the SRGB transfer functions.
186      * Rendering Intent: Colorimetric
187      * Primaries:
188      *                  x       y
189      *  green           0.265   0.690
190      *  blue            0.150   0.060
191      *  red             0.680   0.320
192      *  white (D65)     0.3127  0.3290
193      */
194 
195     std::vector<IComposerClient::PerFrameMetadata> hidlMetadata;
196     hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X, 0.680});
197     hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y, 0.320});
198     hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X, 0.265});
199     hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y, 0.690});
200     hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X, 0.150});
201     hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y, 0.060});
202     hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::WHITE_POINT_X, 0.3127});
203     hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::WHITE_POINT_Y, 0.3290});
204     hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::MAX_LUMINANCE, 100.0});
205     hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::MIN_LUMINANCE, 0.1});
206     hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL, 78.0});
207     hidlMetadata.push_back(
208         {IComposerClient::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, 62.0});
209     mWriter->setLayerPerFrameMetadata(hidlMetadata);
210     execute();
211 
212     if (mReader->mErrors.size() == 1 &&
213         static_cast<Error>(mReader->mErrors[0].second) == Error::UNSUPPORTED) {
214         mReader->mErrors.clear();
215         GTEST_SUCCEED() << "SetLayerPerFrameMetadata is not supported";
216         ASSERT_NO_FATAL_FAILURE(mComposerClient->destroyLayer(mPrimaryDisplay, layer));
217         return;
218     }
219 
220     ASSERT_NO_FATAL_FAILURE(mComposerClient->destroyLayer(mPrimaryDisplay, layer));
221 }
222 
223 /**
224  * Test IComposerClient::getPerFrameMetadataKeys.
225  */
TEST_P(GraphicsComposerHidlTest,GetPerFrameMetadataKeys)226 TEST_P(GraphicsComposerHidlTest, GetPerFrameMetadataKeys) {
227     std::vector<IComposerClient::PerFrameMetadataKey> keys;
228     Error error = Error::NONE;
229     mComposerClient->getRaw()->getPerFrameMetadataKeys(
230             mPrimaryDisplay, [&](const auto& tmpError, const auto& tmpKeys) {
231                 error = tmpError;
232                 keys = tmpKeys;
233             });
234     if (error == Error::UNSUPPORTED) {
235         GTEST_SUCCEED() << "getPerFrameMetadataKeys is not supported";
236         return;
237     }
238     ASSERT_EQ(Error::NONE, error);
239     ASSERT_TRUE(keys.size() >= 0);
240 }
241 
242 /**
243  * Test IComposerClient::createVirtualDisplay_2_2 and
244  * IComposerClient::destroyVirtualDisplay.
245  *
246  * Test that virtual displays can be created and has the correct display type.
247  */
TEST_P(GraphicsComposerHidlTest,CreateVirtualDisplay_2_2)248 TEST_P(GraphicsComposerHidlTest, CreateVirtualDisplay_2_2) {
249     if (mComposerClient->getMaxVirtualDisplayCount() == 0) {
250         GTEST_SUCCEED() << "no virtual display support";
251         return;
252     }
253 
254     Display display;
255     PixelFormat format;
256     ASSERT_NO_FATAL_FAILURE(
257         display = mComposerClient->createVirtualDisplay_2_2(
258             64, 64, PixelFormat::IMPLEMENTATION_DEFINED, kBufferSlotCount, &format));
259 
260     // test display type
261     IComposerClient::DisplayType type = mComposerClient->getDisplayType(display);
262     EXPECT_EQ(IComposerClient::DisplayType::VIRTUAL, type);
263 
264     mComposerClient->destroyVirtualDisplay(display);
265 }
266 
267 /**
268  * Test IComposerClient::getClientTargetSupport_2_2.
269  *
270  * Test that IComposerClient::getClientTargetSupport returns true for the
271  * required client targets.
272  */
TEST_P(GraphicsComposerHidlTest,GetClientTargetSupport_2_2)273 TEST_P(GraphicsComposerHidlTest, GetClientTargetSupport_2_2) {
274     std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
275     for (auto config : configs) {
276         int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
277                                                              IComposerClient::Attribute::WIDTH);
278         int32_t height = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
279                                                               IComposerClient::Attribute::HEIGHT);
280         ASSERT_LT(0, width);
281         ASSERT_LT(0, height);
282 
283         mComposerClient->setActiveConfig(mPrimaryDisplay, config);
284 
285         ASSERT_TRUE(mComposerClient->getClientTargetSupport_2_2(
286             mPrimaryDisplay, width, height, PixelFormat::RGBA_8888, Dataspace::UNKNOWN));
287     }
288 }
289 
290 /**
291  * Test IComposerClient::getClientTargetSupport_2_2
292  *
293  * Test that IComposerClient::getClientTargetSupport_2_2 returns
294  * Error::BAD_DISPLAY when passed in an invalid display handle
295  */
296 
TEST_P(GraphicsComposerHidlTest,GetClientTargetSupport_2_2BadDisplay)297 TEST_P(GraphicsComposerHidlTest, GetClientTargetSupport_2_2BadDisplay) {
298     std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
299     for (auto config : configs) {
300         int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
301                                                              IComposerClient::Attribute::WIDTH);
302         int32_t height = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
303                                                               IComposerClient::Attribute::HEIGHT);
304         ASSERT_LT(0, width);
305         ASSERT_LT(0, height);
306 
307         mComposerClient->setActiveConfig(mPrimaryDisplay, config);
308 
309         Error error = mComposerClient->getRaw()->getClientTargetSupport_2_2(
310             mInvalidDisplayId, width, height, PixelFormat::RGBA_8888, Dataspace::UNKNOWN);
311 
312         EXPECT_EQ(Error::BAD_DISPLAY, error);
313     }
314 }
315 
316 /**
317  * Test IComposerClient::setPowerMode_2_2.
318  */
TEST_P(GraphicsComposerHidlTest,SetPowerMode_2_2)319 TEST_P(GraphicsComposerHidlTest, SetPowerMode_2_2) {
320     std::vector<IComposerClient::PowerMode> modes;
321     modes.push_back(IComposerClient::PowerMode::OFF);
322     modes.push_back(IComposerClient::PowerMode::ON_SUSPEND);
323     modes.push_back(IComposerClient::PowerMode::ON);
324 
325     for (auto mode : modes) {
326         mComposerClient->setPowerMode_2_2(mPrimaryDisplay, mode);
327     }
328 }
329 
330 /**
331  * Test IComposerClient::setPowerMode_2_2
332  *
333  * Test that IComposerClient::setPowerMode_2_2 succeeds for different varations
334  * of PowerMode
335  */
TEST_P(GraphicsComposerHidlTest,SetPowerMode_2_2Variations)336 TEST_P(GraphicsComposerHidlTest, SetPowerMode_2_2Variations) {
337     std::vector<IComposerClient::PowerMode> modes;
338 
339     modes.push_back(IComposerClient::PowerMode::OFF);
340     modes.push_back(IComposerClient::PowerMode::OFF);
341 
342     for (auto mode : modes) {
343         ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode_2_2(mPrimaryDisplay, mode));
344     }
345 
346     modes.clear();
347 
348     modes.push_back(IComposerClient::PowerMode::ON);
349     modes.push_back(IComposerClient::PowerMode::ON);
350 
351     for (auto mode : modes) {
352         ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode_2_2(mPrimaryDisplay, mode));
353     }
354 
355     modes.clear();
356 
357     modes.push_back(IComposerClient::PowerMode::ON_SUSPEND);
358     modes.push_back(IComposerClient::PowerMode::ON_SUSPEND);
359 
360     for (auto mode : modes) {
361         ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode_2_2(mPrimaryDisplay, mode));
362     }
363 
364     if (mComposerClient->getDozeSupport(mPrimaryDisplay)) {
365         modes.clear();
366 
367         modes.push_back(IComposerClient::PowerMode::DOZE);
368         modes.push_back(IComposerClient::PowerMode::DOZE);
369 
370         for (auto mode : modes) {
371             ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode_2_2(mPrimaryDisplay, mode));
372         }
373 
374         modes.clear();
375 
376         modes.push_back(IComposerClient::PowerMode::DOZE_SUSPEND);
377         modes.push_back(IComposerClient::PowerMode::DOZE_SUSPEND);
378 
379         for (auto mode : modes) {
380             ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode_2_2(mPrimaryDisplay, mode));
381         }
382     }
383 }
384 
385 /**
386  * Test IComposerClient::setPowerMode_2_2
387  *
388  * Tests that IComposerClient::setPowerMode_2_2 returns BAD_DISPLAY when passed an
389  * invalid display handle
390  */
TEST_P(GraphicsComposerHidlTest,SetPowerMode_2_2BadDisplay)391 TEST_P(GraphicsComposerHidlTest, SetPowerMode_2_2BadDisplay) {
392     Error error = mComposerClient->getRaw()->setPowerMode_2_2(mInvalidDisplayId,
393                                                               IComposerClient::PowerMode::ON);
394     ASSERT_EQ(Error::BAD_DISPLAY, error);
395 }
396 
397 /**
398  * Test IComposerClient::setPowerMode_2_2
399  *
400  * Test that IComposerClient::setPowerMode_2_2 returns BAD_PARAMETER when passed
401  * an invalid PowerMode
402  */
TEST_P(GraphicsComposerHidlTest,SetPowerMode_2_2BadParameter)403 TEST_P(GraphicsComposerHidlTest, SetPowerMode_2_2BadParameter) {
404     Error error = mComposerClient->getRaw()->setPowerMode_2_2(
405         mPrimaryDisplay, static_cast<IComposerClient::PowerMode>(-1));
406     ASSERT_EQ(Error::BAD_PARAMETER, error);
407 }
408 
409 /**
410  * Test IComposerClient::setPowerMode_2_2
411  *
412  * Test that IComposerClient::setPowerMode_2_2 returns UNSUPPORTED when passed
413  * DOZE or DOZE_SUPPORT on a device that does not support these modes
414  */
TEST_P(GraphicsComposerHidlTest,SetPowerMode_2_2Unsupported)415 TEST_P(GraphicsComposerHidlTest, SetPowerMode_2_2Unsupported) {
416     if (!mComposerClient->getDozeSupport(mPrimaryDisplay)) {
417         Error error = mComposerClient->getRaw()->setPowerMode_2_2(mPrimaryDisplay,
418                                                                   IComposerClient::PowerMode::DOZE);
419         EXPECT_EQ(Error::UNSUPPORTED, error);
420 
421         error = mComposerClient->getRaw()->setPowerMode_2_2(
422             mPrimaryDisplay, IComposerClient::PowerMode::DOZE_SUSPEND);
423         EXPECT_EQ(Error::UNSUPPORTED, error);
424     }
425 }
426 
427 /**
428  * Test IComposerClient::setReadbackBuffer
429  *
430  * Test IComposerClient::setReadbackBuffer
431  */
TEST_P(GraphicsComposerHidlTest,SetReadbackBuffer)432 TEST_P(GraphicsComposerHidlTest, SetReadbackBuffer) {
433     if (!mHasReadbackBuffer) {
434         return;
435     }
436 
437     // BufferUsage::COMPOSER_OUTPUT is missing
438     uint64_t usage =
439             static_cast<uint64_t>(BufferUsage::COMPOSER_OVERLAY | BufferUsage::CPU_READ_OFTEN);
440 
441     std::unique_ptr<Gralloc> gralloc;
442     const native_handle_t* buffer;
443     ASSERT_NO_FATAL_FAILURE(gralloc = std::make_unique<Gralloc>());
444     ASSERT_NO_FATAL_FAILURE(buffer = gralloc->allocate(mDisplayWidth, mDisplayHeight, 1,
445                                                        mReadbackPixelFormat, usage));
446 
447     mComposerClient->setReadbackBuffer(mPrimaryDisplay, buffer, -1);
448 }
449 
450 /**
451  * Test IComposerClient::setReadbackBuffer
452  *
453  * Test that IComposerClient::setReadbackBuffer returns an Error::BAD_DISPLAY
454  * when passed an invalid display handle
455  */
TEST_P(GraphicsComposerHidlTest,SetReadbackBufferBadDisplay)456 TEST_P(GraphicsComposerHidlTest, SetReadbackBufferBadDisplay) {
457     if (!mHasReadbackBuffer) {
458         return;
459     }
460 
461     uint64_t usage =
462             static_cast<uint64_t>(BufferUsage::COMPOSER_OVERLAY | BufferUsage::CPU_READ_OFTEN);
463 
464     std::unique_ptr<Gralloc> gralloc;
465     const native_handle_t* buffer;
466     ASSERT_NO_FATAL_FAILURE(gralloc = std::make_unique<Gralloc>());
467     ASSERT_NO_FATAL_FAILURE(buffer = gralloc->allocate(mDisplayWidth, mDisplayHeight, 1,
468                                                        mReadbackPixelFormat, usage));
469 
470     Error error = mComposerClient->getRaw()->setReadbackBuffer(mInvalidDisplayId, buffer, nullptr);
471     ASSERT_EQ(Error::BAD_DISPLAY, error);
472 }
473 
474 /**
475  * Test IComposerClient::setReadbackBuffer
476  *
477  * Test that IComposerClient::setReadbackBuffer returns Error::BAD_PARAMETER
478  * when passed an invalid buffer handle
479  */
TEST_P(GraphicsComposerHidlTest,SetReadbackBufferBadParameter)480 TEST_P(GraphicsComposerHidlTest, SetReadbackBufferBadParameter) {
481     if (!mHasReadbackBuffer) {
482         return;
483     }
484 
485     Error error = mComposerClient->getRaw()->setReadbackBuffer(mPrimaryDisplay, nullptr, nullptr);
486     ASSERT_EQ(Error::BAD_PARAMETER, error);
487 }
488 
TEST_P(GraphicsComposerHidlTest,GetReadbackBufferFenceInactive)489 TEST_P(GraphicsComposerHidlTest, GetReadbackBufferFenceInactive) {
490     if (!mHasReadbackBuffer) {
491         return;
492     }
493 
494     mComposerClient->getRaw()->getReadbackBufferFence(
495         mPrimaryDisplay, [&](const auto& tmpError, const auto&) {
496             ASSERT_EQ(Error::UNSUPPORTED, tmpError) << "readback buffer is active";
497         });
498 }
499 
500 /**
501  * Test IComposerClient::Command::SET_LAYER_FLOAT_COLOR.
502  */
TEST_P(GraphicsComposerHidlCommandTest,SET_LAYER_FLOAT_COLOR)503 TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_FLOAT_COLOR) {
504     V2_1::Layer layer;
505     ASSERT_NO_FATAL_FAILURE(layer =
506                                 mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
507 
508     mWriter->selectDisplay(mPrimaryDisplay);
509     mWriter->selectLayer(layer);
510     mWriter->setLayerCompositionType(IComposerClient::Composition::SOLID_COLOR);
511     mWriter->setLayerFloatColor(IComposerClient::FloatColor{1.0, 1.0, 1.0, 1.0});
512     mWriter->setLayerFloatColor(IComposerClient::FloatColor{0.0, 0.0, 0.0, 0.0});
513     execute();
514 
515     if (mReader->mErrors.size() == 2 &&
516         static_cast<Error>(mReader->mErrors[0].second) == Error::UNSUPPORTED &&
517         static_cast<Error>(mReader->mErrors[1].second) == Error::UNSUPPORTED) {
518         mReader->mErrors.clear();
519         GTEST_SUCCEED() << "SetLayerFloatColor is not supported";
520         return;
521     }
522 
523     // ensure setting float color on layer with composition type that is not
524     // SOLID_COLOR does not fail
525     V2_1::Layer clientLayer;
526     ASSERT_NO_FATAL_FAILURE(clientLayer =
527                                 mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
528     mWriter->selectDisplay(mPrimaryDisplay);
529     mWriter->selectLayer(clientLayer);
530     mWriter->setLayerCompositionType(IComposerClient::Composition::CLIENT);
531     mWriter->setLayerFloatColor(IComposerClient::FloatColor{1.0, 1.0, 1.0, 1.0});
532     execute();
533 
534     // At this point we know that this function is supported so there should be
535     // no errors (checked upon TearDown)
536 }
537 
538 /**
539  * Test IComposerClient::getDataspaceSaturationMatrix.
540  */
TEST_P(GraphicsComposerHidlTest,GetDataspaceSaturationMatrix)541 TEST_P(GraphicsComposerHidlTest, GetDataspaceSaturationMatrix) {
542     auto matrix = mComposerClient->getDataspaceSaturationMatrix(Dataspace::SRGB_LINEAR);
543     // the last row is known
544     ASSERT_EQ(0.0f, matrix[12]);
545     ASSERT_EQ(0.0f, matrix[13]);
546     ASSERT_EQ(0.0f, matrix[14]);
547     ASSERT_EQ(1.0f, matrix[15]);
548 }
549 
550 /*
551  * Test IComposerClient::getDataspaceSaturationMatrix
552  *
553  * Test that IComposerClient::getDataspaceSaturationMatrix returns
554  * Error::BAD_PARAMETER when passed a dataspace other than
555  * Dataspace::SRGB_LINEAR
556  */
TEST_P(GraphicsComposerHidlTest,GetDataspaceSaturationMatrixBadParameter)557 TEST_P(GraphicsComposerHidlTest, GetDataspaceSaturationMatrixBadParameter) {
558     mComposerClient->getRaw()->getDataspaceSaturationMatrix(
559         Dataspace::UNKNOWN,
560         [&](const auto& tmpError, const auto&) { ASSERT_EQ(Error::BAD_PARAMETER, tmpError); });
561 }
562 
563 /**
564  * Test IComposerClient::getColorMode_2_2.
565  */
TEST_P(GraphicsComposerHidlTest,GetColorMode_2_2)566 TEST_P(GraphicsComposerHidlTest, GetColorMode_2_2) {
567     std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
568 
569     auto nativeMode = std::find(modes.cbegin(), modes.cend(), ColorMode::NATIVE);
570     EXPECT_NE(modes.cend(), nativeMode);
571 }
572 
573 /*
574  * Test IComposerClient::getColorMode_2_2
575  *
576  * Test that IComposerClient::getColorMode returns Error::BAD_DISPLAY when
577  * passed an invalid display handle
578  */
TEST_P(GraphicsComposerHidlTest,GetColorMode_2_2BadDisplay)579 TEST_P(GraphicsComposerHidlTest, GetColorMode_2_2BadDisplay) {
580     mComposerClient->getRaw()->getColorModes_2_2(
581         mInvalidDisplayId,
582         [&](const auto& tmpError, const auto&) { ASSERT_EQ(Error::BAD_DISPLAY, tmpError); });
583 }
584 
585 /**
586  * Test IComposerClient::getRenderIntents.
587  */
TEST_P(GraphicsComposerHidlTest,GetRenderIntents)588 TEST_P(GraphicsComposerHidlTest, GetRenderIntents) {
589     std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
590     for (auto mode : modes) {
591         std::vector<RenderIntent> intents =
592             mComposerClient->getRenderIntents(mPrimaryDisplay, mode);
593 
594         bool isHdr;
595         switch (mode) {
596             case ColorMode::BT2100_PQ:
597             case ColorMode::BT2100_HLG:
598                 isHdr = true;
599                 break;
600             default:
601                 isHdr = false;
602                 break;
603         }
604         RenderIntent requiredIntent =
605             isHdr ? RenderIntent::TONE_MAP_COLORIMETRIC : RenderIntent::COLORIMETRIC;
606 
607         auto iter = std::find(intents.cbegin(), intents.cend(), requiredIntent);
608         EXPECT_NE(intents.cend(), iter);
609     }
610 }
611 
612 /*
613  * Test IComposerClient::getRenderIntents
614  *
615  * Test that IComposerClient::getRenderIntent returns Error::BAD_DISPLAY when
616  * passed an invalid display handle
617  */
TEST_P(GraphicsComposerHidlTest,GetRenderIntentsBadDisplay)618 TEST_P(GraphicsComposerHidlTest, GetRenderIntentsBadDisplay) {
619     std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
620     for (auto mode : modes) {
621         mComposerClient->getRaw()->getRenderIntents(
622             mInvalidDisplayId, mode,
623             [&](const auto& tmpError, const auto&) { EXPECT_EQ(Error::BAD_DISPLAY, tmpError); });
624     }
625 }
626 
627 /*
628  * Test IComposerClient::getRenderIntents
629  *
630  * Test that IComposerClient::getRenderIntents returns Error::BAD_PARAMETER when
631  * pased either an invalid Color mode or an invalid Render Intent
632  */
TEST_P(GraphicsComposerHidlTest,GetRenderIntentsBadParameter)633 TEST_P(GraphicsComposerHidlTest, GetRenderIntentsBadParameter) {
634     mComposerClient->getRaw()->getRenderIntents(
635         mPrimaryDisplay, static_cast<ColorMode>(-1),
636         [&](const auto& tmpError, const auto&) { EXPECT_EQ(Error::BAD_PARAMETER, tmpError); });
637 }
638 
639 /**
640  * Test IComposerClient::setColorMode_2_2.
641  */
TEST_P(GraphicsComposerHidlTest,SetColorMode_2_2)642 TEST_P(GraphicsComposerHidlTest, SetColorMode_2_2) {
643     std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
644     for (auto mode : modes) {
645         std::vector<RenderIntent> intents =
646             mComposerClient->getRenderIntents(mPrimaryDisplay, mode);
647         for (auto intent : intents) {
648             mComposerClient->setColorMode(mPrimaryDisplay, mode, intent);
649         }
650     }
651 
652     mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::NATIVE, RenderIntent::COLORIMETRIC);
653 }
654 
655 /*
656  * Test IComposerClient::setColorMode_2_2
657  *
658  * Test that IComposerClient::setColorMode_2_2 returns an Error::BAD_DISPLAY
659  * when passed an invalid display handle
660  */
TEST_P(GraphicsComposerHidlTest,SetColorMode_2_2BadDisplay)661 TEST_P(GraphicsComposerHidlTest, SetColorMode_2_2BadDisplay) {
662     Error error = mComposerClient->getRaw()->setColorMode_2_2(mInvalidDisplayId, ColorMode::NATIVE,
663                                                               RenderIntent::COLORIMETRIC);
664 
665     ASSERT_EQ(Error::BAD_DISPLAY, error);
666 }
667 
668 /*
669  * Test IComposerClient::setColorMode_2_2
670  *
671  * Test that IComposerClient::setColorMode_2_2 returns Error::BAD_PARAMETER when
672  * passed an invalid Color mode or an invalid render intent
673  */
TEST_P(GraphicsComposerHidlTest,SetColorMode_2_2BadParameter)674 TEST_P(GraphicsComposerHidlTest, SetColorMode_2_2BadParameter) {
675     Error colorModeError = mComposerClient->getRaw()->setColorMode_2_2(
676         mPrimaryDisplay, static_cast<ColorMode>(-1), RenderIntent::COLORIMETRIC);
677     EXPECT_EQ(Error::BAD_PARAMETER, colorModeError);
678 
679     Error renderIntentError = mComposerClient->getRaw()->setColorMode_2_2(
680         mPrimaryDisplay, ColorMode::NATIVE, static_cast<RenderIntent>(-1));
681     EXPECT_EQ(Error::BAD_PARAMETER, renderIntentError);
682 }
683 
684 INSTANTIATE_TEST_SUITE_P(
685         PerInstance, GraphicsComposerHidlTest,
686         testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
687         android::hardware::PrintInstanceNameToString);
688 
689 INSTANTIATE_TEST_SUITE_P(
690         PerInstance, GraphicsComposerHidlCommandTest,
691         testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
692         android::hardware::PrintInstanceNameToString);
693 
694 }  // namespace
695 }  // namespace vts
696 }  // namespace V2_2
697 }  // namespace composer
698 }  // namespace graphics
699 }  // namespace hardware
700 }  // namespace android
701