blob: f72cf55300343a5dfd3b6044e82f35819c73a4ff [file] [log] [blame]
ramindani431aad42022-02-01 21:44:29 +00001/**
2 * Copyright (c) 2022, 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 */
Sally Qi2600d342022-08-16 12:46:17 -070016
ramindanid32ae8e2021-10-01 18:48:39 +000017#include <aidl/Gtest.h>
18#include <aidl/Vintf.h>
Ady Abraham3192f3d2021-12-03 16:08:56 -080019#include <aidl/android/hardware/graphics/common/BlendMode.h>
ramindani3335f7a2021-10-25 17:22:35 +000020#include <aidl/android/hardware/graphics/common/BufferUsage.h>
21#include <aidl/android/hardware/graphics/common/FRect.h>
Leon Scroggins IIIde057582022-01-13 12:26:00 -050022#include <aidl/android/hardware/graphics/common/PixelFormat.h>
ramindani3335f7a2021-10-25 17:22:35 +000023#include <aidl/android/hardware/graphics/common/Rect.h>
ramindani3335f7a2021-10-25 17:22:35 +000024#include <aidl/android/hardware/graphics/composer3/Composition.h>
ramindanid32ae8e2021-10-01 18:48:39 +000025#include <aidl/android/hardware/graphics/composer3/IComposer.h>
26#include <android-base/properties.h>
ramindania9780262021-10-01 18:48:39 +000027#include <android/binder_process.h>
Ady Abraham91c9d1a2021-12-15 18:14:45 -080028#include <android/hardware/graphics/composer3/ComposerClientReader.h>
29#include <android/hardware/graphics/composer3/ComposerClientWriter.h>
ramindanid32ae8e2021-10-01 18:48:39 +000030#include <binder/ProcessState.h>
31#include <gtest/gtest.h>
Ady Abraham72c5b502021-12-10 17:23:39 -080032#include <ui/Fence.h>
ramindani3335f7a2021-10-25 17:22:35 +000033#include <ui/GraphicBuffer.h>
34#include <ui/PixelFormat.h>
ramindani0291f112021-11-04 03:45:46 +000035#include <algorithm>
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -040036#include <iterator>
Joen Chene0a962c2023-08-28 09:49:11 +000037#include <mutex>
ramindani592b6512021-10-08 21:15:19 +000038#include <numeric>
ramindanid32ae8e2021-10-01 18:48:39 +000039#include <string>
ramindani1cb794e2021-10-13 20:45:23 +000040#include <thread>
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -040041#include <unordered_map>
ramindani458e53e2022-02-23 17:30:16 +000042#include "GraphicsComposerCallback.h"
43#include "VtsComposerClient.h"
ramindani3335f7a2021-10-25 17:22:35 +000044
ramindanid32ae8e2021-10-01 18:48:39 +000045#undef LOG_TAG
46#define LOG_TAG "VtsHalGraphicsComposer3_TargetTest"
47
48namespace aidl::android::hardware::graphics::composer3::vts {
ramindanid32ae8e2021-10-01 18:48:39 +000049
ramindani1cb794e2021-10-13 20:45:23 +000050using namespace std::chrono_literals;
51
ramindanidcfe3a82021-11-29 17:00:31 +000052using ::android::GraphicBuffer;
53using ::android::sp;
54
ramindanid32ae8e2021-10-01 18:48:39 +000055class GraphicsComposerAidlTest : public ::testing::TestWithParam<std::string> {
ramindania9780262021-10-01 18:48:39 +000056 protected:
57 void SetUp() override {
ramindani431aad42022-02-01 21:44:29 +000058 mComposerClient = std::make_unique<VtsComposerClient>(GetParam());
59 ASSERT_TRUE(mComposerClient->createClient().isOk());
Jason Macnake531a092022-01-20 08:49:09 -080060
ramindani431aad42022-02-01 21:44:29 +000061 const auto& [status, displays] = mComposerClient->getDisplays();
Jason Macnake531a092022-01-20 08:49:09 -080062 ASSERT_TRUE(status.isOk());
ramindani431aad42022-02-01 21:44:29 +000063 mDisplays = displays;
ramindanidcfe3a82021-11-29 17:00:31 +000064
ramindani3335f7a2021-10-25 17:22:35 +000065 // explicitly disable vsync
66 for (const auto& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +000067 EXPECT_TRUE(mComposerClient->setVsync(display.getDisplayId(), false).isOk());
ramindani3335f7a2021-10-25 17:22:35 +000068 }
ramindani431aad42022-02-01 21:44:29 +000069 mComposerClient->setVsyncAllowed(false);
ramindania9780262021-10-01 18:48:39 +000070 }
71
ramindani3335f7a2021-10-25 17:22:35 +000072 void TearDown() override {
Ady Abrahama00d2462023-12-26 14:21:20 -080073 ASSERT_TRUE(mComposerClient->tearDown(nullptr));
ramindani431aad42022-02-01 21:44:29 +000074 mComposerClient.reset();
ramindani3335f7a2021-10-25 17:22:35 +000075 }
ramindanic2b8d082021-11-06 02:03:50 +000076
ramindanid5751092022-04-22 22:30:20 +000077 void assertServiceSpecificError(const ScopedAStatus& status, int32_t serviceSpecificError) {
78 ASSERT_EQ(status.getExceptionCode(), EX_SERVICE_SPECIFIC);
79 ASSERT_EQ(status.getServiceSpecificError(), serviceSpecificError);
80 }
81
ramindani431aad42022-02-01 21:44:29 +000082 void Test_setContentTypeForDisplay(int64_t display,
83 const std::vector<ContentType>& supportedContentTypes,
84 ContentType contentType, const char* contentTypeStr) {
85 const bool contentTypeSupport =
86 std::find(supportedContentTypes.begin(), supportedContentTypes.end(),
87 contentType) != supportedContentTypes.end();
ramindanidcfe3a82021-11-29 17:00:31 +000088
89 if (!contentTypeSupport) {
ramindani431aad42022-02-01 21:44:29 +000090 const auto& status = mComposerClient->setContentType(display, contentType);
91 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +000092 EXPECT_NO_FATAL_FAILURE(
93 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
ramindanidcfe3a82021-11-29 17:00:31 +000094 GTEST_SUCCEED() << contentTypeStr << " content type is not supported on display "
95 << std::to_string(display) << ", skipping test";
96 return;
97 }
98
99 EXPECT_TRUE(mComposerClient->setContentType(display, contentType).isOk());
100 EXPECT_TRUE(mComposerClient->setContentType(display, ContentType::NONE).isOk());
101 }
102
ramindani431aad42022-02-01 21:44:29 +0000103 void Test_setContentType(ContentType contentType, const char* contentTypeStr) {
ramindanidcfe3a82021-11-29 17:00:31 +0000104 for (const auto& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +0000105 const auto& [status, supportedContentTypes] =
106 mComposerClient->getSupportedContentTypes(display.getDisplayId());
107 EXPECT_TRUE(status.isOk());
108 Test_setContentTypeForDisplay(display.getDisplayId(), supportedContentTypes,
109 contentType, contentTypeStr);
ramindanidcfe3a82021-11-29 17:00:31 +0000110 }
111 }
112
Jason Macnak325e8232022-01-24 14:48:55 -0800113 bool hasCapability(Capability capability) {
ramindani431aad42022-02-01 21:44:29 +0000114 const auto& [status, capabilities] = mComposerClient->getCapabilities();
115 EXPECT_TRUE(status.isOk());
Jason Macnak325e8232022-01-24 14:48:55 -0800116 return std::any_of(
117 capabilities.begin(), capabilities.end(),
118 [&](const Capability& activeCapability) { return activeCapability == capability; });
119 }
120
ramindani17c71102023-03-20 10:51:14 -0700121 int getInterfaceVersion() {
122 const auto& [versionStatus, version] = mComposerClient->getInterfaceVersion();
123 EXPECT_TRUE(versionStatus.isOk());
124 return version;
125 }
126
ramindani431aad42022-02-01 21:44:29 +0000127 const VtsDisplay& getPrimaryDisplay() const { return mDisplays[0]; }
ramindania9780262021-10-01 18:48:39 +0000128
ramindani431aad42022-02-01 21:44:29 +0000129 int64_t getPrimaryDisplayId() const { return getPrimaryDisplay().getDisplayId(); }
ramindania9780262021-10-01 18:48:39 +0000130
ramindani431aad42022-02-01 21:44:29 +0000131 int64_t getInvalidDisplayId() const { return mComposerClient->getInvalidDisplayId(); }
ramindani1cb794e2021-10-13 20:45:23 +0000132
ramindani431aad42022-02-01 21:44:29 +0000133 VtsDisplay& getEditablePrimaryDisplay() { return mDisplays[0]; }
ramindani0291f112021-11-04 03:45:46 +0000134
ramindani3335f7a2021-10-25 17:22:35 +0000135 struct TestParameters {
136 nsecs_t delayForChange;
137 bool refreshMiss;
138 };
139
ramindani431aad42022-02-01 21:44:29 +0000140 std::unique_ptr<VtsComposerClient> mComposerClient;
ramindani1cb794e2021-10-13 20:45:23 +0000141 std::vector<VtsDisplay> mDisplays;
ramindani3335f7a2021-10-25 17:22:35 +0000142 // use the slot count usually set by SF
143 static constexpr uint32_t kBufferSlotCount = 64;
ramindanid32ae8e2021-10-01 18:48:39 +0000144};
145
ramindani431aad42022-02-01 21:44:29 +0000146TEST_P(GraphicsComposerAidlTest, GetDisplayCapabilities_BadDisplay) {
147 const auto& [status, _] = mComposerClient->getDisplayCapabilities(getInvalidDisplayId());
ramindani5f696942021-10-14 16:24:18 +0000148
ramindani431aad42022-02-01 21:44:29 +0000149 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000150 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindania9780262021-10-01 18:48:39 +0000151}
152
ramindani431aad42022-02-01 21:44:29 +0000153TEST_P(GraphicsComposerAidlTest, GetDisplayCapabilities) {
ramindania9780262021-10-01 18:48:39 +0000154 for (const auto& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +0000155 const auto& [status, capabilities] =
156 mComposerClient->getDisplayCapabilities(display.getDisplayId());
ramindania9780262021-10-01 18:48:39 +0000157
ramindani431aad42022-02-01 21:44:29 +0000158 EXPECT_TRUE(status.isOk());
ramindania9780262021-10-01 18:48:39 +0000159 }
ramindanid32ae8e2021-10-01 18:48:39 +0000160}
161
ramindani2740bac2021-11-24 22:58:32 +0000162TEST_P(GraphicsComposerAidlTest, DumpDebugInfo) {
ramindani431aad42022-02-01 21:44:29 +0000163 ASSERT_TRUE(mComposerClient->dumpDebugInfo().isOk());
ramindani2740bac2021-11-24 22:58:32 +0000164}
165
166TEST_P(GraphicsComposerAidlTest, CreateClientSingleton) {
167 std::shared_ptr<IComposerClient> composerClient;
ramindani431aad42022-02-01 21:44:29 +0000168 const auto& status = mComposerClient->createClient();
ramindani2740bac2021-11-24 22:58:32 +0000169
ramindani431aad42022-02-01 21:44:29 +0000170 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000171 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_NO_RESOURCES));
ramindani2740bac2021-11-24 22:58:32 +0000172}
173
ramindani592b6512021-10-08 21:15:19 +0000174TEST_P(GraphicsComposerAidlTest, GetDisplayIdentificationData) {
ramindani431aad42022-02-01 21:44:29 +0000175 const auto& [status0, displayIdentification0] =
176 mComposerClient->getDisplayIdentificationData(getPrimaryDisplayId());
ramindanid5751092022-04-22 22:30:20 +0000177 if (!status0.isOk() && status0.getExceptionCode() == EX_SERVICE_SPECIFIC &&
178 status0.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
ramindani431aad42022-02-01 21:44:29 +0000179 GTEST_SUCCEED() << "Display identification data not supported, skipping test";
ramindani592b6512021-10-08 21:15:19 +0000180 return;
181 }
ramindani431aad42022-02-01 21:44:29 +0000182 ASSERT_TRUE(status0.isOk()) << "failed to get display identification data";
ramindani592b6512021-10-08 21:15:19 +0000183 ASSERT_FALSE(displayIdentification0.data.empty());
184
185 constexpr size_t kEdidBlockSize = 128;
186 ASSERT_TRUE(displayIdentification0.data.size() % kEdidBlockSize == 0)
187 << "EDID blob length is not a multiple of " << kEdidBlockSize;
188
189 const uint8_t kEdidHeader[] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};
190 ASSERT_TRUE(std::equal(std::begin(kEdidHeader), std::end(kEdidHeader),
191 displayIdentification0.data.begin()))
192 << "EDID blob doesn't start with the fixed EDID header";
193 ASSERT_EQ(0, std::accumulate(displayIdentification0.data.begin(),
194 displayIdentification0.data.begin() + kEdidBlockSize,
195 static_cast<uint8_t>(0)))
196 << "EDID base block doesn't checksum";
197
ramindani431aad42022-02-01 21:44:29 +0000198 const auto& [status1, displayIdentification1] =
199 mComposerClient->getDisplayIdentificationData(getPrimaryDisplayId());
200 ASSERT_TRUE(status1.isOk());
ramindani592b6512021-10-08 21:15:19 +0000201
202 ASSERT_EQ(displayIdentification0.port, displayIdentification1.port) << "ports are not stable";
203 ASSERT_TRUE(displayIdentification0.data.size() == displayIdentification1.data.size() &&
204 std::equal(displayIdentification0.data.begin(), displayIdentification0.data.end(),
205 displayIdentification1.data.begin()))
206 << "data is not stable";
207}
208
209TEST_P(GraphicsComposerAidlTest, GetHdrCapabilities) {
ramindani431aad42022-02-01 21:44:29 +0000210 const auto& [status, hdrCapabilities] =
211 mComposerClient->getHdrCapabilities(getPrimaryDisplayId());
ramindani592b6512021-10-08 21:15:19 +0000212
ramindani431aad42022-02-01 21:44:29 +0000213 ASSERT_TRUE(status.isOk());
214 EXPECT_TRUE(hdrCapabilities.maxLuminance >= hdrCapabilities.minLuminance);
ramindani592b6512021-10-08 21:15:19 +0000215}
216
217TEST_P(GraphicsComposerAidlTest, GetPerFrameMetadataKeys) {
ramindani431aad42022-02-01 21:44:29 +0000218 const auto& [status, keys] = mComposerClient->getPerFrameMetadataKeys(getPrimaryDisplayId());
ramindanid5751092022-04-22 22:30:20 +0000219 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
220 status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
ramindanic2b8d082021-11-06 02:03:50 +0000221 GTEST_SUCCEED() << "getPerFrameMetadataKeys is not supported";
222 return;
ramindani592b6512021-10-08 21:15:19 +0000223 }
ramindani431aad42022-02-01 21:44:29 +0000224
225 ASSERT_TRUE(status.isOk());
226 EXPECT_TRUE(keys.size() >= 0);
ramindani592b6512021-10-08 21:15:19 +0000227}
228
229TEST_P(GraphicsComposerAidlTest, GetReadbackBufferAttributes) {
ramindani431aad42022-02-01 21:44:29 +0000230 const auto& [status, _] = mComposerClient->getReadbackBufferAttributes(getPrimaryDisplayId());
ramindanid5751092022-04-22 22:30:20 +0000231 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
232 status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
ramindani431aad42022-02-01 21:44:29 +0000233 GTEST_SUCCEED() << "getReadbackBufferAttributes is not supported";
234 return;
ramindani592b6512021-10-08 21:15:19 +0000235 }
ramindani431aad42022-02-01 21:44:29 +0000236
237 ASSERT_TRUE(status.isOk());
ramindani592b6512021-10-08 21:15:19 +0000238}
239
240TEST_P(GraphicsComposerAidlTest, GetRenderIntents) {
ramindani431aad42022-02-01 21:44:29 +0000241 const auto& [status, modes] = mComposerClient->getColorModes(getPrimaryDisplayId());
242 EXPECT_TRUE(status.isOk());
ramindani592b6512021-10-08 21:15:19 +0000243
ramindani431aad42022-02-01 21:44:29 +0000244 for (auto mode : modes) {
245 const auto& [intentStatus, intents] =
246 mComposerClient->getRenderIntents(getPrimaryDisplayId(), mode);
247 EXPECT_TRUE(intentStatus.isOk());
ramindani592b6512021-10-08 21:15:19 +0000248 bool isHdr;
249 switch (mode) {
250 case ColorMode::BT2100_PQ:
251 case ColorMode::BT2100_HLG:
252 isHdr = true;
253 break;
254 default:
255 isHdr = false;
256 break;
257 }
258 RenderIntent requiredIntent =
259 isHdr ? RenderIntent::TONE_MAP_COLORIMETRIC : RenderIntent::COLORIMETRIC;
260
ramindani431aad42022-02-01 21:44:29 +0000261 const auto iter = std::find(intents.cbegin(), intents.cend(), requiredIntent);
ramindani592b6512021-10-08 21:15:19 +0000262 EXPECT_NE(intents.cend(), iter);
263 }
264}
265
ramindani431aad42022-02-01 21:44:29 +0000266TEST_P(GraphicsComposerAidlTest, GetRenderIntents_BadDisplay) {
267 const auto& [status, modes] = mComposerClient->getColorModes(getPrimaryDisplayId());
268 ASSERT_TRUE(status.isOk());
269
ramindani592b6512021-10-08 21:15:19 +0000270 for (auto mode : modes) {
ramindani431aad42022-02-01 21:44:29 +0000271 const auto& [intentStatus, _] =
272 mComposerClient->getRenderIntents(getInvalidDisplayId(), mode);
273
274 EXPECT_FALSE(intentStatus.isOk());
ramindanid5751092022-04-22 22:30:20 +0000275 EXPECT_NO_FATAL_FAILURE(
276 assertServiceSpecificError(intentStatus, IComposerClient::EX_BAD_DISPLAY));
ramindani592b6512021-10-08 21:15:19 +0000277 }
278}
279
ramindani431aad42022-02-01 21:44:29 +0000280TEST_P(GraphicsComposerAidlTest, GetRenderIntents_BadParameter) {
281 const auto& [status, _] =
282 mComposerClient->getRenderIntents(getPrimaryDisplayId(), static_cast<ColorMode>(-1));
283
284 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000285 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_PARAMETER));
ramindani592b6512021-10-08 21:15:19 +0000286}
287
288TEST_P(GraphicsComposerAidlTest, GetColorModes) {
ramindani431aad42022-02-01 21:44:29 +0000289 const auto& [status, colorModes] = mComposerClient->getColorModes(getPrimaryDisplayId());
290 ASSERT_TRUE(status.isOk());
ramindani592b6512021-10-08 21:15:19 +0000291
ramindani431aad42022-02-01 21:44:29 +0000292 const auto native = std::find(colorModes.cbegin(), colorModes.cend(), ColorMode::NATIVE);
293 EXPECT_NE(colorModes.cend(), native);
ramindani592b6512021-10-08 21:15:19 +0000294}
295
ramindani431aad42022-02-01 21:44:29 +0000296TEST_P(GraphicsComposerAidlTest, GetColorMode_BadDisplay) {
297 const auto& [status, _] = mComposerClient->getColorModes(getInvalidDisplayId());
ramindani592b6512021-10-08 21:15:19 +0000298
ramindani431aad42022-02-01 21:44:29 +0000299 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000300 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani592b6512021-10-08 21:15:19 +0000301}
302
303TEST_P(GraphicsComposerAidlTest, SetColorMode) {
ramindani431aad42022-02-01 21:44:29 +0000304 const auto& [status, colorModes] = mComposerClient->getColorModes(getPrimaryDisplayId());
305 EXPECT_TRUE(status.isOk());
306
ramindani592b6512021-10-08 21:15:19 +0000307 for (auto mode : colorModes) {
ramindani431aad42022-02-01 21:44:29 +0000308 const auto& [intentStatus, intents] =
309 mComposerClient->getRenderIntents(getPrimaryDisplayId(), mode);
310 EXPECT_TRUE(intentStatus.isOk()) << "failed to get render intents";
311
ramindani592b6512021-10-08 21:15:19 +0000312 for (auto intent : intents) {
ramindani431aad42022-02-01 21:44:29 +0000313 const auto modeStatus =
314 mComposerClient->setColorMode(getPrimaryDisplayId(), mode, intent);
315 EXPECT_TRUE(modeStatus.isOk() ||
ramindanid5751092022-04-22 22:30:20 +0000316 (modeStatus.getExceptionCode() == EX_SERVICE_SPECIFIC &&
317 IComposerClient::EX_UNSUPPORTED == modeStatus.getServiceSpecificError()))
ramindani592b6512021-10-08 21:15:19 +0000318 << "failed to set color mode";
319 }
320 }
321
ramindani431aad42022-02-01 21:44:29 +0000322 const auto modeStatus = mComposerClient->setColorMode(getPrimaryDisplayId(), ColorMode::NATIVE,
323 RenderIntent::COLORIMETRIC);
324 EXPECT_TRUE(modeStatus.isOk() ||
ramindanid5751092022-04-22 22:30:20 +0000325 (modeStatus.getExceptionCode() == EX_SERVICE_SPECIFIC &&
326 IComposerClient::EX_UNSUPPORTED == modeStatus.getServiceSpecificError()))
ramindani592b6512021-10-08 21:15:19 +0000327 << "failed to set color mode";
328}
329
ramindani431aad42022-02-01 21:44:29 +0000330TEST_P(GraphicsComposerAidlTest, SetColorMode_BadDisplay) {
331 const auto& [status, colorModes] = mComposerClient->getColorModes(getPrimaryDisplayId());
332 ASSERT_TRUE(status.isOk());
ramindani592b6512021-10-08 21:15:19 +0000333
ramindani431aad42022-02-01 21:44:29 +0000334 for (auto mode : colorModes) {
335 const auto& [intentStatus, intents] =
336 mComposerClient->getRenderIntents(getPrimaryDisplayId(), mode);
337 ASSERT_TRUE(intentStatus.isOk()) << "failed to get render intents";
338
339 for (auto intent : intents) {
340 auto const modeStatus =
341 mComposerClient->setColorMode(getInvalidDisplayId(), mode, intent);
342
343 EXPECT_FALSE(modeStatus.isOk());
ramindanid5751092022-04-22 22:30:20 +0000344 EXPECT_NO_FATAL_FAILURE(
345 assertServiceSpecificError(modeStatus, IComposerClient::EX_BAD_DISPLAY));
ramindani770d7082021-11-30 00:36:42 +0000346 }
347 }
ramindani592b6512021-10-08 21:15:19 +0000348}
349
ramindani431aad42022-02-01 21:44:29 +0000350TEST_P(GraphicsComposerAidlTest, SetColorMode_BadParameter) {
351 auto status = mComposerClient->setColorMode(getPrimaryDisplayId(), static_cast<ColorMode>(-1),
352 RenderIntent::COLORIMETRIC);
ramindani592b6512021-10-08 21:15:19 +0000353
ramindani431aad42022-02-01 21:44:29 +0000354 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000355 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_PARAMETER));
ramindani592b6512021-10-08 21:15:19 +0000356
ramindani431aad42022-02-01 21:44:29 +0000357 status = mComposerClient->setColorMode(getPrimaryDisplayId(), ColorMode::NATIVE,
358 static_cast<RenderIntent>(-1));
ramindani592b6512021-10-08 21:15:19 +0000359
ramindani431aad42022-02-01 21:44:29 +0000360 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000361 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_PARAMETER));
ramindani592b6512021-10-08 21:15:19 +0000362}
363
364TEST_P(GraphicsComposerAidlTest, GetDisplayedContentSamplingAttributes) {
ramindani431aad42022-02-01 21:44:29 +0000365 int constexpr kInvalid = -1;
366 const auto& [status, format] =
367 mComposerClient->getDisplayedContentSamplingAttributes(getPrimaryDisplayId());
ramindani592b6512021-10-08 21:15:19 +0000368
ramindanid5751092022-04-22 22:30:20 +0000369 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
370 status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
ramindani592b6512021-10-08 21:15:19 +0000371 SUCCEED() << "Device does not support optional extension. Test skipped";
372 return;
373 }
374
ramindani431aad42022-02-01 21:44:29 +0000375 ASSERT_TRUE(status.isOk());
376 EXPECT_NE(kInvalid, static_cast<int>(format.format));
377 EXPECT_NE(kInvalid, static_cast<int>(format.dataspace));
378 EXPECT_NE(kInvalid, static_cast<int>(format.componentMask));
ramindani592b6512021-10-08 21:15:19 +0000379};
380
381TEST_P(GraphicsComposerAidlTest, SetDisplayedContentSamplingEnabled) {
ramindani431aad42022-02-01 21:44:29 +0000382 int constexpr kMaxFrames = 10;
ramindani592b6512021-10-08 21:15:19 +0000383 FormatColorComponent enableAllComponents = FormatColorComponent::FORMAT_COMPONENT_0;
ramindani431aad42022-02-01 21:44:29 +0000384 auto status = mComposerClient->setDisplayedContentSamplingEnabled(
385 getPrimaryDisplayId(), /*isEnabled*/ true, enableAllComponents, kMaxFrames);
ramindanid5751092022-04-22 22:30:20 +0000386 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
387 status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
ramindani592b6512021-10-08 21:15:19 +0000388 SUCCEED() << "Device does not support optional extension. Test skipped";
389 return;
390 }
ramindani431aad42022-02-01 21:44:29 +0000391 EXPECT_TRUE(status.isOk());
ramindani592b6512021-10-08 21:15:19 +0000392
ramindani431aad42022-02-01 21:44:29 +0000393 status = mComposerClient->setDisplayedContentSamplingEnabled(
394 getPrimaryDisplayId(), /*isEnabled*/ false, enableAllComponents, kMaxFrames);
395 EXPECT_TRUE(status.isOk());
ramindani592b6512021-10-08 21:15:19 +0000396}
397
398TEST_P(GraphicsComposerAidlTest, GetDisplayedContentSample) {
ramindani431aad42022-02-01 21:44:29 +0000399 const auto& [status, displayContentSamplingAttributes] =
400 mComposerClient->getDisplayedContentSamplingAttributes(getPrimaryDisplayId());
ramindanid5751092022-04-22 22:30:20 +0000401 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
402 status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
ramindanideb059e2021-11-18 01:57:25 +0000403 SUCCEED() << "Sampling attributes aren't supported on this device, test skipped";
404 return;
405 }
ramindani592b6512021-10-08 21:15:19 +0000406
ramindani431aad42022-02-01 21:44:29 +0000407 int64_t constexpr kMaxFrames = 10;
408 int64_t constexpr kTimestamp = 0;
409 const auto& [sampleStatus, displayContentSample] = mComposerClient->getDisplayedContentSample(
410 getPrimaryDisplayId(), kMaxFrames, kTimestamp);
ramindanid5751092022-04-22 22:30:20 +0000411 if (!sampleStatus.isOk() && sampleStatus.getExceptionCode() == EX_SERVICE_SPECIFIC &&
ramindani431aad42022-02-01 21:44:29 +0000412 sampleStatus.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
ramindani592b6512021-10-08 21:15:19 +0000413 SUCCEED() << "Device does not support optional extension. Test skipped";
414 return;
415 }
416
ramindani431aad42022-02-01 21:44:29 +0000417 EXPECT_TRUE(sampleStatus.isOk());
418 const std::vector<std::vector<int64_t>> histogram = {
ramindani592b6512021-10-08 21:15:19 +0000419 displayContentSample.sampleComponent0, displayContentSample.sampleComponent1,
420 displayContentSample.sampleComponent2, displayContentSample.sampleComponent3};
421
ramindani3335f7a2021-10-25 17:22:35 +0000422 for (size_t i = 0; i < histogram.size(); i++) {
423 const bool shouldHaveHistogram =
424 static_cast<int>(displayContentSamplingAttributes.componentMask) & (1 << i);
425 EXPECT_EQ(shouldHaveHistogram, !histogram[i].empty());
ramindani592b6512021-10-08 21:15:19 +0000426 }
427}
428
ramindani431aad42022-02-01 21:44:29 +0000429TEST_P(GraphicsComposerAidlTest, GetDisplayConnectionType) {
430 const auto& [status, type] = mComposerClient->getDisplayConnectionType(getInvalidDisplayId());
431
432 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000433 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani431aad42022-02-01 21:44:29 +0000434
ramindani0291f112021-11-04 03:45:46 +0000435 for (const auto& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +0000436 const auto& [connectionTypeStatus, _] =
437 mComposerClient->getDisplayConnectionType(display.getDisplayId());
438 EXPECT_TRUE(connectionTypeStatus.isOk());
ramindani0291f112021-11-04 03:45:46 +0000439 }
440}
441
ramindani431aad42022-02-01 21:44:29 +0000442TEST_P(GraphicsComposerAidlTest, GetDisplayAttribute) {
ramindani0291f112021-11-04 03:45:46 +0000443 for (const auto& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +0000444 const auto& [status, configs] = mComposerClient->getDisplayConfigs(display.getDisplayId());
445 EXPECT_TRUE(status.isOk());
446
ramindani0291f112021-11-04 03:45:46 +0000447 for (const auto& config : configs) {
448 const std::array<DisplayAttribute, 4> requiredAttributes = {{
449 DisplayAttribute::WIDTH,
450 DisplayAttribute::HEIGHT,
451 DisplayAttribute::VSYNC_PERIOD,
452 DisplayAttribute::CONFIG_GROUP,
453 }};
ramindani0291f112021-11-04 03:45:46 +0000454 for (const auto& attribute : requiredAttributes) {
ramindani431aad42022-02-01 21:44:29 +0000455 const auto& [attribStatus, value] = mComposerClient->getDisplayAttribute(
456 display.getDisplayId(), config, attribute);
457 EXPECT_TRUE(attribStatus.isOk());
ramindani0291f112021-11-04 03:45:46 +0000458 EXPECT_NE(-1, value);
459 }
460
461 const std::array<DisplayAttribute, 2> optionalAttributes = {{
462 DisplayAttribute::DPI_X,
463 DisplayAttribute::DPI_Y,
464 }};
465 for (const auto& attribute : optionalAttributes) {
ramindani431aad42022-02-01 21:44:29 +0000466 const auto& [attribStatus, value] = mComposerClient->getDisplayAttribute(
467 display.getDisplayId(), config, attribute);
ramindanid5751092022-04-22 22:30:20 +0000468 EXPECT_TRUE(attribStatus.isOk() ||
469 (attribStatus.getExceptionCode() == EX_SERVICE_SPECIFIC &&
470 IComposerClient::EX_UNSUPPORTED ==
471 attribStatus.getServiceSpecificError()));
ramindani0291f112021-11-04 03:45:46 +0000472 }
473 }
474 }
475}
476
ramindani431aad42022-02-01 21:44:29 +0000477TEST_P(GraphicsComposerAidlTest, CheckConfigsAreValid) {
ramindani0291f112021-11-04 03:45:46 +0000478 for (const auto& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +0000479 const auto& [status, configs] = mComposerClient->getDisplayConfigs(display.getDisplayId());
480 EXPECT_TRUE(status.isOk());
ramindani0291f112021-11-04 03:45:46 +0000481
482 EXPECT_FALSE(std::any_of(configs.begin(), configs.end(), [](auto config) {
483 return config == IComposerClient::INVALID_CONFIGURATION;
484 }));
485 }
486}
487
ramindani431aad42022-02-01 21:44:29 +0000488TEST_P(GraphicsComposerAidlTest, GetDisplayVsyncPeriod_BadDisplay) {
489 const auto& [status, vsyncPeriodNanos] =
490 mComposerClient->getDisplayVsyncPeriod(getInvalidDisplayId());
491
492 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000493 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani0291f112021-11-04 03:45:46 +0000494}
495
ramindani431aad42022-02-01 21:44:29 +0000496TEST_P(GraphicsComposerAidlTest, SetActiveConfigWithConstraints_BadDisplay) {
ramindani0291f112021-11-04 03:45:46 +0000497 VsyncPeriodChangeConstraints constraints;
ramindani0291f112021-11-04 03:45:46 +0000498 constraints.seamlessRequired = false;
499 constraints.desiredTimeNanos = systemTime();
ramindani431aad42022-02-01 21:44:29 +0000500 auto invalidDisplay = VtsDisplay(getInvalidDisplayId());
ramindani0291f112021-11-04 03:45:46 +0000501
ramindani431aad42022-02-01 21:44:29 +0000502 const auto& [status, timeline] = mComposerClient->setActiveConfigWithConstraints(
503 &invalidDisplay, /*config*/ 0, constraints);
504
505 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000506 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani0291f112021-11-04 03:45:46 +0000507}
508
ramindani431aad42022-02-01 21:44:29 +0000509TEST_P(GraphicsComposerAidlTest, SetActiveConfigWithConstraints_BadConfig) {
ramindani0291f112021-11-04 03:45:46 +0000510 VsyncPeriodChangeConstraints constraints;
ramindani0291f112021-11-04 03:45:46 +0000511 constraints.seamlessRequired = false;
512 constraints.desiredTimeNanos = systemTime();
513
514 for (VtsDisplay& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +0000515 int32_t constexpr kInvalidConfigId = IComposerClient::INVALID_CONFIGURATION;
516 const auto& [status, _] = mComposerClient->setActiveConfigWithConstraints(
517 &display, kInvalidConfigId, constraints);
518
519 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000520 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_CONFIG));
ramindani0291f112021-11-04 03:45:46 +0000521 }
522}
523
ramindani431aad42022-02-01 21:44:29 +0000524TEST_P(GraphicsComposerAidlTest, SetBootDisplayConfig_BadDisplay) {
ramindani476314c2022-03-16 00:17:08 +0000525 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
526 GTEST_SUCCEED() << "Boot Display Config not supported";
527 return;
528 }
ramindani431aad42022-02-01 21:44:29 +0000529 const auto& status = mComposerClient->setBootDisplayConfig(getInvalidDisplayId(), /*config*/ 0);
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100530
ramindani431aad42022-02-01 21:44:29 +0000531 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000532 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100533}
534
ramindani431aad42022-02-01 21:44:29 +0000535TEST_P(GraphicsComposerAidlTest, SetBootDisplayConfig_BadConfig) {
ramindani476314c2022-03-16 00:17:08 +0000536 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
537 GTEST_SUCCEED() << "Boot Display Config not supported";
538 return;
539 }
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100540 for (VtsDisplay& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +0000541 int32_t constexpr kInvalidConfigId = IComposerClient::INVALID_CONFIGURATION;
542 const auto& status =
543 mComposerClient->setBootDisplayConfig(display.getDisplayId(), kInvalidConfigId);
544
545 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000546 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_CONFIG));
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100547 }
548}
549
ramindani431aad42022-02-01 21:44:29 +0000550TEST_P(GraphicsComposerAidlTest, SetBootDisplayConfig) {
ramindani476314c2022-03-16 00:17:08 +0000551 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
552 GTEST_SUCCEED() << "Boot Display Config not supported";
553 return;
554 }
ramindani431aad42022-02-01 21:44:29 +0000555 const auto& [status, configs] = mComposerClient->getDisplayConfigs(getPrimaryDisplayId());
556 EXPECT_TRUE(status.isOk());
557 for (const auto& config : configs) {
558 EXPECT_TRUE(mComposerClient->setBootDisplayConfig(getPrimaryDisplayId(), config).isOk());
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100559 }
560}
561
ramindani431aad42022-02-01 21:44:29 +0000562TEST_P(GraphicsComposerAidlTest, ClearBootDisplayConfig_BadDisplay) {
ramindani476314c2022-03-16 00:17:08 +0000563 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
564 GTEST_SUCCEED() << "Boot Display Config not supported";
565 return;
566 }
ramindani431aad42022-02-01 21:44:29 +0000567 const auto& status = mComposerClient->clearBootDisplayConfig(getInvalidDisplayId());
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100568
ramindani431aad42022-02-01 21:44:29 +0000569 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000570 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100571}
572
ramindani431aad42022-02-01 21:44:29 +0000573TEST_P(GraphicsComposerAidlTest, ClearBootDisplayConfig) {
ramindani476314c2022-03-16 00:17:08 +0000574 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
575 GTEST_SUCCEED() << "Boot Display Config not supported";
576 return;
577 }
ramindani431aad42022-02-01 21:44:29 +0000578 EXPECT_TRUE(mComposerClient->clearBootDisplayConfig(getPrimaryDisplayId()).isOk());
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100579}
580
ramindani431aad42022-02-01 21:44:29 +0000581TEST_P(GraphicsComposerAidlTest, GetPreferredBootDisplayConfig_BadDisplay) {
ramindani476314c2022-03-16 00:17:08 +0000582 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
583 GTEST_SUCCEED() << "Boot Display Config not supported";
584 return;
585 }
ramindani431aad42022-02-01 21:44:29 +0000586 const auto& [status, _] = mComposerClient->getPreferredBootDisplayConfig(getInvalidDisplayId());
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100587
ramindani431aad42022-02-01 21:44:29 +0000588 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000589 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100590}
591
ramindani431aad42022-02-01 21:44:29 +0000592TEST_P(GraphicsComposerAidlTest, GetPreferredBootDisplayConfig) {
ramindani476314c2022-03-16 00:17:08 +0000593 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
594 GTEST_SUCCEED() << "Boot Display Config not supported";
595 return;
596 }
ramindani431aad42022-02-01 21:44:29 +0000597 const auto& [status, preferredDisplayConfig] =
598 mComposerClient->getPreferredBootDisplayConfig(getPrimaryDisplayId());
599 EXPECT_TRUE(status.isOk());
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100600
ramindani431aad42022-02-01 21:44:29 +0000601 const auto& [configStatus, configs] = mComposerClient->getDisplayConfigs(getPrimaryDisplayId());
602
603 EXPECT_TRUE(configStatus.isOk());
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100604 EXPECT_NE(configs.end(), std::find(configs.begin(), configs.end(), preferredDisplayConfig));
605}
606
ramindani476314c2022-03-16 00:17:08 +0000607TEST_P(GraphicsComposerAidlTest, BootDisplayConfig_Unsupported) {
608 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
609 const auto& [configStatus, config] =
610 mComposerClient->getActiveConfig(getPrimaryDisplayId());
611 EXPECT_TRUE(configStatus.isOk());
612
613 auto status = mComposerClient->setBootDisplayConfig(getPrimaryDisplayId(), config);
614 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000615 EXPECT_NO_FATAL_FAILURE(
616 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
ramindani476314c2022-03-16 00:17:08 +0000617
618 status = mComposerClient->getPreferredBootDisplayConfig(getPrimaryDisplayId()).first;
619 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000620 EXPECT_NO_FATAL_FAILURE(
621 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
ramindani476314c2022-03-16 00:17:08 +0000622
623 status = mComposerClient->clearBootDisplayConfig(getPrimaryDisplayId());
624 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000625 EXPECT_NO_FATAL_FAILURE(
626 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
ramindani476314c2022-03-16 00:17:08 +0000627 }
628}
629
Kriti Dang3793ebd2022-12-05 13:03:49 +0100630TEST_P(GraphicsComposerAidlTest, GetHdrConversionCapabilities) {
631 if (!hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG)) {
632 GTEST_SUCCEED() << "HDR output conversion not supported";
633 return;
634 }
635 const auto& [status, conversionCapabilities] = mComposerClient->getHdrConversionCapabilities();
636 EXPECT_TRUE(status.isOk());
637}
638
639TEST_P(GraphicsComposerAidlTest, SetHdrConversionStrategy_Passthrough) {
640 if (!hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG)) {
641 GTEST_SUCCEED() << "HDR output conversion not supported";
642 return;
643 }
644 common::HdrConversionStrategy hdrConversionStrategy;
645 hdrConversionStrategy.set<common::HdrConversionStrategy::Tag::passthrough>(true);
Kriti Dang37622762023-02-09 18:15:37 +0100646 const auto& [status, preferredHdrOutputType] =
647 mComposerClient->setHdrConversionStrategy(hdrConversionStrategy);
Kriti Dang3793ebd2022-12-05 13:03:49 +0100648 EXPECT_TRUE(status.isOk());
Kriti Dang37622762023-02-09 18:15:37 +0100649 EXPECT_EQ(common::Hdr::INVALID, preferredHdrOutputType);
Kriti Dang3793ebd2022-12-05 13:03:49 +0100650}
651
652TEST_P(GraphicsComposerAidlTest, SetHdrConversionStrategy_Force) {
653 if (!hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG)) {
654 GTEST_SUCCEED() << "HDR output conversion not supported";
655 return;
656 }
657 const auto& [status, conversionCapabilities] = mComposerClient->getHdrConversionCapabilities();
Kriti Dang79bbec92023-05-04 17:54:26 +0200658 const auto& [status2, hdrCapabilities] =
659 mComposerClient->getHdrCapabilities(getPrimaryDisplayId());
660 const auto& hdrTypes = hdrCapabilities.types;
Kriti Dang3793ebd2022-12-05 13:03:49 +0100661 for (auto conversionCapability : conversionCapabilities) {
Kriti Dang5fcddd72023-03-07 14:55:51 +0100662 if (conversionCapability.outputType != common::Hdr::INVALID) {
Kriti Dang79bbec92023-05-04 17:54:26 +0200663 if (std::find(hdrTypes.begin(), hdrTypes.end(), conversionCapability.outputType) ==
664 hdrTypes.end()) {
665 continue;
666 }
Kriti Dang3793ebd2022-12-05 13:03:49 +0100667 common::HdrConversionStrategy hdrConversionStrategy;
668 hdrConversionStrategy.set<common::HdrConversionStrategy::Tag::forceHdrConversion>(
Kriti Dang5fcddd72023-03-07 14:55:51 +0100669 conversionCapability.outputType);
Kriti Dang37622762023-02-09 18:15:37 +0100670 const auto& [statusSet, preferredHdrOutputType] =
Kriti Dang3793ebd2022-12-05 13:03:49 +0100671 mComposerClient->setHdrConversionStrategy(hdrConversionStrategy);
Kriti Dang37622762023-02-09 18:15:37 +0100672 EXPECT_TRUE(statusSet.isOk());
673 EXPECT_EQ(common::Hdr::INVALID, preferredHdrOutputType);
Kriti Dang3793ebd2022-12-05 13:03:49 +0100674 }
675 }
676}
677
678TEST_P(GraphicsComposerAidlTest, SetHdrConversionStrategy_Auto) {
679 if (!hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG)) {
680 GTEST_SUCCEED() << "HDR output conversion not supported";
681 return;
682 }
683 const auto& [status, conversionCapabilities] = mComposerClient->getHdrConversionCapabilities();
Kriti Dang79bbec92023-05-04 17:54:26 +0200684 const auto& [status2, hdrCapabilities] =
685 mComposerClient->getHdrCapabilities(getPrimaryDisplayId());
686 if (hdrCapabilities.types.size() <= 0) {
687 return;
688 }
Kriti Dang3793ebd2022-12-05 13:03:49 +0100689 std::vector<aidl::android::hardware::graphics::common::Hdr> autoHdrTypes;
690 for (auto conversionCapability : conversionCapabilities) {
Kriti Dang5fcddd72023-03-07 14:55:51 +0100691 if (conversionCapability.outputType != common::Hdr::INVALID) {
692 autoHdrTypes.push_back(conversionCapability.outputType);
Kriti Dang3793ebd2022-12-05 13:03:49 +0100693 }
694 }
695 common::HdrConversionStrategy hdrConversionStrategy;
696 hdrConversionStrategy.set<common::HdrConversionStrategy::Tag::autoAllowedHdrTypes>(
697 autoHdrTypes);
Kriti Dang37622762023-02-09 18:15:37 +0100698 const auto& [statusSet, preferredHdrOutputType] =
699 mComposerClient->setHdrConversionStrategy(hdrConversionStrategy);
700 EXPECT_TRUE(statusSet.isOk());
701 EXPECT_NE(common::Hdr::INVALID, preferredHdrOutputType);
Kriti Dang3793ebd2022-12-05 13:03:49 +0100702}
703
ramindani431aad42022-02-01 21:44:29 +0000704TEST_P(GraphicsComposerAidlTest, SetAutoLowLatencyMode_BadDisplay) {
705 auto status = mComposerClient->setAutoLowLatencyMode(getInvalidDisplayId(), /*isEnabled*/ true);
706 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000707 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani431aad42022-02-01 21:44:29 +0000708
709 status = mComposerClient->setAutoLowLatencyMode(getInvalidDisplayId(), /*isEnabled*/ false);
710 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000711 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani0291f112021-11-04 03:45:46 +0000712}
713
ramindani431aad42022-02-01 21:44:29 +0000714TEST_P(GraphicsComposerAidlTest, SetAutoLowLatencyMode) {
ramindani0291f112021-11-04 03:45:46 +0000715 for (const auto& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +0000716 const auto& [status, capabilities] =
717 mComposerClient->getDisplayCapabilities(display.getDisplayId());
718 ASSERT_TRUE(status.isOk());
ramindani0291f112021-11-04 03:45:46 +0000719
720 const bool allmSupport =
721 std::find(capabilities.begin(), capabilities.end(),
722 DisplayCapability::AUTO_LOW_LATENCY_MODE) != capabilities.end();
723
724 if (!allmSupport) {
ramindani431aad42022-02-01 21:44:29 +0000725 const auto& statusIsOn = mComposerClient->setAutoLowLatencyMode(display.getDisplayId(),
726 /*isEnabled*/ true);
727 EXPECT_FALSE(statusIsOn.isOk());
ramindanid5751092022-04-22 22:30:20 +0000728 EXPECT_NO_FATAL_FAILURE(
729 assertServiceSpecificError(statusIsOn, IComposerClient::EX_UNSUPPORTED));
ramindani431aad42022-02-01 21:44:29 +0000730 const auto& statusIsOff = mComposerClient->setAutoLowLatencyMode(display.getDisplayId(),
731 /*isEnabled*/ false);
732 EXPECT_FALSE(statusIsOff.isOk());
ramindanid5751092022-04-22 22:30:20 +0000733 EXPECT_NO_FATAL_FAILURE(
734 assertServiceSpecificError(statusIsOff, IComposerClient::EX_UNSUPPORTED));
ramindani0291f112021-11-04 03:45:46 +0000735 GTEST_SUCCEED() << "Auto Low Latency Mode is not supported on display "
ramindani431aad42022-02-01 21:44:29 +0000736 << std::to_string(display.getDisplayId()) << ", skipping test";
ramindani0291f112021-11-04 03:45:46 +0000737 return;
738 }
739
ramindani431aad42022-02-01 21:44:29 +0000740 EXPECT_TRUE(mComposerClient->setAutoLowLatencyMode(display.getDisplayId(), true).isOk());
741 EXPECT_TRUE(mComposerClient->setAutoLowLatencyMode(display.getDisplayId(), false).isOk());
ramindani0291f112021-11-04 03:45:46 +0000742 }
743}
744
ramindani431aad42022-02-01 21:44:29 +0000745TEST_P(GraphicsComposerAidlTest, GetSupportedContentTypes_BadDisplay) {
746 const auto& [status, _] = mComposerClient->getSupportedContentTypes(getInvalidDisplayId());
747
748 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000749 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani0291f112021-11-04 03:45:46 +0000750}
751
ramindani431aad42022-02-01 21:44:29 +0000752TEST_P(GraphicsComposerAidlTest, GetSupportedContentTypes) {
ramindani0291f112021-11-04 03:45:46 +0000753 for (const auto& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +0000754 const auto& [status, supportedContentTypes] =
755 mComposerClient->getSupportedContentTypes(display.getDisplayId());
756 ASSERT_TRUE(status.isOk());
ramindani0291f112021-11-04 03:45:46 +0000757
758 const bool noneSupported =
759 std::find(supportedContentTypes.begin(), supportedContentTypes.end(),
760 ContentType::NONE) != supportedContentTypes.end();
ramindani431aad42022-02-01 21:44:29 +0000761
ramindani0291f112021-11-04 03:45:46 +0000762 EXPECT_FALSE(noneSupported);
763 }
764}
765
ramindani431aad42022-02-01 21:44:29 +0000766TEST_P(GraphicsComposerAidlTest, SetContentTypeNoneAlwaysAccepted) {
ramindani0291f112021-11-04 03:45:46 +0000767 for (const auto& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +0000768 EXPECT_TRUE(
769 mComposerClient->setContentType(display.getDisplayId(), ContentType::NONE).isOk());
ramindani0291f112021-11-04 03:45:46 +0000770 }
771}
772
ramindani431aad42022-02-01 21:44:29 +0000773TEST_P(GraphicsComposerAidlTest, SetContentType_BadDisplay) {
ramindani0291f112021-11-04 03:45:46 +0000774 constexpr ContentType types[] = {ContentType::NONE, ContentType::GRAPHICS, ContentType::PHOTO,
775 ContentType::CINEMA, ContentType::GAME};
776 for (const auto& type : types) {
ramindani431aad42022-02-01 21:44:29 +0000777 const auto& status = mComposerClient->setContentType(getInvalidDisplayId(), type);
ramindani0291f112021-11-04 03:45:46 +0000778
ramindani431aad42022-02-01 21:44:29 +0000779 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000780 EXPECT_NO_FATAL_FAILURE(
781 assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani0291f112021-11-04 03:45:46 +0000782 }
783}
784
ramindani431aad42022-02-01 21:44:29 +0000785TEST_P(GraphicsComposerAidlTest, SetGraphicsContentType) {
ramindani0291f112021-11-04 03:45:46 +0000786 Test_setContentType(ContentType::GRAPHICS, "GRAPHICS");
787}
788
ramindani431aad42022-02-01 21:44:29 +0000789TEST_P(GraphicsComposerAidlTest, SetPhotoContentType) {
ramindani0291f112021-11-04 03:45:46 +0000790 Test_setContentType(ContentType::PHOTO, "PHOTO");
791}
792
ramindani431aad42022-02-01 21:44:29 +0000793TEST_P(GraphicsComposerAidlTest, SetCinemaContentType) {
ramindani0291f112021-11-04 03:45:46 +0000794 Test_setContentType(ContentType::CINEMA, "CINEMA");
795}
796
ramindani431aad42022-02-01 21:44:29 +0000797TEST_P(GraphicsComposerAidlTest, SetGameContentType) {
ramindani0291f112021-11-04 03:45:46 +0000798 Test_setContentType(ContentType::GAME, "GAME");
799}
800
ramindanic2b8d082021-11-06 02:03:50 +0000801TEST_P(GraphicsComposerAidlTest, CreateVirtualDisplay) {
ramindani431aad42022-02-01 21:44:29 +0000802 const auto& [status, maxVirtualDisplayCount] = mComposerClient->getMaxVirtualDisplayCount();
803 EXPECT_TRUE(status.isOk());
804
ramindanic2b8d082021-11-06 02:03:50 +0000805 if (maxVirtualDisplayCount == 0) {
806 GTEST_SUCCEED() << "no virtual display support";
807 return;
808 }
809
ramindani431aad42022-02-01 21:44:29 +0000810 const auto& [virtualDisplayStatus, virtualDisplay] = mComposerClient->createVirtualDisplay(
811 /*width*/ 64, /*height*/ 64, common::PixelFormat::IMPLEMENTATION_DEFINED,
812 kBufferSlotCount);
ramindanic2b8d082021-11-06 02:03:50 +0000813
ramindani431aad42022-02-01 21:44:29 +0000814 ASSERT_TRUE(virtualDisplayStatus.isOk());
ramindanic2b8d082021-11-06 02:03:50 +0000815 EXPECT_TRUE(mComposerClient->destroyVirtualDisplay(virtualDisplay.display).isOk());
816}
817
ramindani431aad42022-02-01 21:44:29 +0000818TEST_P(GraphicsComposerAidlTest, DestroyVirtualDisplay_BadDisplay) {
819 const auto& [status, maxDisplayCount] = mComposerClient->getMaxVirtualDisplayCount();
820 EXPECT_TRUE(status.isOk());
821
ramindani2740bac2021-11-24 22:58:32 +0000822 if (maxDisplayCount == 0) {
823 GTEST_SUCCEED() << "no virtual display support";
824 return;
825 }
ramindani2740bac2021-11-24 22:58:32 +0000826
ramindani431aad42022-02-01 21:44:29 +0000827 const auto& destroyStatus = mComposerClient->destroyVirtualDisplay(getInvalidDisplayId());
828
829 EXPECT_FALSE(destroyStatus.isOk());
ramindanid5751092022-04-22 22:30:20 +0000830 EXPECT_NO_FATAL_FAILURE(
831 assertServiceSpecificError(destroyStatus, IComposerClient::EX_BAD_DISPLAY));
ramindani2740bac2021-11-24 22:58:32 +0000832}
833
834TEST_P(GraphicsComposerAidlTest, CreateLayer) {
Ady Abrahama00d2462023-12-26 14:21:20 -0800835 if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
836 GTEST_SKIP() << "Create layer will be tested in GraphicsComposerAidlBatchedCommandTest";
837 return;
838 }
839
ramindani431aad42022-02-01 21:44:29 +0000840 const auto& [status, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -0800841 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, nullptr);
ramindani2740bac2021-11-24 22:58:32 +0000842
ramindani431aad42022-02-01 21:44:29 +0000843 EXPECT_TRUE(status.isOk());
Ady Abrahama00d2462023-12-26 14:21:20 -0800844 EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, nullptr).isOk());
ramindani2740bac2021-11-24 22:58:32 +0000845}
846
ramindani431aad42022-02-01 21:44:29 +0000847TEST_P(GraphicsComposerAidlTest, CreateLayer_BadDisplay) {
Ady Abrahama00d2462023-12-26 14:21:20 -0800848 if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
849 GTEST_SKIP() << "Create layer will be tested in GraphicsComposerAidlBatchedCommandTest";
850 return;
851 }
852
853 const auto& [status, _] =
854 mComposerClient->createLayer(getInvalidDisplayId(), kBufferSlotCount, nullptr);
ramindani2740bac2021-11-24 22:58:32 +0000855
ramindani431aad42022-02-01 21:44:29 +0000856 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000857 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani2740bac2021-11-24 22:58:32 +0000858}
859
ramindani431aad42022-02-01 21:44:29 +0000860TEST_P(GraphicsComposerAidlTest, DestroyLayer_BadDisplay) {
Ady Abrahama00d2462023-12-26 14:21:20 -0800861 if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
862 GTEST_SKIP() << "Destroy layer will be tested in GraphicsComposerAidlBatchedCommandTest";
863 return;
864 }
865
ramindani431aad42022-02-01 21:44:29 +0000866 const auto& [status, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -0800867 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, nullptr);
ramindani431aad42022-02-01 21:44:29 +0000868 EXPECT_TRUE(status.isOk());
ramindani2740bac2021-11-24 22:58:32 +0000869
Ady Abrahama00d2462023-12-26 14:21:20 -0800870 const auto& destroyStatus =
871 mComposerClient->destroyLayer(getInvalidDisplayId(), layer, nullptr);
ramindani2740bac2021-11-24 22:58:32 +0000872
ramindani431aad42022-02-01 21:44:29 +0000873 EXPECT_FALSE(destroyStatus.isOk());
ramindanid5751092022-04-22 22:30:20 +0000874 EXPECT_NO_FATAL_FAILURE(
875 assertServiceSpecificError(destroyStatus, IComposerClient::EX_BAD_DISPLAY));
Ady Abrahama00d2462023-12-26 14:21:20 -0800876 ASSERT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, nullptr).isOk());
ramindani2740bac2021-11-24 22:58:32 +0000877}
878
ramindani431aad42022-02-01 21:44:29 +0000879TEST_P(GraphicsComposerAidlTest, DestroyLayer_BadLayerError) {
Ady Abrahama00d2462023-12-26 14:21:20 -0800880 if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
881 GTEST_SKIP() << "Destroy layer will be tested in GraphicsComposerAidlBatchedCommandTest";
882 return;
883 }
884
ramindani2740bac2021-11-24 22:58:32 +0000885 // We haven't created any layers yet, so any id should be invalid
Ady Abrahama00d2462023-12-26 14:21:20 -0800886 const auto& status = mComposerClient->destroyLayer(getPrimaryDisplayId(), /*layer*/ 1, nullptr);
ramindani2740bac2021-11-24 22:58:32 +0000887
ramindani431aad42022-02-01 21:44:29 +0000888 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000889 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_LAYER));
ramindani2740bac2021-11-24 22:58:32 +0000890}
891
ramindani431aad42022-02-01 21:44:29 +0000892TEST_P(GraphicsComposerAidlTest, GetActiveConfig_BadDisplay) {
893 const auto& [status, _] = mComposerClient->getActiveConfig(getInvalidDisplayId());
ramindani2740bac2021-11-24 22:58:32 +0000894
ramindani431aad42022-02-01 21:44:29 +0000895 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000896 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani2740bac2021-11-24 22:58:32 +0000897}
898
899TEST_P(GraphicsComposerAidlTest, GetDisplayConfig) {
ramindani431aad42022-02-01 21:44:29 +0000900 const auto& [status, _] = mComposerClient->getDisplayConfigs(getPrimaryDisplayId());
901 EXPECT_TRUE(status.isOk());
ramindani2740bac2021-11-24 22:58:32 +0000902}
903
ramindani431aad42022-02-01 21:44:29 +0000904TEST_P(GraphicsComposerAidlTest, GetDisplayConfig_BadDisplay) {
905 const auto& [status, _] = mComposerClient->getDisplayConfigs(getInvalidDisplayId());
ramindani2740bac2021-11-24 22:58:32 +0000906
ramindani431aad42022-02-01 21:44:29 +0000907 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000908 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani2740bac2021-11-24 22:58:32 +0000909}
910
911TEST_P(GraphicsComposerAidlTest, GetDisplayName) {
ramindani431aad42022-02-01 21:44:29 +0000912 const auto& [status, _] = mComposerClient->getDisplayName(getPrimaryDisplayId());
913 EXPECT_TRUE(status.isOk());
ramindani2740bac2021-11-24 22:58:32 +0000914}
915
ramindani431aad42022-02-01 21:44:29 +0000916TEST_P(GraphicsComposerAidlTest, GetDisplayPhysicalOrientation_BadDisplay) {
917 const auto& [status, _] = mComposerClient->getDisplayPhysicalOrientation(getInvalidDisplayId());
Ady Abrahamae12e382022-01-13 18:06:21 -0800918
ramindani431aad42022-02-01 21:44:29 +0000919 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000920 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
Ady Abrahamae12e382022-01-13 18:06:21 -0800921}
922
923TEST_P(GraphicsComposerAidlTest, GetDisplayPhysicalOrientation) {
924 const auto allowedDisplayOrientations = std::array<Transform, 4>{
925 Transform::NONE,
926 Transform::ROT_90,
927 Transform::ROT_180,
928 Transform::ROT_270,
929 };
930
ramindani431aad42022-02-01 21:44:29 +0000931 const auto& [status, displayOrientation] =
932 mComposerClient->getDisplayPhysicalOrientation(getPrimaryDisplayId());
Ady Abrahamae12e382022-01-13 18:06:21 -0800933
ramindani431aad42022-02-01 21:44:29 +0000934 EXPECT_TRUE(status.isOk());
Ady Abrahamae12e382022-01-13 18:06:21 -0800935 EXPECT_NE(std::find(allowedDisplayOrientations.begin(), allowedDisplayOrientations.end(),
936 displayOrientation),
937 allowedDisplayOrientations.end());
938}
939
ramindani2740bac2021-11-24 22:58:32 +0000940TEST_P(GraphicsComposerAidlTest, SetClientTargetSlotCount) {
ramindani431aad42022-02-01 21:44:29 +0000941 EXPECT_TRUE(mComposerClient->setClientTargetSlotCount(getPrimaryDisplayId(), kBufferSlotCount)
942 .isOk());
ramindani2740bac2021-11-24 22:58:32 +0000943}
944
945TEST_P(GraphicsComposerAidlTest, SetActiveConfig) {
ramindani431aad42022-02-01 21:44:29 +0000946 const auto& [status, configs] = mComposerClient->getDisplayConfigs(getPrimaryDisplayId());
947 EXPECT_TRUE(status.isOk());
948
949 for (const auto& config : configs) {
950 auto display = getEditablePrimaryDisplay();
951 EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config).isOk());
952 const auto& [configStatus, config1] =
953 mComposerClient->getActiveConfig(getPrimaryDisplayId());
954 EXPECT_TRUE(configStatus.isOk());
ramindani2740bac2021-11-24 22:58:32 +0000955 EXPECT_EQ(config, config1);
956 }
957}
958
959TEST_P(GraphicsComposerAidlTest, SetActiveConfigPowerCycle) {
ramindani431aad42022-02-01 21:44:29 +0000960 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
961 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
ramindani2740bac2021-11-24 22:58:32 +0000962
ramindani431aad42022-02-01 21:44:29 +0000963 const auto& [status, configs] = mComposerClient->getDisplayConfigs(getPrimaryDisplayId());
964 EXPECT_TRUE(status.isOk());
965
966 for (const auto& config : configs) {
967 auto display = getEditablePrimaryDisplay();
968 EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config).isOk());
969 const auto& [config1Status, config1] =
970 mComposerClient->getActiveConfig(getPrimaryDisplayId());
971 EXPECT_TRUE(config1Status.isOk());
ramindani2740bac2021-11-24 22:58:32 +0000972 EXPECT_EQ(config, config1);
973
ramindani431aad42022-02-01 21:44:29 +0000974 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
975 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
976 const auto& [config2Status, config2] =
977 mComposerClient->getActiveConfig(getPrimaryDisplayId());
978 EXPECT_TRUE(config2Status.isOk());
979 EXPECT_EQ(config, config2);
ramindani2740bac2021-11-24 22:58:32 +0000980 }
981}
982
ramindani2740bac2021-11-24 22:58:32 +0000983TEST_P(GraphicsComposerAidlTest, SetPowerModeUnsupported) {
ramindani431aad42022-02-01 21:44:29 +0000984 const auto& [status, capabilities] =
985 mComposerClient->getDisplayCapabilities(getPrimaryDisplayId());
986 ASSERT_TRUE(status.isOk());
987
Ady Abraham6679baf2021-12-08 18:28:27 -0800988 const bool isDozeSupported = std::find(capabilities.begin(), capabilities.end(),
989 DisplayCapability::DOZE) != capabilities.end();
990 const bool isSuspendSupported = std::find(capabilities.begin(), capabilities.end(),
991 DisplayCapability::SUSPEND) != capabilities.end();
ramindani2740bac2021-11-24 22:58:32 +0000992
ramindani431aad42022-02-01 21:44:29 +0000993 if (!isDozeSupported) {
994 const auto& powerModeDozeStatus =
995 mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::DOZE);
996 EXPECT_FALSE(powerModeDozeStatus.isOk());
ramindanid5751092022-04-22 22:30:20 +0000997 EXPECT_NO_FATAL_FAILURE(
998 assertServiceSpecificError(powerModeDozeStatus, IComposerClient::EX_UNSUPPORTED));
ramindani431aad42022-02-01 21:44:29 +0000999
1000 const auto& powerModeDozeSuspendStatus =
1001 mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::DOZE_SUSPEND);
1002 EXPECT_FALSE(powerModeDozeSuspendStatus.isOk());
ramindanid5751092022-04-22 22:30:20 +00001003 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(powerModeDozeSuspendStatus,
1004 IComposerClient::EX_UNSUPPORTED));
ramindani2740bac2021-11-24 22:58:32 +00001005 }
Ady Abraham6679baf2021-12-08 18:28:27 -08001006
1007 if (!isSuspendSupported) {
ramindani431aad42022-02-01 21:44:29 +00001008 const auto& powerModeSuspendStatus =
1009 mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON_SUSPEND);
1010 EXPECT_FALSE(powerModeSuspendStatus.isOk());
ramindanid5751092022-04-22 22:30:20 +00001011 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(powerModeSuspendStatus,
1012 IComposerClient::EX_UNSUPPORTED));
Ady Abraham6679baf2021-12-08 18:28:27 -08001013
ramindani431aad42022-02-01 21:44:29 +00001014 const auto& powerModeDozeSuspendStatus =
1015 mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::DOZE_SUSPEND);
1016 EXPECT_FALSE(powerModeDozeSuspendStatus.isOk());
ramindanid5751092022-04-22 22:30:20 +00001017 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(powerModeDozeSuspendStatus,
1018 IComposerClient::EX_UNSUPPORTED));
Ady Abraham6679baf2021-12-08 18:28:27 -08001019 }
ramindani2740bac2021-11-24 22:58:32 +00001020}
1021
1022TEST_P(GraphicsComposerAidlTest, SetVsyncEnabled) {
ramindani431aad42022-02-01 21:44:29 +00001023 mComposerClient->setVsyncAllowed(true);
ramindani2740bac2021-11-24 22:58:32 +00001024
ramindani431aad42022-02-01 21:44:29 +00001025 EXPECT_TRUE(mComposerClient->setVsync(getPrimaryDisplayId(), true).isOk());
ramindani2740bac2021-11-24 22:58:32 +00001026 usleep(60 * 1000);
ramindani431aad42022-02-01 21:44:29 +00001027 EXPECT_TRUE(mComposerClient->setVsync(getPrimaryDisplayId(), false).isOk());
ramindani2740bac2021-11-24 22:58:32 +00001028
ramindani431aad42022-02-01 21:44:29 +00001029 mComposerClient->setVsyncAllowed(false);
ramindani2740bac2021-11-24 22:58:32 +00001030}
1031
ramindanic2b8d082021-11-06 02:03:50 +00001032TEST_P(GraphicsComposerAidlTest, SetPowerMode) {
ramindani431aad42022-02-01 21:44:29 +00001033 const auto& [status, capabilities] =
1034 mComposerClient->getDisplayCapabilities(getPrimaryDisplayId());
1035 ASSERT_TRUE(status.isOk());
1036
Ady Abraham6679baf2021-12-08 18:28:27 -08001037 const bool isDozeSupported = std::find(capabilities.begin(), capabilities.end(),
1038 DisplayCapability::DOZE) != capabilities.end();
1039 const bool isSuspendSupported = std::find(capabilities.begin(), capabilities.end(),
1040 DisplayCapability::SUSPEND) != capabilities.end();
1041
ramindanic2b8d082021-11-06 02:03:50 +00001042 std::vector<PowerMode> modes;
1043 modes.push_back(PowerMode::OFF);
ramindanic2b8d082021-11-06 02:03:50 +00001044 modes.push_back(PowerMode::ON);
1045
Ady Abraham6679baf2021-12-08 18:28:27 -08001046 if (isSuspendSupported) {
1047 modes.push_back(PowerMode::ON_SUSPEND);
1048 }
1049
ramindani770d7082021-11-30 00:36:42 +00001050 if (isDozeSupported) {
1051 modes.push_back(PowerMode::DOZE);
Ady Abraham6679baf2021-12-08 18:28:27 -08001052 }
1053
1054 if (isSuspendSupported && isDozeSupported) {
ramindani770d7082021-11-30 00:36:42 +00001055 modes.push_back(PowerMode::DOZE_SUSPEND);
1056 }
1057
ramindanic2b8d082021-11-06 02:03:50 +00001058 for (auto mode : modes) {
ramindani431aad42022-02-01 21:44:29 +00001059 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), mode).isOk());
ramindanic2b8d082021-11-06 02:03:50 +00001060 }
1061}
1062
1063TEST_P(GraphicsComposerAidlTest, SetPowerModeVariations) {
ramindani431aad42022-02-01 21:44:29 +00001064 const auto& [status, capabilities] =
1065 mComposerClient->getDisplayCapabilities(getPrimaryDisplayId());
1066 ASSERT_TRUE(status.isOk());
1067
Ady Abraham6679baf2021-12-08 18:28:27 -08001068 const bool isDozeSupported = std::find(capabilities.begin(), capabilities.end(),
1069 DisplayCapability::DOZE) != capabilities.end();
1070 const bool isSuspendSupported = std::find(capabilities.begin(), capabilities.end(),
1071 DisplayCapability::SUSPEND) != capabilities.end();
1072
ramindanic2b8d082021-11-06 02:03:50 +00001073 std::vector<PowerMode> modes;
1074
1075 modes.push_back(PowerMode::OFF);
ramindani770d7082021-11-30 00:36:42 +00001076 modes.push_back(PowerMode::ON);
ramindanic2b8d082021-11-06 02:03:50 +00001077 modes.push_back(PowerMode::OFF);
ramindanic2b8d082021-11-06 02:03:50 +00001078 for (auto mode : modes) {
ramindani431aad42022-02-01 21:44:29 +00001079 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), mode).isOk());
ramindanic2b8d082021-11-06 02:03:50 +00001080 }
ramindani770d7082021-11-30 00:36:42 +00001081 modes.clear();
ramindanic2b8d082021-11-06 02:03:50 +00001082
ramindani770d7082021-11-30 00:36:42 +00001083 modes.push_back(PowerMode::OFF);
1084 modes.push_back(PowerMode::OFF);
1085 for (auto mode : modes) {
ramindani431aad42022-02-01 21:44:29 +00001086 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), mode).isOk());
ramindani770d7082021-11-30 00:36:42 +00001087 }
ramindanic2b8d082021-11-06 02:03:50 +00001088 modes.clear();
1089
1090 modes.push_back(PowerMode::ON);
1091 modes.push_back(PowerMode::ON);
ramindanic2b8d082021-11-06 02:03:50 +00001092 for (auto mode : modes) {
ramindani431aad42022-02-01 21:44:29 +00001093 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), mode).isOk());
ramindanic2b8d082021-11-06 02:03:50 +00001094 }
ramindanic2b8d082021-11-06 02:03:50 +00001095 modes.clear();
1096
Ady Abraham6679baf2021-12-08 18:28:27 -08001097 if (isSuspendSupported) {
1098 modes.push_back(PowerMode::ON_SUSPEND);
1099 modes.push_back(PowerMode::ON_SUSPEND);
1100 for (auto mode : modes) {
ramindani431aad42022-02-01 21:44:29 +00001101 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), mode).isOk());
Ady Abraham6679baf2021-12-08 18:28:27 -08001102 }
1103 modes.clear();
ramindanic2b8d082021-11-06 02:03:50 +00001104 }
1105
ramindanic2b8d082021-11-06 02:03:50 +00001106 if (isDozeSupported) {
ramindanic2b8d082021-11-06 02:03:50 +00001107 modes.push_back(PowerMode::DOZE);
1108 modes.push_back(PowerMode::DOZE);
ramindanic2b8d082021-11-06 02:03:50 +00001109 for (auto mode : modes) {
ramindani431aad42022-02-01 21:44:29 +00001110 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), mode).isOk());
ramindanic2b8d082021-11-06 02:03:50 +00001111 }
ramindanic2b8d082021-11-06 02:03:50 +00001112 modes.clear();
Ady Abraham6679baf2021-12-08 18:28:27 -08001113 }
ramindanic2b8d082021-11-06 02:03:50 +00001114
Ady Abraham6679baf2021-12-08 18:28:27 -08001115 if (isSuspendSupported && isDozeSupported) {
ramindanic2b8d082021-11-06 02:03:50 +00001116 modes.push_back(PowerMode::DOZE_SUSPEND);
1117 modes.push_back(PowerMode::DOZE_SUSPEND);
ramindanic2b8d082021-11-06 02:03:50 +00001118 for (auto mode : modes) {
ramindani431aad42022-02-01 21:44:29 +00001119 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), mode).isOk());
ramindanic2b8d082021-11-06 02:03:50 +00001120 }
Ady Abraham6679baf2021-12-08 18:28:27 -08001121 modes.clear();
ramindanic2b8d082021-11-06 02:03:50 +00001122 }
1123}
1124
ramindani431aad42022-02-01 21:44:29 +00001125TEST_P(GraphicsComposerAidlTest, SetPowerMode_BadDisplay) {
1126 const auto& status = mComposerClient->setPowerMode(getInvalidDisplayId(), PowerMode::ON);
ramindanic2b8d082021-11-06 02:03:50 +00001127
ramindani431aad42022-02-01 21:44:29 +00001128 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +00001129 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindanic2b8d082021-11-06 02:03:50 +00001130}
1131
ramindani431aad42022-02-01 21:44:29 +00001132TEST_P(GraphicsComposerAidlTest, SetPowerMode_BadParameter) {
1133 const auto& status =
1134 mComposerClient->setPowerMode(getPrimaryDisplayId(), static_cast<PowerMode>(-1));
ramindanic2b8d082021-11-06 02:03:50 +00001135
ramindani431aad42022-02-01 21:44:29 +00001136 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +00001137 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_PARAMETER));
ramindanic2b8d082021-11-06 02:03:50 +00001138}
1139
ramindanic2b8d082021-11-06 02:03:50 +00001140TEST_P(GraphicsComposerAidlTest, GetDataspaceSaturationMatrix) {
ramindani431aad42022-02-01 21:44:29 +00001141 const auto& [status, matrix] =
1142 mComposerClient->getDataspaceSaturationMatrix(common::Dataspace::SRGB_LINEAR);
1143 ASSERT_TRUE(status.isOk());
1144 ASSERT_EQ(16, matrix.size()); // matrix should not be empty if call succeeded.
ramindanideb059e2021-11-18 01:57:25 +00001145
ramindanic2b8d082021-11-06 02:03:50 +00001146 // the last row is known
ramindani431aad42022-02-01 21:44:29 +00001147 EXPECT_EQ(0.0f, matrix[12]);
1148 EXPECT_EQ(0.0f, matrix[13]);
1149 EXPECT_EQ(0.0f, matrix[14]);
1150 EXPECT_EQ(1.0f, matrix[15]);
ramindanic2b8d082021-11-06 02:03:50 +00001151}
1152
ramindani431aad42022-02-01 21:44:29 +00001153TEST_P(GraphicsComposerAidlTest, GetDataspaceSaturationMatrix_BadParameter) {
1154 const auto& [status, matrix] =
1155 mComposerClient->getDataspaceSaturationMatrix(common::Dataspace::UNKNOWN);
ramindanic2b8d082021-11-06 02:03:50 +00001156
ramindani431aad42022-02-01 21:44:29 +00001157 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +00001158 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_PARAMETER));
ramindanic2b8d082021-11-06 02:03:50 +00001159}
1160
ramindani12423f52023-06-14 20:04:51 -07001161/*
1162 * Test that no two display configs are exactly the same.
1163 */
1164TEST_P(GraphicsComposerAidlTest, GetDisplayConfigNoRepetitions) {
1165 for (const auto& display : mDisplays) {
1166 const auto& [status, configs] = mComposerClient->getDisplayConfigs(display.getDisplayId());
1167 for (std::vector<int>::size_type i = 0; i < configs.size(); i++) {
1168 for (std::vector<int>::size_type j = i + 1; j < configs.size(); j++) {
1169 const auto& [widthStatus1, width1] = mComposerClient->getDisplayAttribute(
1170 display.getDisplayId(), configs[i], DisplayAttribute::WIDTH);
1171 const auto& [heightStatus1, height1] = mComposerClient->getDisplayAttribute(
1172 display.getDisplayId(), configs[i], DisplayAttribute::HEIGHT);
1173 const auto& [vsyncPeriodStatus1, vsyncPeriod1] =
1174 mComposerClient->getDisplayAttribute(display.getDisplayId(), configs[i],
1175 DisplayAttribute::VSYNC_PERIOD);
1176 const auto& [groupStatus1, group1] = mComposerClient->getDisplayAttribute(
1177 display.getDisplayId(), configs[i], DisplayAttribute::CONFIG_GROUP);
1178
1179 const auto& [widthStatus2, width2] = mComposerClient->getDisplayAttribute(
1180 display.getDisplayId(), configs[j], DisplayAttribute::WIDTH);
1181 const auto& [heightStatus2, height2] = mComposerClient->getDisplayAttribute(
1182 display.getDisplayId(), configs[j], DisplayAttribute::HEIGHT);
1183 const auto& [vsyncPeriodStatus2, vsyncPeriod2] =
1184 mComposerClient->getDisplayAttribute(display.getDisplayId(), configs[j],
1185 DisplayAttribute::VSYNC_PERIOD);
1186 const auto& [groupStatus2, group2] = mComposerClient->getDisplayAttribute(
1187 display.getDisplayId(), configs[j], DisplayAttribute::CONFIG_GROUP);
1188
1189 ASSERT_FALSE(width1 == width2 && height1 == height2 &&
1190 vsyncPeriod1 == vsyncPeriod2 && group1 == group2);
1191 }
1192 }
1193 }
1194}
1195
Ady Abrahama00d2462023-12-26 14:21:20 -08001196TEST_P(GraphicsComposerAidlTest, LayerLifecycleCapabilityNotSupportedOnOldVersions) {
1197 if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
1198 EXPECT_GE(getInterfaceVersion(), 3);
1199 }
1200}
1201
ramindani12423f52023-06-14 20:04:51 -07001202class GraphicsComposerAidlV2Test : public GraphicsComposerAidlTest {
1203 protected:
1204 void SetUp() override {
1205 GraphicsComposerAidlTest::SetUp();
1206 if (getInterfaceVersion() <= 1) {
1207 GTEST_SKIP() << "Device interface version is expected to be >= 2";
1208 }
1209 }
1210};
1211
1212TEST_P(GraphicsComposerAidlV2Test, GetOverlaySupport) {
1213 const auto& [status, properties] = mComposerClient->getOverlaySupport();
1214 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
1215 status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
1216 GTEST_SUCCEED() << "getOverlaySupport is not supported";
1217 return;
1218 }
1219
1220 ASSERT_TRUE(status.isOk());
1221 for (const auto& i : properties.combinations) {
1222 for (const auto standard : i.standards) {
1223 const auto val = static_cast<int32_t>(standard) &
1224 static_cast<int32_t>(common::Dataspace::STANDARD_MASK);
1225 ASSERT_TRUE(val == static_cast<int32_t>(standard));
1226 }
1227 for (const auto transfer : i.transfers) {
1228 const auto val = static_cast<int32_t>(transfer) &
1229 static_cast<int32_t>(common::Dataspace::TRANSFER_MASK);
1230 ASSERT_TRUE(val == static_cast<int32_t>(transfer));
1231 }
1232 for (const auto range : i.ranges) {
1233 const auto val = static_cast<int32_t>(range) &
1234 static_cast<int32_t>(common::Dataspace::RANGE_MASK);
1235 ASSERT_TRUE(val == static_cast<int32_t>(range));
1236 }
1237 }
1238}
1239
ramindani02fe4772023-06-30 18:04:41 -07001240class GraphicsComposerAidlV3Test : public GraphicsComposerAidlTest {
1241 protected:
1242 void SetUp() override {
1243 GraphicsComposerAidlTest::SetUp();
1244 if (getInterfaceVersion() <= 2) {
1245 GTEST_SKIP() << "Device interface version is expected to be >= 3";
1246 }
1247 }
1248};
1249
1250TEST_P(GraphicsComposerAidlV3Test, GetDisplayConfigurations) {
1251 for (const auto& display : mDisplays) {
1252 const auto& [status, displayConfigurations] =
1253 mComposerClient->getDisplayConfigurations(display.getDisplayId());
1254 EXPECT_TRUE(status.isOk());
1255 EXPECT_FALSE(displayConfigurations.empty());
1256
1257 for (const auto& displayConfig : displayConfigurations) {
1258 EXPECT_NE(-1, displayConfig.width);
1259 EXPECT_NE(-1, displayConfig.height);
1260 EXPECT_NE(-1, displayConfig.vsyncPeriod);
1261 EXPECT_NE(-1, displayConfig.configGroup);
1262 if (displayConfig.dpi) {
ramindani2b2ec502023-08-25 18:47:38 -07001263 EXPECT_NE(-1.f, displayConfig.dpi->x);
1264 EXPECT_NE(-1.f, displayConfig.dpi->y);
ramindani02fe4772023-06-30 18:04:41 -07001265 }
ramindani2704c5f2023-07-18 20:53:24 -07001266 if (displayConfig.vrrConfig) {
1267 const auto& vrrConfig = *displayConfig.vrrConfig;
1268 EXPECT_GE(vrrConfig.minFrameIntervalNs, displayConfig.vsyncPeriod);
1269
ramindani2b2ec502023-08-25 18:47:38 -07001270 EXPECT_EQ(1, std::count_if(
1271 displayConfigurations.cbegin(), displayConfigurations.cend(),
1272 [displayConfig](const auto& config) {
1273 return config.configGroup == displayConfig.configGroup;
1274 }))
1275 << "There should be only one VRR mode in one ConfigGroup";
1276
ramindani2704c5f2023-07-18 20:53:24 -07001277 const auto verifyFrameIntervalIsDivisorOfVsync = [&](int32_t frameIntervalNs) {
1278 constexpr auto kThreshold = 0.05f; // 5%
1279 const auto ratio =
1280 static_cast<float>(frameIntervalNs) / displayConfig.vsyncPeriod;
1281 return ratio - std::round(ratio) <= kThreshold;
1282 };
1283
1284 EXPECT_TRUE(verifyFrameIntervalIsDivisorOfVsync(vrrConfig.minFrameIntervalNs));
1285
1286 if (vrrConfig.frameIntervalPowerHints) {
1287 const auto& frameIntervalPowerHints = *vrrConfig.frameIntervalPowerHints;
1288 EXPECT_FALSE(frameIntervalPowerHints.empty());
1289
1290 const auto minFrameInterval = *min_element(frameIntervalPowerHints.cbegin(),
1291 frameIntervalPowerHints.cend());
1292 EXPECT_LE(minFrameInterval->frameIntervalNs,
1293 VtsComposerClient::kMaxFrameIntervalNs);
ramindanifc93b732024-02-15 21:36:19 +00001294 const auto maxFrameInterval = *max_element(frameIntervalPowerHints.cbegin(),
1295 frameIntervalPowerHints.cend());
1296 EXPECT_GE(maxFrameInterval->frameIntervalNs, vrrConfig.minFrameIntervalNs);
ramindani2704c5f2023-07-18 20:53:24 -07001297
1298 EXPECT_TRUE(std::all_of(frameIntervalPowerHints.cbegin(),
1299 frameIntervalPowerHints.cend(),
1300 [&](const auto& frameIntervalPowerHint) {
1301 return verifyFrameIntervalIsDivisorOfVsync(
1302 frameIntervalPowerHint->frameIntervalNs);
1303 }));
1304 }
1305
1306 if (vrrConfig.notifyExpectedPresentConfig) {
1307 const auto& notifyExpectedPresentConfig =
1308 *vrrConfig.notifyExpectedPresentConfig;
ramindani52416e02023-12-19 16:03:14 -08001309 EXPECT_GE(notifyExpectedPresentConfig.headsUpNs, 0);
1310 EXPECT_GE(notifyExpectedPresentConfig.timeoutNs, 0);
ramindani2704c5f2023-07-18 20:53:24 -07001311 }
1312 }
ramindani02fe4772023-06-30 18:04:41 -07001313 }
1314 }
1315}
1316
1317TEST_P(GraphicsComposerAidlV3Test, GetDisplayConfigsIsSubsetOfGetDisplayConfigurations) {
1318 for (const auto& display : mDisplays) {
1319 const auto& [status, displayConfigurations] =
1320 mComposerClient->getDisplayConfigurations(display.getDisplayId());
1321 EXPECT_TRUE(status.isOk());
1322
1323 const auto& [legacyConfigStatus, legacyConfigs] =
1324 mComposerClient->getDisplayConfigs(display.getDisplayId());
1325 EXPECT_TRUE(legacyConfigStatus.isOk());
1326 EXPECT_FALSE(legacyConfigs.empty());
1327 EXPECT_TRUE(legacyConfigs.size() <= displayConfigurations.size());
1328
1329 for (const auto legacyConfigId : legacyConfigs) {
1330 const auto& legacyWidth = mComposerClient->getDisplayAttribute(
1331 display.getDisplayId(), legacyConfigId, DisplayAttribute::WIDTH);
1332 const auto& legacyHeight = mComposerClient->getDisplayAttribute(
1333 display.getDisplayId(), legacyConfigId, DisplayAttribute::HEIGHT);
1334 const auto& legacyVsyncPeriod = mComposerClient->getDisplayAttribute(
1335 display.getDisplayId(), legacyConfigId, DisplayAttribute::VSYNC_PERIOD);
1336 const auto& legacyConfigGroup = mComposerClient->getDisplayAttribute(
1337 display.getDisplayId(), legacyConfigId, DisplayAttribute::CONFIG_GROUP);
1338 const auto& legacyDpiX = mComposerClient->getDisplayAttribute(
1339 display.getDisplayId(), legacyConfigId, DisplayAttribute::DPI_X);
1340 const auto& legacyDpiY = mComposerClient->getDisplayAttribute(
1341 display.getDisplayId(), legacyConfigId, DisplayAttribute::DPI_Y);
1342
1343 EXPECT_TRUE(legacyWidth.first.isOk() && legacyHeight.first.isOk() &&
1344 legacyVsyncPeriod.first.isOk() && legacyConfigGroup.first.isOk());
1345
1346 EXPECT_TRUE(std::any_of(
1347 displayConfigurations.begin(), displayConfigurations.end(),
1348 [&](const auto& displayConfiguration) {
1349 const bool requiredAttributesPredicate =
1350 displayConfiguration.configId == legacyConfigId &&
1351 displayConfiguration.width == legacyWidth.second &&
1352 displayConfiguration.height == legacyHeight.second &&
1353 displayConfiguration.vsyncPeriod == legacyVsyncPeriod.second &&
1354 displayConfiguration.configGroup == legacyConfigGroup.second;
1355
1356 if (!requiredAttributesPredicate) {
1357 // Required attributes did not match
1358 return false;
1359 }
1360
1361 // Check optional attributes
1362 const auto& [legacyDpiXStatus, legacyDpiXValue] = legacyDpiX;
1363 const auto& [legacyDpiYStatus, legacyDpiYValue] = legacyDpiY;
1364 if (displayConfiguration.dpi) {
1365 if (!legacyDpiXStatus.isOk() || !legacyDpiYStatus.isOk()) {
1366 // getDisplayAttribute failed for optional attributes
1367 return false;
1368 }
1369
1370 // DPI values in DisplayConfigurations are not scaled (* 1000.f)
1371 // the way they are in the legacy DisplayConfigs.
1372 constexpr float kEpsilon = 0.001f;
1373 return std::abs(displayConfiguration.dpi->x -
1374 legacyDpiXValue / 1000.f) < kEpsilon &&
1375 std::abs(displayConfiguration.dpi->y -
1376 legacyDpiYValue / 1000.f) < kEpsilon;
1377 } else {
1378 return !legacyDpiXStatus.isOk() && !legacyDpiYStatus.isOk() &&
1379 EX_SERVICE_SPECIFIC == legacyDpiXStatus.getExceptionCode() &&
1380 EX_SERVICE_SPECIFIC == legacyDpiYStatus.getExceptionCode() &&
1381 IComposerClient::EX_UNSUPPORTED ==
1382 legacyDpiXStatus.getServiceSpecificError() &&
1383 IComposerClient::EX_UNSUPPORTED ==
1384 legacyDpiYStatus.getServiceSpecificError();
1385 }
1386 }));
1387 }
1388 }
1389}
1390
ramindanidcfe3a82021-11-29 17:00:31 +00001391// Tests for Command.
1392class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest {
1393 protected:
ramindanidcfe3a82021-11-29 17:00:31 +00001394 void TearDown() override {
Leon Scroggins III94f4b202024-01-09 11:43:45 -05001395 ASSERT_FALSE(mDisplays.empty());
Ady Abraham3192f3d2021-12-03 16:08:56 -08001396 ASSERT_TRUE(mReader.takeErrors().empty());
ramindani431aad42022-02-01 21:44:29 +00001397 ASSERT_TRUE(mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty());
Ady Abraham3192f3d2021-12-03 16:08:56 -08001398
Ady Abrahama00d2462023-12-26 14:21:20 -08001399 ASSERT_TRUE(mComposerClient->tearDown(&getWriter(getPrimaryDisplayId())));
ramindanidcfe3a82021-11-29 17:00:31 +00001400 ASSERT_NO_FATAL_FAILURE(GraphicsComposerAidlTest::TearDown());
1401 }
1402
1403 void execute() {
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001404 std::vector<CommandResultPayload> payloads;
1405 for (auto& [_, writer] : mWriters) {
Joen Chene0a962c2023-08-28 09:49:11 +00001406 executeInternal(writer, payloads);
ramindanidcfe3a82021-11-29 17:00:31 +00001407 }
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001408 mReader.parse(std::move(payloads));
ramindanidcfe3a82021-11-29 17:00:31 +00001409 }
1410
Joen Chene0a962c2023-08-28 09:49:11 +00001411 void execute(ComposerClientWriter& writer, ComposerClientReader& reader) {
1412 std::vector<CommandResultPayload> payloads;
1413 executeInternal(writer, payloads);
1414 reader.parse(std::move(payloads));
1415 }
1416
ramindanidcfe3a82021-11-29 17:00:31 +00001417 static inline auto toTimePoint(nsecs_t time) {
1418 return std::chrono::time_point<std::chrono::steady_clock>(std::chrono::nanoseconds(time));
1419 }
1420
ramindanidcfe3a82021-11-29 17:00:31 +00001421 void forEachTwoConfigs(int64_t display, std::function<void(int32_t, int32_t)> func) {
ramindani431aad42022-02-01 21:44:29 +00001422 const auto& [status, displayConfigs] = mComposerClient->getDisplayConfigs(display);
1423 ASSERT_TRUE(status.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001424 for (const int32_t config1 : displayConfigs) {
1425 for (const int32_t config2 : displayConfigs) {
1426 if (config1 != config2) {
1427 func(config1, config2);
1428 }
1429 }
1430 }
1431 }
1432
1433 void waitForVsyncPeriodChange(int64_t display, const VsyncPeriodChangeTimeline& timeline,
1434 int64_t desiredTimeNanos, int64_t oldPeriodNanos,
1435 int64_t newPeriodNanos) {
1436 const auto kChangeDeadline = toTimePoint(timeline.newVsyncAppliedTimeNanos) + 100ms;
1437 while (std::chrono::steady_clock::now() <= kChangeDeadline) {
ramindani431aad42022-02-01 21:44:29 +00001438 const auto& [status, vsyncPeriodNanos] =
1439 mComposerClient->getDisplayVsyncPeriod(display);
1440 EXPECT_TRUE(status.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001441 if (systemTime() <= desiredTimeNanos) {
1442 EXPECT_EQ(vsyncPeriodNanos, oldPeriodNanos);
1443 } else if (vsyncPeriodNanos == newPeriodNanos) {
1444 break;
1445 }
1446 std::this_thread::sleep_for(std::chrono::nanoseconds(oldPeriodNanos));
1447 }
1448 }
1449
ramindani9dd8c482023-02-21 18:07:56 -08001450 bool checkIfCallbackRefreshRateChangedDebugEnabledReceived(
1451 std::function<bool(RefreshRateChangedDebugData)> filter) {
1452 const auto list = mComposerClient->takeListOfRefreshRateChangedDebugData();
1453 return std::any_of(list.begin(), list.end(), [&](auto refreshRateChangedDebugData) {
1454 return filter(refreshRateChangedDebugData);
1455 });
1456 }
1457
Brian Lindahl25e0d092022-12-09 00:32:11 -07001458 sp<GraphicBuffer> allocate(uint32_t width, uint32_t height,
1459 ::android::PixelFormat pixelFormat) {
Brian Lindahl14bd07b2023-01-17 14:54:39 -07001460 return sp<GraphicBuffer>::make(
Brian Lindahl25e0d092022-12-09 00:32:11 -07001461 width, height, pixelFormat, /*layerCount*/ 1U,
1462 static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
1463 static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
1464 static_cast<uint64_t>(common::BufferUsage::COMPOSER_OVERLAY),
Brian Lindahl14bd07b2023-01-17 14:54:39 -07001465 "VtsHalGraphicsComposer3_TargetTest");
Brian Lindahlca3eef22022-12-09 00:32:11 -07001466 }
1467
Brian Lindahl25e0d092022-12-09 00:32:11 -07001468 sp<GraphicBuffer> allocate(::android::PixelFormat pixelFormat) {
1469 return allocate(static_cast<uint32_t>(getPrimaryDisplay().getDisplayWidth()),
1470 static_cast<uint32_t>(getPrimaryDisplay().getDisplayHeight()), pixelFormat);
1471 }
1472
ramindanidcfe3a82021-11-29 17:00:31 +00001473 void sendRefreshFrame(const VtsDisplay& display, const VsyncPeriodChangeTimeline* timeline) {
1474 if (timeline != nullptr) {
1475 // Refresh time should be before newVsyncAppliedTimeNanos
1476 EXPECT_LT(timeline->refreshTimeNanos, timeline->newVsyncAppliedTimeNanos);
1477
1478 std::this_thread::sleep_until(toTimePoint(timeline->refreshTimeNanos));
1479 }
1480
ramindani431aad42022-02-01 21:44:29 +00001481 EXPECT_TRUE(mComposerClient->setPowerMode(display.getDisplayId(), PowerMode::ON).isOk());
1482 EXPECT_TRUE(mComposerClient
1483 ->setColorMode(display.getDisplayId(), ColorMode::NATIVE,
1484 RenderIntent::COLORIMETRIC)
1485 .isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001486
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001487 auto& writer = getWriter(display.getDisplayId());
Ady Abrahama00d2462023-12-26 14:21:20 -08001488 const auto& [status, layer] =
1489 mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount, &writer);
1490 EXPECT_TRUE(status.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001491 {
Leon Scroggins IIIde057582022-01-13 12:26:00 -05001492 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ramindanidcfe3a82021-11-29 17:00:31 +00001493 ASSERT_NE(nullptr, buffer);
1494 ASSERT_EQ(::android::OK, buffer->initCheck());
1495 ASSERT_NE(nullptr, buffer->handle);
1496
ramindani431aad42022-02-01 21:44:29 +00001497 configureLayer(display, layer, Composition::DEVICE, display.getFrameRect(),
1498 display.getCrop());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001499 writer.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, buffer->handle,
1500 /*acquireFence*/ -1);
1501 writer.setLayerDataspace(display.getDisplayId(), layer, common::Dataspace::UNKNOWN);
ramindanidcfe3a82021-11-29 17:00:31 +00001502
ramindanicdcfcaf2023-11-09 10:00:10 -08001503 writer.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp,
1504 VtsComposerClient::kNoFrameIntervalNs);
ramindanidcfe3a82021-11-29 17:00:31 +00001505 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08001506 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00001507
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001508 writer.presentDisplay(display.getDisplayId());
ramindanidcfe3a82021-11-29 17:00:31 +00001509 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08001510 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00001511 }
1512
1513 {
Leon Scroggins IIIde057582022-01-13 12:26:00 -05001514 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ramindanidcfe3a82021-11-29 17:00:31 +00001515 ASSERT_NE(nullptr, buffer->handle);
1516
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001517 writer.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, buffer->handle,
1518 /*acquireFence*/ -1);
1519 writer.setLayerSurfaceDamage(display.getDisplayId(), layer,
1520 std::vector<Rect>(1, {0, 0, 10, 10}));
ramindanicdcfcaf2023-11-09 10:00:10 -08001521 writer.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp,
1522 VtsComposerClient::kNoFrameIntervalNs);
ramindanidcfe3a82021-11-29 17:00:31 +00001523 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08001524 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00001525
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001526 writer.presentDisplay(display.getDisplayId());
ramindanidcfe3a82021-11-29 17:00:31 +00001527 execute();
1528 }
1529
Ady Abrahama00d2462023-12-26 14:21:20 -08001530 EXPECT_TRUE(mComposerClient->destroyLayer(display.getDisplayId(), layer, &writer).isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001531 }
1532
Ady Abraham72c5b502021-12-10 17:23:39 -08001533 sp<::android::Fence> presentAndGetFence(
ramindanifc93b732024-02-15 21:36:19 +00001534 std::optional<ClockMonotonicTimestamp> expectedPresentTime,
1535 std::optional<int64_t> displayIdOpt = {},
1536 int32_t frameIntervalNs = VtsComposerClient::kNoFrameIntervalNs) {
1537 const auto displayId = displayIdOpt.value_or(getPrimaryDisplayId());
1538 auto& writer = getWriter(displayId);
1539 writer.validateDisplay(displayId, expectedPresentTime, frameIntervalNs);
Ady Abraham72c5b502021-12-10 17:23:39 -08001540 execute();
1541 EXPECT_TRUE(mReader.takeErrors().empty());
1542
ramindanifc93b732024-02-15 21:36:19 +00001543 writer.presentDisplay(displayId);
Ady Abraham72c5b502021-12-10 17:23:39 -08001544 execute();
1545 EXPECT_TRUE(mReader.takeErrors().empty());
1546
ramindanifc93b732024-02-15 21:36:19 +00001547 auto presentFence = mReader.takePresentFence(displayId);
Ady Abraham46219f52021-12-20 09:44:31 -08001548 // take ownership
1549 const int fenceOwner = presentFence.get();
1550 *presentFence.getR() = -1;
1551 EXPECT_NE(-1, fenceOwner);
1552 return sp<::android::Fence>::make(fenceOwner);
Ady Abraham72c5b502021-12-10 17:23:39 -08001553 }
1554
1555 int32_t getVsyncPeriod() {
ramindani431aad42022-02-01 21:44:29 +00001556 const auto& [status, activeConfig] =
1557 mComposerClient->getActiveConfig(getPrimaryDisplayId());
1558 EXPECT_TRUE(status.isOk());
Ady Abraham72c5b502021-12-10 17:23:39 -08001559
ramindani431aad42022-02-01 21:44:29 +00001560 const auto& [vsyncPeriodStatus, vsyncPeriod] = mComposerClient->getDisplayAttribute(
1561 getPrimaryDisplayId(), activeConfig, DisplayAttribute::VSYNC_PERIOD);
1562 EXPECT_TRUE(vsyncPeriodStatus.isOk());
Ady Abraham72c5b502021-12-10 17:23:39 -08001563 return vsyncPeriod;
1564 }
1565
ramindanifc93b732024-02-15 21:36:19 +00001566 int64_t createOnScreenLayer(const VtsDisplay& display,
1567 Composition composition = Composition::DEVICE) {
1568 auto& writer = getWriter(display.getDisplayId());
ramindani431aad42022-02-01 21:44:29 +00001569 const auto& [status, layer] =
ramindanifc93b732024-02-15 21:36:19 +00001570 mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00001571 EXPECT_TRUE(status.isOk());
ramindanifc93b732024-02-15 21:36:19 +00001572 Rect displayFrame{0, 0, display.getDisplayWidth(), display.getDisplayHeight()};
1573 FRect cropRect{0, 0, (float)display.getDisplayWidth(), (float)display.getDisplayHeight()};
1574 configureLayer(display, layer, composition, displayFrame, cropRect);
Ady Abrahama00d2462023-12-26 14:21:20 -08001575
ramindanifc93b732024-02-15 21:36:19 +00001576 writer.setLayerDataspace(display.getDisplayId(), layer, common::Dataspace::UNKNOWN);
Ady Abraham72c5b502021-12-10 17:23:39 -08001577 return layer;
1578 }
1579
ramindani9dd8c482023-02-21 18:07:56 -08001580 void sendBufferUpdate(int64_t layer) {
1581 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
1582 ASSERT_NE(nullptr, buffer->handle);
1583
1584 auto& writer = getWriter(getPrimaryDisplayId());
1585 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer->handle,
1586 /*acquireFence*/ -1);
1587
1588 const sp<::android::Fence> presentFence =
1589 presentAndGetFence(ComposerClientWriter::kNoTimestamp);
1590 presentFence->waitForever(LOG_TAG);
1591 }
1592
Midas Chiena0b56bd2022-01-13 23:27:33 +08001593 bool hasDisplayCapability(int64_t display, DisplayCapability cap) {
ramindani431aad42022-02-01 21:44:29 +00001594 const auto& [status, capabilities] = mComposerClient->getDisplayCapabilities(display);
1595 EXPECT_TRUE(status.isOk());
Midas Chiena0b56bd2022-01-13 23:27:33 +08001596
1597 return std::find(capabilities.begin(), capabilities.end(), cap) != capabilities.end();
1598 }
1599
ramindanidcfe3a82021-11-29 17:00:31 +00001600 void Test_setActiveConfigWithConstraints(const TestParameters& params) {
1601 for (VtsDisplay& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +00001602 forEachTwoConfigs(display.getDisplayId(), [&](int32_t config1, int32_t config2) {
1603 EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config1).isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001604 sendRefreshFrame(display, nullptr);
1605
ramindani431aad42022-02-01 21:44:29 +00001606 const auto displayConfigGroup1 = display.getDisplayConfig(config1);
1607 int32_t vsyncPeriod1 = displayConfigGroup1.vsyncPeriod;
1608 int32_t configGroup1 = displayConfigGroup1.configGroup;
1609
1610 const auto displayConfigGroup2 = display.getDisplayConfig(config2);
1611 int32_t vsyncPeriod2 = displayConfigGroup2.vsyncPeriod;
1612 int32_t configGroup2 = displayConfigGroup2.configGroup;
ramindanidcfe3a82021-11-29 17:00:31 +00001613
1614 if (vsyncPeriod1 == vsyncPeriod2) {
1615 return; // continue
1616 }
1617
1618 // We don't allow delayed change when changing config groups
1619 if (params.delayForChange > 0 && configGroup1 != configGroup2) {
1620 return; // continue
1621 }
1622
ramindanidcfe3a82021-11-29 17:00:31 +00001623 VsyncPeriodChangeConstraints constraints = {
1624 .desiredTimeNanos = systemTime() + params.delayForChange,
1625 .seamlessRequired = false};
ramindani431aad42022-02-01 21:44:29 +00001626 const auto& [status, timeline] = mComposerClient->setActiveConfigWithConstraints(
1627 &display, config2, constraints);
1628 EXPECT_TRUE(status.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001629
1630 EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos >= constraints.desiredTimeNanos);
1631 // Refresh rate should change within a reasonable time
1632 constexpr std::chrono::nanoseconds kReasonableTimeForChange = 1s; // 1 second
1633 EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos - constraints.desiredTimeNanos <=
1634 kReasonableTimeForChange.count());
1635
1636 if (timeline.refreshRequired) {
1637 if (params.refreshMiss) {
1638 // Miss the refresh frame on purpose to make sure the implementation sends a
1639 // callback
1640 std::this_thread::sleep_until(toTimePoint(timeline.refreshTimeNanos) +
1641 100ms);
1642 }
1643 sendRefreshFrame(display, &timeline);
1644 }
ramindani431aad42022-02-01 21:44:29 +00001645 waitForVsyncPeriodChange(display.getDisplayId(), timeline,
1646 constraints.desiredTimeNanos, vsyncPeriod1, vsyncPeriod2);
ramindanidcfe3a82021-11-29 17:00:31 +00001647
1648 // At this point the refresh rate should have changed already, however in rare
1649 // cases the implementation might have missed the deadline. In this case a new
1650 // timeline should have been provided.
ramindani431aad42022-02-01 21:44:29 +00001651 auto newTimeline = mComposerClient->takeLastVsyncPeriodChangeTimeline();
ramindanidcfe3a82021-11-29 17:00:31 +00001652 if (timeline.refreshRequired && params.refreshMiss) {
1653 EXPECT_TRUE(newTimeline.has_value());
1654 }
1655
1656 if (newTimeline.has_value()) {
1657 if (newTimeline->refreshRequired) {
1658 sendRefreshFrame(display, &newTimeline.value());
1659 }
ramindani431aad42022-02-01 21:44:29 +00001660 waitForVsyncPeriodChange(display.getDisplayId(), newTimeline.value(),
ramindanidcfe3a82021-11-29 17:00:31 +00001661 constraints.desiredTimeNanos, vsyncPeriod1,
1662 vsyncPeriod2);
1663 }
1664
ramindani431aad42022-02-01 21:44:29 +00001665 const auto& [vsyncPeriodNanosStatus, vsyncPeriodNanos] =
1666 mComposerClient->getDisplayVsyncPeriod(display.getDisplayId());
1667 EXPECT_TRUE(vsyncPeriodNanosStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001668 EXPECT_EQ(vsyncPeriodNanos, vsyncPeriod2);
1669 });
1670 }
1671 }
1672
Ady Abraham72c5b502021-12-10 17:23:39 -08001673 void Test_expectedPresentTime(std::optional<int> framesDelay) {
Jason Macnak325e8232022-01-24 14:48:55 -08001674 if (hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
1675 GTEST_SUCCEED() << "Device has unreliable present fences capability, skipping";
1676 return;
1677 }
1678
ramindani431aad42022-02-01 21:44:29 +00001679 ASSERT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
Ady Abraham72c5b502021-12-10 17:23:39 -08001680
1681 const auto vsyncPeriod = getVsyncPeriod();
1682
Leon Scroggins IIIde057582022-01-13 12:26:00 -05001683 const auto buffer1 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
1684 const auto buffer2 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
Ady Abraham72c5b502021-12-10 17:23:39 -08001685 ASSERT_NE(nullptr, buffer1);
1686 ASSERT_NE(nullptr, buffer2);
1687
ramindanifc93b732024-02-15 21:36:19 +00001688 const auto layer = createOnScreenLayer(getPrimaryDisplay());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001689 auto& writer = getWriter(getPrimaryDisplayId());
1690 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer1->handle,
1691 /*acquireFence*/ -1);
Ady Abraham72c5b502021-12-10 17:23:39 -08001692 const sp<::android::Fence> presentFence1 =
1693 presentAndGetFence(ComposerClientWriter::kNoTimestamp);
1694 presentFence1->waitForever(LOG_TAG);
1695
1696 auto expectedPresentTime = presentFence1->getSignalTime() + vsyncPeriod;
1697 if (framesDelay.has_value()) {
1698 expectedPresentTime += *framesDelay * vsyncPeriod;
1699 }
1700
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001701 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer2->handle,
1702 /*acquireFence*/ -1);
Ady Abraham72c5b502021-12-10 17:23:39 -08001703 const auto setExpectedPresentTime = [&]() -> std::optional<ClockMonotonicTimestamp> {
1704 if (!framesDelay.has_value()) {
1705 return ComposerClientWriter::kNoTimestamp;
1706 } else if (*framesDelay == 0) {
1707 return ClockMonotonicTimestamp{0};
1708 }
1709 return ClockMonotonicTimestamp{expectedPresentTime};
1710 }();
1711
1712 const sp<::android::Fence> presentFence2 = presentAndGetFence(setExpectedPresentTime);
1713 presentFence2->waitForever(LOG_TAG);
1714
1715 const auto actualPresentTime = presentFence2->getSignalTime();
Ady Abrahamdf084f32022-01-10 14:10:23 -08001716 EXPECT_GE(actualPresentTime, expectedPresentTime - vsyncPeriod / 2);
Ady Abraham72c5b502021-12-10 17:23:39 -08001717
ramindani431aad42022-02-01 21:44:29 +00001718 ASSERT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
Ady Abraham72c5b502021-12-10 17:23:39 -08001719 }
1720
ramindanifc93b732024-02-15 21:36:19 +00001721 void forEachNotifyExpectedPresentConfig(
1722 std::function<void(VtsDisplay&, const DisplayConfiguration&)> func) {
1723 for (VtsDisplay& display : mDisplays) {
1724 const auto displayId = display.getDisplayId();
1725 EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
1726 const auto& [status, displayConfigurations] =
1727 mComposerClient->getDisplayConfigurations(displayId);
1728 EXPECT_TRUE(status.isOk());
1729 EXPECT_FALSE(displayConfigurations.empty());
1730 for (const auto& config : displayConfigurations) {
1731 if (config.vrrConfig && config.vrrConfig->notifyExpectedPresentConfig) {
1732 const auto [vsyncPeriodStatus, oldVsyncPeriod] =
1733 mComposerClient->getDisplayVsyncPeriod(displayId);
1734 ASSERT_TRUE(vsyncPeriodStatus.isOk());
1735 const auto& [timelineStatus, timeline] =
1736 mComposerClient->setActiveConfigWithConstraints(
1737 &display, config.configId,
1738 VsyncPeriodChangeConstraints{.seamlessRequired = false});
1739 ASSERT_TRUE(timelineStatus.isOk());
1740 if (timeline.refreshRequired) {
1741 sendRefreshFrame(display, &timeline);
1742 }
1743 waitForVsyncPeriodChange(displayId, timeline, systemTime(), oldVsyncPeriod,
1744 config.vsyncPeriod);
1745 func(display, config);
1746 }
1747 }
1748 EXPECT_TRUE(
1749 mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
1750 }
1751 }
1752
ramindani431aad42022-02-01 21:44:29 +00001753 void configureLayer(const VtsDisplay& display, int64_t layer, Composition composition,
1754 const Rect& displayFrame, const FRect& cropRect) {
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001755 auto& writer = getWriter(display.getDisplayId());
1756 writer.setLayerCompositionType(display.getDisplayId(), layer, composition);
1757 writer.setLayerDisplayFrame(display.getDisplayId(), layer, displayFrame);
1758 writer.setLayerPlaneAlpha(display.getDisplayId(), layer, /*alpha*/ 1);
1759 writer.setLayerSourceCrop(display.getDisplayId(), layer, cropRect);
1760 writer.setLayerTransform(display.getDisplayId(), layer, static_cast<Transform>(0));
1761 writer.setLayerVisibleRegion(display.getDisplayId(), layer,
1762 std::vector<Rect>(1, displayFrame));
1763 writer.setLayerZOrder(display.getDisplayId(), layer, /*z*/ 10);
1764 writer.setLayerBlendMode(display.getDisplayId(), layer, BlendMode::NONE);
1765 writer.setLayerSurfaceDamage(display.getDisplayId(), layer,
1766 std::vector<Rect>(1, displayFrame));
ramindani431aad42022-02-01 21:44:29 +00001767 }
ramindanidcfe3a82021-11-29 17:00:31 +00001768 // clang-format off
1769 const std::array<float, 16> kIdentity = {{
1770 1.0f, 0.0f, 0.0f, 0.0f,
1771 0.0f, 1.0f, 0.0f, 0.0f,
1772 0.0f, 0.0f, 1.0f, 0.0f,
1773 0.0f, 0.0f, 0.0f, 1.0f,
1774 }};
1775 // clang-format on
1776
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001777 ComposerClientWriter& getWriter(int64_t display) {
Joen Chene0a962c2023-08-28 09:49:11 +00001778 std::lock_guard guard{mWritersMutex};
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001779 auto [it, _] = mWriters.try_emplace(display, display);
1780 return it->second;
1781 }
1782
Ady Abraham91c9d1a2021-12-15 18:14:45 -08001783 ComposerClientReader mReader;
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001784
1785 private:
Joen Chene0a962c2023-08-28 09:49:11 +00001786 void executeInternal(ComposerClientWriter& writer,
1787 std::vector<CommandResultPayload>& payloads) {
1788 auto commands = writer.takePendingCommands();
1789 if (commands.empty()) {
1790 return;
1791 }
1792
1793 auto [status, results] = mComposerClient->executeCommands(commands);
1794 ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription();
1795
1796 payloads.reserve(payloads.size() + results.size());
1797 payloads.insert(payloads.end(), std::make_move_iterator(results.begin()),
1798 std::make_move_iterator(results.end()));
1799 }
1800
1801 // Guards access to the map itself. Callers must ensure not to attempt to
1802 // - modify the same writer from multiple threads
1803 // - insert a new writer into the map during concurrent access, which would invalidate
1804 // references from other threads
1805 std::mutex mWritersMutex;
1806 std::unordered_map<int64_t, ComposerClientWriter> mWriters GUARDED_BY(mWritersMutex);
ramindanidcfe3a82021-11-29 17:00:31 +00001807};
1808
ramindani431aad42022-02-01 21:44:29 +00001809TEST_P(GraphicsComposerAidlCommandTest, SetColorTransform) {
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001810 auto& writer = getWriter(getPrimaryDisplayId());
1811 writer.setColorTransform(getPrimaryDisplayId(), kIdentity.data());
ramindanidcfe3a82021-11-29 17:00:31 +00001812 execute();
1813}
1814
1815TEST_P(GraphicsComposerAidlCommandTest, SetLayerColorTransform) {
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001816 auto& writer = getWriter(getPrimaryDisplayId());
Ady Abrahama00d2462023-12-26 14:21:20 -08001817 const auto& [status, layer] =
1818 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
1819 EXPECT_TRUE(status.isOk());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001820 writer.setLayerColorTransform(getPrimaryDisplayId(), layer, kIdentity.data());
ramindanidcfe3a82021-11-29 17:00:31 +00001821 execute();
1822
Ady Abraham3192f3d2021-12-03 16:08:56 -08001823 const auto errors = mReader.takeErrors();
Jason Macnak062bc9a2022-01-20 15:00:09 -08001824 if (errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_UNSUPPORTED) {
ramindanidcfe3a82021-11-29 17:00:31 +00001825 GTEST_SUCCEED() << "setLayerColorTransform is not supported";
1826 return;
1827 }
1828}
1829
Alec Mouri60564e12021-12-09 18:48:20 -08001830TEST_P(GraphicsComposerAidlCommandTest, SetDisplayBrightness) {
Peter Linb9fbd4e2023-12-14 05:43:25 +00001831 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
ramindani431aad42022-02-01 21:44:29 +00001832 const auto& [status, capabilities] =
1833 mComposerClient->getDisplayCapabilities(getPrimaryDisplayId());
1834 ASSERT_TRUE(status.isOk());
Alec Mouri60564e12021-12-09 18:48:20 -08001835 bool brightnessSupport = std::find(capabilities.begin(), capabilities.end(),
1836 DisplayCapability::BRIGHTNESS) != capabilities.end();
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001837 auto& writer = getWriter(getPrimaryDisplayId());
Alec Mouri60564e12021-12-09 18:48:20 -08001838 if (!brightnessSupport) {
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001839 writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.5f, -1.f);
Alec Mouri60564e12021-12-09 18:48:20 -08001840 execute();
1841 const auto errors = mReader.takeErrors();
1842 EXPECT_EQ(1, errors.size());
Jason Macnak062bc9a2022-01-20 15:00:09 -08001843 EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, errors[0].errorCode);
Alec Mouri60564e12021-12-09 18:48:20 -08001844 GTEST_SUCCEED() << "SetDisplayBrightness is not supported";
1845 return;
1846 }
1847
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001848 writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.0f, -1.f);
Alec Mouri60564e12021-12-09 18:48:20 -08001849 execute();
1850 EXPECT_TRUE(mReader.takeErrors().empty());
1851
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001852 writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.5f, -1.f);
Alec Mouri60564e12021-12-09 18:48:20 -08001853 execute();
1854 EXPECT_TRUE(mReader.takeErrors().empty());
1855
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001856 writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 1.0f, -1.f);
Alec Mouri60564e12021-12-09 18:48:20 -08001857 execute();
1858 EXPECT_TRUE(mReader.takeErrors().empty());
1859
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001860 writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ -1.0f, -1.f);
Alec Mouri60564e12021-12-09 18:48:20 -08001861 execute();
1862 EXPECT_TRUE(mReader.takeErrors().empty());
1863
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001864 writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 2.0f, -1.f);
Alec Mouri60564e12021-12-09 18:48:20 -08001865 execute();
1866 {
1867 const auto errors = mReader.takeErrors();
ramindanib3bdf052022-01-12 18:27:05 +00001868 ASSERT_EQ(1, errors.size());
Alec Mouri60564e12021-12-09 18:48:20 -08001869 EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
1870 }
1871
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001872 writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ -2.0f, -1.f);
Alec Mouri60564e12021-12-09 18:48:20 -08001873 execute();
1874 {
1875 const auto errors = mReader.takeErrors();
ramindanib3bdf052022-01-12 18:27:05 +00001876 ASSERT_EQ(1, errors.size());
Alec Mouri60564e12021-12-09 18:48:20 -08001877 EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
1878 }
1879}
1880
ramindani431aad42022-02-01 21:44:29 +00001881TEST_P(GraphicsComposerAidlCommandTest, SetClientTarget) {
1882 EXPECT_TRUE(mComposerClient->setClientTargetSlotCount(getPrimaryDisplayId(), kBufferSlotCount)
1883 .isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001884
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001885 auto& writer = getWriter(getPrimaryDisplayId());
1886 writer.setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, nullptr, /*acquireFence*/ -1,
Alec Mouri8062f1f2023-09-06 02:14:47 +00001887 Dataspace::UNKNOWN, std::vector<Rect>(), 1.0f);
ramindanidcfe3a82021-11-29 17:00:31 +00001888
1889 execute();
1890}
1891
ramindani431aad42022-02-01 21:44:29 +00001892TEST_P(GraphicsComposerAidlCommandTest, SetOutputBuffer) {
1893 const auto& [status, virtualDisplayCount] = mComposerClient->getMaxVirtualDisplayCount();
1894 EXPECT_TRUE(status.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001895 if (virtualDisplayCount == 0) {
1896 GTEST_SUCCEED() << "no virtual display support";
1897 return;
1898 }
1899
ramindani431aad42022-02-01 21:44:29 +00001900 const auto& [displayStatus, display] = mComposerClient->createVirtualDisplay(
1901 /*width*/ 64, /*height*/ 64, common::PixelFormat::IMPLEMENTATION_DEFINED,
1902 kBufferSlotCount);
1903 EXPECT_TRUE(displayStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001904
Leon Scroggins IIIde057582022-01-13 12:26:00 -05001905 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ramindani3d18f922021-12-13 20:24:47 +00001906 const auto handle = buffer->handle;
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001907 auto& writer = getWriter(display.display);
1908 writer.setOutputBuffer(display.display, /*slot*/ 0, handle, /*releaseFence*/ -1);
ramindanidcfe3a82021-11-29 17:00:31 +00001909 execute();
1910}
1911
ramindani431aad42022-02-01 21:44:29 +00001912TEST_P(GraphicsComposerAidlCommandTest, ValidDisplay) {
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001913 auto& writer = getWriter(getPrimaryDisplayId());
ramindanicdcfcaf2023-11-09 10:00:10 -08001914 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
1915 VtsComposerClient::kNoFrameIntervalNs);
ramindanidcfe3a82021-11-29 17:00:31 +00001916 execute();
1917}
1918
ramindani431aad42022-02-01 21:44:29 +00001919TEST_P(GraphicsComposerAidlCommandTest, AcceptDisplayChanges) {
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001920 auto& writer = getWriter(getPrimaryDisplayId());
ramindanicdcfcaf2023-11-09 10:00:10 -08001921 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
1922 VtsComposerClient::kNoFrameIntervalNs);
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001923 writer.acceptDisplayChanges(getPrimaryDisplayId());
ramindanidcfe3a82021-11-29 17:00:31 +00001924 execute();
1925}
1926
ramindani431aad42022-02-01 21:44:29 +00001927TEST_P(GraphicsComposerAidlCommandTest, PresentDisplay) {
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001928 auto& writer = getWriter(getPrimaryDisplayId());
ramindanicdcfcaf2023-11-09 10:00:10 -08001929 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
1930 VtsComposerClient::kNoFrameIntervalNs);
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001931 writer.presentDisplay(getPrimaryDisplayId());
ramindanidcfe3a82021-11-29 17:00:31 +00001932 execute();
1933}
1934
1935/**
1936 * Test IComposerClient::Command::PRESENT_DISPLAY
1937 *
1938 * Test that IComposerClient::Command::PRESENT_DISPLAY works without
1939 * additional call to validateDisplay when only the layer buffer handle and
1940 * surface damage have been set
1941 */
ramindani431aad42022-02-01 21:44:29 +00001942TEST_P(GraphicsComposerAidlCommandTest, PresentDisplayNoLayerStateChanges) {
ramindani431aad42022-02-01 21:44:29 +00001943 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001944
ramindani431aad42022-02-01 21:44:29 +00001945 const auto& [renderIntentsStatus, renderIntents] =
1946 mComposerClient->getRenderIntents(getPrimaryDisplayId(), ColorMode::NATIVE);
1947 EXPECT_TRUE(renderIntentsStatus.isOk());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001948 auto& writer = getWriter(getPrimaryDisplayId());
ramindanidcfe3a82021-11-29 17:00:31 +00001949 for (auto intent : renderIntents) {
ramindani431aad42022-02-01 21:44:29 +00001950 EXPECT_TRUE(mComposerClient->setColorMode(getPrimaryDisplayId(), ColorMode::NATIVE, intent)
1951 .isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001952
Leon Scroggins IIIde057582022-01-13 12:26:00 -05001953 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ramindani3d18f922021-12-13 20:24:47 +00001954 const auto handle = buffer->handle;
ramindanidcfe3a82021-11-29 17:00:31 +00001955 ASSERT_NE(nullptr, handle);
1956
ramindani431aad42022-02-01 21:44:29 +00001957 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08001958 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00001959 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001960
ramindani431aad42022-02-01 21:44:29 +00001961 Rect displayFrame{0, 0, getPrimaryDisplay().getDisplayWidth(),
1962 getPrimaryDisplay().getDisplayHeight()};
1963 FRect cropRect{0, 0, (float)getPrimaryDisplay().getDisplayWidth(),
1964 (float)getPrimaryDisplay().getDisplayHeight()};
1965 configureLayer(getPrimaryDisplay(), layer, Composition::CURSOR, displayFrame, cropRect);
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001966 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle,
1967 /*acquireFence*/ -1);
1968 writer.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
ramindanicdcfcaf2023-11-09 10:00:10 -08001969 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
1970 VtsComposerClient::kNoFrameIntervalNs);
ramindanidcfe3a82021-11-29 17:00:31 +00001971 execute();
ramindani431aad42022-02-01 21:44:29 +00001972 if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
ramindanidcfe3a82021-11-29 17:00:31 +00001973 GTEST_SUCCEED() << "Composition change requested, skipping test";
1974 return;
1975 }
1976
Ady Abraham3192f3d2021-12-03 16:08:56 -08001977 ASSERT_TRUE(mReader.takeErrors().empty());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001978 writer.presentDisplay(getPrimaryDisplayId());
ramindanidcfe3a82021-11-29 17:00:31 +00001979 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08001980 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00001981
Leon Scroggins IIIde057582022-01-13 12:26:00 -05001982 const auto buffer2 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ramindani3d18f922021-12-13 20:24:47 +00001983 const auto handle2 = buffer2->handle;
ramindanidcfe3a82021-11-29 17:00:31 +00001984 ASSERT_NE(nullptr, handle2);
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001985 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle2,
1986 /*acquireFence*/ -1);
1987 writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer,
1988 std::vector<Rect>(1, {0, 0, 10, 10}));
1989 writer.presentDisplay(getPrimaryDisplayId());
ramindanidcfe3a82021-11-29 17:00:31 +00001990 execute();
1991 }
1992}
1993
ramindani431aad42022-02-01 21:44:29 +00001994TEST_P(GraphicsComposerAidlCommandTest, SetLayerCursorPosition) {
Ady Abrahama00d2462023-12-26 14:21:20 -08001995 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00001996 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08001997 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00001998 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001999
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002000 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ramindani3d18f922021-12-13 20:24:47 +00002001 const auto handle = buffer->handle;
ramindanidcfe3a82021-11-29 17:00:31 +00002002 ASSERT_NE(nullptr, handle);
ramindanidcfe3a82021-11-29 17:00:31 +00002003
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002004 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
ramindani431aad42022-02-01 21:44:29 +00002005
2006 Rect displayFrame{0, 0, getPrimaryDisplay().getDisplayWidth(),
2007 getPrimaryDisplay().getDisplayHeight()};
2008 FRect cropRect{0, 0, (float)getPrimaryDisplay().getDisplayWidth(),
2009 (float)getPrimaryDisplay().getDisplayHeight()};
2010 configureLayer(getPrimaryDisplay(), layer, Composition::CURSOR, displayFrame, cropRect);
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002011 writer.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
ramindanicdcfcaf2023-11-09 10:00:10 -08002012 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
2013 VtsComposerClient::kNoFrameIntervalNs);
ramindanidcfe3a82021-11-29 17:00:31 +00002014
2015 execute();
Ady Abraham46219f52021-12-20 09:44:31 -08002016
ramindani431aad42022-02-01 21:44:29 +00002017 if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
ramindanidcfe3a82021-11-29 17:00:31 +00002018 GTEST_SUCCEED() << "Composition change requested, skipping test";
2019 return;
2020 }
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002021 writer.presentDisplay(getPrimaryDisplayId());
Ady Abraham3192f3d2021-12-03 16:08:56 -08002022 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00002023
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002024 writer.setLayerCursorPosition(getPrimaryDisplayId(), layer, /*x*/ 1, /*y*/ 1);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002025 execute();
2026
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002027 writer.setLayerCursorPosition(getPrimaryDisplayId(), layer, /*x*/ 0, /*y*/ 0);
ramindanicdcfcaf2023-11-09 10:00:10 -08002028 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
2029 VtsComposerClient::kNoFrameIntervalNs);
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002030 writer.presentDisplay(getPrimaryDisplayId());
ramindanidcfe3a82021-11-29 17:00:31 +00002031 execute();
2032}
2033
ramindani431aad42022-02-01 21:44:29 +00002034TEST_P(GraphicsComposerAidlCommandTest, SetLayerBuffer) {
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002035 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ramindani3d18f922021-12-13 20:24:47 +00002036 const auto handle = buffer->handle;
ramindanidcfe3a82021-11-29 17:00:31 +00002037 ASSERT_NE(nullptr, handle);
2038
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002039 auto& writer = getWriter(getPrimaryDisplayId());
Ady Abrahama00d2462023-12-26 14:21:20 -08002040 const auto& [layerStatus, layer] =
2041 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2042 EXPECT_TRUE(layerStatus.isOk());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002043 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
ramindanidcfe3a82021-11-29 17:00:31 +00002044 execute();
2045}
2046
Brian Lindahl25e0d092022-12-09 00:32:11 -07002047TEST_P(GraphicsComposerAidlCommandTest, SetLayerBufferMultipleTimes) {
Brian Lindahl25e0d092022-12-09 00:32:11 -07002048 auto& writer = getWriter(getPrimaryDisplayId());
Ady Abrahama00d2462023-12-26 14:21:20 -08002049 const auto& [layerStatus, layer] =
2050 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2051 EXPECT_TRUE(layerStatus.isOk());
Brian Lindahl25e0d092022-12-09 00:32:11 -07002052
2053 // Setup 3 buffers in the buffer cache, with the last buffer being active. Then, emulate the
2054 // Android platform code that clears all 3 buffer slots by setting all but the active buffer
2055 // slot to a placeholder buffer, and then restoring the active buffer.
2056
2057 // This is used on HALs that don't support setLayerBufferSlotsToClear (version <= 3.1).
2058
2059 const auto buffer1 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2060 ASSERT_NE(nullptr, buffer1);
2061 const auto handle1 = buffer1->handle;
2062 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle1, /*acquireFence*/ -1);
2063 execute();
2064 ASSERT_TRUE(mReader.takeErrors().empty());
2065
2066 const auto buffer2 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2067 ASSERT_NE(nullptr, buffer2);
2068 const auto handle2 = buffer2->handle;
2069 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 1, handle2, /*acquireFence*/ -1);
2070 execute();
2071 ASSERT_TRUE(mReader.takeErrors().empty());
2072
2073 const auto buffer3 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2074 ASSERT_NE(nullptr, buffer3);
2075 const auto handle3 = buffer3->handle;
2076 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 2, handle3, /*acquireFence*/ -1);
2077 execute();
2078 ASSERT_TRUE(mReader.takeErrors().empty());
2079
2080 // Older versions of the HAL clear all but the active buffer slot with a placeholder buffer,
2081 // and then restoring the current active buffer at the end
2082 auto clearSlotBuffer = allocate(1u, 1u, ::android::PIXEL_FORMAT_RGB_888);
2083 ASSERT_NE(nullptr, clearSlotBuffer);
2084 auto clearSlotBufferHandle = clearSlotBuffer->handle;
2085
2086 // clear buffer slots 0 and 1 with new layer commands... and then...
2087 writer.setLayerBufferWithNewCommand(getPrimaryDisplayId(), layer, /* slot */ 0,
2088 clearSlotBufferHandle, /*acquireFence*/ -1);
2089 writer.setLayerBufferWithNewCommand(getPrimaryDisplayId(), layer, /* slot */ 1,
2090 clearSlotBufferHandle, /*acquireFence*/ -1);
2091 // ...reset the layer buffer to the current active buffer slot with a final new command
2092 writer.setLayerBufferWithNewCommand(getPrimaryDisplayId(), layer, /*slot*/ 2, nullptr,
2093 /*acquireFence*/ -1);
2094 execute();
2095 ASSERT_TRUE(mReader.takeErrors().empty());
2096}
2097
ramindani431aad42022-02-01 21:44:29 +00002098TEST_P(GraphicsComposerAidlCommandTest, SetLayerSurfaceDamage) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002099 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002100 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002101 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002102 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002103
2104 Rect empty{0, 0, 0, 0};
2105 Rect unit{0, 0, 1, 1};
2106
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002107 writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
ramindanidcfe3a82021-11-29 17:00:31 +00002108 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08002109 ASSERT_TRUE(mReader.takeErrors().empty());
2110
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002111 writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>(1, unit));
Ady Abraham3192f3d2021-12-03 16:08:56 -08002112 execute();
2113 ASSERT_TRUE(mReader.takeErrors().empty());
2114
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002115 writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>());
Ady Abraham3192f3d2021-12-03 16:08:56 -08002116 execute();
2117 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00002118}
2119
ramindani431aad42022-02-01 21:44:29 +00002120TEST_P(GraphicsComposerAidlCommandTest, SetLayerBlockingRegion) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002121 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002122 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002123 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002124 EXPECT_TRUE(layerStatus.isOk());
Leon Scroggins III03318152022-01-13 12:24:19 -05002125
2126 Rect empty{0, 0, 0, 0};
2127 Rect unit{0, 0, 1, 1};
2128
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002129 writer.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
Leon Scroggins III03318152022-01-13 12:24:19 -05002130 execute();
2131 ASSERT_TRUE(mReader.takeErrors().empty());
2132
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002133 writer.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, unit));
Leon Scroggins III03318152022-01-13 12:24:19 -05002134 execute();
2135 ASSERT_TRUE(mReader.takeErrors().empty());
2136
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002137 writer.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>());
Leon Scroggins III03318152022-01-13 12:24:19 -05002138 execute();
2139 ASSERT_TRUE(mReader.takeErrors().empty());
2140}
2141
ramindani431aad42022-02-01 21:44:29 +00002142TEST_P(GraphicsComposerAidlCommandTest, SetLayerBlendMode) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002143 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002144 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002145 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002146 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002147
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002148 writer.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::NONE);
ramindanidcfe3a82021-11-29 17:00:31 +00002149 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08002150 ASSERT_TRUE(mReader.takeErrors().empty());
2151
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002152 writer.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::PREMULTIPLIED);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002153 execute();
2154 ASSERT_TRUE(mReader.takeErrors().empty());
2155
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002156 writer.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::COVERAGE);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002157 execute();
2158 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00002159}
2160
ramindani431aad42022-02-01 21:44:29 +00002161TEST_P(GraphicsComposerAidlCommandTest, SetLayerColor) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002162 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002163 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002164 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002165 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002166
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002167 writer.setLayerColor(getPrimaryDisplayId(), layer, Color{1.0f, 1.0f, 1.0f, 1.0f});
ramindanidcfe3a82021-11-29 17:00:31 +00002168 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08002169 ASSERT_TRUE(mReader.takeErrors().empty());
2170
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002171 writer.setLayerColor(getPrimaryDisplayId(), layer, Color{0.0f, 0.0f, 0.0f, 0.0f});
Ady Abraham3192f3d2021-12-03 16:08:56 -08002172 execute();
2173 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00002174}
2175
ramindani431aad42022-02-01 21:44:29 +00002176TEST_P(GraphicsComposerAidlCommandTest, SetLayerCompositionType) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002177 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002178 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002179 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002180 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002181
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002182 writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::CLIENT);
ramindanidcfe3a82021-11-29 17:00:31 +00002183 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08002184 ASSERT_TRUE(mReader.takeErrors().empty());
2185
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002186 writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::DEVICE);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002187 execute();
2188 ASSERT_TRUE(mReader.takeErrors().empty());
2189
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002190 writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::SOLID_COLOR);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002191 execute();
2192 ASSERT_TRUE(mReader.takeErrors().empty());
2193
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002194 writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::CURSOR);
ramindani431aad42022-02-01 21:44:29 +00002195 execute();
2196}
2197
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002198TEST_P(GraphicsComposerAidlCommandTest, DisplayDecoration) {
2199 for (VtsDisplay& display : mDisplays) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002200 auto& writer = getWriter(display.getDisplayId());
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002201 const auto [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002202 mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount, &writer);
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002203 EXPECT_TRUE(layerStatus.isOk());
2204
2205 const auto [error, support] =
2206 mComposerClient->getDisplayDecorationSupport(display.getDisplayId());
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002207
Leon Scroggins III91590872022-02-23 09:51:21 -05002208 const auto format = (error.isOk() && support) ? support->format
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002209 : aidl::android::hardware::graphics::common::PixelFormat::RGBA_8888;
2210 const auto decorBuffer = allocate(static_cast<::android::PixelFormat>(format));
2211 ASSERT_NE(nullptr, decorBuffer);
2212 if (::android::OK != decorBuffer->initCheck()) {
2213 if (support) {
2214 FAIL() << "Device advertised display decoration support with format "
2215 << aidl::android::hardware::graphics::common::toString(format)
2216 << " but failed to allocate it!";
2217 } else {
2218 FAIL() << "Device advertised NO display decoration support, but it should "
2219 << "still be able to allocate "
2220 << aidl::android::hardware::graphics::common::toString(format);
2221 }
2222 }
2223
Midas Chien7d55d422022-06-07 02:32:28 +08002224 configureLayer(display, layer, Composition::DISPLAY_DECORATION, display.getFrameRect(),
Ady Abrahama00d2462023-12-26 14:21:20 -08002225 display.getCrop());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002226 writer.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, decorBuffer->handle,
2227 /*acquireFence*/ -1);
ramindanicdcfcaf2023-11-09 10:00:10 -08002228 writer.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp,
2229 VtsComposerClient::kNoFrameIntervalNs);
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002230 execute();
2231 if (support) {
2232 ASSERT_TRUE(mReader.takeErrors().empty());
2233 } else {
2234 const auto errors = mReader.takeErrors();
2235 ASSERT_EQ(1, errors.size());
Leon Scroggins III6455e792022-02-24 12:18:58 -05002236 EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, errors[0].errorCode);
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002237 }
2238 }
2239}
2240
ramindani431aad42022-02-01 21:44:29 +00002241TEST_P(GraphicsComposerAidlCommandTest, SetLayerDataspace) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002242 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002243 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002244 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002245 EXPECT_TRUE(layerStatus.isOk());
2246
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002247 writer.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
ramindani431aad42022-02-01 21:44:29 +00002248 execute();
2249}
2250
2251TEST_P(GraphicsComposerAidlCommandTest, SetLayerDisplayFrame) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002252 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002253 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002254 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002255 EXPECT_TRUE(layerStatus.isOk());
2256
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002257 writer.setLayerDisplayFrame(getPrimaryDisplayId(), layer, Rect{0, 0, 1, 1});
ramindani431aad42022-02-01 21:44:29 +00002258 execute();
2259}
2260
2261TEST_P(GraphicsComposerAidlCommandTest, SetLayerPlaneAlpha) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002262 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002263 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002264 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002265 EXPECT_TRUE(layerStatus.isOk());
2266
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002267 writer.setLayerPlaneAlpha(getPrimaryDisplayId(), layer, /*alpha*/ 0.0f);
ramindani431aad42022-02-01 21:44:29 +00002268 execute();
2269 ASSERT_TRUE(mReader.takeErrors().empty());
2270
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002271 writer.setLayerPlaneAlpha(getPrimaryDisplayId(), layer, /*alpha*/ 1.0f);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002272 execute();
2273 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00002274}
2275
ramindani431aad42022-02-01 21:44:29 +00002276TEST_P(GraphicsComposerAidlCommandTest, SetLayerSidebandStream) {
Jason Macnak325e8232022-01-24 14:48:55 -08002277 if (!hasCapability(Capability::SIDEBAND_STREAM)) {
ramindanidcfe3a82021-11-29 17:00:31 +00002278 GTEST_SUCCEED() << "no sideband stream support";
2279 return;
2280 }
2281
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002282 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ramindani3d18f922021-12-13 20:24:47 +00002283 const auto handle = buffer->handle;
ramindanidcfe3a82021-11-29 17:00:31 +00002284 ASSERT_NE(nullptr, handle);
2285
Ady Abrahama00d2462023-12-26 14:21:20 -08002286 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002287 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002288 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002289 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002290
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002291 writer.setLayerSidebandStream(getPrimaryDisplayId(), layer, handle);
ramindanidcfe3a82021-11-29 17:00:31 +00002292 execute();
2293}
2294
ramindani431aad42022-02-01 21:44:29 +00002295TEST_P(GraphicsComposerAidlCommandTest, SetLayerSourceCrop) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002296 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002297 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002298 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002299 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002300
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002301 writer.setLayerSourceCrop(getPrimaryDisplayId(), layer, FRect{0.0f, 0.0f, 1.0f, 1.0f});
ramindanidcfe3a82021-11-29 17:00:31 +00002302 execute();
2303}
2304
ramindani431aad42022-02-01 21:44:29 +00002305TEST_P(GraphicsComposerAidlCommandTest, SetLayerTransform) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002306 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002307 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002308 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002309 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002310
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002311 writer.setLayerTransform(getPrimaryDisplayId(), layer, static_cast<Transform>(0));
ramindanidcfe3a82021-11-29 17:00:31 +00002312 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08002313 ASSERT_TRUE(mReader.takeErrors().empty());
2314
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002315 writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::FLIP_H);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002316 execute();
2317 ASSERT_TRUE(mReader.takeErrors().empty());
2318
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002319 writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::FLIP_V);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002320 execute();
2321 ASSERT_TRUE(mReader.takeErrors().empty());
2322
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002323 writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::ROT_90);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002324 execute();
2325 ASSERT_TRUE(mReader.takeErrors().empty());
2326
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002327 writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::ROT_180);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002328 execute();
2329 ASSERT_TRUE(mReader.takeErrors().empty());
2330
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002331 writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::ROT_270);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002332 execute();
2333 ASSERT_TRUE(mReader.takeErrors().empty());
2334
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002335 writer.setLayerTransform(getPrimaryDisplayId(), layer,
2336 static_cast<Transform>(static_cast<int>(Transform::FLIP_H) |
2337 static_cast<int>(Transform::ROT_90)));
Ady Abraham3192f3d2021-12-03 16:08:56 -08002338 execute();
2339 ASSERT_TRUE(mReader.takeErrors().empty());
2340
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002341 writer.setLayerTransform(getPrimaryDisplayId(), layer,
2342 static_cast<Transform>(static_cast<int>(Transform::FLIP_V) |
2343 static_cast<int>(Transform::ROT_90)));
Ady Abraham3192f3d2021-12-03 16:08:56 -08002344 execute();
2345 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00002346}
2347
ramindani431aad42022-02-01 21:44:29 +00002348TEST_P(GraphicsComposerAidlCommandTest, SetLayerVisibleRegion) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002349 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002350 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002351 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002352 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002353
2354 Rect empty{0, 0, 0, 0};
2355 Rect unit{0, 0, 1, 1};
2356
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002357 writer.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
ramindanidcfe3a82021-11-29 17:00:31 +00002358 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08002359 ASSERT_TRUE(mReader.takeErrors().empty());
2360
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002361 writer.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, unit));
Ady Abraham3192f3d2021-12-03 16:08:56 -08002362 execute();
2363 ASSERT_TRUE(mReader.takeErrors().empty());
2364
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002365 writer.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>());
Ady Abraham3192f3d2021-12-03 16:08:56 -08002366 execute();
2367 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00002368}
2369
ramindani431aad42022-02-01 21:44:29 +00002370TEST_P(GraphicsComposerAidlCommandTest, SetLayerZOrder) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002371 auto& writer = getWriter(getPrimaryDisplayId());
2372
ramindani431aad42022-02-01 21:44:29 +00002373 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002374 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002375 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002376
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002377 writer.setLayerZOrder(getPrimaryDisplayId(), layer, /*z*/ 10);
ramindanidcfe3a82021-11-29 17:00:31 +00002378 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08002379 ASSERT_TRUE(mReader.takeErrors().empty());
2380
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002381 writer.setLayerZOrder(getPrimaryDisplayId(), layer, /*z*/ 0);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002382 execute();
2383 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00002384}
2385
ramindani431aad42022-02-01 21:44:29 +00002386TEST_P(GraphicsComposerAidlCommandTest, SetLayerPerFrameMetadata) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002387 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002388 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002389 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002390 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002391
ramindanidcfe3a82021-11-29 17:00:31 +00002392 /**
2393 * DISPLAY_P3 is a color space that uses the DCI_P3 primaries,
2394 * the D65 white point and the SRGB transfer functions.
2395 * Rendering Intent: Colorimetric
2396 * Primaries:
2397 * x y
2398 * green 0.265 0.690
2399 * blue 0.150 0.060
2400 * red 0.680 0.320
2401 * white (D65) 0.3127 0.3290
2402 */
2403
2404 std::vector<PerFrameMetadata> aidlMetadata;
2405 aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X, 0.680f});
2406 aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y, 0.320f});
2407 aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X, 0.265f});
2408 aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y, 0.690f});
2409 aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X, 0.150f});
2410 aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y, 0.060f});
2411 aidlMetadata.push_back({PerFrameMetadataKey::WHITE_POINT_X, 0.3127f});
2412 aidlMetadata.push_back({PerFrameMetadataKey::WHITE_POINT_Y, 0.3290f});
2413 aidlMetadata.push_back({PerFrameMetadataKey::MAX_LUMINANCE, 100.0f});
2414 aidlMetadata.push_back({PerFrameMetadataKey::MIN_LUMINANCE, 0.1f});
2415 aidlMetadata.push_back({PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL, 78.0});
2416 aidlMetadata.push_back({PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, 62.0});
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002417 writer.setLayerPerFrameMetadata(getPrimaryDisplayId(), layer, aidlMetadata);
ramindanidcfe3a82021-11-29 17:00:31 +00002418 execute();
2419
Ady Abraham3192f3d2021-12-03 16:08:56 -08002420 const auto errors = mReader.takeErrors();
2421 if (errors.size() == 1 && errors[0].errorCode == EX_UNSUPPORTED_OPERATION) {
ramindanidcfe3a82021-11-29 17:00:31 +00002422 GTEST_SUCCEED() << "SetLayerPerFrameMetadata is not supported";
Ady Abrahama00d2462023-12-26 14:21:20 -08002423 EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, &writer).isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002424 return;
2425 }
2426
Ady Abrahama00d2462023-12-26 14:21:20 -08002427 EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, &writer).isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002428}
2429
Alec Mourib1f16722022-02-07 13:03:44 -08002430TEST_P(GraphicsComposerAidlCommandTest, setLayerBrightness) {
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002431 auto& writer = getWriter(getPrimaryDisplayId());
Ady Abrahama00d2462023-12-26 14:21:20 -08002432
2433 const auto& [layerStatus, layer] =
2434 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2435
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002436 writer.setLayerBrightness(getPrimaryDisplayId(), layer, 0.2f);
Alec Mouri95e490b2022-01-06 13:46:58 -08002437 execute();
2438 ASSERT_TRUE(mReader.takeErrors().empty());
2439
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002440 writer.setLayerBrightness(getPrimaryDisplayId(), layer, 1.f);
Alec Mouri95e490b2022-01-06 13:46:58 -08002441 execute();
2442 ASSERT_TRUE(mReader.takeErrors().empty());
2443
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002444 writer.setLayerBrightness(getPrimaryDisplayId(), layer, 0.f);
Alec Mouri95e490b2022-01-06 13:46:58 -08002445 execute();
2446 ASSERT_TRUE(mReader.takeErrors().empty());
2447
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002448 writer.setLayerBrightness(getPrimaryDisplayId(), layer, -1.f);
Alec Mouri95e490b2022-01-06 13:46:58 -08002449 execute();
Alec Mourib1f16722022-02-07 13:03:44 -08002450 {
2451 const auto errors = mReader.takeErrors();
2452 ASSERT_EQ(1, errors.size());
2453 EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
2454 }
2455
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002456 writer.setLayerBrightness(getPrimaryDisplayId(), layer, std::nanf(""));
Alec Mourib1f16722022-02-07 13:03:44 -08002457 execute();
2458 {
2459 const auto errors = mReader.takeErrors();
2460 ASSERT_EQ(1, errors.size());
2461 EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
2462 }
Alec Mouri95e490b2022-01-06 13:46:58 -08002463}
2464
ramindani431aad42022-02-01 21:44:29 +00002465TEST_P(GraphicsComposerAidlCommandTest, SetActiveConfigWithConstraints) {
ramindanidcfe3a82021-11-29 17:00:31 +00002466 Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = false});
2467}
2468
ramindani431aad42022-02-01 21:44:29 +00002469TEST_P(GraphicsComposerAidlCommandTest, SetActiveConfigWithConstraints_Delayed) {
ramindanidcfe3a82021-11-29 17:00:31 +00002470 Test_setActiveConfigWithConstraints({.delayForChange = 300'000'000, // 300ms
2471 .refreshMiss = false});
2472}
2473
ramindani431aad42022-02-01 21:44:29 +00002474TEST_P(GraphicsComposerAidlCommandTest, SetActiveConfigWithConstraints_MissRefresh) {
ramindanidcfe3a82021-11-29 17:00:31 +00002475 Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = true});
2476}
2477
ramindani431aad42022-02-01 21:44:29 +00002478TEST_P(GraphicsComposerAidlCommandTest, GetDisplayVsyncPeriod) {
ramindanidcfe3a82021-11-29 17:00:31 +00002479 for (VtsDisplay& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +00002480 const auto& [status, configs] = mComposerClient->getDisplayConfigs(display.getDisplayId());
2481 EXPECT_TRUE(status.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002482
ramindani431aad42022-02-01 21:44:29 +00002483 for (int32_t config : configs) {
2484 int32_t expectedVsyncPeriodNanos = display.getDisplayConfig(config).vsyncPeriod;
2485
ramindanidcfe3a82021-11-29 17:00:31 +00002486 VsyncPeriodChangeConstraints constraints;
2487
2488 constraints.desiredTimeNanos = systemTime();
2489 constraints.seamlessRequired = false;
ramindani431aad42022-02-01 21:44:29 +00002490
2491 const auto& [timelineStatus, timeline] =
2492 mComposerClient->setActiveConfigWithConstraints(&display, config, constraints);
2493 EXPECT_TRUE(timelineStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002494
2495 if (timeline.refreshRequired) {
2496 sendRefreshFrame(display, &timeline);
2497 }
ramindani431aad42022-02-01 21:44:29 +00002498 waitForVsyncPeriodChange(display.getDisplayId(), timeline, constraints.desiredTimeNanos,
2499 /*odPeriodNanos*/ 0, expectedVsyncPeriodNanos);
ramindanidcfe3a82021-11-29 17:00:31 +00002500
2501 int32_t vsyncPeriodNanos;
2502 int retryCount = 100;
2503 do {
2504 std::this_thread::sleep_for(10ms);
ramindani431aad42022-02-01 21:44:29 +00002505 const auto& [vsyncPeriodNanosStatus, vsyncPeriodNanosValue] =
2506 mComposerClient->getDisplayVsyncPeriod(display.getDisplayId());
2507
2508 EXPECT_TRUE(vsyncPeriodNanosStatus.isOk());
2509 vsyncPeriodNanos = vsyncPeriodNanosValue;
ramindanidcfe3a82021-11-29 17:00:31 +00002510 --retryCount;
2511 } while (vsyncPeriodNanos != expectedVsyncPeriodNanos && retryCount > 0);
2512
2513 EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
2514
2515 // Make sure that the vsync period stays the same if the active config is not
2516 // changed.
2517 auto timeout = 1ms;
2518 for (int i = 0; i < 10; i++) {
2519 std::this_thread::sleep_for(timeout);
2520 timeout *= 2;
2521 vsyncPeriodNanos = 0;
ramindani431aad42022-02-01 21:44:29 +00002522 const auto& [vsyncPeriodNanosStatus, vsyncPeriodNanosValue] =
2523 mComposerClient->getDisplayVsyncPeriod(display.getDisplayId());
2524
2525 EXPECT_TRUE(vsyncPeriodNanosStatus.isOk());
2526 vsyncPeriodNanos = vsyncPeriodNanosValue;
ramindanidcfe3a82021-11-29 17:00:31 +00002527 EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
2528 }
2529 }
2530 }
2531}
2532
ramindani431aad42022-02-01 21:44:29 +00002533TEST_P(GraphicsComposerAidlCommandTest, SetActiveConfigWithConstraints_SeamlessNotAllowed) {
ramindanidcfe3a82021-11-29 17:00:31 +00002534 VsyncPeriodChangeConstraints constraints;
ramindanidcfe3a82021-11-29 17:00:31 +00002535 constraints.seamlessRequired = true;
2536 constraints.desiredTimeNanos = systemTime();
2537
2538 for (VtsDisplay& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +00002539 forEachTwoConfigs(display.getDisplayId(), [&](int32_t config1, int32_t config2) {
2540 int32_t configGroup1 = display.getDisplayConfig(config1).configGroup;
2541 int32_t configGroup2 = display.getDisplayConfig(config2).configGroup;
ramindanidcfe3a82021-11-29 17:00:31 +00002542 if (configGroup1 != configGroup2) {
ramindani431aad42022-02-01 21:44:29 +00002543 EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config1).isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002544 sendRefreshFrame(display, nullptr);
ramindani431aad42022-02-01 21:44:29 +00002545 const auto& [status, _] = mComposerClient->setActiveConfigWithConstraints(
2546 &display, config2, constraints);
2547 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +00002548 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(
2549 status, IComposerClient::EX_SEAMLESS_NOT_ALLOWED));
ramindanidcfe3a82021-11-29 17:00:31 +00002550 }
2551 });
2552 }
2553}
2554
ramindani431aad42022-02-01 21:44:29 +00002555TEST_P(GraphicsComposerAidlCommandTest, ExpectedPresentTime_NoTimestamp) {
2556 ASSERT_NO_FATAL_FAILURE(Test_expectedPresentTime(/*framesDelay*/ std::nullopt));
Ady Abraham72c5b502021-12-10 17:23:39 -08002557}
2558
ramindani431aad42022-02-01 21:44:29 +00002559TEST_P(GraphicsComposerAidlCommandTest, ExpectedPresentTime_0) {
2560 ASSERT_NO_FATAL_FAILURE(Test_expectedPresentTime(/*framesDelay*/ 0));
Ady Abraham72c5b502021-12-10 17:23:39 -08002561}
2562
ramindani431aad42022-02-01 21:44:29 +00002563TEST_P(GraphicsComposerAidlCommandTest, ExpectedPresentTime_5) {
2564 ASSERT_NO_FATAL_FAILURE(Test_expectedPresentTime(/*framesDelay*/ 5));
Ady Abraham72c5b502021-12-10 17:23:39 -08002565}
2566
ramindani431aad42022-02-01 21:44:29 +00002567TEST_P(GraphicsComposerAidlCommandTest, SetIdleTimerEnabled_Unsupported) {
2568 const bool hasDisplayIdleTimerSupport =
2569 hasDisplayCapability(getPrimaryDisplayId(), DisplayCapability::DISPLAY_IDLE_TIMER);
Midas Chiena0b56bd2022-01-13 23:27:33 +08002570 if (!hasDisplayIdleTimerSupport) {
ramindani431aad42022-02-01 21:44:29 +00002571 const auto& status =
2572 mComposerClient->setIdleTimerEnabled(getPrimaryDisplayId(), /*timeout*/ 0);
2573 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +00002574 EXPECT_NO_FATAL_FAILURE(
2575 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
Midas Chiena0b56bd2022-01-13 23:27:33 +08002576 }
2577}
2578
ramindani431aad42022-02-01 21:44:29 +00002579TEST_P(GraphicsComposerAidlCommandTest, SetIdleTimerEnabled_BadParameter) {
2580 const bool hasDisplayIdleTimerSupport =
2581 hasDisplayCapability(getPrimaryDisplayId(), DisplayCapability::DISPLAY_IDLE_TIMER);
Midas Chiena0b56bd2022-01-13 23:27:33 +08002582 if (!hasDisplayIdleTimerSupport) {
2583 GTEST_SUCCEED() << "DisplayCapability::DISPLAY_IDLE_TIMER is not supported";
2584 return;
2585 }
2586
ramindani431aad42022-02-01 21:44:29 +00002587 const auto& status =
2588 mComposerClient->setIdleTimerEnabled(getPrimaryDisplayId(), /*timeout*/ -1);
2589 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +00002590 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_PARAMETER));
Midas Chiena0b56bd2022-01-13 23:27:33 +08002591}
2592
ramindani431aad42022-02-01 21:44:29 +00002593TEST_P(GraphicsComposerAidlCommandTest, SetIdleTimerEnabled_Disable) {
2594 const bool hasDisplayIdleTimerSupport =
2595 hasDisplayCapability(getPrimaryDisplayId(), DisplayCapability::DISPLAY_IDLE_TIMER);
Midas Chiena0b56bd2022-01-13 23:27:33 +08002596 if (!hasDisplayIdleTimerSupport) {
2597 GTEST_SUCCEED() << "DisplayCapability::DISPLAY_IDLE_TIMER is not supported";
2598 return;
2599 }
2600
ramindani431aad42022-02-01 21:44:29 +00002601 EXPECT_TRUE(mComposerClient->setIdleTimerEnabled(getPrimaryDisplayId(), /*timeout*/ 0).isOk());
Midas Chiena0b56bd2022-01-13 23:27:33 +08002602 std::this_thread::sleep_for(1s);
ramindani431aad42022-02-01 21:44:29 +00002603 EXPECT_EQ(0, mComposerClient->getVsyncIdleCount());
Midas Chiena0b56bd2022-01-13 23:27:33 +08002604}
2605
ramindani431aad42022-02-01 21:44:29 +00002606TEST_P(GraphicsComposerAidlCommandTest, SetIdleTimerEnabled_Timeout_2) {
2607 const bool hasDisplayIdleTimerSupport =
2608 hasDisplayCapability(getPrimaryDisplayId(), DisplayCapability::DISPLAY_IDLE_TIMER);
Midas Chiena0b56bd2022-01-13 23:27:33 +08002609 if (!hasDisplayIdleTimerSupport) {
2610 GTEST_SUCCEED() << "DisplayCapability::DISPLAY_IDLE_TIMER is not supported";
2611 return;
2612 }
2613
ramindani431aad42022-02-01 21:44:29 +00002614 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
2615 EXPECT_TRUE(mComposerClient->setIdleTimerEnabled(getPrimaryDisplayId(), /*timeout*/ 0).isOk());
Midas Chiena0b56bd2022-01-13 23:27:33 +08002616
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002617 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
Midas Chiena0b56bd2022-01-13 23:27:33 +08002618 ASSERT_NE(nullptr, buffer->handle);
2619
ramindanifc93b732024-02-15 21:36:19 +00002620 const auto layer = createOnScreenLayer(getPrimaryDisplay());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002621 auto& writer = getWriter(getPrimaryDisplayId());
2622 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer->handle,
2623 /*acquireFence*/ -1);
ramindani431aad42022-02-01 21:44:29 +00002624 int32_t vsyncIdleCount = mComposerClient->getVsyncIdleCount();
Midas Chiena0b56bd2022-01-13 23:27:33 +08002625 auto earlyVsyncIdleTime = systemTime() + std::chrono::nanoseconds(2s).count();
ramindani431aad42022-02-01 21:44:29 +00002626 EXPECT_TRUE(
2627 mComposerClient->setIdleTimerEnabled(getPrimaryDisplayId(), /*timeout*/ 2000).isOk());
Midas Chiena0b56bd2022-01-13 23:27:33 +08002628
2629 const sp<::android::Fence> presentFence =
ramindani431aad42022-02-01 21:44:29 +00002630 presentAndGetFence(ComposerClientWriter::kNoTimestamp);
Midas Chiena0b56bd2022-01-13 23:27:33 +08002631 presentFence->waitForever(LOG_TAG);
2632
2633 std::this_thread::sleep_for(3s);
ramindani431aad42022-02-01 21:44:29 +00002634 if (vsyncIdleCount < mComposerClient->getVsyncIdleCount()) {
2635 EXPECT_GE(mComposerClient->getVsyncIdleTime(), earlyVsyncIdleTime);
Midas Chiena0b56bd2022-01-13 23:27:33 +08002636 }
2637
ramindani431aad42022-02-01 21:44:29 +00002638 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
Midas Chiena0b56bd2022-01-13 23:27:33 +08002639}
2640
ramindani12423f52023-06-14 20:04:51 -07002641class GraphicsComposerAidlCommandV2Test : public GraphicsComposerAidlCommandTest {
2642 protected:
2643 void SetUp() override {
2644 GraphicsComposerAidlTest::SetUp();
2645 if (getInterfaceVersion() <= 1) {
2646 GTEST_SKIP() << "Device interface version is expected to be >= 2";
2647 }
ramindani17c71102023-03-20 10:51:14 -07002648 }
ramindani12423f52023-06-14 20:04:51 -07002649};
2650/**
2651 * Test Capability::SKIP_VALIDATE
2652 *
2653 * Capability::SKIP_VALIDATE has been deprecated and should not be enabled.
2654 */
2655TEST_P(GraphicsComposerAidlCommandV2Test, SkipValidateDeprecatedTest) {
Leon Scroggins III79d7ae82023-10-11 16:03:52 -04002656#pragma clang diagnostic push
2657#pragma clang diagnostic ignored "-Wdeprecated-declarations"
ramindani12423f52023-06-14 20:04:51 -07002658 ASSERT_FALSE(hasCapability(Capability::SKIP_VALIDATE))
2659 << "Found Capability::SKIP_VALIDATE capability.";
Leon Scroggins III79d7ae82023-10-11 16:03:52 -04002660#pragma clang diagnostic pop
ramindani12423f52023-06-14 20:04:51 -07002661}
2662
2663TEST_P(GraphicsComposerAidlCommandV2Test, SetLayerBufferSlotsToClear) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002664 auto& writer = getWriter(getPrimaryDisplayId());
ramindani12423f52023-06-14 20:04:51 -07002665 // Older HAL versions use a backwards compatible way of clearing buffer slots
2666 // HAL at version 1 or lower does not have LayerCommand::bufferSlotsToClear
2667 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002668 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani12423f52023-06-14 20:04:51 -07002669 EXPECT_TRUE(layerStatus.isOk());
ramindani12423f52023-06-14 20:04:51 -07002670
2671 // setup 3 buffers in the buffer cache, with the last buffer being active
2672 // then emulate the Android platform code that clears all 3 buffer slots
2673
2674 const auto buffer1 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2675 ASSERT_NE(nullptr, buffer1);
2676 const auto handle1 = buffer1->handle;
2677 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle1, /*acquireFence*/ -1);
2678 execute();
2679 ASSERT_TRUE(mReader.takeErrors().empty());
2680
2681 const auto buffer2 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2682 ASSERT_NE(nullptr, buffer2);
2683 const auto handle2 = buffer2->handle;
2684 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 1, handle2, /*acquireFence*/ -1);
2685 execute();
2686 ASSERT_TRUE(mReader.takeErrors().empty());
2687
2688 const auto buffer3 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2689 ASSERT_NE(nullptr, buffer3);
2690 const auto handle3 = buffer3->handle;
2691 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 2, handle3, /*acquireFence*/ -1);
2692 execute();
2693 ASSERT_TRUE(mReader.takeErrors().empty());
2694
2695 // Ensure we can clear all 3 buffer slots, even the active buffer - it is assumed the
2696 // current active buffer's slot will be cleared, but still remain the active buffer and no
2697 // errors will occur.
2698 writer.setLayerBufferSlotsToClear(getPrimaryDisplayId(), layer, {0, 1, 2});
2699 execute();
2700 ASSERT_TRUE(mReader.takeErrors().empty());
2701}
2702
2703TEST_P(GraphicsComposerAidlCommandV2Test, SetRefreshRateChangedCallbackDebug_Unsupported) {
ramindani9dd8c482023-02-21 18:07:56 -08002704 if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
2705 auto status = mComposerClient->setRefreshRateChangedCallbackDebugEnabled(
2706 getPrimaryDisplayId(), /*enabled*/ true);
2707 EXPECT_FALSE(status.isOk());
2708 EXPECT_NO_FATAL_FAILURE(
2709 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
2710
2711 status = mComposerClient->setRefreshRateChangedCallbackDebugEnabled(getPrimaryDisplayId(),
2712 /*enabled*/ false);
2713 EXPECT_FALSE(status.isOk());
2714 EXPECT_NO_FATAL_FAILURE(
2715 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
2716 }
2717}
2718
ramindani12423f52023-06-14 20:04:51 -07002719TEST_P(GraphicsComposerAidlCommandV2Test, SetRefreshRateChangedCallbackDebug_Enabled) {
ramindani9dd8c482023-02-21 18:07:56 -08002720 if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
2721 GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported";
2722 return;
2723 }
2724
ramindania2a6dea2023-12-11 13:42:36 -08002725 for (VtsDisplay& display : mDisplays) {
2726 const auto displayId = display.getDisplayId();
2727 EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
2728 // Enable the callback
2729 ASSERT_TRUE(mComposerClient
2730 ->setRefreshRateChangedCallbackDebugEnabled(displayId,
2731 /*enabled*/ true)
2732 .isOk());
2733 std::this_thread::sleep_for(100ms);
ramindani9dd8c482023-02-21 18:07:56 -08002734
ramindania2a6dea2023-12-11 13:42:36 -08002735 const auto [status, configId] = mComposerClient->getActiveConfig(display.getDisplayId());
2736 EXPECT_TRUE(status.isOk());
ramindani9dd8c482023-02-21 18:07:56 -08002737
ramindania2a6dea2023-12-11 13:42:36 -08002738 const auto displayFilter = [&](auto refreshRateChangedDebugData) {
2739 bool nonVrrRateMatching = true;
2740 if (std::optional<VrrConfig> vrrConfigOpt =
2741 display.getDisplayConfig(configId).vrrConfig;
2742 getInterfaceVersion() >= 3 && !vrrConfigOpt) {
2743 nonVrrRateMatching = refreshRateChangedDebugData.refreshPeriodNanos ==
2744 refreshRateChangedDebugData.vsyncPeriodNanos;
2745 }
2746 const bool isDisplaySame =
2747 display.getDisplayId() == refreshRateChangedDebugData.display;
2748 return nonVrrRateMatching && isDisplaySame;
2749 };
ramindani9dd8c482023-02-21 18:07:56 -08002750
ramindania2a6dea2023-12-11 13:42:36 -08002751 // Check that we immediately got a callback
2752 EXPECT_TRUE(checkIfCallbackRefreshRateChangedDebugEnabledReceived(displayFilter));
2753
2754 ASSERT_TRUE(mComposerClient
2755 ->setRefreshRateChangedCallbackDebugEnabled(displayId,
2756 /*enabled*/ false)
2757 .isOk());
2758 }
ramindani9dd8c482023-02-21 18:07:56 -08002759}
2760
ramindani12423f52023-06-14 20:04:51 -07002761TEST_P(GraphicsComposerAidlCommandV2Test,
ramindani9dd8c482023-02-21 18:07:56 -08002762 SetRefreshRateChangedCallbackDebugEnabled_noCallbackWhenIdle) {
2763 if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
2764 GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported";
2765 return;
2766 }
2767
2768 auto display = getEditablePrimaryDisplay();
2769 const auto displayId = display.getDisplayId();
2770
2771 if (!hasDisplayCapability(displayId, DisplayCapability::DISPLAY_IDLE_TIMER)) {
2772 GTEST_SUCCEED() << "DisplayCapability::DISPLAY_IDLE_TIMER is not supported";
2773 return;
2774 }
2775
2776 EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
2777 EXPECT_TRUE(mComposerClient->setPeakRefreshRateConfig(&display).isOk());
2778
2779 ASSERT_TRUE(mComposerClient->setIdleTimerEnabled(displayId, /*timeoutMs*/ 500).isOk());
2780 // Enable the callback
2781 ASSERT_TRUE(mComposerClient
2782 ->setRefreshRateChangedCallbackDebugEnabled(displayId,
2783 /*enabled*/ true)
2784 .isOk());
2785
ramindani91518892023-03-03 16:55:09 +00002786 const auto displayFilter = [displayId](auto refreshRateChangedDebugData) {
2787 return displayId == refreshRateChangedDebugData.display;
2788 };
ramindani9dd8c482023-02-21 18:07:56 -08002789
2790 int retryCount = 3;
2791 do {
2792 // Wait for 1s so that we enter the idle state
2793 std::this_thread::sleep_for(1s);
ramindani91518892023-03-03 16:55:09 +00002794 if (!checkIfCallbackRefreshRateChangedDebugEnabledReceived(displayFilter)) {
ramindani9dd8c482023-02-21 18:07:56 -08002795 // DID NOT receive a callback, we are in the idle state.
2796 break;
2797 }
2798 } while (--retryCount > 0);
2799
2800 if (retryCount == 0) {
2801 GTEST_SUCCEED() << "Unable to enter the idle mode";
2802 return;
2803 }
2804
2805 // Send the REFRESH_RATE_INDICATOR update
ramindanifc93b732024-02-15 21:36:19 +00002806 ASSERT_NO_FATAL_FAILURE(sendBufferUpdate(
2807 createOnScreenLayer(getPrimaryDisplay(), Composition::REFRESH_RATE_INDICATOR)));
ramindani9dd8c482023-02-21 18:07:56 -08002808 std::this_thread::sleep_for(1s);
ramindani91518892023-03-03 16:55:09 +00002809 EXPECT_FALSE(checkIfCallbackRefreshRateChangedDebugEnabledReceived(displayFilter))
ramindani9dd8c482023-02-21 18:07:56 -08002810 << "A callback should not be received for REFRESH_RATE_INDICATOR";
2811
2812 EXPECT_TRUE(mComposerClient
2813 ->setRefreshRateChangedCallbackDebugEnabled(displayId,
2814 /*enabled*/ false)
2815 .isOk());
2816}
2817
ramindani12423f52023-06-14 20:04:51 -07002818TEST_P(GraphicsComposerAidlCommandV2Test,
ramindani9dd8c482023-02-21 18:07:56 -08002819 SetRefreshRateChangedCallbackDebugEnabled_SetActiveConfigWithConstraints) {
2820 if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
2821 GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported";
2822 return;
2823 }
2824
2825 VsyncPeriodChangeConstraints constraints;
2826 constraints.seamlessRequired = false;
2827 constraints.desiredTimeNanos = systemTime();
2828
2829 for (VtsDisplay& display : mDisplays) {
2830 const auto displayId = display.getDisplayId();
2831 EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
2832
2833 // Enable the callback
2834 ASSERT_TRUE(mComposerClient
2835 ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ true)
2836 .isOk());
2837
2838 forEachTwoConfigs(displayId, [&](int32_t config1, int32_t config2) {
2839 const int32_t vsyncPeriod1 = display.getDisplayConfig(config1).vsyncPeriod;
2840 const int32_t vsyncPeriod2 = display.getDisplayConfig(config2).vsyncPeriod;
2841
2842 if (vsyncPeriod1 == vsyncPeriod2) {
2843 return; // continue
2844 }
2845
2846 EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config1).isOk());
2847 sendRefreshFrame(display, nullptr);
2848
2849 const auto& [status, timeline] =
2850 mComposerClient->setActiveConfigWithConstraints(&display, config2, constraints);
2851 EXPECT_TRUE(status.isOk());
2852
2853 if (timeline.refreshRequired) {
2854 sendRefreshFrame(display, &timeline);
2855 }
2856
ramindani91518892023-03-03 16:55:09 +00002857 const auto callbackFilter = [displayId,
2858 vsyncPeriod2](auto refreshRateChangedDebugData) {
2859 constexpr int kVsyncThreshold = 1000;
2860 return displayId == refreshRateChangedDebugData.display &&
2861 std::abs(vsyncPeriod2 - refreshRateChangedDebugData.vsyncPeriodNanos) <=
2862 kVsyncThreshold;
2863 };
ramindani9dd8c482023-02-21 18:07:56 -08002864
2865 int retryCount = 3;
2866 do {
2867 std::this_thread::sleep_for(100ms);
ramindani91518892023-03-03 16:55:09 +00002868 if (checkIfCallbackRefreshRateChangedDebugEnabledReceived(callbackFilter)) {
ramindani9dd8c482023-02-21 18:07:56 -08002869 GTEST_SUCCEED() << "Received a callback successfully";
2870 break;
2871 }
2872 } while (--retryCount > 0);
2873
2874 if (retryCount == 0) {
2875 GTEST_FAIL() << "failed to get a callback for the display " << displayId
2876 << " with config " << config2;
2877 }
2878 });
2879
2880 EXPECT_TRUE(
2881 mComposerClient
2882 ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ false)
2883 .isOk());
2884 }
2885}
2886
Joen Chene0a962c2023-08-28 09:49:11 +00002887TEST_P(GraphicsComposerAidlCommandTest, MultiThreadedPresent) {
2888 std::vector<VtsDisplay*> displays;
2889 for (auto& display : mDisplays) {
2890 if (hasDisplayCapability(display.getDisplayId(),
2891 DisplayCapability::MULTI_THREADED_PRESENT)) {
2892 displays.push_back(&display);
2893 }
2894 }
2895
2896 const size_t numDisplays = displays.size();
2897 if (numDisplays <= 1u) {
2898 GTEST_SKIP();
2899 }
2900
2901 // When multi-threaded, use a reader per display. As with mWriters, this mutex
2902 // guards access to the map.
2903 std::mutex readersMutex;
2904 std::unordered_map<int64_t, ComposerClientReader> readers;
2905 std::vector<std::thread> threads;
2906 threads.reserve(numDisplays);
2907
2908 // Each display will have a layer to present. This maps from the display to
2909 // the layer, so we can properly destroy each layer at the end.
2910 std::unordered_map<int64_t, int64_t> layers;
2911
2912 for (auto* const display : displays) {
2913 const int64_t displayId = display->getDisplayId();
2914
2915 // Ensure that all writers and readers have been added to their respective
2916 // maps initially, so that the following loop never modifies the maps. The
2917 // maps are accessed from different threads, and if the maps were modified,
2918 // this would invalidate their iterators, and therefore references to the
2919 // writers and readers.
2920 auto& writer = getWriter(displayId);
2921 {
2922 std::lock_guard guard{readersMutex};
2923 readers.try_emplace(displayId, displayId);
2924 }
2925
2926 EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
2927
Ady Abrahama00d2462023-12-26 14:21:20 -08002928 const auto& [status, layer] =
2929 mComposerClient->createLayer(displayId, kBufferSlotCount, &writer);
Joen Chene0a962c2023-08-28 09:49:11 +00002930 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2931 ASSERT_NE(nullptr, buffer);
2932 ASSERT_EQ(::android::OK, buffer->initCheck());
2933 ASSERT_NE(nullptr, buffer->handle);
2934
2935 configureLayer(*display, layer, Composition::DEVICE, display->getFrameRect(),
2936 display->getCrop());
2937 writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
2938 /*acquireFence*/ -1);
2939 writer.setLayerDataspace(displayId, layer, common::Dataspace::UNKNOWN);
2940 layers.try_emplace(displayId, layer);
2941 }
2942
2943 for (auto* const display : displays) {
2944 const int64_t displayId = display->getDisplayId();
2945 auto& writer = getWriter(displayId);
2946 std::unique_lock lock{readersMutex};
2947 auto& reader = readers.at(displayId);
2948 lock.unlock();
2949
ramindanicdcfcaf2023-11-09 10:00:10 -08002950 writer.validateDisplay(displayId, ComposerClientWriter::kNoTimestamp,
2951 VtsComposerClient::kNoFrameIntervalNs);
Joen Chene0a962c2023-08-28 09:49:11 +00002952 execute(writer, reader);
2953
2954 threads.emplace_back([this, displayId, &readers, &readersMutex]() {
2955 auto& writer = getWriter(displayId);
2956 std::unique_lock lock{readersMutex};
2957 ComposerClientReader& reader = readers.at(displayId);
2958 lock.unlock();
2959
2960 writer.presentDisplay(displayId);
2961 execute(writer, reader);
2962 ASSERT_TRUE(reader.takeErrors().empty());
2963
2964 auto presentFence = reader.takePresentFence(displayId);
2965 // take ownership
2966 const int fenceOwner = presentFence.get();
2967 *presentFence.getR() = -1;
2968 EXPECT_NE(-1, fenceOwner);
2969 const auto presentFence2 = sp<::android::Fence>::make(fenceOwner);
2970 presentFence2->waitForever(LOG_TAG);
2971 });
2972 }
2973
2974 for (auto& thread : threads) {
2975 thread.join();
2976 }
2977
2978 for (auto& [displayId, layer] : layers) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002979 auto& writer = getWriter(displayId);
2980 EXPECT_TRUE(mComposerClient->destroyLayer(displayId, layer, &writer).isOk());
Joen Chene0a962c2023-08-28 09:49:11 +00002981 }
2982
2983 std::lock_guard guard{readersMutex};
2984 for (auto& [displayId, reader] : readers) {
2985 ASSERT_TRUE(reader.takeErrors().empty());
2986 ASSERT_TRUE(reader.takeChangedCompositionTypes(displayId).empty());
2987 }
2988}
2989
Ady Abrahama00d2462023-12-26 14:21:20 -08002990class GraphicsComposerAidlCommandV3Test : public GraphicsComposerAidlCommandTest {
Manali Bhutiyani38565cc2023-11-11 06:16:24 +00002991 protected:
2992 void SetUp() override {
Ady Abrahama00d2462023-12-26 14:21:20 -08002993 GraphicsComposerAidlTest::SetUp();
Manali Bhutiyani38565cc2023-11-11 06:16:24 +00002994 if (getInterfaceVersion() <= 2) {
2995 GTEST_SKIP() << "Device interface version is expected to be >= 3";
2996 }
2997 }
Manali Bhutiyani38565cc2023-11-11 06:16:24 +00002998};
2999
Ady Abrahama00d2462023-12-26 14:21:20 -08003000TEST_P(GraphicsComposerAidlCommandV3Test, CreateBatchedCommand) {
3001 if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
3002 GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
3003 return;
3004 }
3005
Manali Bhutiyani38565cc2023-11-11 06:16:24 +00003006 auto& writer = getWriter(getPrimaryDisplayId());
3007 int64_t layer = 5;
3008 writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
3009 LayerLifecycleBatchCommandType::CREATE);
3010 writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
3011 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
3012 VtsComposerClient::kNoFrameIntervalNs);
3013 execute();
3014 ASSERT_TRUE(mReader.takeErrors().empty());
3015}
3016
Ady Abrahama00d2462023-12-26 14:21:20 -08003017TEST_P(GraphicsComposerAidlCommandV3Test, CreateBatchedCommand_BadDisplay) {
3018 if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
3019 GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
3020 return;
3021 }
3022
3023 auto& writer = getWriter(getPrimaryDisplayId());
3024 int64_t layer = 5;
3025 writer.setLayerLifecycleBatchCommandType(getInvalidDisplayId(), layer,
3026 LayerLifecycleBatchCommandType::CREATE);
3027 writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
3028 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
3029 VtsComposerClient::kNoFrameIntervalNs);
3030 execute();
3031 const auto errors = mReader.takeErrors();
3032 ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_DISPLAY);
3033}
3034
3035TEST_P(GraphicsComposerAidlCommandV3Test, DestroyBatchedCommand) {
3036 if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
3037 GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
3038 return;
3039 }
3040
Manali Bhutiyani38565cc2023-11-11 06:16:24 +00003041 auto& writer = getWriter(getPrimaryDisplayId());
3042 int64_t layer = 5;
3043 writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
3044 LayerLifecycleBatchCommandType::CREATE);
3045 writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
3046 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
3047 VtsComposerClient::kNoFrameIntervalNs);
3048 execute();
3049 ASSERT_TRUE(mReader.takeErrors().empty());
3050 writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
3051 LayerLifecycleBatchCommandType::DESTROY);
3052 layer++;
3053 writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
3054 LayerLifecycleBatchCommandType::CREATE);
3055 writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
3056
3057 execute();
Ady Abrahama00d2462023-12-26 14:21:20 -08003058 const auto errors = mReader.takeErrors();
3059 ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_DISPLAY);
3060}
3061
3062TEST_P(GraphicsComposerAidlCommandV3Test, DestroyBatchedCommand_BadDisplay) {
3063 if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
3064 GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
3065 return;
3066 }
3067
3068 auto& writer = getWriter(getPrimaryDisplayId());
3069 int64_t layer = 5;
3070 writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
3071 LayerLifecycleBatchCommandType::CREATE);
3072 writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
3073 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
3074 VtsComposerClient::kNoFrameIntervalNs);
3075 execute();
3076 ASSERT_TRUE(mReader.takeErrors().empty());
3077 writer.setLayerLifecycleBatchCommandType(getInvalidDisplayId(), layer,
3078 LayerLifecycleBatchCommandType::DESTROY);
3079 layer++;
3080 writer.setLayerLifecycleBatchCommandType(getInvalidDisplayId(), layer,
3081 LayerLifecycleBatchCommandType::CREATE);
3082 writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
3083
3084 execute();
Manali Bhutiyani38565cc2023-11-11 06:16:24 +00003085 ASSERT_TRUE(mReader.takeErrors().empty());
3086}
3087
Ady Abrahama00d2462023-12-26 14:21:20 -08003088TEST_P(GraphicsComposerAidlCommandV3Test, NoCreateDestroyBatchedCommandIncorrectLayer) {
3089 if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
3090 GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
3091 return;
3092 }
3093
Manali Bhutiyani38565cc2023-11-11 06:16:24 +00003094 auto& writer = getWriter(getPrimaryDisplayId());
3095 int64_t layer = 5;
3096 writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
3097 LayerLifecycleBatchCommandType::DESTROY);
3098 execute();
3099 const auto errors = mReader.takeErrors();
3100 ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_LAYER);
3101}
3102
ramindanifc93b732024-02-15 21:36:19 +00003103TEST_P(GraphicsComposerAidlCommandV3Test, notifyExpectedPresentTimeout) {
3104 if (hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
3105 GTEST_SUCCEED() << "Device has unreliable present fences capability, skipping";
3106 return;
3107 }
3108 forEachNotifyExpectedPresentConfig([&](VtsDisplay& display,
3109 const DisplayConfiguration& config) {
3110 const auto displayId = display.getDisplayId();
3111 auto minFrameIntervalNs = config.vrrConfig->minFrameIntervalNs;
3112 const auto timeoutNs = config.vrrConfig->notifyExpectedPresentConfig->timeoutNs;
3113
3114 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
3115 ASSERT_NE(nullptr, buffer);
3116 const auto layer = createOnScreenLayer(display);
3117 auto& writer = getWriter(displayId);
3118 writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
3119 /*acquireFence*/ -1);
3120 sp<::android::Fence> presentFence = presentAndGetFence(ComposerClientWriter::kNoTimestamp,
3121 displayId, minFrameIntervalNs);
3122 presentFence->waitForever(LOG_TAG);
3123 auto lastPresentTimeNs = presentFence->getSignalTime();
3124
3125 // Frame presents 30ms after timeout
3126 const auto timeout = static_cast<const std::chrono::nanoseconds>(timeoutNs);
3127 const auto vsyncPeriod = config.vsyncPeriod;
3128 int32_t frameAfterTimeoutNs =
3129 vsyncPeriod * static_cast<int32_t>((timeout + 30ms).count() / vsyncPeriod);
3130 auto expectedPresentTimestamp =
3131 ClockMonotonicTimestamp{lastPresentTimeNs + frameAfterTimeoutNs};
3132 std::this_thread::sleep_for(timeout);
3133 mComposerClient->notifyExpectedPresent(displayId, expectedPresentTimestamp,
3134 minFrameIntervalNs);
3135 presentFence = presentAndGetFence(expectedPresentTimestamp, displayId, minFrameIntervalNs);
3136 presentFence->waitForever(LOG_TAG);
3137 lastPresentTimeNs = presentFence->getSignalTime();
3138 ASSERT_GE(lastPresentTimeNs, expectedPresentTimestamp.timestampNanos - vsyncPeriod / 2);
3139 mComposerClient->destroyLayer(displayId, layer, &writer);
3140 });
3141}
3142
3143TEST_P(GraphicsComposerAidlCommandV3Test, notifyExpectedPresentFrameIntervalChange) {
3144 if (hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
3145 GTEST_SUCCEED() << "Device has unreliable present fences capability, skipping";
3146 return;
3147 }
3148 forEachNotifyExpectedPresentConfig([&](VtsDisplay& display,
3149 const DisplayConfiguration& config) {
3150 const auto displayId = display.getDisplayId();
3151 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
3152 ASSERT_NE(nullptr, buffer);
3153 const auto layer = createOnScreenLayer(display);
3154 auto& writer = getWriter(displayId);
3155 writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
3156 /*acquireFence*/ -1);
3157 auto minFrameIntervalNs = config.vrrConfig->minFrameIntervalNs;
3158 sp<::android::Fence> presentFence = presentAndGetFence(ComposerClientWriter::kNoTimestamp,
3159 displayId, minFrameIntervalNs);
3160 presentFence->waitForever(LOG_TAG);
3161 auto lastPresentTimeNs = presentFence->getSignalTime();
3162
3163 auto vsyncPeriod = config.vsyncPeriod;
3164 int32_t highestDivisor = VtsComposerClient::kMaxFrameIntervalNs / vsyncPeriod;
3165 int32_t lowestDivisor = minFrameIntervalNs / vsyncPeriod;
3166 const auto headsUpNs = config.vrrConfig->notifyExpectedPresentConfig->headsUpNs;
3167 float totalDivisorsPassed = 0.f;
3168 for (int divisor = lowestDivisor; divisor <= highestDivisor; divisor++) {
3169 const auto frameIntervalNs = vsyncPeriod * divisor;
3170 const auto frameAfterHeadsUp = frameIntervalNs * (headsUpNs / frameIntervalNs);
3171 auto presentTime = lastPresentTimeNs + frameIntervalNs + frameAfterHeadsUp;
3172 const auto expectedPresentTimestamp = ClockMonotonicTimestamp{presentTime};
3173 ASSERT_TRUE(mComposerClient
3174 ->notifyExpectedPresent(displayId, expectedPresentTimestamp,
3175 frameIntervalNs)
3176 .isOk());
3177 presentFence = presentAndGetFence(expectedPresentTimestamp, displayId, frameIntervalNs);
3178 presentFence->waitForever(LOG_TAG);
3179 lastPresentTimeNs = presentFence->getSignalTime();
3180 if (lastPresentTimeNs >= expectedPresentTimestamp.timestampNanos - vsyncPeriod / 2) {
3181 ++totalDivisorsPassed;
3182 }
3183 }
3184 EXPECT_TRUE(totalDivisorsPassed >
3185 (static_cast<float>(highestDivisor - lowestDivisor)) * 0.75f);
3186 mComposerClient->destroyLayer(displayId, layer, &writer);
3187 });
3188}
3189
3190TEST_P(GraphicsComposerAidlCommandV3Test, frameIntervalChangeAtPresentFrame) {
3191 if (hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
3192 GTEST_SUCCEED() << "Device has unreliable present fences capability, skipping";
3193 return;
3194 }
3195 forEachNotifyExpectedPresentConfig([&](VtsDisplay& display,
3196 const DisplayConfiguration& config) {
3197 const auto displayId = display.getDisplayId();
3198 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
3199 ASSERT_NE(nullptr, buffer);
3200 const auto layer = createOnScreenLayer(display);
3201 auto& writer = getWriter(displayId);
3202 writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
3203 /*acquireFence*/ -1);
3204 auto minFrameIntervalNs = config.vrrConfig->minFrameIntervalNs;
3205
3206 auto vsyncPeriod = config.vsyncPeriod;
3207 int32_t highestDivisor = VtsComposerClient::kMaxFrameIntervalNs / vsyncPeriod;
3208 int32_t lowestDivisor = minFrameIntervalNs / vsyncPeriod;
3209 const auto headsUpNs = config.vrrConfig->notifyExpectedPresentConfig->headsUpNs;
3210 float totalDivisorsPassed = 0.f;
3211 int divisor = lowestDivisor;
3212 auto frameIntervalNs = vsyncPeriod * divisor;
3213 sp<::android::Fence> presentFence =
3214 presentAndGetFence(ComposerClientWriter::kNoTimestamp, displayId, frameIntervalNs);
3215 presentFence->waitForever(LOG_TAG);
3216 auto lastPresentTimeNs = presentFence->getSignalTime();
3217 do {
3218 frameIntervalNs = vsyncPeriod * divisor;
3219 ++divisor;
3220 const auto nextFrameIntervalNs = vsyncPeriod * divisor;
3221 const auto frameAfterHeadsUp = frameIntervalNs * (headsUpNs / frameIntervalNs);
3222 auto presentTime = lastPresentTimeNs + frameIntervalNs + frameAfterHeadsUp;
3223 const auto expectedPresentTimestamp = ClockMonotonicTimestamp{presentTime};
3224 presentFence =
3225 presentAndGetFence(expectedPresentTimestamp, displayId, nextFrameIntervalNs);
3226 presentFence->waitForever(LOG_TAG);
3227 lastPresentTimeNs = presentFence->getSignalTime();
3228 if (lastPresentTimeNs >= expectedPresentTimestamp.timestampNanos - vsyncPeriod / 2) {
3229 ++totalDivisorsPassed;
3230 }
3231 } while (divisor < highestDivisor);
3232 EXPECT_TRUE(totalDivisorsPassed >
3233 (static_cast<float>(highestDivisor - lowestDivisor)) * 0.75f);
3234 mComposerClient->destroyLayer(displayId, layer, &writer);
3235 });
3236}
3237
ramindanidcfe3a82021-11-29 17:00:31 +00003238GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandTest);
3239INSTANTIATE_TEST_SUITE_P(
3240 PerInstance, GraphicsComposerAidlCommandTest,
3241 testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
3242 ::android::PrintInstanceNameToString);
ramindanid32ae8e2021-10-01 18:48:39 +00003243GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlTest);
3244INSTANTIATE_TEST_SUITE_P(
3245 PerInstance, GraphicsComposerAidlTest,
3246 testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
3247 ::android::PrintInstanceNameToString);
ramindani12423f52023-06-14 20:04:51 -07003248GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlV2Test);
3249INSTANTIATE_TEST_SUITE_P(
3250 PerInstance, GraphicsComposerAidlV2Test,
3251 testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
3252 ::android::PrintInstanceNameToString);
ramindani02fe4772023-06-30 18:04:41 -07003253GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlV3Test);
3254INSTANTIATE_TEST_SUITE_P(
3255 PerInstance, GraphicsComposerAidlV3Test,
3256 testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
3257 ::android::PrintInstanceNameToString);
ramindani12423f52023-06-14 20:04:51 -07003258GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandV2Test);
3259INSTANTIATE_TEST_SUITE_P(
3260 PerInstance, GraphicsComposerAidlCommandV2Test,
3261 testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
3262 ::android::PrintInstanceNameToString);
Ady Abrahama00d2462023-12-26 14:21:20 -08003263GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandV3Test);
3264INSTANTIATE_TEST_SUITE_P(
3265 PerInstance, GraphicsComposerAidlCommandV3Test,
3266 testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
3267 ::android::PrintInstanceNameToString);
ramindanid32ae8e2021-10-01 18:48:39 +00003268} // namespace aidl::android::hardware::graphics::composer3::vts
3269
3270int main(int argc, char** argv) {
3271 ::testing::InitGoogleTest(&argc, argv);
3272
3273 using namespace std::chrono_literals;
3274 if (!android::base::WaitForProperty("init.svc.surfaceflinger", "stopped", 10s)) {
3275 ALOGE("Failed to stop init.svc.surfaceflinger");
3276 return -1;
3277 }
ramindanibeea10e2021-12-07 21:02:49 +00003278
3279 android::ProcessState::self()->setThreadPoolMaxThreadCount(4);
3280
3281 // The binder threadpool we start will inherit sched policy and priority
3282 // of (this) creating thread. We want the binder thread pool to have
3283 // SCHED_FIFO policy and priority 1 (lowest RT priority)
3284 // Once the pool is created we reset this thread's priority back to
3285 // original.
3286 // This thread policy is based on what we do in the SurfaceFlinger while starting
3287 // the thread pool and we need to replicate that for the VTS tests.
3288 int newPriority = 0;
3289 int origPolicy = sched_getscheduler(0);
3290 struct sched_param origSchedParam;
3291
3292 int errorInPriorityModification = sched_getparam(0, &origSchedParam);
3293 if (errorInPriorityModification == 0) {
3294 int policy = SCHED_FIFO;
3295 newPriority = sched_get_priority_min(policy);
3296
3297 struct sched_param param;
3298 param.sched_priority = newPriority;
3299
3300 errorInPriorityModification = sched_setscheduler(0, policy, &param);
3301 }
3302
3303 // start the thread pool
3304 android::ProcessState::self()->startThreadPool();
3305
3306 // Reset current thread's policy and priority
3307 if (errorInPriorityModification == 0) {
3308 errorInPriorityModification = sched_setscheduler(0, origPolicy, &origSchedParam);
3309 } else {
3310 ALOGE("Failed to set VtsHalGraphicsComposer3_TargetTest binder threadpool priority to "
3311 "SCHED_FIFO");
3312 }
3313
ramindanid32ae8e2021-10-01 18:48:39 +00003314 return RUN_ALL_TESTS();
Leon Scroggins III45095052023-03-23 18:23:15 -04003315}