blob: 2c24bfb8f5750ee63202952f2ccddc79984f6aa4 [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 }
Ady Abrahama00d2462023-12-26 14:21:20 -080036
37 const auto& [status, capabilities] = getCapabilities();
38 EXPECT_TRUE(status.isOk());
39 if (std::any_of(capabilities.begin(), capabilities.end(), [&](const Capability& cap) {
40 return cap == Capability::LAYER_LIFECYCLE_BATCH_COMMAND;
41 })) {
42 mSupportsBatchedCreateLayer = true;
43 }
ramindaniedf3ef92022-01-07 00:04:23 +000044}
45
46ScopedAStatus VtsComposerClient::createClient() {
47 if (mComposer == nullptr) {
48 ALOGE("IComposer not initialized");
49 return ScopedAStatus::fromServiceSpecificError(IComposerClient::INVALID_CONFIGURATION);
50 }
51 auto status = mComposer->createClient(&mComposerClient);
52 if (!status.isOk() || mComposerClient == nullptr) {
53 ALOGE("Failed to create client for IComposerClient with %s",
54 status.getDescription().c_str());
55 return status;
56 }
57 mComposerCallback = SharedRefBase::make<GraphicsComposerCallback>();
58 if (mComposerCallback == nullptr) {
59 ALOGE("Unable to create ComposerCallback");
60 return ScopedAStatus::fromServiceSpecificError(IComposerClient::INVALID_CONFIGURATION);
61 }
62 return mComposerClient->registerCallback(mComposerCallback);
63}
64
Ady Abrahama00d2462023-12-26 14:21:20 -080065bool VtsComposerClient::tearDown(ComposerClientWriter* writer) {
66 return verifyComposerCallbackParams() && destroyAllLayers(writer);
ramindaniedf3ef92022-01-07 00:04:23 +000067}
68
ramindani02fe4772023-06-30 18:04:41 -070069std::pair<ScopedAStatus, int32_t> VtsComposerClient::getInterfaceVersion() const {
Brian Lindahl78ff2d62022-12-18 11:21:41 -070070 int32_t version = 1;
71 auto status = mComposerClient->getInterfaceVersion(&version);
72 return {std::move(status), version};
73}
74
ramindaniedf3ef92022-01-07 00:04:23 +000075std::pair<ScopedAStatus, VirtualDisplay> VtsComposerClient::createVirtualDisplay(
76 int32_t width, int32_t height, PixelFormat pixelFormat, int32_t bufferSlotCount) {
77 VirtualDisplay outVirtualDisplay;
78 auto status = mComposerClient->createVirtualDisplay(width, height, pixelFormat, bufferSlotCount,
79 &outVirtualDisplay);
80 if (!status.isOk()) {
81 return {std::move(status), outVirtualDisplay};
82 }
83 return {addDisplayToDisplayResources(outVirtualDisplay.display, /*isVirtual*/ true),
84 outVirtualDisplay};
85}
86
87ScopedAStatus VtsComposerClient::destroyVirtualDisplay(int64_t display) {
88 auto status = mComposerClient->destroyVirtualDisplay(display);
89 if (!status.isOk()) {
90 return status;
91 }
92 mDisplayResources.erase(display);
93 return status;
94}
95
96std::pair<ScopedAStatus, int64_t> VtsComposerClient::createLayer(int64_t display,
Ady Abrahama00d2462023-12-26 14:21:20 -080097 int32_t bufferSlotCount,
98 ComposerClientWriter* writer) {
99 if (mSupportsBatchedCreateLayer) {
100 int64_t layer = mNextLayerHandle++;
101 writer->setLayerLifecycleBatchCommandType(display, layer,
102 LayerLifecycleBatchCommandType::CREATE);
103 writer->setNewBufferSlotCount(display, layer, bufferSlotCount);
104 return {addLayerToDisplayResources(display, layer), layer};
105 }
106
ramindaniedf3ef92022-01-07 00:04:23 +0000107 int64_t outLayer;
108 auto status = mComposerClient->createLayer(display, bufferSlotCount, &outLayer);
109
110 if (!status.isOk()) {
111 return {std::move(status), outLayer};
112 }
113 return {addLayerToDisplayResources(display, outLayer), outLayer};
114}
115
Ady Abrahama00d2462023-12-26 14:21:20 -0800116ScopedAStatus VtsComposerClient::destroyLayer(int64_t display, int64_t layer,
117 ComposerClientWriter* writer) {
118 if (mSupportsBatchedCreateLayer) {
119 writer->setLayerLifecycleBatchCommandType(display, layer,
120 LayerLifecycleBatchCommandType::DESTROY);
121 } else {
122 auto status = mComposerClient->destroyLayer(display, layer);
123 if (!status.isOk()) {
124 return status;
125 }
ramindaniedf3ef92022-01-07 00:04:23 +0000126 }
Ady Abrahama00d2462023-12-26 14:21:20 -0800127
ramindaniedf3ef92022-01-07 00:04:23 +0000128 removeLayerFromDisplayResources(display, layer);
Ady Abrahama00d2462023-12-26 14:21:20 -0800129 return ScopedAStatus::ok();
ramindaniedf3ef92022-01-07 00:04:23 +0000130}
131
132std::pair<ScopedAStatus, int32_t> VtsComposerClient::getActiveConfig(int64_t display) {
133 int32_t outConfig;
134 return {mComposerClient->getActiveConfig(display, &outConfig), outConfig};
135}
136
137ScopedAStatus VtsComposerClient::setActiveConfig(VtsDisplay* vtsDisplay, int32_t config) {
138 auto status = mComposerClient->setActiveConfig(vtsDisplay->getDisplayId(), config);
139 if (!status.isOk()) {
140 return status;
141 }
142 return updateDisplayProperties(vtsDisplay, config);
143}
144
ramindani9dd8c482023-02-21 18:07:56 -0800145ScopedAStatus VtsComposerClient::setPeakRefreshRateConfig(VtsDisplay* vtsDisplay) {
146 const auto displayId = vtsDisplay->getDisplayId();
147 auto [activeStatus, activeConfig] = getActiveConfig(displayId);
148 EXPECT_TRUE(activeStatus.isOk());
149 auto peakDisplayConfig = vtsDisplay->getDisplayConfig(activeConfig);
150 auto peakConfig = activeConfig;
151
152 const auto displayConfigs = vtsDisplay->getDisplayConfigs();
153 for (const auto [config, displayConfig] : displayConfigs) {
154 if (displayConfig.configGroup == peakDisplayConfig.configGroup &&
155 displayConfig.vsyncPeriod < peakDisplayConfig.vsyncPeriod) {
156 peakDisplayConfig = displayConfig;
157 peakConfig = config;
158 }
159 }
160 return setActiveConfig(vtsDisplay, peakConfig);
161}
162
ramindaniedf3ef92022-01-07 00:04:23 +0000163std::pair<ScopedAStatus, int32_t> VtsComposerClient::getDisplayAttribute(
164 int64_t display, int32_t config, DisplayAttribute displayAttribute) {
165 int32_t outDisplayAttribute;
166 return {mComposerClient->getDisplayAttribute(display, config, displayAttribute,
167 &outDisplayAttribute),
168 outDisplayAttribute};
169}
170
171ScopedAStatus VtsComposerClient::setPowerMode(int64_t display, PowerMode powerMode) {
172 return mComposerClient->setPowerMode(display, powerMode);
173}
174
175ScopedAStatus VtsComposerClient::setVsync(int64_t display, bool enable) {
176 return mComposerClient->setVsyncEnabled(display, enable);
177}
178
179void VtsComposerClient::setVsyncAllowed(bool isAllowed) {
180 mComposerCallback->setVsyncAllowed(isAllowed);
181}
182
183std::pair<ScopedAStatus, std::vector<float>> VtsComposerClient::getDataspaceSaturationMatrix(
184 Dataspace dataspace) {
185 std::vector<float> outMatrix;
186 return {mComposerClient->getDataspaceSaturationMatrix(dataspace, &outMatrix), outMatrix};
187}
188
189std::pair<ScopedAStatus, std::vector<CommandResultPayload>> VtsComposerClient::executeCommands(
190 const std::vector<DisplayCommand>& commands) {
191 std::vector<CommandResultPayload> outResultPayload;
192 return {mComposerClient->executeCommands(commands, &outResultPayload),
193 std::move(outResultPayload)};
194}
195
196std::optional<VsyncPeriodChangeTimeline> VtsComposerClient::takeLastVsyncPeriodChangeTimeline() {
197 return mComposerCallback->takeLastVsyncPeriodChangeTimeline();
198}
199
200ScopedAStatus VtsComposerClient::setContentType(int64_t display, ContentType contentType) {
201 return mComposerClient->setContentType(display, contentType);
202}
203
204std::pair<ScopedAStatus, VsyncPeriodChangeTimeline>
205VtsComposerClient::setActiveConfigWithConstraints(VtsDisplay* vtsDisplay, int32_t config,
206 const VsyncPeriodChangeConstraints& constraints) {
207 VsyncPeriodChangeTimeline outTimeline;
208 auto status = mComposerClient->setActiveConfigWithConstraints(
209 vtsDisplay->getDisplayId(), config, constraints, &outTimeline);
210 if (!status.isOk()) {
211 return {std::move(status), outTimeline};
212 }
213 return {updateDisplayProperties(vtsDisplay, config), outTimeline};
214}
215
216std::pair<ScopedAStatus, std::vector<DisplayCapability>> VtsComposerClient::getDisplayCapabilities(
217 int64_t display) {
218 std::vector<DisplayCapability> outCapabilities;
219 return {mComposerClient->getDisplayCapabilities(display, &outCapabilities), outCapabilities};
220}
221
222ScopedAStatus VtsComposerClient::dumpDebugInfo() {
Ady Abraham89d72702022-02-18 17:04:55 -0800223 int pipefds[2];
224 if (pipe(pipefds) < 0) {
225 return ScopedAStatus::fromServiceSpecificError(IComposer::EX_NO_RESOURCES);
226 }
227
228 const auto status = mComposer->dump(pipefds[1], /*args*/ nullptr, /*numArgs*/ 0);
229 close(pipefds[0]);
230 close(pipefds[1]);
231 return ScopedAStatus::fromStatus(status);
ramindaniedf3ef92022-01-07 00:04:23 +0000232}
233
234std::pair<ScopedAStatus, DisplayIdentification> VtsComposerClient::getDisplayIdentificationData(
235 int64_t display) {
236 DisplayIdentification outDisplayIdentification;
237 return {mComposerClient->getDisplayIdentificationData(display, &outDisplayIdentification),
238 outDisplayIdentification};
239}
240
241std::pair<ScopedAStatus, HdrCapabilities> VtsComposerClient::getHdrCapabilities(int64_t display) {
242 HdrCapabilities outHdrCapabilities;
243 return {mComposerClient->getHdrCapabilities(display, &outHdrCapabilities), outHdrCapabilities};
244}
245
246std::pair<ScopedAStatus, std::vector<PerFrameMetadataKey>>
247VtsComposerClient::getPerFrameMetadataKeys(int64_t display) {
248 std::vector<PerFrameMetadataKey> outPerFrameMetadataKeys;
249 return {mComposerClient->getPerFrameMetadataKeys(display, &outPerFrameMetadataKeys),
250 outPerFrameMetadataKeys};
251}
252
253std::pair<ScopedAStatus, ReadbackBufferAttributes> VtsComposerClient::getReadbackBufferAttributes(
254 int64_t display) {
255 ReadbackBufferAttributes outReadbackBufferAttributes;
256 return {mComposerClient->getReadbackBufferAttributes(display, &outReadbackBufferAttributes),
257 outReadbackBufferAttributes};
258}
259
260ScopedAStatus VtsComposerClient::setReadbackBuffer(int64_t display, const native_handle_t* buffer,
261 const ScopedFileDescriptor& releaseFence) {
262 return mComposerClient->setReadbackBuffer(display, ::android::dupToAidl(buffer), releaseFence);
263}
264
265std::pair<ScopedAStatus, ScopedFileDescriptor> VtsComposerClient::getReadbackBufferFence(
266 int64_t display) {
267 ScopedFileDescriptor outReleaseFence;
268 return {mComposerClient->getReadbackBufferFence(display, &outReleaseFence),
269 std::move(outReleaseFence)};
270}
271
272std::pair<ScopedAStatus, std::vector<ColorMode>> VtsComposerClient::getColorModes(int64_t display) {
273 std::vector<ColorMode> outColorModes;
274 return {mComposerClient->getColorModes(display, &outColorModes), outColorModes};
275}
276
277std::pair<ScopedAStatus, std::vector<RenderIntent>> VtsComposerClient::getRenderIntents(
278 int64_t display, ColorMode colorMode) {
279 std::vector<RenderIntent> outRenderIntents;
280 return {mComposerClient->getRenderIntents(display, colorMode, &outRenderIntents),
281 outRenderIntents};
282}
283
284ScopedAStatus VtsComposerClient::setColorMode(int64_t display, ColorMode colorMode,
285 RenderIntent renderIntent) {
286 return mComposerClient->setColorMode(display, colorMode, renderIntent);
287}
288
289std::pair<ScopedAStatus, DisplayContentSamplingAttributes>
290VtsComposerClient::getDisplayedContentSamplingAttributes(int64_t display) {
291 DisplayContentSamplingAttributes outAttributes;
292 return {mComposerClient->getDisplayedContentSamplingAttributes(display, &outAttributes),
293 outAttributes};
294}
295
296ScopedAStatus VtsComposerClient::setDisplayedContentSamplingEnabled(
297 int64_t display, bool isEnabled, FormatColorComponent formatColorComponent,
298 int64_t maxFrames) {
299 return mComposerClient->setDisplayedContentSamplingEnabled(display, isEnabled,
300 formatColorComponent, maxFrames);
301}
302
303std::pair<ScopedAStatus, DisplayContentSample> VtsComposerClient::getDisplayedContentSample(
304 int64_t display, int64_t maxFrames, int64_t timestamp) {
305 DisplayContentSample outDisplayContentSample;
306 return {mComposerClient->getDisplayedContentSample(display, maxFrames, timestamp,
307 &outDisplayContentSample),
308 outDisplayContentSample};
309}
310
311std::pair<ScopedAStatus, DisplayConnectionType> VtsComposerClient::getDisplayConnectionType(
312 int64_t display) {
313 DisplayConnectionType outDisplayConnectionType;
314 return {mComposerClient->getDisplayConnectionType(display, &outDisplayConnectionType),
315 outDisplayConnectionType};
316}
317
318std::pair<ScopedAStatus, std::vector<int32_t>> VtsComposerClient::getDisplayConfigs(
319 int64_t display) {
320 std::vector<int32_t> outConfigs;
ramindani02fe4772023-06-30 18:04:41 -0700321 if (!getDisplayConfigurationSupported()) {
322 return {mComposerClient->getDisplayConfigs(display, &outConfigs), outConfigs};
323 }
324
325 auto [status, configs] = getDisplayConfigurations(display);
326 if (!status.isOk()) {
327 return {std::move(status), outConfigs};
328 }
329 for (const auto& config : configs) {
330 outConfigs.emplace_back(config.configId);
331 }
332 return {std::move(status), outConfigs};
333}
334
335std::pair<ScopedAStatus, std::vector<DisplayConfiguration>>
336VtsComposerClient::getDisplayConfigurations(int64_t display) {
337 std::vector<DisplayConfiguration> outConfigs;
ramindani2704c5f2023-07-18 20:53:24 -0700338 return {mComposerClient->getDisplayConfigurations(display, kMaxFrameIntervalNs, &outConfigs),
339 outConfigs};
340}
341
342ScopedAStatus VtsComposerClient::notifyExpectedPresent(int64_t display,
343 ClockMonotonicTimestamp expectedPresentTime,
344 int frameIntervalNs) {
345 return mComposerClient->notifyExpectedPresent(display, expectedPresentTime, frameIntervalNs);
ramindaniedf3ef92022-01-07 00:04:23 +0000346}
347
348std::pair<ScopedAStatus, int32_t> VtsComposerClient::getDisplayVsyncPeriod(int64_t display) {
349 int32_t outVsyncPeriodNanos;
350 return {mComposerClient->getDisplayVsyncPeriod(display, &outVsyncPeriodNanos),
351 outVsyncPeriodNanos};
352}
353
354ScopedAStatus VtsComposerClient::setAutoLowLatencyMode(int64_t display, bool isEnabled) {
355 return mComposerClient->setAutoLowLatencyMode(display, isEnabled);
356}
357
358std::pair<ScopedAStatus, std::vector<ContentType>> VtsComposerClient::getSupportedContentTypes(
359 int64_t display) {
360 std::vector<ContentType> outContentTypes;
361 return {mComposerClient->getSupportedContentTypes(display, &outContentTypes), outContentTypes};
362}
363
Leon Scroggins IIIde057582022-01-13 12:26:00 -0500364std::pair<ScopedAStatus, std::optional<DisplayDecorationSupport>>
365VtsComposerClient::getDisplayDecorationSupport(int64_t display) {
366 std::optional<DisplayDecorationSupport> outSupport;
367 return {mComposerClient->getDisplayDecorationSupport(display, &outSupport), outSupport};
368}
369
ramindaniedf3ef92022-01-07 00:04:23 +0000370std::pair<ScopedAStatus, int32_t> VtsComposerClient::getMaxVirtualDisplayCount() {
371 int32_t outMaxVirtualDisplayCount;
372 return {mComposerClient->getMaxVirtualDisplayCount(&outMaxVirtualDisplayCount),
373 outMaxVirtualDisplayCount};
374}
375
376std::pair<ScopedAStatus, std::string> VtsComposerClient::getDisplayName(int64_t display) {
377 std::string outDisplayName;
378 return {mComposerClient->getDisplayName(display, &outDisplayName), outDisplayName};
379}
380
381ScopedAStatus VtsComposerClient::setClientTargetSlotCount(int64_t display,
382 int32_t bufferSlotCount) {
383 return mComposerClient->setClientTargetSlotCount(display, bufferSlotCount);
384}
385
386std::pair<ScopedAStatus, std::vector<Capability>> VtsComposerClient::getCapabilities() {
387 std::vector<Capability> outCapabilities;
388 return {mComposer->getCapabilities(&outCapabilities), outCapabilities};
389}
390
391ScopedAStatus VtsComposerClient::setBootDisplayConfig(int64_t display, int32_t config) {
392 return mComposerClient->setBootDisplayConfig(display, config);
393}
394
395ScopedAStatus VtsComposerClient::clearBootDisplayConfig(int64_t display) {
396 return mComposerClient->clearBootDisplayConfig(display);
397}
398
399std::pair<ScopedAStatus, int32_t> VtsComposerClient::getPreferredBootDisplayConfig(
400 int64_t display) {
401 int32_t outConfig;
402 return {mComposerClient->getPreferredBootDisplayConfig(display, &outConfig), outConfig};
403}
404
Kriti Dang3793ebd2022-12-05 13:03:49 +0100405std::pair<ScopedAStatus, std::vector<common::HdrConversionCapability>>
406VtsComposerClient::getHdrConversionCapabilities() {
407 std::vector<common::HdrConversionCapability> hdrConversionCapability;
408 return {mComposerClient->getHdrConversionCapabilities(&hdrConversionCapability),
409 hdrConversionCapability};
410}
411
Kriti Dang37622762023-02-09 18:15:37 +0100412std::pair<ScopedAStatus, common::Hdr> VtsComposerClient::setHdrConversionStrategy(
Kriti Dang3793ebd2022-12-05 13:03:49 +0100413 const common::HdrConversionStrategy& conversionStrategy) {
Kriti Dang37622762023-02-09 18:15:37 +0100414 common::Hdr preferredHdrOutputType;
415 return {mComposerClient->setHdrConversionStrategy(conversionStrategy, &preferredHdrOutputType),
416 preferredHdrOutputType};
Kriti Dang3793ebd2022-12-05 13:03:49 +0100417}
418
ramindaniedf3ef92022-01-07 00:04:23 +0000419std::pair<ScopedAStatus, common::Transform> VtsComposerClient::getDisplayPhysicalOrientation(
420 int64_t display) {
421 common::Transform outDisplayOrientation;
422 return {mComposerClient->getDisplayPhysicalOrientation(display, &outDisplayOrientation),
423 outDisplayOrientation};
424}
425
Sally Qi2600d342022-08-16 12:46:17 -0700426std::pair<ScopedAStatus, composer3::OverlayProperties> VtsComposerClient::getOverlaySupport() {
427 OverlayProperties properties;
428 return {mComposerClient->getOverlaySupport(&properties), properties};
429}
430
ramindaniedf3ef92022-01-07 00:04:23 +0000431ScopedAStatus VtsComposerClient::setIdleTimerEnabled(int64_t display, int32_t timeoutMs) {
432 return mComposerClient->setIdleTimerEnabled(display, timeoutMs);
433}
434
435int32_t VtsComposerClient::getVsyncIdleCount() {
436 return mComposerCallback->getVsyncIdleCount();
437}
438
439int64_t VtsComposerClient::getVsyncIdleTime() {
440 return mComposerCallback->getVsyncIdleTime();
441}
442
ramindani9dd8c482023-02-21 18:07:56 -0800443ndk::ScopedAStatus VtsComposerClient::setRefreshRateChangedCallbackDebugEnabled(int64_t display,
444 bool enabled) {
445 mComposerCallback->setRefreshRateChangedDebugDataEnabledCallbackAllowed(enabled);
446 return mComposerClient->setRefreshRateChangedCallbackDebugEnabled(display, enabled);
447}
448
449std::vector<RefreshRateChangedDebugData>
450VtsComposerClient::takeListOfRefreshRateChangedDebugData() {
451 return mComposerCallback->takeListOfRefreshRateChangedDebugData();
ramindani83450342023-02-03 12:52:08 -0800452}
453
ramindaniedf3ef92022-01-07 00:04:23 +0000454int64_t VtsComposerClient::getInvalidDisplayId() {
455 // returns an invalid display id (one that has not been registered to a
456 // display. Currently assuming that a device will never have close to
457 // std::numeric_limit<uint64_t>::max() displays registered while running tests
458 int64_t id = std::numeric_limits<int64_t>::max();
459 std::vector<int64_t> displays = mComposerCallback->getDisplays();
460 while (id > 0) {
461 if (std::none_of(displays.begin(), displays.end(),
462 [id](const auto& display) { return id == display; })) {
463 return id;
464 }
465 id--;
466 }
467
468 // Although 0 could be an invalid display, a return value of 0
469 // from getInvalidDisplayId means all other ids are in use, a condition which
470 // we are assuming a device will never have
471 EXPECT_NE(0, id);
472 return id;
473}
474
475std::pair<ScopedAStatus, std::vector<VtsDisplay>> VtsComposerClient::getDisplays() {
476 while (true) {
477 // Sleep for a small period of time to allow all built-in displays
478 // to post hotplug events
479 std::this_thread::sleep_for(5ms);
480 std::vector<int64_t> displays = mComposerCallback->getDisplays();
481 if (displays.empty()) {
482 continue;
483 }
484
485 std::vector<VtsDisplay> vtsDisplays;
486 vtsDisplays.reserve(displays.size());
487 for (int64_t display : displays) {
488 auto vtsDisplay = VtsDisplay{display};
ramindani02fe4772023-06-30 18:04:41 -0700489 if (getDisplayConfigurationSupported()) {
490 auto [status, configs] = getDisplayConfigurations(display);
ramindaniedf3ef92022-01-07 00:04:23 +0000491 if (!status.isOk()) {
ramindani02fe4772023-06-30 18:04:41 -0700492 ALOGE("Unable to get the displays for test, failed to get the DisplayConfigs "
ramindaniedf3ef92022-01-07 00:04:23 +0000493 "for display %" PRId64,
494 display);
495 return {std::move(status), vtsDisplays};
496 }
ramindani02fe4772023-06-30 18:04:41 -0700497 addDisplayConfigs(&vtsDisplay, configs);
498 } else {
499 auto [status, configs] = getDisplayConfigs(display);
500 if (!status.isOk()) {
501 ALOGE("Unable to get the displays for test, failed to get the configs "
502 "for display %" PRId64,
503 display);
504 return {std::move(status), vtsDisplays};
505 }
506 for (int config : configs) {
507 status = addDisplayConfigLegacy(&vtsDisplay, config);
508 if (!status.isOk()) {
509 ALOGE("Unable to get the displays for test, failed to add config "
510 "for display %" PRId64,
511 display);
512 return {std::move(status), vtsDisplays};
513 }
514 }
ramindaniedf3ef92022-01-07 00:04:23 +0000515 }
ramindani02fe4772023-06-30 18:04:41 -0700516 auto activeConfig = getActiveConfig(display);
517 if (!activeConfig.first.isOk()) {
HyunKyoung4775bdc2022-11-09 20:43:34 +0900518 ALOGE("Unable to get the displays for test, failed to get active config "
ramindani02fe4772023-06-30 18:04:41 -0700519 "for display %" PRId64,
520 display);
521 return {std::move(activeConfig.first), vtsDisplays};
HyunKyoung4775bdc2022-11-09 20:43:34 +0900522 }
ramindani02fe4772023-06-30 18:04:41 -0700523 auto status = updateDisplayProperties(&vtsDisplay, activeConfig.second);
HyunKyoung4775bdc2022-11-09 20:43:34 +0900524 if (!status.isOk()) {
525 ALOGE("Unable to get the displays for test, "
526 "failed to update the properties "
527 "for display %" PRId64,
528 display);
529 return {std::move(status), vtsDisplays};
530 }
531
ramindaniedf3ef92022-01-07 00:04:23 +0000532 vtsDisplays.emplace_back(vtsDisplay);
533 addDisplayToDisplayResources(display, /*isVirtual*/ false);
534 }
535
536 return {ScopedAStatus::ok(), vtsDisplays};
537 }
538}
539
ramindani02fe4772023-06-30 18:04:41 -0700540void VtsComposerClient::addDisplayConfigs(VtsDisplay* vtsDisplay,
541 const std::vector<DisplayConfiguration>& configs) {
542 for (const auto& config : configs) {
ramindania2a6dea2023-12-11 13:42:36 -0800543 vtsDisplay->addDisplayConfig(config.configId,
544 {config.vsyncPeriod, config.configGroup, config.vrrConfig});
ramindani02fe4772023-06-30 18:04:41 -0700545 }
546}
547
548ScopedAStatus VtsComposerClient::addDisplayConfigLegacy(VtsDisplay* vtsDisplay, int32_t config) {
ramindaniedf3ef92022-01-07 00:04:23 +0000549 const auto vsyncPeriod =
550 getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::VSYNC_PERIOD);
551 const auto configGroup =
552 getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::CONFIG_GROUP);
ramindani02fe4772023-06-30 18:04:41 -0700553 if (vsyncPeriod.first.isOk() && configGroup.first.isOk()) {
ramindaniedf3ef92022-01-07 00:04:23 +0000554 vtsDisplay->addDisplayConfig(config, {vsyncPeriod.second, configGroup.second});
555 return ScopedAStatus::ok();
556 }
557
ramindani02fe4772023-06-30 18:04:41 -0700558 LOG(ERROR) << "Failed to update display property vsync: " << vsyncPeriod.first.isOk()
ramindaniedf3ef92022-01-07 00:04:23 +0000559 << ", config: " << configGroup.first.isOk();
560 return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_CONFIG);
561}
562
HyunKyoung4775bdc2022-11-09 20:43:34 +0900563ScopedAStatus VtsComposerClient::updateDisplayProperties(VtsDisplay* vtsDisplay, int32_t config) {
ramindani02fe4772023-06-30 18:04:41 -0700564 if (getDisplayConfigurationSupported()) {
565 auto [status, configs] = getDisplayConfigurations(vtsDisplay->getDisplayId());
566 if (status.isOk()) {
567 for (const auto& displayConfig : configs) {
568 if (displayConfig.configId == config) {
569 vtsDisplay->setDimensions(displayConfig.width, displayConfig.height);
570 return ScopedAStatus::ok();
571 }
572 }
573 }
574 LOG(ERROR) << "Failed to update display property with DisplayConfig";
575 } else {
576 const auto width =
577 getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::WIDTH);
578 const auto height =
579 getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::HEIGHT);
580 if (width.first.isOk() && height.first.isOk()) {
581 vtsDisplay->setDimensions(width.second, height.second);
582 return ScopedAStatus::ok();
583 }
HyunKyoung4775bdc2022-11-09 20:43:34 +0900584
ramindani02fe4772023-06-30 18:04:41 -0700585 LOG(ERROR) << "Failed to update display property for width: " << width.first.isOk()
586 << ", height: " << height.first.isOk();
587 }
HyunKyoung4775bdc2022-11-09 20:43:34 +0900588 return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_CONFIG);
589}
590
ramindaniedf3ef92022-01-07 00:04:23 +0000591ScopedAStatus VtsComposerClient::addDisplayToDisplayResources(int64_t display, bool isVirtual) {
592 if (mDisplayResources.insert({display, DisplayResource(isVirtual)}).second) {
593 return ScopedAStatus::ok();
594 }
595
596 ALOGE("Duplicate display id %" PRId64, display);
597 return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_DISPLAY);
598}
599
600ScopedAStatus VtsComposerClient::addLayerToDisplayResources(int64_t display, int64_t layer) {
601 auto resource = mDisplayResources.find(display);
602 if (resource == mDisplayResources.end()) {
603 resource = mDisplayResources.insert({display, DisplayResource(false)}).first;
604 }
605
606 if (!resource->second.layers.insert(layer).second) {
607 ALOGE("Duplicate layer id %" PRId64, layer);
608 return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_LAYER);
609 }
610 return ScopedAStatus::ok();
611}
612
613void VtsComposerClient::removeLayerFromDisplayResources(int64_t display, int64_t layer) {
614 auto resource = mDisplayResources.find(display);
615 if (resource != mDisplayResources.end()) {
616 resource->second.layers.erase(layer);
617 }
618}
619
620bool VtsComposerClient::verifyComposerCallbackParams() {
621 bool isValid = true;
622 if (mComposerCallback != nullptr) {
623 if (mComposerCallback->getInvalidHotplugCount() != 0) {
624 ALOGE("Invalid hotplug count");
625 isValid = false;
626 }
627 if (mComposerCallback->getInvalidRefreshCount() != 0) {
628 ALOGE("Invalid refresh count");
629 isValid = false;
630 }
631 if (mComposerCallback->getInvalidVsyncCount() != 0) {
632 ALOGE("Invalid vsync count");
633 isValid = false;
634 }
635 if (mComposerCallback->getInvalidVsyncPeriodChangeCount() != 0) {
636 ALOGE("Invalid vsync period change count");
637 isValid = false;
638 }
639 if (mComposerCallback->getInvalidSeamlessPossibleCount() != 0) {
640 ALOGE("Invalid seamless possible count");
641 isValid = false;
642 }
ramindani9dd8c482023-02-21 18:07:56 -0800643 if (mComposerCallback->getInvalidRefreshRateDebugEnabledCallbackCount() != 0) {
644 ALOGE("Invalid refresh rate debug enabled callback count");
645 isValid = false;
646 }
ramindaniedf3ef92022-01-07 00:04:23 +0000647 }
648 return isValid;
649}
650
ramindani02fe4772023-06-30 18:04:41 -0700651bool VtsComposerClient::getDisplayConfigurationSupported() const {
652 auto [status, interfaceVersion] = getInterfaceVersion();
653 EXPECT_TRUE(status.isOk());
654 // getDisplayConfigurations api is supported starting interface version 3
655 return interfaceVersion >= 3;
656}
657
Ady Abrahama00d2462023-12-26 14:21:20 -0800658bool VtsComposerClient::destroyAllLayers(ComposerClientWriter* writer) {
JihCheng Chiud0dbe4e2022-06-11 01:53:11 +0800659 std::unordered_map<int64_t, DisplayResource> physicalDisplays;
660 while (!mDisplayResources.empty()) {
661 const auto& it = mDisplayResources.begin();
662 const auto& [display, resource] = *it;
ramindaniedf3ef92022-01-07 00:04:23 +0000663
JihCheng Chiud0dbe4e2022-06-11 01:53:11 +0800664 while (!resource.layers.empty()) {
665 auto layer = *resource.layers.begin();
Ady Abrahama00d2462023-12-26 14:21:20 -0800666 const auto status = destroyLayer(display, layer, writer);
ramindaniedf3ef92022-01-07 00:04:23 +0000667 if (!status.isOk()) {
668 ALOGE("Unable to destroy all the layers, failed at layer %" PRId64 " with error %s",
669 layer, status.getDescription().c_str());
670 return false;
671 }
672 }
673
674 if (resource.isVirtual) {
675 const auto status = destroyVirtualDisplay(display);
676 if (!status.isOk()) {
677 ALOGE("Unable to destroy the display %" PRId64 " failed with error %s", display,
678 status.getDescription().c_str());
679 return false;
680 }
JihCheng Chiud0dbe4e2022-06-11 01:53:11 +0800681 } else {
682 auto extractIter = mDisplayResources.extract(it);
683 physicalDisplays.insert(std::move(extractIter));
ramindaniedf3ef92022-01-07 00:04:23 +0000684 }
685 }
JihCheng Chiud0dbe4e2022-06-11 01:53:11 +0800686 mDisplayResources.swap(physicalDisplays);
ramindaniedf3ef92022-01-07 00:04:23 +0000687 mDisplayResources.clear();
688 return true;
689}
Leon Scroggins IIIde057582022-01-13 12:26:00 -0500690} // namespace aidl::android::hardware::graphics::composer3::vts