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