• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
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 
17 #include "VtsComposerClient.h"
18 #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 
25 using namespace std::chrono_literals;
26 
27 namespace aidl::android::hardware::graphics::composer3::vts {
28 
VtsComposerClient(const std::string & name)29 VtsComposerClient::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 
createClient()38 ScopedAStatus 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 
tearDown()57 bool VtsComposerClient::tearDown() {
58     return verifyComposerCallbackParams() && destroyAllLayers();
59 }
60 
getInterfaceVersion()61 std::pair<ScopedAStatus, int32_t> VtsComposerClient::getInterfaceVersion() {
62     int32_t version = 1;
63     auto status = mComposerClient->getInterfaceVersion(&version);
64     return {std::move(status), version};
65 }
66 
createVirtualDisplay(int32_t width,int32_t height,PixelFormat pixelFormat,int32_t bufferSlotCount)67 std::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 
destroyVirtualDisplay(int64_t display)79 ScopedAStatus 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 
createLayer(int64_t display,int32_t bufferSlotCount)88 std::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 
destroyLayer(int64_t display,int64_t layer)99 ScopedAStatus 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 
getActiveConfig(int64_t display)109 std::pair<ScopedAStatus, int32_t> VtsComposerClient::getActiveConfig(int64_t display) {
110     int32_t outConfig;
111     return {mComposerClient->getActiveConfig(display, &outConfig), outConfig};
112 }
113 
setActiveConfig(VtsDisplay * vtsDisplay,int32_t config)114 ScopedAStatus 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 
setPeakRefreshRateConfig(VtsDisplay * vtsDisplay)122 ScopedAStatus 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 
getDisplayAttribute(int64_t display,int32_t config,DisplayAttribute displayAttribute)140 std::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 
setPowerMode(int64_t display,PowerMode powerMode)148 ScopedAStatus VtsComposerClient::setPowerMode(int64_t display, PowerMode powerMode) {
149     return mComposerClient->setPowerMode(display, powerMode);
150 }
151 
setVsync(int64_t display,bool enable)152 ScopedAStatus VtsComposerClient::setVsync(int64_t display, bool enable) {
153     return mComposerClient->setVsyncEnabled(display, enable);
154 }
155 
setVsyncAllowed(bool isAllowed)156 void VtsComposerClient::setVsyncAllowed(bool isAllowed) {
157     mComposerCallback->setVsyncAllowed(isAllowed);
158 }
159 
getDataspaceSaturationMatrix(Dataspace dataspace)160 std::pair<ScopedAStatus, std::vector<float>> VtsComposerClient::getDataspaceSaturationMatrix(
161         Dataspace dataspace) {
162     std::vector<float> outMatrix;
163     return {mComposerClient->getDataspaceSaturationMatrix(dataspace, &outMatrix), outMatrix};
164 }
165 
executeCommands(const std::vector<DisplayCommand> & commands)166 std::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 
takeLastVsyncPeriodChangeTimeline()173 std::optional<VsyncPeriodChangeTimeline> VtsComposerClient::takeLastVsyncPeriodChangeTimeline() {
174     return mComposerCallback->takeLastVsyncPeriodChangeTimeline();
175 }
176 
setContentType(int64_t display,ContentType contentType)177 ScopedAStatus VtsComposerClient::setContentType(int64_t display, ContentType contentType) {
178     return mComposerClient->setContentType(display, contentType);
179 }
180 
181 std::pair<ScopedAStatus, VsyncPeriodChangeTimeline>
setActiveConfigWithConstraints(VtsDisplay * vtsDisplay,int32_t config,const VsyncPeriodChangeConstraints & constraints)182 VtsComposerClient::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 
getDisplayCapabilities(int64_t display)193 std::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 
dumpDebugInfo()199 ScopedAStatus VtsComposerClient::dumpDebugInfo() {
200     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);
209 }
210 
getDisplayIdentificationData(int64_t display)211 std::pair<ScopedAStatus, DisplayIdentification> VtsComposerClient::getDisplayIdentificationData(
212         int64_t display) {
213     DisplayIdentification outDisplayIdentification;
214     return {mComposerClient->getDisplayIdentificationData(display, &outDisplayIdentification),
215             outDisplayIdentification};
216 }
217 
getHdrCapabilities(int64_t display)218 std::pair<ScopedAStatus, HdrCapabilities> VtsComposerClient::getHdrCapabilities(int64_t display) {
219     HdrCapabilities outHdrCapabilities;
220     return {mComposerClient->getHdrCapabilities(display, &outHdrCapabilities), outHdrCapabilities};
221 }
222 
223 std::pair<ScopedAStatus, std::vector<PerFrameMetadataKey>>
getPerFrameMetadataKeys(int64_t display)224 VtsComposerClient::getPerFrameMetadataKeys(int64_t display) {
225     std::vector<PerFrameMetadataKey> outPerFrameMetadataKeys;
226     return {mComposerClient->getPerFrameMetadataKeys(display, &outPerFrameMetadataKeys),
227             outPerFrameMetadataKeys};
228 }
229 
getReadbackBufferAttributes(int64_t display)230 std::pair<ScopedAStatus, ReadbackBufferAttributes> VtsComposerClient::getReadbackBufferAttributes(
231         int64_t display) {
232     ReadbackBufferAttributes outReadbackBufferAttributes;
233     return {mComposerClient->getReadbackBufferAttributes(display, &outReadbackBufferAttributes),
234             outReadbackBufferAttributes};
235 }
236 
setReadbackBuffer(int64_t display,const native_handle_t * buffer,const ScopedFileDescriptor & releaseFence)237 ScopedAStatus 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 
getReadbackBufferFence(int64_t display)242 std::pair<ScopedAStatus, ScopedFileDescriptor> VtsComposerClient::getReadbackBufferFence(
243         int64_t display) {
244     ScopedFileDescriptor outReleaseFence;
245     return {mComposerClient->getReadbackBufferFence(display, &outReleaseFence),
246             std::move(outReleaseFence)};
247 }
248 
getColorModes(int64_t display)249 std::pair<ScopedAStatus, std::vector<ColorMode>> VtsComposerClient::getColorModes(int64_t display) {
250     std::vector<ColorMode> outColorModes;
251     return {mComposerClient->getColorModes(display, &outColorModes), outColorModes};
252 }
253 
getRenderIntents(int64_t display,ColorMode colorMode)254 std::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 
setColorMode(int64_t display,ColorMode colorMode,RenderIntent renderIntent)261 ScopedAStatus VtsComposerClient::setColorMode(int64_t display, ColorMode colorMode,
262                                               RenderIntent renderIntent) {
263     return mComposerClient->setColorMode(display, colorMode, renderIntent);
264 }
265 
266 std::pair<ScopedAStatus, DisplayContentSamplingAttributes>
getDisplayedContentSamplingAttributes(int64_t display)267 VtsComposerClient::getDisplayedContentSamplingAttributes(int64_t display) {
268     DisplayContentSamplingAttributes outAttributes;
269     return {mComposerClient->getDisplayedContentSamplingAttributes(display, &outAttributes),
270             outAttributes};
271 }
272 
setDisplayedContentSamplingEnabled(int64_t display,bool isEnabled,FormatColorComponent formatColorComponent,int64_t maxFrames)273 ScopedAStatus 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 
getDisplayedContentSample(int64_t display,int64_t maxFrames,int64_t timestamp)280 std::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 
getDisplayConnectionType(int64_t display)288 std::pair<ScopedAStatus, DisplayConnectionType> VtsComposerClient::getDisplayConnectionType(
289         int64_t display) {
290     DisplayConnectionType outDisplayConnectionType;
291     return {mComposerClient->getDisplayConnectionType(display, &outDisplayConnectionType),
292             outDisplayConnectionType};
293 }
294 
getDisplayConfigs(int64_t display)295 std::pair<ScopedAStatus, std::vector<int32_t>> VtsComposerClient::getDisplayConfigs(
296         int64_t display) {
297     std::vector<int32_t> outConfigs;
298     return {mComposerClient->getDisplayConfigs(display, &outConfigs), outConfigs};
299 }
300 
getDisplayVsyncPeriod(int64_t display)301 std::pair<ScopedAStatus, int32_t> VtsComposerClient::getDisplayVsyncPeriod(int64_t display) {
302     int32_t outVsyncPeriodNanos;
303     return {mComposerClient->getDisplayVsyncPeriod(display, &outVsyncPeriodNanos),
304             outVsyncPeriodNanos};
305 }
306 
setAutoLowLatencyMode(int64_t display,bool isEnabled)307 ScopedAStatus VtsComposerClient::setAutoLowLatencyMode(int64_t display, bool isEnabled) {
308     return mComposerClient->setAutoLowLatencyMode(display, isEnabled);
309 }
310 
getSupportedContentTypes(int64_t display)311 std::pair<ScopedAStatus, std::vector<ContentType>> VtsComposerClient::getSupportedContentTypes(
312         int64_t display) {
313     std::vector<ContentType> outContentTypes;
314     return {mComposerClient->getSupportedContentTypes(display, &outContentTypes), outContentTypes};
315 }
316 
317 std::pair<ScopedAStatus, std::optional<DisplayDecorationSupport>>
getDisplayDecorationSupport(int64_t display)318 VtsComposerClient::getDisplayDecorationSupport(int64_t display) {
319     std::optional<DisplayDecorationSupport> outSupport;
320     return {mComposerClient->getDisplayDecorationSupport(display, &outSupport), outSupport};
321 }
322 
getMaxVirtualDisplayCount()323 std::pair<ScopedAStatus, int32_t> VtsComposerClient::getMaxVirtualDisplayCount() {
324     int32_t outMaxVirtualDisplayCount;
325     return {mComposerClient->getMaxVirtualDisplayCount(&outMaxVirtualDisplayCount),
326             outMaxVirtualDisplayCount};
327 }
328 
getDisplayName(int64_t display)329 std::pair<ScopedAStatus, std::string> VtsComposerClient::getDisplayName(int64_t display) {
330     std::string outDisplayName;
331     return {mComposerClient->getDisplayName(display, &outDisplayName), outDisplayName};
332 }
333 
setClientTargetSlotCount(int64_t display,int32_t bufferSlotCount)334 ScopedAStatus VtsComposerClient::setClientTargetSlotCount(int64_t display,
335                                                           int32_t bufferSlotCount) {
336     return mComposerClient->setClientTargetSlotCount(display, bufferSlotCount);
337 }
338 
getCapabilities()339 std::pair<ScopedAStatus, std::vector<Capability>> VtsComposerClient::getCapabilities() {
340     std::vector<Capability> outCapabilities;
341     return {mComposer->getCapabilities(&outCapabilities), outCapabilities};
342 }
343 
setBootDisplayConfig(int64_t display,int32_t config)344 ScopedAStatus VtsComposerClient::setBootDisplayConfig(int64_t display, int32_t config) {
345     return mComposerClient->setBootDisplayConfig(display, config);
346 }
347 
clearBootDisplayConfig(int64_t display)348 ScopedAStatus VtsComposerClient::clearBootDisplayConfig(int64_t display) {
349     return mComposerClient->clearBootDisplayConfig(display);
350 }
351 
getPreferredBootDisplayConfig(int64_t display)352 std::pair<ScopedAStatus, int32_t> VtsComposerClient::getPreferredBootDisplayConfig(
353         int64_t display) {
354     int32_t outConfig;
355     return {mComposerClient->getPreferredBootDisplayConfig(display, &outConfig), outConfig};
356 }
357 
358 std::pair<ScopedAStatus, std::vector<common::HdrConversionCapability>>
getHdrConversionCapabilities()359 VtsComposerClient::getHdrConversionCapabilities() {
360     std::vector<common::HdrConversionCapability> hdrConversionCapability;
361     return {mComposerClient->getHdrConversionCapabilities(&hdrConversionCapability),
362             hdrConversionCapability};
363 }
364 
setHdrConversionStrategy(const common::HdrConversionStrategy & conversionStrategy)365 std::pair<ScopedAStatus, common::Hdr> VtsComposerClient::setHdrConversionStrategy(
366         const common::HdrConversionStrategy& conversionStrategy) {
367     common::Hdr preferredHdrOutputType;
368     return {mComposerClient->setHdrConversionStrategy(conversionStrategy, &preferredHdrOutputType),
369             preferredHdrOutputType};
370 }
371 
getDisplayPhysicalOrientation(int64_t display)372 std::pair<ScopedAStatus, common::Transform> VtsComposerClient::getDisplayPhysicalOrientation(
373         int64_t display) {
374     common::Transform outDisplayOrientation;
375     return {mComposerClient->getDisplayPhysicalOrientation(display, &outDisplayOrientation),
376             outDisplayOrientation};
377 }
378 
getOverlaySupport()379 std::pair<ScopedAStatus, composer3::OverlayProperties> VtsComposerClient::getOverlaySupport() {
380     OverlayProperties properties;
381     return {mComposerClient->getOverlaySupport(&properties), properties};
382 }
383 
setIdleTimerEnabled(int64_t display,int32_t timeoutMs)384 ScopedAStatus VtsComposerClient::setIdleTimerEnabled(int64_t display, int32_t timeoutMs) {
385     return mComposerClient->setIdleTimerEnabled(display, timeoutMs);
386 }
387 
getVsyncIdleCount()388 int32_t VtsComposerClient::getVsyncIdleCount() {
389     return mComposerCallback->getVsyncIdleCount();
390 }
391 
getVsyncIdleTime()392 int64_t VtsComposerClient::getVsyncIdleTime() {
393     return mComposerCallback->getVsyncIdleTime();
394 }
395 
setRefreshRateChangedCallbackDebugEnabled(int64_t display,bool enabled)396 ndk::ScopedAStatus VtsComposerClient::setRefreshRateChangedCallbackDebugEnabled(int64_t display,
397                                                                                 bool enabled) {
398     mComposerCallback->setRefreshRateChangedDebugDataEnabledCallbackAllowed(enabled);
399     return mComposerClient->setRefreshRateChangedCallbackDebugEnabled(display, enabled);
400 }
401 
402 std::vector<RefreshRateChangedDebugData>
takeListOfRefreshRateChangedDebugData()403 VtsComposerClient::takeListOfRefreshRateChangedDebugData() {
404     return mComposerCallback->takeListOfRefreshRateChangedDebugData();
405 }
406 
getInvalidDisplayId()407 int64_t VtsComposerClient::getInvalidDisplayId() {
408     // returns an invalid display id (one that has not been registered to a
409     // display. Currently assuming that a device will never have close to
410     // std::numeric_limit<uint64_t>::max() displays registered while running tests
411     int64_t id = std::numeric_limits<int64_t>::max();
412     std::vector<int64_t> displays = mComposerCallback->getDisplays();
413     while (id > 0) {
414         if (std::none_of(displays.begin(), displays.end(),
415                          [id](const auto& display) { return id == display; })) {
416             return id;
417         }
418         id--;
419     }
420 
421     // Although 0 could be an invalid display, a return value of 0
422     // from getInvalidDisplayId means all other ids are in use, a condition which
423     // we are assuming a device will never have
424     EXPECT_NE(0, id);
425     return id;
426 }
427 
getDisplays()428 std::pair<ScopedAStatus, std::vector<VtsDisplay>> VtsComposerClient::getDisplays() {
429     while (true) {
430         // Sleep for a small period of time to allow all built-in displays
431         // to post hotplug events
432         std::this_thread::sleep_for(5ms);
433         std::vector<int64_t> displays = mComposerCallback->getDisplays();
434         if (displays.empty()) {
435             continue;
436         }
437 
438         std::vector<VtsDisplay> vtsDisplays;
439         vtsDisplays.reserve(displays.size());
440         for (int64_t display : displays) {
441             auto vtsDisplay = VtsDisplay{display};
442             auto configs = getDisplayConfigs(display);
443             if (!configs.first.isOk()) {
444                 ALOGE("Unable to get the displays for test, failed to get the configs "
445                       "for display %" PRId64,
446                       display);
447                 return {std::move(configs.first), vtsDisplays};
448             }
449             for (int config : configs.second) {
450                 auto status = addDisplayConfig(&vtsDisplay, config);
451                 if (!status.isOk()) {
452                     ALOGE("Unable to get the displays for test, failed to add config "
453                           "for display %" PRId64,
454                           display);
455                     return {std::move(status), vtsDisplays};
456                 }
457             }
458 
459             auto config = getActiveConfig(display);
460             if (!config.first.isOk()) {
461                 ALOGE("Unable to get the displays for test, failed to get active config "
462                       "for display %" PRId64, display);
463                 return {std::move(config.first), vtsDisplays};
464             }
465 
466             auto status = updateDisplayProperties(&vtsDisplay, config.second);
467             if (!status.isOk()) {
468                 ALOGE("Unable to get the displays for test, "
469                       "failed to update the properties "
470                       "for display %" PRId64,
471                       display);
472                 return {std::move(status), vtsDisplays};
473             }
474 
475             vtsDisplays.emplace_back(vtsDisplay);
476             addDisplayToDisplayResources(display, /*isVirtual*/ false);
477         }
478 
479         return {ScopedAStatus::ok(), vtsDisplays};
480     }
481 }
482 
addDisplayConfig(VtsDisplay * vtsDisplay,int32_t config)483 ScopedAStatus VtsComposerClient::addDisplayConfig(VtsDisplay* vtsDisplay, int32_t config) {
484     const auto width =
485             getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::WIDTH);
486     const auto height =
487             getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::HEIGHT);
488     const auto vsyncPeriod =
489             getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::VSYNC_PERIOD);
490     const auto configGroup =
491             getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::CONFIG_GROUP);
492     if (width.first.isOk() && height.first.isOk() && vsyncPeriod.first.isOk() &&
493         configGroup.first.isOk()) {
494         vtsDisplay->addDisplayConfig(config, {vsyncPeriod.second, configGroup.second});
495         return ScopedAStatus::ok();
496     }
497 
498     LOG(ERROR) << "Failed to update display property for width: " << width.first.isOk()
499                << ", height: " << height.first.isOk() << ", vsync: " << vsyncPeriod.first.isOk()
500                << ", config: " << configGroup.first.isOk();
501     return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_CONFIG);
502 }
503 
updateDisplayProperties(VtsDisplay * vtsDisplay,int32_t config)504 ScopedAStatus VtsComposerClient::updateDisplayProperties(VtsDisplay* vtsDisplay, int32_t config) {
505     const auto width =
506             getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::WIDTH);
507     const auto height =
508             getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::HEIGHT);
509     if (width.first.isOk() && height.first.isOk()) {
510         vtsDisplay->setDimensions(width.second, height.second);
511         return ScopedAStatus::ok();
512     }
513 
514     LOG(ERROR) << "Failed to update display property for width: " << width.first.isOk()
515                << ", height: " << height.first.isOk();
516     return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_CONFIG);
517 }
518 
addDisplayToDisplayResources(int64_t display,bool isVirtual)519 ScopedAStatus VtsComposerClient::addDisplayToDisplayResources(int64_t display, bool isVirtual) {
520     if (mDisplayResources.insert({display, DisplayResource(isVirtual)}).second) {
521         return ScopedAStatus::ok();
522     }
523 
524     ALOGE("Duplicate display id %" PRId64, display);
525     return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_DISPLAY);
526 }
527 
addLayerToDisplayResources(int64_t display,int64_t layer)528 ScopedAStatus VtsComposerClient::addLayerToDisplayResources(int64_t display, int64_t layer) {
529     auto resource = mDisplayResources.find(display);
530     if (resource == mDisplayResources.end()) {
531         resource = mDisplayResources.insert({display, DisplayResource(false)}).first;
532     }
533 
534     if (!resource->second.layers.insert(layer).second) {
535         ALOGE("Duplicate layer id %" PRId64, layer);
536         return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_LAYER);
537     }
538     return ScopedAStatus::ok();
539 }
540 
removeLayerFromDisplayResources(int64_t display,int64_t layer)541 void VtsComposerClient::removeLayerFromDisplayResources(int64_t display, int64_t layer) {
542     auto resource = mDisplayResources.find(display);
543     if (resource != mDisplayResources.end()) {
544         resource->second.layers.erase(layer);
545     }
546 }
547 
verifyComposerCallbackParams()548 bool VtsComposerClient::verifyComposerCallbackParams() {
549     bool isValid = true;
550     if (mComposerCallback != nullptr) {
551         if (mComposerCallback->getInvalidHotplugCount() != 0) {
552             ALOGE("Invalid hotplug count");
553             isValid = false;
554         }
555         if (mComposerCallback->getInvalidRefreshCount() != 0) {
556             ALOGE("Invalid refresh count");
557             isValid = false;
558         }
559         if (mComposerCallback->getInvalidVsyncCount() != 0) {
560             ALOGE("Invalid vsync count");
561             isValid = false;
562         }
563         if (mComposerCallback->getInvalidVsyncPeriodChangeCount() != 0) {
564             ALOGE("Invalid vsync period change count");
565             isValid = false;
566         }
567         if (mComposerCallback->getInvalidSeamlessPossibleCount() != 0) {
568             ALOGE("Invalid seamless possible count");
569             isValid = false;
570         }
571         if (mComposerCallback->getInvalidRefreshRateDebugEnabledCallbackCount() != 0) {
572             ALOGE("Invalid refresh rate debug enabled callback count");
573             isValid = false;
574         }
575     }
576     return isValid;
577 }
578 
destroyAllLayers()579 bool VtsComposerClient::destroyAllLayers() {
580     std::unordered_map<int64_t, DisplayResource> physicalDisplays;
581     while (!mDisplayResources.empty()) {
582         const auto& it = mDisplayResources.begin();
583         const auto& [display, resource] = *it;
584 
585         while (!resource.layers.empty()) {
586             auto layer = *resource.layers.begin();
587             const auto status = destroyLayer(display, layer);
588             if (!status.isOk()) {
589                 ALOGE("Unable to destroy all the layers, failed at layer %" PRId64 " with error %s",
590                       layer, status.getDescription().c_str());
591                 return false;
592             }
593         }
594 
595         if (resource.isVirtual) {
596             const auto status = destroyVirtualDisplay(display);
597             if (!status.isOk()) {
598                 ALOGE("Unable to destroy the display %" PRId64 " failed with error %s", display,
599                       status.getDescription().c_str());
600                 return false;
601             }
602         } else {
603             auto extractIter = mDisplayResources.extract(it);
604             physicalDisplays.insert(std::move(extractIter));
605         }
606     }
607     mDisplayResources.swap(physicalDisplays);
608     mDisplayResources.clear();
609     return true;
610 }
611 }  // namespace aidl::android::hardware::graphics::composer3::vts
612