• 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 
createVirtualDisplay(int32_t width,int32_t height,PixelFormat pixelFormat,int32_t bufferSlotCount)61 std::pair<ScopedAStatus, VirtualDisplay> VtsComposerClient::createVirtualDisplay(
62         int32_t width, int32_t height, PixelFormat pixelFormat, int32_t bufferSlotCount) {
63     VirtualDisplay outVirtualDisplay;
64     auto status = mComposerClient->createVirtualDisplay(width, height, pixelFormat, bufferSlotCount,
65                                                         &outVirtualDisplay);
66     if (!status.isOk()) {
67         return {std::move(status), outVirtualDisplay};
68     }
69     return {addDisplayToDisplayResources(outVirtualDisplay.display, /*isVirtual*/ true),
70             outVirtualDisplay};
71 }
72 
destroyVirtualDisplay(int64_t display)73 ScopedAStatus VtsComposerClient::destroyVirtualDisplay(int64_t display) {
74     auto status = mComposerClient->destroyVirtualDisplay(display);
75     if (!status.isOk()) {
76         return status;
77     }
78     mDisplayResources.erase(display);
79     return status;
80 }
81 
createLayer(int64_t display,int32_t bufferSlotCount)82 std::pair<ScopedAStatus, int64_t> VtsComposerClient::createLayer(int64_t display,
83                                                                  int32_t bufferSlotCount) {
84     int64_t outLayer;
85     auto status = mComposerClient->createLayer(display, bufferSlotCount, &outLayer);
86 
87     if (!status.isOk()) {
88         return {std::move(status), outLayer};
89     }
90     return {addLayerToDisplayResources(display, outLayer), outLayer};
91 }
92 
destroyLayer(int64_t display,int64_t layer)93 ScopedAStatus VtsComposerClient::destroyLayer(int64_t display, int64_t layer) {
94     auto status = mComposerClient->destroyLayer(display, layer);
95 
96     if (!status.isOk()) {
97         return status;
98     }
99     removeLayerFromDisplayResources(display, layer);
100     return status;
101 }
102 
getActiveConfig(int64_t display)103 std::pair<ScopedAStatus, int32_t> VtsComposerClient::getActiveConfig(int64_t display) {
104     int32_t outConfig;
105     return {mComposerClient->getActiveConfig(display, &outConfig), outConfig};
106 }
107 
setActiveConfig(VtsDisplay * vtsDisplay,int32_t config)108 ScopedAStatus VtsComposerClient::setActiveConfig(VtsDisplay* vtsDisplay, int32_t config) {
109     auto status = mComposerClient->setActiveConfig(vtsDisplay->getDisplayId(), config);
110     if (!status.isOk()) {
111         return status;
112     }
113     return updateDisplayProperties(vtsDisplay, config);
114 }
115 
getDisplayAttribute(int64_t display,int32_t config,DisplayAttribute displayAttribute)116 std::pair<ScopedAStatus, int32_t> VtsComposerClient::getDisplayAttribute(
117         int64_t display, int32_t config, DisplayAttribute displayAttribute) {
118     int32_t outDisplayAttribute;
119     return {mComposerClient->getDisplayAttribute(display, config, displayAttribute,
120                                                  &outDisplayAttribute),
121             outDisplayAttribute};
122 }
123 
setPowerMode(int64_t display,PowerMode powerMode)124 ScopedAStatus VtsComposerClient::setPowerMode(int64_t display, PowerMode powerMode) {
125     return mComposerClient->setPowerMode(display, powerMode);
126 }
127 
setVsync(int64_t display,bool enable)128 ScopedAStatus VtsComposerClient::setVsync(int64_t display, bool enable) {
129     return mComposerClient->setVsyncEnabled(display, enable);
130 }
131 
setVsyncAllowed(bool isAllowed)132 void VtsComposerClient::setVsyncAllowed(bool isAllowed) {
133     mComposerCallback->setVsyncAllowed(isAllowed);
134 }
135 
getDataspaceSaturationMatrix(Dataspace dataspace)136 std::pair<ScopedAStatus, std::vector<float>> VtsComposerClient::getDataspaceSaturationMatrix(
137         Dataspace dataspace) {
138     std::vector<float> outMatrix;
139     return {mComposerClient->getDataspaceSaturationMatrix(dataspace, &outMatrix), outMatrix};
140 }
141 
executeCommands(const std::vector<DisplayCommand> & commands)142 std::pair<ScopedAStatus, std::vector<CommandResultPayload>> VtsComposerClient::executeCommands(
143         const std::vector<DisplayCommand>& commands) {
144     std::vector<CommandResultPayload> outResultPayload;
145     return {mComposerClient->executeCommands(commands, &outResultPayload),
146             std::move(outResultPayload)};
147 }
148 
takeLastVsyncPeriodChangeTimeline()149 std::optional<VsyncPeriodChangeTimeline> VtsComposerClient::takeLastVsyncPeriodChangeTimeline() {
150     return mComposerCallback->takeLastVsyncPeriodChangeTimeline();
151 }
152 
setContentType(int64_t display,ContentType contentType)153 ScopedAStatus VtsComposerClient::setContentType(int64_t display, ContentType contentType) {
154     return mComposerClient->setContentType(display, contentType);
155 }
156 
157 std::pair<ScopedAStatus, VsyncPeriodChangeTimeline>
setActiveConfigWithConstraints(VtsDisplay * vtsDisplay,int32_t config,const VsyncPeriodChangeConstraints & constraints)158 VtsComposerClient::setActiveConfigWithConstraints(VtsDisplay* vtsDisplay, int32_t config,
159                                                   const VsyncPeriodChangeConstraints& constraints) {
160     VsyncPeriodChangeTimeline outTimeline;
161     auto status = mComposerClient->setActiveConfigWithConstraints(
162             vtsDisplay->getDisplayId(), config, constraints, &outTimeline);
163     if (!status.isOk()) {
164         return {std::move(status), outTimeline};
165     }
166     return {updateDisplayProperties(vtsDisplay, config), outTimeline};
167 }
168 
getDisplayCapabilities(int64_t display)169 std::pair<ScopedAStatus, std::vector<DisplayCapability>> VtsComposerClient::getDisplayCapabilities(
170         int64_t display) {
171     std::vector<DisplayCapability> outCapabilities;
172     return {mComposerClient->getDisplayCapabilities(display, &outCapabilities), outCapabilities};
173 }
174 
dumpDebugInfo()175 ScopedAStatus VtsComposerClient::dumpDebugInfo() {
176     int pipefds[2];
177     if (pipe(pipefds) < 0) {
178         return ScopedAStatus::fromServiceSpecificError(IComposer::EX_NO_RESOURCES);
179     }
180 
181     const auto status = mComposer->dump(pipefds[1], /*args*/ nullptr, /*numArgs*/ 0);
182     close(pipefds[0]);
183     close(pipefds[1]);
184     return ScopedAStatus::fromStatus(status);
185 }
186 
getDisplayIdentificationData(int64_t display)187 std::pair<ScopedAStatus, DisplayIdentification> VtsComposerClient::getDisplayIdentificationData(
188         int64_t display) {
189     DisplayIdentification outDisplayIdentification;
190     return {mComposerClient->getDisplayIdentificationData(display, &outDisplayIdentification),
191             outDisplayIdentification};
192 }
193 
getHdrCapabilities(int64_t display)194 std::pair<ScopedAStatus, HdrCapabilities> VtsComposerClient::getHdrCapabilities(int64_t display) {
195     HdrCapabilities outHdrCapabilities;
196     return {mComposerClient->getHdrCapabilities(display, &outHdrCapabilities), outHdrCapabilities};
197 }
198 
199 std::pair<ScopedAStatus, std::vector<PerFrameMetadataKey>>
getPerFrameMetadataKeys(int64_t display)200 VtsComposerClient::getPerFrameMetadataKeys(int64_t display) {
201     std::vector<PerFrameMetadataKey> outPerFrameMetadataKeys;
202     return {mComposerClient->getPerFrameMetadataKeys(display, &outPerFrameMetadataKeys),
203             outPerFrameMetadataKeys};
204 }
205 
getReadbackBufferAttributes(int64_t display)206 std::pair<ScopedAStatus, ReadbackBufferAttributes> VtsComposerClient::getReadbackBufferAttributes(
207         int64_t display) {
208     ReadbackBufferAttributes outReadbackBufferAttributes;
209     return {mComposerClient->getReadbackBufferAttributes(display, &outReadbackBufferAttributes),
210             outReadbackBufferAttributes};
211 }
212 
setReadbackBuffer(int64_t display,const native_handle_t * buffer,const ScopedFileDescriptor & releaseFence)213 ScopedAStatus VtsComposerClient::setReadbackBuffer(int64_t display, const native_handle_t* buffer,
214                                                    const ScopedFileDescriptor& releaseFence) {
215     return mComposerClient->setReadbackBuffer(display, ::android::dupToAidl(buffer), releaseFence);
216 }
217 
getReadbackBufferFence(int64_t display)218 std::pair<ScopedAStatus, ScopedFileDescriptor> VtsComposerClient::getReadbackBufferFence(
219         int64_t display) {
220     ScopedFileDescriptor outReleaseFence;
221     return {mComposerClient->getReadbackBufferFence(display, &outReleaseFence),
222             std::move(outReleaseFence)};
223 }
224 
getColorModes(int64_t display)225 std::pair<ScopedAStatus, std::vector<ColorMode>> VtsComposerClient::getColorModes(int64_t display) {
226     std::vector<ColorMode> outColorModes;
227     return {mComposerClient->getColorModes(display, &outColorModes), outColorModes};
228 }
229 
getRenderIntents(int64_t display,ColorMode colorMode)230 std::pair<ScopedAStatus, std::vector<RenderIntent>> VtsComposerClient::getRenderIntents(
231         int64_t display, ColorMode colorMode) {
232     std::vector<RenderIntent> outRenderIntents;
233     return {mComposerClient->getRenderIntents(display, colorMode, &outRenderIntents),
234             outRenderIntents};
235 }
236 
setColorMode(int64_t display,ColorMode colorMode,RenderIntent renderIntent)237 ScopedAStatus VtsComposerClient::setColorMode(int64_t display, ColorMode colorMode,
238                                               RenderIntent renderIntent) {
239     return mComposerClient->setColorMode(display, colorMode, renderIntent);
240 }
241 
242 std::pair<ScopedAStatus, DisplayContentSamplingAttributes>
getDisplayedContentSamplingAttributes(int64_t display)243 VtsComposerClient::getDisplayedContentSamplingAttributes(int64_t display) {
244     DisplayContentSamplingAttributes outAttributes;
245     return {mComposerClient->getDisplayedContentSamplingAttributes(display, &outAttributes),
246             outAttributes};
247 }
248 
setDisplayedContentSamplingEnabled(int64_t display,bool isEnabled,FormatColorComponent formatColorComponent,int64_t maxFrames)249 ScopedAStatus VtsComposerClient::setDisplayedContentSamplingEnabled(
250         int64_t display, bool isEnabled, FormatColorComponent formatColorComponent,
251         int64_t maxFrames) {
252     return mComposerClient->setDisplayedContentSamplingEnabled(display, isEnabled,
253                                                                formatColorComponent, maxFrames);
254 }
255 
getDisplayedContentSample(int64_t display,int64_t maxFrames,int64_t timestamp)256 std::pair<ScopedAStatus, DisplayContentSample> VtsComposerClient::getDisplayedContentSample(
257         int64_t display, int64_t maxFrames, int64_t timestamp) {
258     DisplayContentSample outDisplayContentSample;
259     return {mComposerClient->getDisplayedContentSample(display, maxFrames, timestamp,
260                                                        &outDisplayContentSample),
261             outDisplayContentSample};
262 }
263 
getDisplayConnectionType(int64_t display)264 std::pair<ScopedAStatus, DisplayConnectionType> VtsComposerClient::getDisplayConnectionType(
265         int64_t display) {
266     DisplayConnectionType outDisplayConnectionType;
267     return {mComposerClient->getDisplayConnectionType(display, &outDisplayConnectionType),
268             outDisplayConnectionType};
269 }
270 
getDisplayConfigs(int64_t display)271 std::pair<ScopedAStatus, std::vector<int32_t>> VtsComposerClient::getDisplayConfigs(
272         int64_t display) {
273     std::vector<int32_t> outConfigs;
274     return {mComposerClient->getDisplayConfigs(display, &outConfigs), outConfigs};
275 }
276 
getDisplayVsyncPeriod(int64_t display)277 std::pair<ScopedAStatus, int32_t> VtsComposerClient::getDisplayVsyncPeriod(int64_t display) {
278     int32_t outVsyncPeriodNanos;
279     return {mComposerClient->getDisplayVsyncPeriod(display, &outVsyncPeriodNanos),
280             outVsyncPeriodNanos};
281 }
282 
setAutoLowLatencyMode(int64_t display,bool isEnabled)283 ScopedAStatus VtsComposerClient::setAutoLowLatencyMode(int64_t display, bool isEnabled) {
284     return mComposerClient->setAutoLowLatencyMode(display, isEnabled);
285 }
286 
getSupportedContentTypes(int64_t display)287 std::pair<ScopedAStatus, std::vector<ContentType>> VtsComposerClient::getSupportedContentTypes(
288         int64_t display) {
289     std::vector<ContentType> outContentTypes;
290     return {mComposerClient->getSupportedContentTypes(display, &outContentTypes), outContentTypes};
291 }
292 
293 std::pair<ScopedAStatus, std::optional<DisplayDecorationSupport>>
getDisplayDecorationSupport(int64_t display)294 VtsComposerClient::getDisplayDecorationSupport(int64_t display) {
295     std::optional<DisplayDecorationSupport> outSupport;
296     return {mComposerClient->getDisplayDecorationSupport(display, &outSupport), outSupport};
297 }
298 
getMaxVirtualDisplayCount()299 std::pair<ScopedAStatus, int32_t> VtsComposerClient::getMaxVirtualDisplayCount() {
300     int32_t outMaxVirtualDisplayCount;
301     return {mComposerClient->getMaxVirtualDisplayCount(&outMaxVirtualDisplayCount),
302             outMaxVirtualDisplayCount};
303 }
304 
getDisplayName(int64_t display)305 std::pair<ScopedAStatus, std::string> VtsComposerClient::getDisplayName(int64_t display) {
306     std::string outDisplayName;
307     return {mComposerClient->getDisplayName(display, &outDisplayName), outDisplayName};
308 }
309 
setClientTargetSlotCount(int64_t display,int32_t bufferSlotCount)310 ScopedAStatus VtsComposerClient::setClientTargetSlotCount(int64_t display,
311                                                           int32_t bufferSlotCount) {
312     return mComposerClient->setClientTargetSlotCount(display, bufferSlotCount);
313 }
314 
getCapabilities()315 std::pair<ScopedAStatus, std::vector<Capability>> VtsComposerClient::getCapabilities() {
316     std::vector<Capability> outCapabilities;
317     return {mComposer->getCapabilities(&outCapabilities), outCapabilities};
318 }
319 
setBootDisplayConfig(int64_t display,int32_t config)320 ScopedAStatus VtsComposerClient::setBootDisplayConfig(int64_t display, int32_t config) {
321     return mComposerClient->setBootDisplayConfig(display, config);
322 }
323 
clearBootDisplayConfig(int64_t display)324 ScopedAStatus VtsComposerClient::clearBootDisplayConfig(int64_t display) {
325     return mComposerClient->clearBootDisplayConfig(display);
326 }
327 
getPreferredBootDisplayConfig(int64_t display)328 std::pair<ScopedAStatus, int32_t> VtsComposerClient::getPreferredBootDisplayConfig(
329         int64_t display) {
330     int32_t outConfig;
331     return {mComposerClient->getPreferredBootDisplayConfig(display, &outConfig), outConfig};
332 }
333 
getDisplayPhysicalOrientation(int64_t display)334 std::pair<ScopedAStatus, common::Transform> VtsComposerClient::getDisplayPhysicalOrientation(
335         int64_t display) {
336     common::Transform outDisplayOrientation;
337     return {mComposerClient->getDisplayPhysicalOrientation(display, &outDisplayOrientation),
338             outDisplayOrientation};
339 }
340 
setIdleTimerEnabled(int64_t display,int32_t timeoutMs)341 ScopedAStatus VtsComposerClient::setIdleTimerEnabled(int64_t display, int32_t timeoutMs) {
342     return mComposerClient->setIdleTimerEnabled(display, timeoutMs);
343 }
344 
getVsyncIdleCount()345 int32_t VtsComposerClient::getVsyncIdleCount() {
346     return mComposerCallback->getVsyncIdleCount();
347 }
348 
getVsyncIdleTime()349 int64_t VtsComposerClient::getVsyncIdleTime() {
350     return mComposerCallback->getVsyncIdleTime();
351 }
352 
getInvalidDisplayId()353 int64_t VtsComposerClient::getInvalidDisplayId() {
354     // returns an invalid display id (one that has not been registered to a
355     // display. Currently assuming that a device will never have close to
356     // std::numeric_limit<uint64_t>::max() displays registered while running tests
357     int64_t id = std::numeric_limits<int64_t>::max();
358     std::vector<int64_t> displays = mComposerCallback->getDisplays();
359     while (id > 0) {
360         if (std::none_of(displays.begin(), displays.end(),
361                          [id](const auto& display) { return id == display; })) {
362             return id;
363         }
364         id--;
365     }
366 
367     // Although 0 could be an invalid display, a return value of 0
368     // from getInvalidDisplayId means all other ids are in use, a condition which
369     // we are assuming a device will never have
370     EXPECT_NE(0, id);
371     return id;
372 }
373 
getDisplays()374 std::pair<ScopedAStatus, std::vector<VtsDisplay>> VtsComposerClient::getDisplays() {
375     while (true) {
376         // Sleep for a small period of time to allow all built-in displays
377         // to post hotplug events
378         std::this_thread::sleep_for(5ms);
379         std::vector<int64_t> displays = mComposerCallback->getDisplays();
380         if (displays.empty()) {
381             continue;
382         }
383 
384         std::vector<VtsDisplay> vtsDisplays;
385         vtsDisplays.reserve(displays.size());
386         for (int64_t display : displays) {
387             auto vtsDisplay = VtsDisplay{display};
388             auto configs = getDisplayConfigs(display);
389             if (!configs.first.isOk()) {
390                 ALOGE("Unable to get the displays for test, failed to get the configs "
391                       "for display %" PRId64,
392                       display);
393                 return {std::move(configs.first), vtsDisplays};
394             }
395             for (int config : configs.second) {
396                 auto status = addDisplayConfig(&vtsDisplay, config);
397                 if (!status.isOk()) {
398                     ALOGE("Unable to get the displays for test, failed to add config "
399                           "for display %" PRId64,
400                           display);
401                     return {std::move(status), vtsDisplays};
402                 }
403             }
404 
405             auto config = getActiveConfig(display);
406             if (!config.first.isOk()) {
407                 ALOGE("Unable to get the displays for test, failed to get active config "
408                       "for display %" PRId64, display);
409                 return {std::move(config.first), vtsDisplays};
410             }
411 
412             auto status = updateDisplayProperties(&vtsDisplay, config.second);
413             if (!status.isOk()) {
414                 ALOGE("Unable to get the displays for test, "
415                       "failed to update the properties "
416                       "for display %" PRId64,
417                       display);
418                 return {std::move(status), vtsDisplays};
419             }
420 
421             vtsDisplays.emplace_back(vtsDisplay);
422             addDisplayToDisplayResources(display, /*isVirtual*/ false);
423         }
424 
425         return {ScopedAStatus::ok(), vtsDisplays};
426     }
427 }
428 
addDisplayConfig(VtsDisplay * vtsDisplay,int32_t config)429 ScopedAStatus VtsComposerClient::addDisplayConfig(VtsDisplay* vtsDisplay, int32_t config) {
430     const auto width =
431             getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::WIDTH);
432     const auto height =
433             getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::HEIGHT);
434     const auto vsyncPeriod =
435             getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::VSYNC_PERIOD);
436     const auto configGroup =
437             getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::CONFIG_GROUP);
438     if (width.first.isOk() && height.first.isOk() && vsyncPeriod.first.isOk() &&
439         configGroup.first.isOk()) {
440         vtsDisplay->addDisplayConfig(config, {vsyncPeriod.second, configGroup.second});
441         return ScopedAStatus::ok();
442     }
443 
444     LOG(ERROR) << "Failed to update display property for width: " << width.first.isOk()
445                << ", height: " << height.first.isOk() << ", vsync: " << vsyncPeriod.first.isOk()
446                << ", config: " << configGroup.first.isOk();
447     return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_CONFIG);
448 }
449 
updateDisplayProperties(VtsDisplay * vtsDisplay,int32_t config)450 ScopedAStatus VtsComposerClient::updateDisplayProperties(VtsDisplay* vtsDisplay, int32_t config) {
451     const auto width =
452             getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::WIDTH);
453     const auto height =
454             getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::HEIGHT);
455     if (width.first.isOk() && height.first.isOk()) {
456         vtsDisplay->setDimensions(width.second, height.second);
457         return ScopedAStatus::ok();
458     }
459 
460     LOG(ERROR) << "Failed to update display property for width: " << width.first.isOk()
461                << ", height: " << height.first.isOk();
462     return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_CONFIG);
463 }
464 
addDisplayToDisplayResources(int64_t display,bool isVirtual)465 ScopedAStatus VtsComposerClient::addDisplayToDisplayResources(int64_t display, bool isVirtual) {
466     if (mDisplayResources.insert({display, DisplayResource(isVirtual)}).second) {
467         return ScopedAStatus::ok();
468     }
469 
470     ALOGE("Duplicate display id %" PRId64, display);
471     return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_DISPLAY);
472 }
473 
addLayerToDisplayResources(int64_t display,int64_t layer)474 ScopedAStatus VtsComposerClient::addLayerToDisplayResources(int64_t display, int64_t layer) {
475     auto resource = mDisplayResources.find(display);
476     if (resource == mDisplayResources.end()) {
477         resource = mDisplayResources.insert({display, DisplayResource(false)}).first;
478     }
479 
480     if (!resource->second.layers.insert(layer).second) {
481         ALOGE("Duplicate layer id %" PRId64, layer);
482         return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_LAYER);
483     }
484     return ScopedAStatus::ok();
485 }
486 
removeLayerFromDisplayResources(int64_t display,int64_t layer)487 void VtsComposerClient::removeLayerFromDisplayResources(int64_t display, int64_t layer) {
488     auto resource = mDisplayResources.find(display);
489     if (resource != mDisplayResources.end()) {
490         resource->second.layers.erase(layer);
491     }
492 }
493 
verifyComposerCallbackParams()494 bool VtsComposerClient::verifyComposerCallbackParams() {
495     bool isValid = true;
496     if (mComposerCallback != nullptr) {
497         if (mComposerCallback->getInvalidHotplugCount() != 0) {
498             ALOGE("Invalid hotplug count");
499             isValid = false;
500         }
501         if (mComposerCallback->getInvalidRefreshCount() != 0) {
502             ALOGE("Invalid refresh count");
503             isValid = false;
504         }
505         if (mComposerCallback->getInvalidVsyncCount() != 0) {
506             ALOGE("Invalid vsync count");
507             isValid = false;
508         }
509         if (mComposerCallback->getInvalidVsyncPeriodChangeCount() != 0) {
510             ALOGE("Invalid vsync period change count");
511             isValid = false;
512         }
513         if (mComposerCallback->getInvalidSeamlessPossibleCount() != 0) {
514             ALOGE("Invalid seamless possible count");
515             isValid = false;
516         }
517     }
518     return isValid;
519 }
520 
destroyAllLayers()521 bool VtsComposerClient::destroyAllLayers() {
522     std::unordered_map<int64_t, DisplayResource> physicalDisplays;
523     while (!mDisplayResources.empty()) {
524         const auto& it = mDisplayResources.begin();
525         const auto& [display, resource] = *it;
526 
527         while (!resource.layers.empty()) {
528             auto layer = *resource.layers.begin();
529             const auto status = destroyLayer(display, layer);
530             if (!status.isOk()) {
531                 ALOGE("Unable to destroy all the layers, failed at layer %" PRId64 " with error %s",
532                       layer, status.getDescription().c_str());
533                 return false;
534             }
535         }
536 
537         if (resource.isVirtual) {
538             const auto status = destroyVirtualDisplay(display);
539             if (!status.isOk()) {
540                 ALOGE("Unable to destroy the display %" PRId64 " failed with error %s", display,
541                       status.getDescription().c_str());
542                 return false;
543             }
544         } else {
545             auto extractIter = mDisplayResources.extract(it);
546             physicalDisplays.insert(std::move(extractIter));
547         }
548     }
549     mDisplayResources.swap(physicalDisplays);
550     mDisplayResources.clear();
551     return true;
552 }
553 }  // namespace aidl::android::hardware::graphics::composer3::vts
554