• 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 "ComposerClientWrapper.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 "ComposerClientWrapper"
24 
25 using namespace std::chrono_literals;
26 
27 namespace aidl::android::hardware::graphics::composer3::libhwc_aidl_test {
28 
ComposerClientWrapper(const std::string & name)29 ComposerClientWrapper::ComposerClientWrapper(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     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     }
44 }
45 
createClient()46 ScopedAStatus ComposerClientWrapper::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 
tearDown(std::unordered_map<int64_t,ComposerClientWriter * > displayWriters)65 bool ComposerClientWrapper::tearDown(
66         std::unordered_map<int64_t, ComposerClientWriter*> displayWriters) {
67     return verifyComposerCallbackParams() && destroyAllLayers(displayWriters);
68 }
69 
getInterfaceVersion() const70 std::pair<ScopedAStatus, int32_t> ComposerClientWrapper::getInterfaceVersion() const {
71     int32_t version = 1;
72     if (!mComposerClient) {
73         return {ScopedAStatus{nullptr}, version};
74     }
75     auto status = mComposerClient->getInterfaceVersion(&version);
76     return {std::move(status), version};
77 }
78 
createVirtualDisplay(int32_t width,int32_t height,PixelFormat pixelFormat,int32_t bufferSlotCount)79 std::pair<ScopedAStatus, VirtualDisplay> ComposerClientWrapper::createVirtualDisplay(
80         int32_t width, int32_t height, PixelFormat pixelFormat, int32_t bufferSlotCount) {
81     VirtualDisplay outVirtualDisplay;
82     auto status = mComposerClient->createVirtualDisplay(width, height, pixelFormat, bufferSlotCount,
83                                                         &outVirtualDisplay);
84     if (!status.isOk()) {
85         return {std::move(status), outVirtualDisplay};
86     }
87     return {addDisplayToDisplayResources(outVirtualDisplay.display, /*isVirtual*/ true),
88             outVirtualDisplay};
89 }
90 
destroyVirtualDisplay(int64_t display)91 ScopedAStatus ComposerClientWrapper::destroyVirtualDisplay(int64_t display) {
92     auto status = mComposerClient->destroyVirtualDisplay(display);
93     if (!status.isOk()) {
94         return status;
95     }
96     mDisplayResources.erase(display);
97     return status;
98 }
99 
createLayer(int64_t display,int32_t bufferSlotCount,ComposerClientWriter * writer)100 std::pair<ScopedAStatus, int64_t> ComposerClientWrapper::createLayer(int64_t display,
101                                                                      int32_t bufferSlotCount,
102                                                                      ComposerClientWriter* writer) {
103     if (mSupportsBatchedCreateLayer) {
104         int64_t layer = mNextLayerHandle++;
105         writer->setLayerLifecycleBatchCommandType(display, layer,
106                                                   LayerLifecycleBatchCommandType::CREATE);
107         writer->setNewBufferSlotCount(display, layer, bufferSlotCount);
108         return {addLayerToDisplayResources(display, layer), layer};
109     }
110 
111     int64_t outLayer;
112     auto status = mComposerClient->createLayer(display, bufferSlotCount, &outLayer);
113 
114     if (!status.isOk()) {
115         return {std::move(status), outLayer};
116     }
117     return {addLayerToDisplayResources(display, outLayer), outLayer};
118 }
119 
destroyLayer(int64_t display,int64_t layer,ComposerClientWriter * writer)120 ScopedAStatus ComposerClientWrapper::destroyLayer(int64_t display, int64_t layer,
121                                                   ComposerClientWriter* writer) {
122     if (mSupportsBatchedCreateLayer) {
123         writer->setLayerLifecycleBatchCommandType(display, layer,
124                                                   LayerLifecycleBatchCommandType::DESTROY);
125     } else {
126         auto status = mComposerClient->destroyLayer(display, layer);
127         if (!status.isOk()) {
128             return status;
129         }
130     }
131 
132     removeLayerFromDisplayResources(display, layer);
133     return ScopedAStatus::ok();
134 }
135 
getActiveConfig(int64_t display)136 std::pair<ScopedAStatus, int32_t> ComposerClientWrapper::getActiveConfig(int64_t display) {
137     int32_t outConfig;
138     return {mComposerClient->getActiveConfig(display, &outConfig), outConfig};
139 }
140 
setActiveConfig(DisplayWrapper * display,int32_t config)141 ScopedAStatus ComposerClientWrapper::setActiveConfig(DisplayWrapper* display, int32_t config) {
142     auto status = mComposerClient->setActiveConfig(display->getDisplayId(), config);
143     if (!status.isOk()) {
144         return status;
145     }
146     return updateDisplayProperties(display, config);
147 }
148 
setPeakRefreshRateConfig(DisplayWrapper * display)149 ScopedAStatus ComposerClientWrapper::setPeakRefreshRateConfig(DisplayWrapper* display) {
150     const auto displayId = display->getDisplayId();
151     auto [activeStatus, activeConfig] = getActiveConfig(displayId);
152     EXPECT_TRUE(activeStatus.isOk());
153     auto peakDisplayConfig = display->getDisplayConfig(activeConfig);
154     auto peakConfig = activeConfig;
155 
156     const auto displayConfigs = display->getDisplayConfigs();
157     for (const auto [config, displayConfig] : displayConfigs) {
158         if (displayConfig.configGroup == peakDisplayConfig.configGroup &&
159             displayConfig.vsyncPeriod < peakDisplayConfig.vsyncPeriod) {
160             peakDisplayConfig = displayConfig;
161             peakConfig = config;
162         }
163     }
164     return setActiveConfig(display, peakConfig);
165 }
166 
getDisplayAttribute(int64_t display,int32_t config,DisplayAttribute displayAttribute)167 std::pair<ScopedAStatus, int32_t> ComposerClientWrapper::getDisplayAttribute(
168         int64_t display, int32_t config, DisplayAttribute displayAttribute) {
169     int32_t outDisplayAttribute;
170     return {mComposerClient->getDisplayAttribute(display, config, displayAttribute,
171                                                  &outDisplayAttribute),
172             outDisplayAttribute};
173 }
174 
setPowerMode(int64_t display,PowerMode powerMode)175 ScopedAStatus ComposerClientWrapper::setPowerMode(int64_t display, PowerMode powerMode) {
176     return mComposerClient->setPowerMode(display, powerMode);
177 }
178 
setVsync(int64_t display,bool enable)179 ScopedAStatus ComposerClientWrapper::setVsync(int64_t display, bool enable) {
180     return mComposerClient->setVsyncEnabled(display, enable);
181 }
182 
setVsyncAllowed(bool isAllowed)183 void ComposerClientWrapper::setVsyncAllowed(bool isAllowed) {
184     mComposerCallback->setVsyncAllowed(isAllowed);
185 }
186 
getDataspaceSaturationMatrix(Dataspace dataspace)187 std::pair<ScopedAStatus, std::vector<float>> ComposerClientWrapper::getDataspaceSaturationMatrix(
188         Dataspace dataspace) {
189     std::vector<float> outMatrix;
190     return {mComposerClient->getDataspaceSaturationMatrix(dataspace, &outMatrix), outMatrix};
191 }
192 
executeCommands(const std::vector<DisplayCommand> & commands)193 std::pair<ScopedAStatus, std::vector<CommandResultPayload>> ComposerClientWrapper::executeCommands(
194         const std::vector<DisplayCommand>& commands) {
195     std::vector<CommandResultPayload> outResultPayload;
196     return {mComposerClient->executeCommands(commands, &outResultPayload),
197             std::move(outResultPayload)};
198 }
199 
200 std::optional<VsyncPeriodChangeTimeline>
takeLastVsyncPeriodChangeTimeline()201 ComposerClientWrapper::takeLastVsyncPeriodChangeTimeline() {
202     return mComposerCallback->takeLastVsyncPeriodChangeTimeline();
203 }
204 
setContentType(int64_t display,ContentType contentType)205 ScopedAStatus ComposerClientWrapper::setContentType(int64_t display, ContentType contentType) {
206     return mComposerClient->setContentType(display, contentType);
207 }
208 
209 std::pair<ScopedAStatus, VsyncPeriodChangeTimeline>
setActiveConfigWithConstraints(DisplayWrapper * display,int32_t config,const VsyncPeriodChangeConstraints & constraints)210 ComposerClientWrapper::setActiveConfigWithConstraints(
211         DisplayWrapper* display, int32_t config, const VsyncPeriodChangeConstraints& constraints) {
212     VsyncPeriodChangeTimeline outTimeline;
213     auto status = mComposerClient->setActiveConfigWithConstraints(display->getDisplayId(), config,
214                                                                   constraints, &outTimeline);
215     if (!status.isOk()) {
216         return {std::move(status), outTimeline};
217     }
218     return {updateDisplayProperties(display, config), outTimeline};
219 }
220 
221 std::pair<ScopedAStatus, std::vector<DisplayCapability>>
getDisplayCapabilities(int64_t display)222 ComposerClientWrapper::getDisplayCapabilities(int64_t display) {
223     std::vector<DisplayCapability> outCapabilities;
224     return {mComposerClient->getDisplayCapabilities(display, &outCapabilities), outCapabilities};
225 }
226 
dumpDebugInfo()227 ScopedAStatus ComposerClientWrapper::dumpDebugInfo() {
228     int pipefds[2];
229     if (pipe(pipefds) < 0) {
230         return ScopedAStatus::fromServiceSpecificError(IComposer::EX_NO_RESOURCES);
231     }
232 
233     const auto status = mComposer->dump(pipefds[1], /*args*/ nullptr, /*numArgs*/ 0);
234     close(pipefds[0]);
235     close(pipefds[1]);
236     return ScopedAStatus::fromStatus(status);
237 }
238 
getDisplayIdentificationData(int64_t display)239 std::pair<ScopedAStatus, DisplayIdentification> ComposerClientWrapper::getDisplayIdentificationData(
240         int64_t display) {
241     DisplayIdentification outDisplayIdentification;
242     return {mComposerClient->getDisplayIdentificationData(display, &outDisplayIdentification),
243             outDisplayIdentification};
244 }
245 
getHdrCapabilities(int64_t display)246 std::pair<ScopedAStatus, HdrCapabilities> ComposerClientWrapper::getHdrCapabilities(
247         int64_t display) {
248     HdrCapabilities outHdrCapabilities;
249     return {mComposerClient->getHdrCapabilities(display, &outHdrCapabilities), outHdrCapabilities};
250 }
251 
252 std::pair<ScopedAStatus, std::vector<PerFrameMetadataKey>>
getPerFrameMetadataKeys(int64_t display)253 ComposerClientWrapper::getPerFrameMetadataKeys(int64_t display) {
254     std::vector<PerFrameMetadataKey> outPerFrameMetadataKeys;
255     return {mComposerClient->getPerFrameMetadataKeys(display, &outPerFrameMetadataKeys),
256             outPerFrameMetadataKeys};
257 }
258 
259 std::pair<ScopedAStatus, ReadbackBufferAttributes>
getReadbackBufferAttributes(int64_t display)260 ComposerClientWrapper::getReadbackBufferAttributes(int64_t display) {
261     ReadbackBufferAttributes outReadbackBufferAttributes;
262     return {mComposerClient->getReadbackBufferAttributes(display, &outReadbackBufferAttributes),
263             outReadbackBufferAttributes};
264 }
265 
setReadbackBuffer(int64_t display,const native_handle_t * buffer,const ScopedFileDescriptor & releaseFence)266 ScopedAStatus ComposerClientWrapper::setReadbackBuffer(int64_t display,
267                                                        const native_handle_t* buffer,
268                                                        const ScopedFileDescriptor& releaseFence) {
269     return mComposerClient->setReadbackBuffer(display, ::android::dupToAidl(buffer), releaseFence);
270 }
271 
getReadbackBufferFence(int64_t display)272 std::pair<ScopedAStatus, ScopedFileDescriptor> ComposerClientWrapper::getReadbackBufferFence(
273         int64_t display) {
274     ScopedFileDescriptor outReleaseFence;
275     return {mComposerClient->getReadbackBufferFence(display, &outReleaseFence),
276             std::move(outReleaseFence)};
277 }
278 
getColorModes(int64_t display)279 std::pair<ScopedAStatus, std::vector<ColorMode>> ComposerClientWrapper::getColorModes(
280         int64_t display) {
281     std::vector<ColorMode> outColorModes;
282     return {mComposerClient->getColorModes(display, &outColorModes), outColorModes};
283 }
284 
getRenderIntents(int64_t display,ColorMode colorMode)285 std::pair<ScopedAStatus, std::vector<RenderIntent>> ComposerClientWrapper::getRenderIntents(
286         int64_t display, ColorMode colorMode) {
287     std::vector<RenderIntent> outRenderIntents;
288     return {mComposerClient->getRenderIntents(display, colorMode, &outRenderIntents),
289             outRenderIntents};
290 }
291 
setColorMode(int64_t display,ColorMode colorMode,RenderIntent renderIntent)292 ScopedAStatus ComposerClientWrapper::setColorMode(int64_t display, ColorMode colorMode,
293                                                   RenderIntent renderIntent) {
294     return mComposerClient->setColorMode(display, colorMode, renderIntent);
295 }
296 
297 std::pair<ScopedAStatus, DisplayContentSamplingAttributes>
getDisplayedContentSamplingAttributes(int64_t display)298 ComposerClientWrapper::getDisplayedContentSamplingAttributes(int64_t display) {
299     DisplayContentSamplingAttributes outAttributes;
300     return {mComposerClient->getDisplayedContentSamplingAttributes(display, &outAttributes),
301             outAttributes};
302 }
303 
setDisplayedContentSamplingEnabled(int64_t display,bool isEnabled,FormatColorComponent formatColorComponent,int64_t maxFrames)304 ScopedAStatus ComposerClientWrapper::setDisplayedContentSamplingEnabled(
305         int64_t display, bool isEnabled, FormatColorComponent formatColorComponent,
306         int64_t maxFrames) {
307     return mComposerClient->setDisplayedContentSamplingEnabled(display, isEnabled,
308                                                                formatColorComponent, maxFrames);
309 }
310 
getDisplayedContentSample(int64_t display,int64_t maxFrames,int64_t timestamp)311 std::pair<ScopedAStatus, DisplayContentSample> ComposerClientWrapper::getDisplayedContentSample(
312         int64_t display, int64_t maxFrames, int64_t timestamp) {
313     DisplayContentSample outDisplayContentSample;
314     return {mComposerClient->getDisplayedContentSample(display, maxFrames, timestamp,
315                                                        &outDisplayContentSample),
316             outDisplayContentSample};
317 }
318 
getDisplayConnectionType(int64_t display)319 std::pair<ScopedAStatus, DisplayConnectionType> ComposerClientWrapper::getDisplayConnectionType(
320         int64_t display) {
321     DisplayConnectionType outDisplayConnectionType;
322     return {mComposerClient->getDisplayConnectionType(display, &outDisplayConnectionType),
323             outDisplayConnectionType};
324 }
325 
getDisplayConfigs(int64_t display)326 std::pair<ScopedAStatus, std::vector<int32_t>> ComposerClientWrapper::getDisplayConfigs(
327         int64_t display) {
328     std::vector<int32_t> outConfigs;
329     if (!getDisplayConfigurationSupported()) {
330         return {mComposerClient->getDisplayConfigs(display, &outConfigs), outConfigs};
331     }
332 
333     auto [status, configs] = getDisplayConfigurations(display);
334     if (!status.isOk()) {
335         return {std::move(status), outConfigs};
336     }
337     for (const auto& config : configs) {
338         outConfigs.emplace_back(config.configId);
339     }
340     return {std::move(status), outConfigs};
341 }
342 
343 std::pair<ScopedAStatus, std::vector<DisplayConfiguration>>
getDisplayConfigurations(int64_t display)344 ComposerClientWrapper::getDisplayConfigurations(int64_t display) {
345     std::vector<DisplayConfiguration> outConfigs;
346     return {mComposerClient->getDisplayConfigurations(display, kMaxFrameIntervalNs, &outConfigs),
347             outConfigs};
348 }
349 
notifyExpectedPresent(int64_t display,ClockMonotonicTimestamp expectedPresentTime,int frameIntervalNs)350 ScopedAStatus ComposerClientWrapper::notifyExpectedPresent(
351         int64_t display, ClockMonotonicTimestamp expectedPresentTime, int frameIntervalNs) {
352     return mComposerClient->notifyExpectedPresent(display, expectedPresentTime, frameIntervalNs);
353 }
354 
getDisplayVsyncPeriod(int64_t display)355 std::pair<ScopedAStatus, int32_t> ComposerClientWrapper::getDisplayVsyncPeriod(int64_t display) {
356     int32_t outVsyncPeriodNanos;
357     return {mComposerClient->getDisplayVsyncPeriod(display, &outVsyncPeriodNanos),
358             outVsyncPeriodNanos};
359 }
360 
setAutoLowLatencyMode(int64_t display,bool isEnabled)361 ScopedAStatus ComposerClientWrapper::setAutoLowLatencyMode(int64_t display, bool isEnabled) {
362     return mComposerClient->setAutoLowLatencyMode(display, isEnabled);
363 }
364 
getSupportedContentTypes(int64_t display)365 std::pair<ScopedAStatus, std::vector<ContentType>> ComposerClientWrapper::getSupportedContentTypes(
366         int64_t display) {
367     std::vector<ContentType> outContentTypes;
368     return {mComposerClient->getSupportedContentTypes(display, &outContentTypes), outContentTypes};
369 }
370 
371 std::pair<ScopedAStatus, std::optional<DisplayDecorationSupport>>
getDisplayDecorationSupport(int64_t display)372 ComposerClientWrapper::getDisplayDecorationSupport(int64_t display) {
373     std::optional<DisplayDecorationSupport> outSupport;
374     return {mComposerClient->getDisplayDecorationSupport(display, &outSupport), outSupport};
375 }
376 
getMaxVirtualDisplayCount()377 std::pair<ScopedAStatus, int32_t> ComposerClientWrapper::getMaxVirtualDisplayCount() {
378     int32_t outMaxVirtualDisplayCount;
379     return {mComposerClient->getMaxVirtualDisplayCount(&outMaxVirtualDisplayCount),
380             outMaxVirtualDisplayCount};
381 }
382 
getDisplayName(int64_t display)383 std::pair<ScopedAStatus, std::string> ComposerClientWrapper::getDisplayName(int64_t display) {
384     std::string outDisplayName;
385     return {mComposerClient->getDisplayName(display, &outDisplayName), outDisplayName};
386 }
387 
setClientTargetSlotCount(int64_t display,int32_t bufferSlotCount)388 ScopedAStatus ComposerClientWrapper::setClientTargetSlotCount(int64_t display,
389                                                               int32_t bufferSlotCount) {
390     return mComposerClient->setClientTargetSlotCount(display, bufferSlotCount);
391 }
392 
getCapabilities()393 std::pair<ScopedAStatus, std::vector<Capability>> ComposerClientWrapper::getCapabilities() {
394     std::vector<Capability> outCapabilities;
395     return {mComposer->getCapabilities(&outCapabilities), outCapabilities};
396 }
397 
setBootDisplayConfig(int64_t display,int32_t config)398 ScopedAStatus ComposerClientWrapper::setBootDisplayConfig(int64_t display, int32_t config) {
399     return mComposerClient->setBootDisplayConfig(display, config);
400 }
401 
clearBootDisplayConfig(int64_t display)402 ScopedAStatus ComposerClientWrapper::clearBootDisplayConfig(int64_t display) {
403     return mComposerClient->clearBootDisplayConfig(display);
404 }
405 
getPreferredBootDisplayConfig(int64_t display)406 std::pair<ScopedAStatus, int32_t> ComposerClientWrapper::getPreferredBootDisplayConfig(
407         int64_t display) {
408     int32_t outConfig;
409     return {mComposerClient->getPreferredBootDisplayConfig(display, &outConfig), outConfig};
410 }
411 
412 std::pair<ScopedAStatus, std::vector<common::HdrConversionCapability>>
getHdrConversionCapabilities()413 ComposerClientWrapper::getHdrConversionCapabilities() {
414     std::vector<common::HdrConversionCapability> hdrConversionCapability;
415     return {mComposerClient->getHdrConversionCapabilities(&hdrConversionCapability),
416             hdrConversionCapability};
417 }
418 
setHdrConversionStrategy(const common::HdrConversionStrategy & conversionStrategy)419 std::pair<ScopedAStatus, common::Hdr> ComposerClientWrapper::setHdrConversionStrategy(
420         const common::HdrConversionStrategy& conversionStrategy) {
421     common::Hdr preferredHdrOutputType;
422     return {mComposerClient->setHdrConversionStrategy(conversionStrategy, &preferredHdrOutputType),
423             preferredHdrOutputType};
424 }
425 
getDisplayPhysicalOrientation(int64_t display)426 std::pair<ScopedAStatus, common::Transform> ComposerClientWrapper::getDisplayPhysicalOrientation(
427         int64_t display) {
428     common::Transform outDisplayOrientation;
429     return {mComposerClient->getDisplayPhysicalOrientation(display, &outDisplayOrientation),
430             outDisplayOrientation};
431 }
432 
getOverlaySupport()433 std::pair<ScopedAStatus, composer3::OverlayProperties> ComposerClientWrapper::getOverlaySupport() {
434     OverlayProperties properties;
435     return {mComposerClient->getOverlaySupport(&properties), properties};
436 }
437 
setIdleTimerEnabled(int64_t display,int32_t timeoutMs)438 ScopedAStatus ComposerClientWrapper::setIdleTimerEnabled(int64_t display, int32_t timeoutMs) {
439     return mComposerClient->setIdleTimerEnabled(display, timeoutMs);
440 }
441 
getVsyncIdleCount()442 int32_t ComposerClientWrapper::getVsyncIdleCount() {
443     return mComposerCallback->getVsyncIdleCount();
444 }
445 
getVsyncIdleTime()446 int64_t ComposerClientWrapper::getVsyncIdleTime() {
447     return mComposerCallback->getVsyncIdleTime();
448 }
449 
setRefreshRateChangedCallbackDebugEnabled(int64_t display,bool enabled)450 ndk::ScopedAStatus ComposerClientWrapper::setRefreshRateChangedCallbackDebugEnabled(int64_t display,
451                                                                                     bool enabled) {
452     mComposerCallback->setRefreshRateChangedDebugDataEnabledCallbackAllowed(enabled);
453     return mComposerClient->setRefreshRateChangedCallbackDebugEnabled(display, enabled);
454 }
455 
456 std::vector<RefreshRateChangedDebugData>
takeListOfRefreshRateChangedDebugData()457 ComposerClientWrapper::takeListOfRefreshRateChangedDebugData() {
458     return mComposerCallback->takeListOfRefreshRateChangedDebugData();
459 }
460 
461 std::vector<std::pair<int64_t, common::DisplayHotplugEvent>>
getAndClearLatestHotplugs()462 ComposerClientWrapper::getAndClearLatestHotplugs() {
463     return mComposerCallback->getAndClearLatestHotplugs();
464 }
465 
getInvalidDisplayId()466 int64_t ComposerClientWrapper::getInvalidDisplayId() {
467     // returns an invalid display id (one that has not been registered to a
468     // display. Currently assuming that a device will never have close to
469     // std::numeric_limit<uint64_t>::max() displays registered while running tests
470     int64_t id = std::numeric_limits<int64_t>::max();
471     std::vector<int64_t> displayIds = mComposerCallback->getDisplays();
472     while (id > 0) {
473         if (std::none_of(displayIds.begin(), displayIds.end(),
474                          [id](const auto& display) { return id == display; })) {
475             return id;
476         }
477         id--;
478     }
479 
480     // Although 0 could be an invalid display, a return value of 0
481     // from getInvalidDisplayId means all other ids are in use, a condition which
482     // we are assuming a device will never have
483     EXPECT_NE(0, id);
484     return id;
485 }
486 
getDisplays()487 std::pair<ScopedAStatus, std::vector<DisplayWrapper>> ComposerClientWrapper::getDisplays() {
488     while (true) {
489         // Sleep for a small period of time to allow all built-in displays
490         // to post hotplug events
491         std::this_thread::sleep_for(5ms);
492         std::vector<int64_t> displayIds = mComposerCallback->getDisplays();
493         if (displayIds.empty()) {
494             continue;
495         }
496 
497         std::vector<DisplayWrapper> displays;
498         displays.reserve(displayIds.size());
499         for (int64_t displayId : displayIds) {
500             auto display = DisplayWrapper{displayId};
501             if (getDisplayConfigurationSupported()) {
502                 auto [status, configs] = getDisplayConfigurations(displayId);
503                 if (!status.isOk()) {
504                     ALOGE("Unable to get the displays for test, failed to get the DisplayConfigs "
505                           "for displayId %" PRId64,
506                           displayId);
507                     return {std::move(status), displays};
508                 }
509                 addDisplayConfigs(&display, configs);
510             } else {
511                 auto [status, configs] = getDisplayConfigs(displayId);
512                 if (!status.isOk()) {
513                     ALOGE("Unable to get the displays for test, failed to get the configs "
514                           "for displayId %" PRId64,
515                           displayId);
516                     return {std::move(status), displays};
517                 }
518                 for (int config : configs) {
519                     status = addDisplayConfigLegacy(&display, config);
520                     if (!status.isOk()) {
521                         ALOGE("Unable to get the displays for test, failed to add config "
522                               "for displayId %" PRId64,
523                               displayId);
524                         return {std::move(status), displays};
525                     }
526                 }
527             }
528             auto activeConfig = getActiveConfig(displayId);
529             if (!activeConfig.first.isOk()) {
530                 ALOGE("Unable to get the displays for test, failed to get active config "
531                       "for displayId %" PRId64,
532                       displayId);
533                 return {std::move(activeConfig.first), displays};
534             }
535             auto status = updateDisplayProperties(&display, activeConfig.second);
536             if (!status.isOk()) {
537                 ALOGE("Unable to get the displays for test, "
538                       "failed to update the properties "
539                       "for displayId %" PRId64,
540                       displayId);
541                 return {std::move(status), displays};
542             }
543 
544             displays.emplace_back(display);
545             addDisplayToDisplayResources(displayId, /*isVirtual*/ false);
546         }
547 
548         return {ScopedAStatus::ok(), displays};
549     }
550 }
551 
addDisplayConfigs(DisplayWrapper * display,const std::vector<DisplayConfiguration> & configs)552 void ComposerClientWrapper::addDisplayConfigs(DisplayWrapper* display,
553                                               const std::vector<DisplayConfiguration>& configs) {
554     for (const auto& config : configs) {
555         display->addDisplayConfig(config.configId,
556                                   {config.vsyncPeriod, config.configGroup, config.vrrConfig});
557     }
558 }
559 
addDisplayConfigLegacy(DisplayWrapper * display,int32_t config)560 ScopedAStatus ComposerClientWrapper::addDisplayConfigLegacy(DisplayWrapper* display,
561                                                             int32_t config) {
562     const auto vsyncPeriod =
563             getDisplayAttribute(display->getDisplayId(), config, DisplayAttribute::VSYNC_PERIOD);
564     const auto configGroup =
565             getDisplayAttribute(display->getDisplayId(), config, DisplayAttribute::CONFIG_GROUP);
566     if (vsyncPeriod.first.isOk() && configGroup.first.isOk()) {
567         display->addDisplayConfig(config, {vsyncPeriod.second, configGroup.second});
568         return ScopedAStatus::ok();
569     }
570 
571     LOG(ERROR) << "Failed to update display property vsync: " << vsyncPeriod.first.isOk()
572                << ", config: " << configGroup.first.isOk();
573     return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_CONFIG);
574 }
575 
updateDisplayProperties(DisplayWrapper * display,int32_t config)576 ScopedAStatus ComposerClientWrapper::updateDisplayProperties(DisplayWrapper* display,
577                                                              int32_t config) {
578     if (getDisplayConfigurationSupported()) {
579         auto [status, configs] = getDisplayConfigurations(display->getDisplayId());
580         if (status.isOk()) {
581             for (const auto& displayConfig : configs) {
582                 if (displayConfig.configId == config) {
583                     display->setDimensions(displayConfig.width, displayConfig.height);
584                     return ScopedAStatus::ok();
585                 }
586             }
587         }
588         LOG(ERROR) << "Failed to update display property with DisplayConfig";
589     } else {
590         const auto width =
591                 getDisplayAttribute(display->getDisplayId(), config, DisplayAttribute::WIDTH);
592         const auto height =
593                 getDisplayAttribute(display->getDisplayId(), config, DisplayAttribute::HEIGHT);
594         if (width.first.isOk() && height.first.isOk()) {
595             display->setDimensions(width.second, height.second);
596             return ScopedAStatus::ok();
597         }
598 
599         LOG(ERROR) << "Failed to update display property for width: " << width.first.isOk()
600                    << ", height: " << height.first.isOk();
601     }
602     return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_CONFIG);
603 }
604 
addDisplayToDisplayResources(int64_t display,bool isVirtual)605 ScopedAStatus ComposerClientWrapper::addDisplayToDisplayResources(int64_t display, bool isVirtual) {
606     if (mDisplayResources.insert({display, DisplayResource(isVirtual)}).second) {
607         return ScopedAStatus::ok();
608     }
609 
610     ALOGE("Duplicate display id %" PRId64, display);
611     return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_DISPLAY);
612 }
613 
addLayerToDisplayResources(int64_t display,int64_t layer)614 ScopedAStatus ComposerClientWrapper::addLayerToDisplayResources(int64_t display, int64_t layer) {
615     auto resource = mDisplayResources.find(display);
616     if (resource == mDisplayResources.end()) {
617         resource = mDisplayResources.insert({display, DisplayResource(false)}).first;
618     }
619 
620     if (!resource->second.layers.insert(layer).second) {
621         ALOGE("Duplicate layer id %" PRId64, layer);
622         return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_LAYER);
623     }
624     return ScopedAStatus::ok();
625 }
626 
removeLayerFromDisplayResources(int64_t display,int64_t layer)627 void ComposerClientWrapper::removeLayerFromDisplayResources(int64_t display, int64_t layer) {
628     auto resource = mDisplayResources.find(display);
629     if (resource != mDisplayResources.end()) {
630         resource->second.layers.erase(layer);
631     }
632 }
633 
verifyComposerCallbackParams()634 bool ComposerClientWrapper::verifyComposerCallbackParams() {
635     bool isValid = true;
636     if (mComposerCallback != nullptr) {
637         if (mComposerCallback->getInvalidHotplugCount() != 0) {
638             ALOGE("Invalid hotplug count");
639             isValid = false;
640         }
641         if (mComposerCallback->getInvalidRefreshCount() != 0) {
642             ALOGE("Invalid refresh count");
643             isValid = false;
644         }
645         if (mComposerCallback->getInvalidVsyncCount() != 0) {
646             ALOGE("Invalid vsync count");
647             isValid = false;
648         }
649         if (mComposerCallback->getInvalidVsyncPeriodChangeCount() != 0) {
650             ALOGE("Invalid vsync period change count");
651             isValid = false;
652         }
653         if (mComposerCallback->getInvalidSeamlessPossibleCount() != 0) {
654             ALOGE("Invalid seamless possible count");
655             isValid = false;
656         }
657         if (mComposerCallback->getInvalidRefreshRateDebugEnabledCallbackCount() != 0) {
658             ALOGE("Invalid refresh rate debug enabled callback count");
659             isValid = false;
660         }
661     }
662     return isValid;
663 }
664 
getDisplayConfigurationSupported() const665 bool ComposerClientWrapper::getDisplayConfigurationSupported() const {
666     auto [status, interfaceVersion] = getInterfaceVersion();
667     EXPECT_TRUE(status.isOk());
668     // getDisplayConfigurations api is supported starting interface version 3
669     return interfaceVersion >= 3;
670 }
671 
destroyAllLayers(std::unordered_map<int64_t,ComposerClientWriter * > displayWriters)672 bool ComposerClientWrapper::destroyAllLayers(
673         std::unordered_map<int64_t, ComposerClientWriter*> displayWriters) {
674     std::unordered_map<int64_t, DisplayResource> physicalDisplays;
675     while (!mDisplayResources.empty()) {
676         const auto& it = mDisplayResources.begin();
677         const auto& [display, resource] = *it;
678 
679         ComposerClientWriter* writer =
680                 displayWriters.count(display) > 0 ? displayWriters.at(display) : nullptr;
681 
682         while (!resource.layers.empty()) {
683             auto layer = *resource.layers.begin();
684             const auto status = destroyLayer(display, layer, writer);
685             if (!status.isOk()) {
686                 ALOGE("Unable to destroy all the layers, failed at layer %" PRId64 " with error %s",
687                       layer, status.getDescription().c_str());
688                 return false;
689             }
690         }
691 
692         if (resource.isVirtual) {
693             const auto status = destroyVirtualDisplay(display);
694             if (!status.isOk()) {
695                 ALOGE("Unable to destroy the display %" PRId64 " failed with error %s", display,
696                       status.getDescription().c_str());
697                 return false;
698             }
699         } else {
700             auto extractIter = mDisplayResources.extract(it);
701             physicalDisplays.insert(std::move(extractIter));
702         }
703     }
704     mDisplayResources.swap(physicalDisplays);
705     mDisplayResources.clear();
706     return true;
707 }
708 
getMaxLayerPictureProfiles(int64_t display)709 std::pair<ScopedAStatus, int32_t> ComposerClientWrapper::getMaxLayerPictureProfiles(
710         int64_t display) {
711     int32_t outMaxProfiles = 0;
712     return {mComposerClient->getMaxLayerPictureProfiles(display, &outMaxProfiles), outMaxProfiles};
713 }
714 
getLuts(int64_t display,const std::vector<Buffer> & buffers)715 std::pair<ScopedAStatus, std::vector<Luts>> ComposerClientWrapper::getLuts(
716         int64_t display, const std::vector<Buffer>& buffers) {
717     std::vector<Luts> outLuts;
718     return {mComposerClient->getLuts(display, buffers, &outLuts), std::move(outLuts)};
719 }
720 
721 }  // namespace aidl::android::hardware::graphics::composer3::libhwc_aidl_test
722