blob: 11b995e2e23338e11410f691cec253e7e8cfab46 [file] [log] [blame]
ramindaniedf3ef92022-01-07 00:04:23 +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 */
16
ramindani458e53e2022-02-23 17:30:16 +000017#include "VtsComposerClient.h"
ramindaniedf3ef92022-01-07 00:04:23 +000018#include <aidlcommonsupport/NativeHandle.h>
19#include <android-base/logging.h>
20#include <log/log_main.h>
21
22#undef LOG_TAG
23#define LOG_TAG "VtsComposerClient"
24
25using namespace std::chrono_literals;
26
27namespace aidl::android::hardware::graphics::composer3::vts {
28
29VtsComposerClient::VtsComposerClient(const std::string& name) {
30 SpAIBinder binder(AServiceManager_waitForService(name.c_str()));
31 ALOGE_IF(binder == nullptr, "Could not initialize the service binder");
32 if (binder != nullptr) {
33 mComposer = IComposer::fromBinder(binder);
34 ALOGE_IF(mComposer == nullptr, "Failed to acquire the composer from the binder");
35 }
36}
37
38ScopedAStatus VtsComposerClient::createClient() {
39 if (mComposer == nullptr) {
40 ALOGE("IComposer not initialized");
41 return ScopedAStatus::fromServiceSpecificError(IComposerClient::INVALID_CONFIGURATION);
42 }
43 auto status = mComposer->createClient(&mComposerClient);
44 if (!status.isOk() || mComposerClient == nullptr) {
45 ALOGE("Failed to create client for IComposerClient with %s",
46 status.getDescription().c_str());
47 return status;
48 }
49 mComposerCallback = SharedRefBase::make<GraphicsComposerCallback>();
50 if (mComposerCallback == nullptr) {
51 ALOGE("Unable to create ComposerCallback");
52 return ScopedAStatus::fromServiceSpecificError(IComposerClient::INVALID_CONFIGURATION);
53 }
54 return mComposerClient->registerCallback(mComposerCallback);
55}
56
57bool VtsComposerClient::tearDown() {
58 return verifyComposerCallbackParams() && destroyAllLayers();
59}
60
ramindani02fe4772023-06-30 18:04:41 -070061std::pair<ScopedAStatus, int32_t> VtsComposerClient::getInterfaceVersion() const {
Brian Lindahl78ff2d62022-12-18 11:21:41 -070062 int32_t version = 1;
63 auto status = mComposerClient->getInterfaceVersion(&version);
64 return {std::move(status), version};
65}
66
ramindaniedf3ef92022-01-07 00:04:23 +000067std::pair<ScopedAStatus, VirtualDisplay> VtsComposerClient::createVirtualDisplay(
68 int32_t width, int32_t height, PixelFormat pixelFormat, int32_t bufferSlotCount) {
69 VirtualDisplay outVirtualDisplay;
70 auto status = mComposerClient->createVirtualDisplay(width, height, pixelFormat, bufferSlotCount,
71 &outVirtualDisplay);
72 if (!status.isOk()) {
73 return {std::move(status), outVirtualDisplay};
74 }
75 return {addDisplayToDisplayResources(outVirtualDisplay.display, /*isVirtual*/ true),
76 outVirtualDisplay};
77}
78
79ScopedAStatus VtsComposerClient::destroyVirtualDisplay(int64_t display) {
80 auto status = mComposerClient->destroyVirtualDisplay(display);
81 if (!status.isOk()) {
82 return status;
83 }
84 mDisplayResources.erase(display);
85 return status;
86}
87
88std::pair<ScopedAStatus, int64_t> VtsComposerClient::createLayer(int64_t display,
89 int32_t bufferSlotCount) {
90 int64_t outLayer;
91 auto status = mComposerClient->createLayer(display, bufferSlotCount, &outLayer);
92
93 if (!status.isOk()) {
94 return {std::move(status), outLayer};
95 }
96 return {addLayerToDisplayResources(display, outLayer), outLayer};
97}
98
99ScopedAStatus VtsComposerClient::destroyLayer(int64_t display, int64_t layer) {
100 auto status = mComposerClient->destroyLayer(display, layer);
101
102 if (!status.isOk()) {
103 return status;
104 }
105 removeLayerFromDisplayResources(display, layer);
106 return status;
107}
108
109std::pair<ScopedAStatus, int32_t> VtsComposerClient::getActiveConfig(int64_t display) {
110 int32_t outConfig;
111 return {mComposerClient->getActiveConfig(display, &outConfig), outConfig};
112}
113
114ScopedAStatus VtsComposerClient::setActiveConfig(VtsDisplay* vtsDisplay, int32_t config) {
115 auto status = mComposerClient->setActiveConfig(vtsDisplay->getDisplayId(), config);
116 if (!status.isOk()) {
117 return status;
118 }
119 return updateDisplayProperties(vtsDisplay, config);
120}
121
ramindani9dd8c482023-02-21 18:07:56 -0800122ScopedAStatus VtsComposerClient::setPeakRefreshRateConfig(VtsDisplay* vtsDisplay) {
123 const auto displayId = vtsDisplay->getDisplayId();
124 auto [activeStatus, activeConfig] = getActiveConfig(displayId);
125 EXPECT_TRUE(activeStatus.isOk());
126 auto peakDisplayConfig = vtsDisplay->getDisplayConfig(activeConfig);
127 auto peakConfig = activeConfig;
128
129 const auto displayConfigs = vtsDisplay->getDisplayConfigs();
130 for (const auto [config, displayConfig] : displayConfigs) {
131 if (displayConfig.configGroup == peakDisplayConfig.configGroup &&
132 displayConfig.vsyncPeriod < peakDisplayConfig.vsyncPeriod) {
133 peakDisplayConfig = displayConfig;
134 peakConfig = config;
135 }
136 }
137 return setActiveConfig(vtsDisplay, peakConfig);
138}
139
ramindaniedf3ef92022-01-07 00:04:23 +0000140std::pair<ScopedAStatus, int32_t> VtsComposerClient::getDisplayAttribute(
141 int64_t display, int32_t config, DisplayAttribute displayAttribute) {
142 int32_t outDisplayAttribute;
143 return {mComposerClient->getDisplayAttribute(display, config, displayAttribute,
144 &outDisplayAttribute),
145 outDisplayAttribute};
146}
147
148ScopedAStatus VtsComposerClient::setPowerMode(int64_t display, PowerMode powerMode) {
149 return mComposerClient->setPowerMode(display, powerMode);
150}
151
152ScopedAStatus VtsComposerClient::setVsync(int64_t display, bool enable) {
153 return mComposerClient->setVsyncEnabled(display, enable);
154}
155
156void VtsComposerClient::setVsyncAllowed(bool isAllowed) {
157 mComposerCallback->setVsyncAllowed(isAllowed);
158}
159
160std::pair<ScopedAStatus, std::vector<float>> VtsComposerClient::getDataspaceSaturationMatrix(
161 Dataspace dataspace) {
162 std::vector<float> outMatrix;
163 return {mComposerClient->getDataspaceSaturationMatrix(dataspace, &outMatrix), outMatrix};
164}
165
166std::pair<ScopedAStatus, std::vector<CommandResultPayload>> VtsComposerClient::executeCommands(
167 const std::vector<DisplayCommand>& commands) {
168 std::vector<CommandResultPayload> outResultPayload;
169 return {mComposerClient->executeCommands(commands, &outResultPayload),
170 std::move(outResultPayload)};
171}
172
173std::optional<VsyncPeriodChangeTimeline> VtsComposerClient::takeLastVsyncPeriodChangeTimeline() {
174 return mComposerCallback->takeLastVsyncPeriodChangeTimeline();
175}
176
177ScopedAStatus VtsComposerClient::setContentType(int64_t display, ContentType contentType) {
178 return mComposerClient->setContentType(display, contentType);
179}
180
181std::pair<ScopedAStatus, VsyncPeriodChangeTimeline>
182VtsComposerClient::setActiveConfigWithConstraints(VtsDisplay* vtsDisplay, int32_t config,
183 const VsyncPeriodChangeConstraints& constraints) {
184 VsyncPeriodChangeTimeline outTimeline;
185 auto status = mComposerClient->setActiveConfigWithConstraints(
186 vtsDisplay->getDisplayId(), config, constraints, &outTimeline);
187 if (!status.isOk()) {
188 return {std::move(status), outTimeline};
189 }
190 return {updateDisplayProperties(vtsDisplay, config), outTimeline};
191}
192
193std::pair<ScopedAStatus, std::vector<DisplayCapability>> VtsComposerClient::getDisplayCapabilities(
194 int64_t display) {
195 std::vector<DisplayCapability> outCapabilities;
196 return {mComposerClient->getDisplayCapabilities(display, &outCapabilities), outCapabilities};
197}
198
199ScopedAStatus VtsComposerClient::dumpDebugInfo() {
Ady Abraham89d72702022-02-18 17:04:55 -0800200 int pipefds[2];
201 if (pipe(pipefds) < 0) {
202 return ScopedAStatus::fromServiceSpecificError(IComposer::EX_NO_RESOURCES);
203 }
204
205 const auto status = mComposer->dump(pipefds[1], /*args*/ nullptr, /*numArgs*/ 0);
206 close(pipefds[0]);
207 close(pipefds[1]);
208 return ScopedAStatus::fromStatus(status);
ramindaniedf3ef92022-01-07 00:04:23 +0000209}
210
211std::pair<ScopedAStatus, DisplayIdentification> VtsComposerClient::getDisplayIdentificationData(
212 int64_t display) {
213 DisplayIdentification outDisplayIdentification;
214 return {mComposerClient->getDisplayIdentificationData(display, &outDisplayIdentification),
215 outDisplayIdentification};
216}
217
218std::pair<ScopedAStatus, HdrCapabilities> VtsComposerClient::getHdrCapabilities(int64_t display) {
219 HdrCapabilities outHdrCapabilities;
220 return {mComposerClient->getHdrCapabilities(display, &outHdrCapabilities), outHdrCapabilities};
221}
222
223std::pair<ScopedAStatus, std::vector<PerFrameMetadataKey>>
224VtsComposerClient::getPerFrameMetadataKeys(int64_t display) {
225 std::vector<PerFrameMetadataKey> outPerFrameMetadataKeys;
226 return {mComposerClient->getPerFrameMetadataKeys(display, &outPerFrameMetadataKeys),
227 outPerFrameMetadataKeys};
228}
229
230std::pair<ScopedAStatus, ReadbackBufferAttributes> VtsComposerClient::getReadbackBufferAttributes(
231 int64_t display) {
232 ReadbackBufferAttributes outReadbackBufferAttributes;
233 return {mComposerClient->getReadbackBufferAttributes(display, &outReadbackBufferAttributes),
234 outReadbackBufferAttributes};
235}
236
237ScopedAStatus VtsComposerClient::setReadbackBuffer(int64_t display, const native_handle_t* buffer,
238 const ScopedFileDescriptor& releaseFence) {
239 return mComposerClient->setReadbackBuffer(display, ::android::dupToAidl(buffer), releaseFence);
240}
241
242std::pair<ScopedAStatus, ScopedFileDescriptor> VtsComposerClient::getReadbackBufferFence(
243 int64_t display) {
244 ScopedFileDescriptor outReleaseFence;
245 return {mComposerClient->getReadbackBufferFence(display, &outReleaseFence),
246 std::move(outReleaseFence)};
247}
248
249std::pair<ScopedAStatus, std::vector<ColorMode>> VtsComposerClient::getColorModes(int64_t display) {
250 std::vector<ColorMode> outColorModes;
251 return {mComposerClient->getColorModes(display, &outColorModes), outColorModes};
252}
253
254std::pair<ScopedAStatus, std::vector<RenderIntent>> VtsComposerClient::getRenderIntents(
255 int64_t display, ColorMode colorMode) {
256 std::vector<RenderIntent> outRenderIntents;
257 return {mComposerClient->getRenderIntents(display, colorMode, &outRenderIntents),
258 outRenderIntents};
259}
260
261ScopedAStatus VtsComposerClient::setColorMode(int64_t display, ColorMode colorMode,
262 RenderIntent renderIntent) {
263 return mComposerClient->setColorMode(display, colorMode, renderIntent);
264}
265
266std::pair<ScopedAStatus, DisplayContentSamplingAttributes>
267VtsComposerClient::getDisplayedContentSamplingAttributes(int64_t display) {
268 DisplayContentSamplingAttributes outAttributes;
269 return {mComposerClient->getDisplayedContentSamplingAttributes(display, &outAttributes),
270 outAttributes};
271}
272
273ScopedAStatus VtsComposerClient::setDisplayedContentSamplingEnabled(
274 int64_t display, bool isEnabled, FormatColorComponent formatColorComponent,
275 int64_t maxFrames) {
276 return mComposerClient->setDisplayedContentSamplingEnabled(display, isEnabled,
277 formatColorComponent, maxFrames);
278}
279
280std::pair<ScopedAStatus, DisplayContentSample> VtsComposerClient::getDisplayedContentSample(
281 int64_t display, int64_t maxFrames, int64_t timestamp) {
282 DisplayContentSample outDisplayContentSample;
283 return {mComposerClient->getDisplayedContentSample(display, maxFrames, timestamp,
284 &outDisplayContentSample),
285 outDisplayContentSample};
286}
287
288std::pair<ScopedAStatus, DisplayConnectionType> VtsComposerClient::getDisplayConnectionType(
289 int64_t display) {
290 DisplayConnectionType outDisplayConnectionType;
291 return {mComposerClient->getDisplayConnectionType(display, &outDisplayConnectionType),
292 outDisplayConnectionType};
293}
294
295std::pair<ScopedAStatus, std::vector<int32_t>> VtsComposerClient::getDisplayConfigs(
296 int64_t display) {
297 std::vector<int32_t> outConfigs;
ramindani02fe4772023-06-30 18:04:41 -0700298 if (!getDisplayConfigurationSupported()) {
299 return {mComposerClient->getDisplayConfigs(display, &outConfigs), outConfigs};
300 }
301
302 auto [status, configs] = getDisplayConfigurations(display);
303 if (!status.isOk()) {
304 return {std::move(status), outConfigs};
305 }
306 for (const auto& config : configs) {
307 outConfigs.emplace_back(config.configId);
308 }
309 return {std::move(status), outConfigs};
310}
311
312std::pair<ScopedAStatus, std::vector<DisplayConfiguration>>
313VtsComposerClient::getDisplayConfigurations(int64_t display) {
314 std::vector<DisplayConfiguration> outConfigs;
ramindani2704c5f2023-07-18 20:53:24 -0700315 return {mComposerClient->getDisplayConfigurations(display, kMaxFrameIntervalNs, &outConfigs),
316 outConfigs};
317}
318
319ScopedAStatus VtsComposerClient::notifyExpectedPresent(int64_t display,
320 ClockMonotonicTimestamp expectedPresentTime,
321 int frameIntervalNs) {
322 return mComposerClient->notifyExpectedPresent(display, expectedPresentTime, frameIntervalNs);
ramindaniedf3ef92022-01-07 00:04:23 +0000323}
324
325std::pair<ScopedAStatus, int32_t> VtsComposerClient::getDisplayVsyncPeriod(int64_t display) {
326 int32_t outVsyncPeriodNanos;
327 return {mComposerClient->getDisplayVsyncPeriod(display, &outVsyncPeriodNanos),
328 outVsyncPeriodNanos};
329}
330
331ScopedAStatus VtsComposerClient::setAutoLowLatencyMode(int64_t display, bool isEnabled) {
332 return mComposerClient->setAutoLowLatencyMode(display, isEnabled);
333}
334
335std::pair<ScopedAStatus, std::vector<ContentType>> VtsComposerClient::getSupportedContentTypes(
336 int64_t display) {
337 std::vector<ContentType> outContentTypes;
338 return {mComposerClient->getSupportedContentTypes(display, &outContentTypes), outContentTypes};
339}
340
Leon Scroggins IIIde057582022-01-13 12:26:00 -0500341std::pair<ScopedAStatus, std::optional<DisplayDecorationSupport>>
342VtsComposerClient::getDisplayDecorationSupport(int64_t display) {
343 std::optional<DisplayDecorationSupport> outSupport;
344 return {mComposerClient->getDisplayDecorationSupport(display, &outSupport), outSupport};
345}
346
ramindaniedf3ef92022-01-07 00:04:23 +0000347std::pair<ScopedAStatus, int32_t> VtsComposerClient::getMaxVirtualDisplayCount() {
348 int32_t outMaxVirtualDisplayCount;
349 return {mComposerClient->getMaxVirtualDisplayCount(&outMaxVirtualDisplayCount),
350 outMaxVirtualDisplayCount};
351}
352
353std::pair<ScopedAStatus, std::string> VtsComposerClient::getDisplayName(int64_t display) {
354 std::string outDisplayName;
355 return {mComposerClient->getDisplayName(display, &outDisplayName), outDisplayName};
356}
357
358ScopedAStatus VtsComposerClient::setClientTargetSlotCount(int64_t display,
359 int32_t bufferSlotCount) {
360 return mComposerClient->setClientTargetSlotCount(display, bufferSlotCount);
361}
362
363std::pair<ScopedAStatus, std::vector<Capability>> VtsComposerClient::getCapabilities() {
364 std::vector<Capability> outCapabilities;
365 return {mComposer->getCapabilities(&outCapabilities), outCapabilities};
366}
367
368ScopedAStatus VtsComposerClient::setBootDisplayConfig(int64_t display, int32_t config) {
369 return mComposerClient->setBootDisplayConfig(display, config);
370}
371
372ScopedAStatus VtsComposerClient::clearBootDisplayConfig(int64_t display) {
373 return mComposerClient->clearBootDisplayConfig(display);
374}
375
376std::pair<ScopedAStatus, int32_t> VtsComposerClient::getPreferredBootDisplayConfig(
377 int64_t display) {
378 int32_t outConfig;
379 return {mComposerClient->getPreferredBootDisplayConfig(display, &outConfig), outConfig};
380}
381
Kriti Dang3793ebd2022-12-05 13:03:49 +0100382std::pair<ScopedAStatus, std::vector<common::HdrConversionCapability>>
383VtsComposerClient::getHdrConversionCapabilities() {
384 std::vector<common::HdrConversionCapability> hdrConversionCapability;
385 return {mComposerClient->getHdrConversionCapabilities(&hdrConversionCapability),
386 hdrConversionCapability};
387}
388
Kriti Dang37622762023-02-09 18:15:37 +0100389std::pair<ScopedAStatus, common::Hdr> VtsComposerClient::setHdrConversionStrategy(
Kriti Dang3793ebd2022-12-05 13:03:49 +0100390 const common::HdrConversionStrategy& conversionStrategy) {
Kriti Dang37622762023-02-09 18:15:37 +0100391 common::Hdr preferredHdrOutputType;
392 return {mComposerClient->setHdrConversionStrategy(conversionStrategy, &preferredHdrOutputType),
393 preferredHdrOutputType};
Kriti Dang3793ebd2022-12-05 13:03:49 +0100394}
395
ramindaniedf3ef92022-01-07 00:04:23 +0000396std::pair<ScopedAStatus, common::Transform> VtsComposerClient::getDisplayPhysicalOrientation(
397 int64_t display) {
398 common::Transform outDisplayOrientation;
399 return {mComposerClient->getDisplayPhysicalOrientation(display, &outDisplayOrientation),
400 outDisplayOrientation};
401}
402
Sally Qi2600d342022-08-16 12:46:17 -0700403std::pair<ScopedAStatus, composer3::OverlayProperties> VtsComposerClient::getOverlaySupport() {
404 OverlayProperties properties;
405 return {mComposerClient->getOverlaySupport(&properties), properties};
406}
407
ramindaniedf3ef92022-01-07 00:04:23 +0000408ScopedAStatus VtsComposerClient::setIdleTimerEnabled(int64_t display, int32_t timeoutMs) {
409 return mComposerClient->setIdleTimerEnabled(display, timeoutMs);
410}
411
412int32_t VtsComposerClient::getVsyncIdleCount() {
413 return mComposerCallback->getVsyncIdleCount();
414}
415
416int64_t VtsComposerClient::getVsyncIdleTime() {
417 return mComposerCallback->getVsyncIdleTime();
418}
419
ramindani9dd8c482023-02-21 18:07:56 -0800420ndk::ScopedAStatus VtsComposerClient::setRefreshRateChangedCallbackDebugEnabled(int64_t display,
421 bool enabled) {
422 mComposerCallback->setRefreshRateChangedDebugDataEnabledCallbackAllowed(enabled);
423 return mComposerClient->setRefreshRateChangedCallbackDebugEnabled(display, enabled);
424}
425
426std::vector<RefreshRateChangedDebugData>
427VtsComposerClient::takeListOfRefreshRateChangedDebugData() {
428 return mComposerCallback->takeListOfRefreshRateChangedDebugData();
ramindani83450342023-02-03 12:52:08 -0800429}
430
ramindaniedf3ef92022-01-07 00:04:23 +0000431int64_t VtsComposerClient::getInvalidDisplayId() {
432 // returns an invalid display id (one that has not been registered to a
433 // display. Currently assuming that a device will never have close to
434 // std::numeric_limit<uint64_t>::max() displays registered while running tests
435 int64_t id = std::numeric_limits<int64_t>::max();
436 std::vector<int64_t> displays = mComposerCallback->getDisplays();
437 while (id > 0) {
438 if (std::none_of(displays.begin(), displays.end(),
439 [id](const auto& display) { return id == display; })) {
440 return id;
441 }
442 id--;
443 }
444
445 // Although 0 could be an invalid display, a return value of 0
446 // from getInvalidDisplayId means all other ids are in use, a condition which
447 // we are assuming a device will never have
448 EXPECT_NE(0, id);
449 return id;
450}
451
452std::pair<ScopedAStatus, std::vector<VtsDisplay>> VtsComposerClient::getDisplays() {
453 while (true) {
454 // Sleep for a small period of time to allow all built-in displays
455 // to post hotplug events
456 std::this_thread::sleep_for(5ms);
457 std::vector<int64_t> displays = mComposerCallback->getDisplays();
458 if (displays.empty()) {
459 continue;
460 }
461
462 std::vector<VtsDisplay> vtsDisplays;
463 vtsDisplays.reserve(displays.size());
464 for (int64_t display : displays) {
465 auto vtsDisplay = VtsDisplay{display};
ramindani02fe4772023-06-30 18:04:41 -0700466 if (getDisplayConfigurationSupported()) {
467 auto [status, configs] = getDisplayConfigurations(display);
ramindaniedf3ef92022-01-07 00:04:23 +0000468 if (!status.isOk()) {
ramindani02fe4772023-06-30 18:04:41 -0700469 ALOGE("Unable to get the displays for test, failed to get the DisplayConfigs "
ramindaniedf3ef92022-01-07 00:04:23 +0000470 "for display %" PRId64,
471 display);
472 return {std::move(status), vtsDisplays};
473 }
ramindani02fe4772023-06-30 18:04:41 -0700474 addDisplayConfigs(&vtsDisplay, configs);
475 } else {
476 auto [status, configs] = getDisplayConfigs(display);
477 if (!status.isOk()) {
478 ALOGE("Unable to get the displays for test, failed to get the configs "
479 "for display %" PRId64,
480 display);
481 return {std::move(status), vtsDisplays};
482 }
483 for (int config : configs) {
484 status = addDisplayConfigLegacy(&vtsDisplay, config);
485 if (!status.isOk()) {
486 ALOGE("Unable to get the displays for test, failed to add config "
487 "for display %" PRId64,
488 display);
489 return {std::move(status), vtsDisplays};
490 }
491 }
ramindaniedf3ef92022-01-07 00:04:23 +0000492 }
ramindani02fe4772023-06-30 18:04:41 -0700493 auto activeConfig = getActiveConfig(display);
494 if (!activeConfig.first.isOk()) {
HyunKyoung4775bdc2022-11-09 20:43:34 +0900495 ALOGE("Unable to get the displays for test, failed to get active config "
ramindani02fe4772023-06-30 18:04:41 -0700496 "for display %" PRId64,
497 display);
498 return {std::move(activeConfig.first), vtsDisplays};
HyunKyoung4775bdc2022-11-09 20:43:34 +0900499 }
ramindani02fe4772023-06-30 18:04:41 -0700500 auto status = updateDisplayProperties(&vtsDisplay, activeConfig.second);
HyunKyoung4775bdc2022-11-09 20:43:34 +0900501 if (!status.isOk()) {
502 ALOGE("Unable to get the displays for test, "
503 "failed to update the properties "
504 "for display %" PRId64,
505 display);
506 return {std::move(status), vtsDisplays};
507 }
508
ramindaniedf3ef92022-01-07 00:04:23 +0000509 vtsDisplays.emplace_back(vtsDisplay);
510 addDisplayToDisplayResources(display, /*isVirtual*/ false);
511 }
512
513 return {ScopedAStatus::ok(), vtsDisplays};
514 }
515}
516
ramindani02fe4772023-06-30 18:04:41 -0700517void VtsComposerClient::addDisplayConfigs(VtsDisplay* vtsDisplay,
518 const std::vector<DisplayConfiguration>& configs) {
519 for (const auto& config : configs) {
520 vtsDisplay->addDisplayConfig(config.configId, {config.vsyncPeriod, config.configGroup});
521 }
522}
523
524ScopedAStatus VtsComposerClient::addDisplayConfigLegacy(VtsDisplay* vtsDisplay, int32_t config) {
ramindaniedf3ef92022-01-07 00:04:23 +0000525 const auto vsyncPeriod =
526 getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::VSYNC_PERIOD);
527 const auto configGroup =
528 getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::CONFIG_GROUP);
ramindani02fe4772023-06-30 18:04:41 -0700529 if (vsyncPeriod.first.isOk() && configGroup.first.isOk()) {
ramindaniedf3ef92022-01-07 00:04:23 +0000530 vtsDisplay->addDisplayConfig(config, {vsyncPeriod.second, configGroup.second});
531 return ScopedAStatus::ok();
532 }
533
ramindani02fe4772023-06-30 18:04:41 -0700534 LOG(ERROR) << "Failed to update display property vsync: " << vsyncPeriod.first.isOk()
ramindaniedf3ef92022-01-07 00:04:23 +0000535 << ", config: " << configGroup.first.isOk();
536 return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_CONFIG);
537}
538
HyunKyoung4775bdc2022-11-09 20:43:34 +0900539ScopedAStatus VtsComposerClient::updateDisplayProperties(VtsDisplay* vtsDisplay, int32_t config) {
ramindani02fe4772023-06-30 18:04:41 -0700540 if (getDisplayConfigurationSupported()) {
541 auto [status, configs] = getDisplayConfigurations(vtsDisplay->getDisplayId());
542 if (status.isOk()) {
543 for (const auto& displayConfig : configs) {
544 if (displayConfig.configId == config) {
545 vtsDisplay->setDimensions(displayConfig.width, displayConfig.height);
546 return ScopedAStatus::ok();
547 }
548 }
549 }
550 LOG(ERROR) << "Failed to update display property with DisplayConfig";
551 } else {
552 const auto width =
553 getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::WIDTH);
554 const auto height =
555 getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::HEIGHT);
556 if (width.first.isOk() && height.first.isOk()) {
557 vtsDisplay->setDimensions(width.second, height.second);
558 return ScopedAStatus::ok();
559 }
HyunKyoung4775bdc2022-11-09 20:43:34 +0900560
ramindani02fe4772023-06-30 18:04:41 -0700561 LOG(ERROR) << "Failed to update display property for width: " << width.first.isOk()
562 << ", height: " << height.first.isOk();
563 }
HyunKyoung4775bdc2022-11-09 20:43:34 +0900564 return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_CONFIG);
565}
566
ramindaniedf3ef92022-01-07 00:04:23 +0000567ScopedAStatus VtsComposerClient::addDisplayToDisplayResources(int64_t display, bool isVirtual) {
568 if (mDisplayResources.insert({display, DisplayResource(isVirtual)}).second) {
569 return ScopedAStatus::ok();
570 }
571
572 ALOGE("Duplicate display id %" PRId64, display);
573 return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_DISPLAY);
574}
575
576ScopedAStatus VtsComposerClient::addLayerToDisplayResources(int64_t display, int64_t layer) {
577 auto resource = mDisplayResources.find(display);
578 if (resource == mDisplayResources.end()) {
579 resource = mDisplayResources.insert({display, DisplayResource(false)}).first;
580 }
581
582 if (!resource->second.layers.insert(layer).second) {
583 ALOGE("Duplicate layer id %" PRId64, layer);
584 return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_LAYER);
585 }
586 return ScopedAStatus::ok();
587}
588
589void VtsComposerClient::removeLayerFromDisplayResources(int64_t display, int64_t layer) {
590 auto resource = mDisplayResources.find(display);
591 if (resource != mDisplayResources.end()) {
592 resource->second.layers.erase(layer);
593 }
594}
595
596bool VtsComposerClient::verifyComposerCallbackParams() {
597 bool isValid = true;
598 if (mComposerCallback != nullptr) {
599 if (mComposerCallback->getInvalidHotplugCount() != 0) {
600 ALOGE("Invalid hotplug count");
601 isValid = false;
602 }
603 if (mComposerCallback->getInvalidRefreshCount() != 0) {
604 ALOGE("Invalid refresh count");
605 isValid = false;
606 }
607 if (mComposerCallback->getInvalidVsyncCount() != 0) {
608 ALOGE("Invalid vsync count");
609 isValid = false;
610 }
611 if (mComposerCallback->getInvalidVsyncPeriodChangeCount() != 0) {
612 ALOGE("Invalid vsync period change count");
613 isValid = false;
614 }
615 if (mComposerCallback->getInvalidSeamlessPossibleCount() != 0) {
616 ALOGE("Invalid seamless possible count");
617 isValid = false;
618 }
ramindani9dd8c482023-02-21 18:07:56 -0800619 if (mComposerCallback->getInvalidRefreshRateDebugEnabledCallbackCount() != 0) {
620 ALOGE("Invalid refresh rate debug enabled callback count");
621 isValid = false;
622 }
ramindaniedf3ef92022-01-07 00:04:23 +0000623 }
624 return isValid;
625}
626
ramindani02fe4772023-06-30 18:04:41 -0700627bool VtsComposerClient::getDisplayConfigurationSupported() const {
628 auto [status, interfaceVersion] = getInterfaceVersion();
629 EXPECT_TRUE(status.isOk());
630 // getDisplayConfigurations api is supported starting interface version 3
631 return interfaceVersion >= 3;
632}
633
ramindaniedf3ef92022-01-07 00:04:23 +0000634bool VtsComposerClient::destroyAllLayers() {
JihCheng Chiud0dbe4e2022-06-11 01:53:11 +0800635 std::unordered_map<int64_t, DisplayResource> physicalDisplays;
636 while (!mDisplayResources.empty()) {
637 const auto& it = mDisplayResources.begin();
638 const auto& [display, resource] = *it;
ramindaniedf3ef92022-01-07 00:04:23 +0000639
JihCheng Chiud0dbe4e2022-06-11 01:53:11 +0800640 while (!resource.layers.empty()) {
641 auto layer = *resource.layers.begin();
ramindaniedf3ef92022-01-07 00:04:23 +0000642 const auto status = destroyLayer(display, layer);
643 if (!status.isOk()) {
644 ALOGE("Unable to destroy all the layers, failed at layer %" PRId64 " with error %s",
645 layer, status.getDescription().c_str());
646 return false;
647 }
648 }
649
650 if (resource.isVirtual) {
651 const auto status = destroyVirtualDisplay(display);
652 if (!status.isOk()) {
653 ALOGE("Unable to destroy the display %" PRId64 " failed with error %s", display,
654 status.getDescription().c_str());
655 return false;
656 }
JihCheng Chiud0dbe4e2022-06-11 01:53:11 +0800657 } else {
658 auto extractIter = mDisplayResources.extract(it);
659 physicalDisplays.insert(std::move(extractIter));
ramindaniedf3ef92022-01-07 00:04:23 +0000660 }
661 }
JihCheng Chiud0dbe4e2022-06-11 01:53:11 +0800662 mDisplayResources.swap(physicalDisplays);
ramindaniedf3ef92022-01-07 00:04:23 +0000663 mDisplayResources.clear();
664 return true;
665}
Leon Scroggins IIIde057582022-01-13 12:26:00 -0500666} // namespace aidl::android::hardware::graphics::composer3::vts