• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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 // TODO(b/129481165): remove the #pragma below and fix conversion issues
18 #pragma clang diagnostic push
19 #pragma clang diagnostic ignored "-Wconversion"
20 
21 // #define LOG_NDEBUG 0
22 
23 #undef LOG_TAG
24 #define LOG_TAG "HWComposer"
25 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
26 
27 #include "HWComposer.h"
28 
29 #include <android-base/properties.h>
30 #include <compositionengine/Output.h>
31 #include <compositionengine/OutputLayer.h>
32 #include <compositionengine/impl/OutputLayerCompositionState.h>
33 #include <log/log.h>
34 #include <ui/DebugUtils.h>
35 #include <ui/GraphicBuffer.h>
36 #include <utils/Errors.h>
37 #include <utils/Trace.h>
38 
39 #include "../Layer.h" // needed only for debugging
40 #include "../SurfaceFlingerProperties.h"
41 #include "ComposerHal.h"
42 #include "HWC2.h"
43 
44 #define LOG_HWC_DISPLAY_ERROR(hwcDisplayId, msg) \
45     ALOGE("%s failed for HWC display %" PRIu64 ": %s", __FUNCTION__, hwcDisplayId, msg)
46 
47 #define LOG_DISPLAY_ERROR(displayId, msg) \
48     ALOGE("%s failed for display %s: %s", __FUNCTION__, to_string(displayId).c_str(), msg)
49 
50 #define LOG_HWC_ERROR(what, error, displayId)                          \
51     ALOGE("%s: %s failed for display %s: %s (%d)", __FUNCTION__, what, \
52           to_string(displayId).c_str(), to_string(error).c_str(), static_cast<int32_t>(error))
53 
54 #define RETURN_IF_INVALID_DISPLAY(displayId, ...)            \
55     do {                                                     \
56         if (mDisplayData.count(displayId) == 0) {            \
57             LOG_DISPLAY_ERROR(displayId, "Invalid display"); \
58             return __VA_ARGS__;                              \
59         }                                                    \
60     } while (false)
61 
62 #define RETURN_IF_HWC_ERROR_FOR(what, error, displayId, ...) \
63     do {                                                     \
64         if (error != hal::Error::NONE) {                     \
65             LOG_HWC_ERROR(what, error, displayId);           \
66             return __VA_ARGS__;                              \
67         }                                                    \
68     } while (false)
69 
70 #define RETURN_IF_HWC_ERROR(error, displayId, ...) \
71     RETURN_IF_HWC_ERROR_FOR(__FUNCTION__, error, displayId, __VA_ARGS__)
72 
73 using aidl::android::hardware::graphics::composer3::Capability;
74 using aidl::android::hardware::graphics::composer3::DisplayCapability;
75 namespace hal = android::hardware::graphics::composer::hal;
76 
77 namespace android {
78 
79 HWComposer::~HWComposer() = default;
80 
81 namespace impl {
82 
HWComposer(std::unique_ptr<Hwc2::Composer> composer)83 HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer)
84       : mComposer(std::move(composer)),
85         mMaxVirtualDisplayDimension(static_cast<size_t>(sysprop::max_virtual_display_dimension(0))),
86         mUpdateDeviceProductInfoOnHotplugReconnect(
87                 sysprop::update_device_product_info_on_hotplug_reconnect(false)) {}
88 
HWComposer(const std::string & composerServiceName)89 HWComposer::HWComposer(const std::string& composerServiceName)
90       : HWComposer(Hwc2::Composer::create(composerServiceName)) {}
91 
~HWComposer()92 HWComposer::~HWComposer() {
93     mDisplayData.clear();
94 }
95 
setCallback(HWC2::ComposerCallback & callback)96 void HWComposer::setCallback(HWC2::ComposerCallback& callback) {
97     loadCapabilities();
98     loadLayerMetadataSupport();
99 
100     if (mRegisteredCallback) {
101         ALOGW("Callback already registered. Ignored extra registration attempt.");
102         return;
103     }
104     mRegisteredCallback = true;
105 
106     mComposer->registerCallback(callback);
107 }
108 
getDisplayIdentificationData(hal::HWDisplayId hwcDisplayId,uint8_t * outPort,DisplayIdentificationData * outData) const109 bool HWComposer::getDisplayIdentificationData(hal::HWDisplayId hwcDisplayId, uint8_t* outPort,
110                                               DisplayIdentificationData* outData) const {
111     const auto error = static_cast<hal::Error>(
112             mComposer->getDisplayIdentificationData(hwcDisplayId, outPort, outData));
113     if (error != hal::Error::NONE) {
114         if (error != hal::Error::UNSUPPORTED) {
115             LOG_HWC_DISPLAY_ERROR(hwcDisplayId, to_string(error).c_str());
116         }
117         return false;
118     }
119     return true;
120 }
121 
hasCapability(Capability capability) const122 bool HWComposer::hasCapability(Capability capability) const {
123     return mCapabilities.count(capability) > 0;
124 }
125 
hasDisplayCapability(HalDisplayId displayId,DisplayCapability capability) const126 bool HWComposer::hasDisplayCapability(HalDisplayId displayId, DisplayCapability capability) const {
127     RETURN_IF_INVALID_DISPLAY(displayId, false);
128     return mDisplayData.at(displayId).hwcDisplay->hasCapability(capability);
129 }
130 
onHotplug(hal::HWDisplayId hwcDisplayId,hal::Connection connection)131 std::optional<DisplayIdentificationInfo> HWComposer::onHotplug(hal::HWDisplayId hwcDisplayId,
132                                                                hal::Connection connection) {
133     switch (connection) {
134         case hal::Connection::CONNECTED:
135             return onHotplugConnect(hwcDisplayId);
136         case hal::Connection::DISCONNECTED:
137             return onHotplugDisconnect(hwcDisplayId);
138         case hal::Connection::INVALID:
139             return {};
140     }
141 }
142 
updatesDeviceProductInfoOnHotplugReconnect() const143 bool HWComposer::updatesDeviceProductInfoOnHotplugReconnect() const {
144     return mUpdateDeviceProductInfoOnHotplugReconnect;
145 }
146 
onVsync(hal::HWDisplayId hwcDisplayId,int64_t timestamp)147 bool HWComposer::onVsync(hal::HWDisplayId hwcDisplayId, int64_t timestamp) {
148     const auto displayId = toPhysicalDisplayId(hwcDisplayId);
149     if (!displayId) {
150         LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Invalid HWC display");
151         return false;
152     }
153 
154     RETURN_IF_INVALID_DISPLAY(*displayId, false);
155 
156     auto& displayData = mDisplayData[*displayId];
157 
158     {
159         // There have been reports of HWCs that signal several vsync events
160         // with the same timestamp when turning the display off and on. This
161         // is a bug in the HWC implementation, but filter the extra events
162         // out here so they don't cause havoc downstream.
163         if (timestamp == displayData.lastHwVsync) {
164             ALOGW("Ignoring duplicate VSYNC event from HWC for display %s (t=%" PRId64 ")",
165                   to_string(*displayId).c_str(), timestamp);
166             return false;
167         }
168 
169         displayData.lastHwVsync = timestamp;
170     }
171 
172     const auto tag = "HW_VSYNC_" + to_string(*displayId);
173     ATRACE_INT(tag.c_str(), displayData.vsyncTraceToggle);
174     displayData.vsyncTraceToggle = !displayData.vsyncTraceToggle;
175 
176     return true;
177 }
178 
getMaxVirtualDisplayCount() const179 size_t HWComposer::getMaxVirtualDisplayCount() const {
180     return mComposer->getMaxVirtualDisplayCount();
181 }
182 
getMaxVirtualDisplayDimension() const183 size_t HWComposer::getMaxVirtualDisplayDimension() const {
184     return mMaxVirtualDisplayDimension;
185 }
186 
allocateVirtualDisplay(HalVirtualDisplayId displayId,ui::Size resolution,ui::PixelFormat * format)187 bool HWComposer::allocateVirtualDisplay(HalVirtualDisplayId displayId, ui::Size resolution,
188                                         ui::PixelFormat* format) {
189     if (!resolution.isValid()) {
190         ALOGE("%s: Invalid resolution %dx%d", __func__, resolution.width, resolution.height);
191         return false;
192     }
193 
194     const uint32_t width = static_cast<uint32_t>(resolution.width);
195     const uint32_t height = static_cast<uint32_t>(resolution.height);
196 
197     if (mMaxVirtualDisplayDimension > 0 &&
198         (width > mMaxVirtualDisplayDimension || height > mMaxVirtualDisplayDimension)) {
199         ALOGE("%s: Resolution %ux%u exceeds maximum dimension %zu", __func__, width, height,
200               mMaxVirtualDisplayDimension);
201         return false;
202     }
203 
204     hal::HWDisplayId hwcDisplayId;
205     const auto error = static_cast<hal::Error>(
206             mComposer->createVirtualDisplay(width, height, format, &hwcDisplayId));
207     RETURN_IF_HWC_ERROR_FOR("createVirtualDisplay", error, displayId, false);
208 
209     auto display = std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities,
210                                                          hwcDisplayId, hal::DisplayType::VIRTUAL);
211     display->setConnected(true);
212     auto& displayData = mDisplayData[displayId];
213     displayData.hwcDisplay = std::move(display);
214     return true;
215 }
216 
allocatePhysicalDisplay(hal::HWDisplayId hwcDisplayId,PhysicalDisplayId displayId)217 void HWComposer::allocatePhysicalDisplay(hal::HWDisplayId hwcDisplayId,
218                                          PhysicalDisplayId displayId) {
219     mPhysicalDisplayIdMap[hwcDisplayId] = displayId;
220 
221     if (!mPrimaryHwcDisplayId) {
222         mPrimaryHwcDisplayId = hwcDisplayId;
223     }
224 
225     auto& displayData = mDisplayData[displayId];
226     auto newDisplay =
227             std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities, hwcDisplayId,
228                                                   hal::DisplayType::PHYSICAL);
229     newDisplay->setConnected(true);
230     displayData.hwcDisplay = std::move(newDisplay);
231 }
232 
getAttribute(hal::HWDisplayId hwcDisplayId,hal::HWConfigId configId,hal::Attribute attribute) const233 int32_t HWComposer::getAttribute(hal::HWDisplayId hwcDisplayId, hal::HWConfigId configId,
234                                  hal::Attribute attribute) const {
235     int32_t value = 0;
236     auto error = static_cast<hal::Error>(
237             mComposer->getDisplayAttribute(hwcDisplayId, configId, attribute, &value));
238 
239     RETURN_IF_HWC_ERROR_FOR("getDisplayAttribute", error, *toPhysicalDisplayId(hwcDisplayId), -1);
240     return value;
241 }
242 
createLayer(HalDisplayId displayId)243 std::shared_ptr<HWC2::Layer> HWComposer::createLayer(HalDisplayId displayId) {
244     RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
245 
246     auto expected = mDisplayData[displayId].hwcDisplay->createLayer();
247     if (!expected.has_value()) {
248         auto error = std::move(expected).error();
249         RETURN_IF_HWC_ERROR(error, displayId, nullptr);
250     }
251     return std::move(expected).value();
252 }
253 
isConnected(PhysicalDisplayId displayId) const254 bool HWComposer::isConnected(PhysicalDisplayId displayId) const {
255     if (mDisplayData.count(displayId)) {
256         return mDisplayData.at(displayId).hwcDisplay->isConnected();
257     }
258 
259     return false;
260 }
261 
getModes(PhysicalDisplayId displayId) const262 std::vector<HWComposer::HWCDisplayMode> HWComposer::getModes(PhysicalDisplayId displayId) const {
263     RETURN_IF_INVALID_DISPLAY(displayId, {});
264 
265     const auto hwcDisplayId = mDisplayData.at(displayId).hwcDisplay->getId();
266     std::vector<hal::HWConfigId> configIds;
267     auto error = static_cast<hal::Error>(mComposer->getDisplayConfigs(hwcDisplayId, &configIds));
268     RETURN_IF_HWC_ERROR_FOR("getDisplayConfigs", error, *toPhysicalDisplayId(hwcDisplayId), {});
269 
270     std::vector<HWCDisplayMode> modes;
271     modes.reserve(configIds.size());
272     for (auto configId : configIds) {
273         modes.push_back(HWCDisplayMode{
274                 .hwcId = configId,
275                 .width = getAttribute(hwcDisplayId, configId, hal::Attribute::WIDTH),
276                 .height = getAttribute(hwcDisplayId, configId, hal::Attribute::HEIGHT),
277                 .vsyncPeriod = getAttribute(hwcDisplayId, configId, hal::Attribute::VSYNC_PERIOD),
278                 .dpiX = getAttribute(hwcDisplayId, configId, hal::Attribute::DPI_X),
279                 .dpiY = getAttribute(hwcDisplayId, configId, hal::Attribute::DPI_Y),
280                 .configGroup = getAttribute(hwcDisplayId, configId, hal::Attribute::CONFIG_GROUP),
281         });
282     }
283 
284     return modes;
285 }
286 
getActiveMode(PhysicalDisplayId displayId) const287 std::optional<hal::HWConfigId> HWComposer::getActiveMode(PhysicalDisplayId displayId) const {
288     RETURN_IF_INVALID_DISPLAY(displayId, std::nullopt);
289 
290     const auto hwcId = *fromPhysicalDisplayId(displayId);
291     ALOGV("[%" PRIu64 "] getActiveMode", hwcId);
292     hal::HWConfigId configId;
293     auto error = static_cast<hal::Error>(mComposer->getActiveConfig(hwcId, &configId));
294 
295     if (error == hal::Error::BAD_CONFIG) {
296         LOG_DISPLAY_ERROR(displayId, "No active mode");
297         return std::nullopt;
298     }
299 
300     return configId;
301 }
302 
303 // Composer 2.4
304 
getDisplayConnectionType(PhysicalDisplayId displayId) const305 ui::DisplayConnectionType HWComposer::getDisplayConnectionType(PhysicalDisplayId displayId) const {
306     RETURN_IF_INVALID_DISPLAY(displayId, ui::DisplayConnectionType::Internal);
307     const auto& hwcDisplay = mDisplayData.at(displayId).hwcDisplay;
308 
309     ui::DisplayConnectionType type;
310     const auto error = hwcDisplay->getConnectionType(&type);
311 
312     const auto FALLBACK_TYPE = hwcDisplay->getId() == mPrimaryHwcDisplayId
313             ? ui::DisplayConnectionType::Internal
314             : ui::DisplayConnectionType::External;
315 
316     RETURN_IF_HWC_ERROR(error, displayId, FALLBACK_TYPE);
317     return type;
318 }
319 
isVsyncPeriodSwitchSupported(PhysicalDisplayId displayId) const320 bool HWComposer::isVsyncPeriodSwitchSupported(PhysicalDisplayId displayId) const {
321     RETURN_IF_INVALID_DISPLAY(displayId, false);
322     return mDisplayData.at(displayId).hwcDisplay->isVsyncPeriodSwitchSupported();
323 }
324 
getDisplayVsyncPeriod(PhysicalDisplayId displayId,nsecs_t * outVsyncPeriod) const325 status_t HWComposer::getDisplayVsyncPeriod(PhysicalDisplayId displayId,
326                                            nsecs_t* outVsyncPeriod) const {
327     RETURN_IF_INVALID_DISPLAY(displayId, 0);
328 
329     if (!isVsyncPeriodSwitchSupported(displayId)) {
330         return INVALID_OPERATION;
331     }
332     const auto hwcId = *fromPhysicalDisplayId(displayId);
333     Hwc2::VsyncPeriodNanos vsyncPeriodNanos = 0;
334     auto error =
335             static_cast<hal::Error>(mComposer->getDisplayVsyncPeriod(hwcId, &vsyncPeriodNanos));
336     RETURN_IF_HWC_ERROR(error, displayId, 0);
337     *outVsyncPeriod = static_cast<nsecs_t>(vsyncPeriodNanos);
338     return NO_ERROR;
339 }
340 
getColorModes(PhysicalDisplayId displayId) const341 std::vector<ui::ColorMode> HWComposer::getColorModes(PhysicalDisplayId displayId) const {
342     RETURN_IF_INVALID_DISPLAY(displayId, {});
343 
344     std::vector<ui::ColorMode> modes;
345     auto error = mDisplayData.at(displayId).hwcDisplay->getColorModes(&modes);
346     RETURN_IF_HWC_ERROR(error, displayId, {});
347     return modes;
348 }
349 
setActiveColorMode(PhysicalDisplayId displayId,ui::ColorMode mode,ui::RenderIntent renderIntent)350 status_t HWComposer::setActiveColorMode(PhysicalDisplayId displayId, ui::ColorMode mode,
351                                         ui::RenderIntent renderIntent) {
352     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
353 
354     auto& displayData = mDisplayData[displayId];
355     auto error = displayData.hwcDisplay->setColorMode(mode, renderIntent);
356     RETURN_IF_HWC_ERROR_FOR(("setColorMode(" + decodeColorMode(mode) + ", " +
357                              decodeRenderIntent(renderIntent) + ")")
358                                     .c_str(),
359                             error, displayId, UNKNOWN_ERROR);
360 
361     return NO_ERROR;
362 }
363 
setVsyncEnabled(PhysicalDisplayId displayId,hal::Vsync enabled)364 void HWComposer::setVsyncEnabled(PhysicalDisplayId displayId, hal::Vsync enabled) {
365     RETURN_IF_INVALID_DISPLAY(displayId);
366     auto& displayData = mDisplayData[displayId];
367 
368     // NOTE: we use our own internal lock here because we have to call
369     // into the HWC with the lock held, and we want to make sure
370     // that even if HWC blocks (which it shouldn't), it won't
371     // affect other threads.
372     std::lock_guard lock(displayData.vsyncEnabledLock);
373     if (enabled == displayData.vsyncEnabled) {
374         return;
375     }
376 
377     ATRACE_CALL();
378     auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
379     RETURN_IF_HWC_ERROR(error, displayId);
380 
381     displayData.vsyncEnabled = enabled;
382 
383     const auto tag = "HW_VSYNC_ON_" + to_string(displayId);
384     ATRACE_INT(tag.c_str(), enabled == hal::Vsync::ENABLE ? 1 : 0);
385 }
386 
setClientTarget(HalDisplayId displayId,uint32_t slot,const sp<Fence> & acquireFence,const sp<GraphicBuffer> & target,ui::Dataspace dataspace)387 status_t HWComposer::setClientTarget(HalDisplayId displayId, uint32_t slot,
388                                      const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
389                                      ui::Dataspace dataspace) {
390     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
391 
392     ALOGV("%s for display %s", __FUNCTION__, to_string(displayId).c_str());
393     auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
394     auto error = hwcDisplay->setClientTarget(slot, target, acquireFence, dataspace);
395     RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
396     return NO_ERROR;
397 }
398 
getDeviceCompositionChanges(HalDisplayId displayId,bool frameUsesClientComposition,std::chrono::steady_clock::time_point earliestPresentTime,const std::shared_ptr<FenceTime> & previousPresentFence,nsecs_t expectedPresentTime,std::optional<android::HWComposer::DeviceRequestedChanges> * outChanges)399 status_t HWComposer::getDeviceCompositionChanges(
400         HalDisplayId displayId, bool frameUsesClientComposition,
401         std::chrono::steady_clock::time_point earliestPresentTime,
402         const std::shared_ptr<FenceTime>& previousPresentFence, nsecs_t expectedPresentTime,
403         std::optional<android::HWComposer::DeviceRequestedChanges>* outChanges) {
404     ATRACE_CALL();
405 
406     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
407 
408     auto& displayData = mDisplayData[displayId];
409     auto& hwcDisplay = displayData.hwcDisplay;
410     if (!hwcDisplay->isConnected()) {
411         return NO_ERROR;
412     }
413 
414     uint32_t numTypes = 0;
415     uint32_t numRequests = 0;
416 
417     hal::Error error = hal::Error::NONE;
418 
419     // First try to skip validate altogether. We can do that when
420     // 1. The previous frame has not been presented yet or already passed the
421     // earliest time to present. Otherwise, we may present a frame too early.
422     // 2. There is no client composition. Otherwise, we first need to render the
423     // client target buffer.
424     const bool canSkipValidate = [&] {
425         // We must call validate if we have client composition
426         if (frameUsesClientComposition) {
427             return false;
428         }
429 
430         // If composer supports getting the expected present time, we can skip
431         // as composer will make sure to prevent early presentation
432         if (mComposer->isSupported(Hwc2::Composer::OptionalFeature::ExpectedPresentTime)) {
433             return true;
434         }
435 
436         // composer doesn't support getting the expected present time. We can only
437         // skip validate if we know that we are not going to present early.
438         return std::chrono::steady_clock::now() >= earliestPresentTime ||
439                 previousPresentFence->getSignalTime() == Fence::SIGNAL_TIME_PENDING;
440     }();
441 
442     displayData.validateWasSkipped = false;
443     if (canSkipValidate) {
444         sp<Fence> outPresentFence;
445         uint32_t state = UINT32_MAX;
446         error = hwcDisplay->presentOrValidate(expectedPresentTime, &numTypes, &numRequests,
447                                               &outPresentFence, &state);
448         if (!hasChangesError(error)) {
449             RETURN_IF_HWC_ERROR_FOR("presentOrValidate", error, displayId, UNKNOWN_ERROR);
450         }
451         if (state == 1) { //Present Succeeded.
452             std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
453             error = hwcDisplay->getReleaseFences(&releaseFences);
454             displayData.releaseFences = std::move(releaseFences);
455             displayData.lastPresentFence = outPresentFence;
456             displayData.validateWasSkipped = true;
457             displayData.presentError = error;
458             return NO_ERROR;
459         }
460         // Present failed but Validate ran.
461     } else {
462         error = hwcDisplay->validate(expectedPresentTime, &numTypes, &numRequests);
463     }
464     ALOGV("SkipValidate failed, Falling back to SLOW validate/present");
465     if (!hasChangesError(error)) {
466         RETURN_IF_HWC_ERROR_FOR("validate", error, displayId, BAD_INDEX);
467     }
468 
469     android::HWComposer::DeviceRequestedChanges::ChangedTypes changedTypes;
470     changedTypes.reserve(numTypes);
471     error = hwcDisplay->getChangedCompositionTypes(&changedTypes);
472     RETURN_IF_HWC_ERROR_FOR("getChangedCompositionTypes", error, displayId, BAD_INDEX);
473 
474     auto displayRequests = static_cast<hal::DisplayRequest>(0);
475     android::HWComposer::DeviceRequestedChanges::LayerRequests layerRequests;
476     layerRequests.reserve(numRequests);
477     error = hwcDisplay->getRequests(&displayRequests, &layerRequests);
478     RETURN_IF_HWC_ERROR_FOR("getRequests", error, displayId, BAD_INDEX);
479 
480     DeviceRequestedChanges::ClientTargetProperty clientTargetProperty;
481     error = hwcDisplay->getClientTargetProperty(&clientTargetProperty);
482 
483     outChanges->emplace(DeviceRequestedChanges{std::move(changedTypes), std::move(displayRequests),
484                                                std::move(layerRequests),
485                                                std::move(clientTargetProperty)});
486     error = hwcDisplay->acceptChanges();
487     RETURN_IF_HWC_ERROR_FOR("acceptChanges", error, displayId, BAD_INDEX);
488 
489     return NO_ERROR;
490 }
491 
getPresentFence(HalDisplayId displayId) const492 sp<Fence> HWComposer::getPresentFence(HalDisplayId displayId) const {
493     RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
494     return mDisplayData.at(displayId).lastPresentFence;
495 }
496 
getLayerReleaseFence(HalDisplayId displayId,HWC2::Layer * layer) const497 sp<Fence> HWComposer::getLayerReleaseFence(HalDisplayId displayId, HWC2::Layer* layer) const {
498     RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
499     const auto& displayFences = mDisplayData.at(displayId).releaseFences;
500     auto fence = displayFences.find(layer);
501     if (fence == displayFences.end()) {
502         ALOGV("getLayerReleaseFence: Release fence not found");
503         return Fence::NO_FENCE;
504     }
505     return fence->second;
506 }
507 
presentAndGetReleaseFences(HalDisplayId displayId,std::chrono::steady_clock::time_point earliestPresentTime,const std::shared_ptr<FenceTime> & previousPresentFence)508 status_t HWComposer::presentAndGetReleaseFences(
509         HalDisplayId displayId, std::chrono::steady_clock::time_point earliestPresentTime,
510         const std::shared_ptr<FenceTime>& previousPresentFence) {
511     ATRACE_CALL();
512 
513     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
514 
515     auto& displayData = mDisplayData[displayId];
516     auto& hwcDisplay = displayData.hwcDisplay;
517 
518     if (displayData.validateWasSkipped) {
519         // explicitly flush all pending commands
520         auto error = static_cast<hal::Error>(mComposer->executeCommands());
521         RETURN_IF_HWC_ERROR_FOR("executeCommands", error, displayId, UNKNOWN_ERROR);
522         RETURN_IF_HWC_ERROR_FOR("present", displayData.presentError, displayId, UNKNOWN_ERROR);
523         return NO_ERROR;
524     }
525 
526     const bool waitForEarliestPresent =
527             !mComposer->isSupported(Hwc2::Composer::OptionalFeature::ExpectedPresentTime) &&
528             previousPresentFence->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
529 
530     if (waitForEarliestPresent) {
531         ATRACE_NAME("wait for earliest present time");
532         std::this_thread::sleep_until(earliestPresentTime);
533     }
534 
535     auto error = hwcDisplay->present(&displayData.lastPresentFence);
536     RETURN_IF_HWC_ERROR_FOR("present", error, displayId, UNKNOWN_ERROR);
537 
538     std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
539     error = hwcDisplay->getReleaseFences(&releaseFences);
540     RETURN_IF_HWC_ERROR_FOR("getReleaseFences", error, displayId, UNKNOWN_ERROR);
541 
542     displayData.releaseFences = std::move(releaseFences);
543 
544     return NO_ERROR;
545 }
546 
setPowerMode(PhysicalDisplayId displayId,hal::PowerMode mode)547 status_t HWComposer::setPowerMode(PhysicalDisplayId displayId, hal::PowerMode mode) {
548     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
549 
550     if (mode == hal::PowerMode::OFF) {
551         setVsyncEnabled(displayId, hal::Vsync::DISABLE);
552     }
553 
554     const auto& displayData = mDisplayData[displayId];
555     auto& hwcDisplay = displayData.hwcDisplay;
556     switch (mode) {
557         case hal::PowerMode::OFF:
558         case hal::PowerMode::ON:
559             ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
560             {
561                 auto error = hwcDisplay->setPowerMode(mode);
562                 if (error != hal::Error::NONE) {
563                     LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), error,
564                                   displayId);
565                 }
566             }
567             break;
568         case hal::PowerMode::DOZE:
569         case hal::PowerMode::DOZE_SUSPEND:
570             ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
571             {
572                 bool supportsDoze = false;
573                 auto error = hwcDisplay->supportsDoze(&supportsDoze);
574                 if (error != hal::Error::NONE) {
575                     LOG_HWC_ERROR("supportsDoze", error, displayId);
576                 }
577 
578                 if (!supportsDoze) {
579                     mode = hal::PowerMode::ON;
580                 }
581 
582                 error = hwcDisplay->setPowerMode(mode);
583                 if (error != hal::Error::NONE) {
584                     LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), error,
585                                   displayId);
586                 }
587             }
588             break;
589         default:
590             ALOGV("setPowerMode: Not calling HWC");
591             break;
592     }
593 
594     return NO_ERROR;
595 }
596 
setActiveModeWithConstraints(PhysicalDisplayId displayId,hal::HWConfigId hwcModeId,const hal::VsyncPeriodChangeConstraints & constraints,hal::VsyncPeriodChangeTimeline * outTimeline)597 status_t HWComposer::setActiveModeWithConstraints(
598         PhysicalDisplayId displayId, hal::HWConfigId hwcModeId,
599         const hal::VsyncPeriodChangeConstraints& constraints,
600         hal::VsyncPeriodChangeTimeline* outTimeline) {
601     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
602 
603     auto error = mDisplayData[displayId].hwcDisplay->setActiveConfigWithConstraints(hwcModeId,
604                                                                                     constraints,
605                                                                                     outTimeline);
606     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
607     return NO_ERROR;
608 }
609 
setColorTransform(HalDisplayId displayId,const mat4 & transform)610 status_t HWComposer::setColorTransform(HalDisplayId displayId, const mat4& transform) {
611     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
612 
613     auto& displayData = mDisplayData[displayId];
614     auto error = displayData.hwcDisplay->setColorTransform(transform);
615     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
616     return NO_ERROR;
617 }
618 
disconnectDisplay(HalDisplayId displayId)619 void HWComposer::disconnectDisplay(HalDisplayId displayId) {
620     RETURN_IF_INVALID_DISPLAY(displayId);
621     auto& displayData = mDisplayData[displayId];
622     const auto hwcDisplayId = displayData.hwcDisplay->getId();
623 
624     mPhysicalDisplayIdMap.erase(hwcDisplayId);
625     mDisplayData.erase(displayId);
626 
627     // Reset the primary display ID if we're disconnecting it.
628     // This way isHeadless() will return false, which is necessary
629     // because getPrimaryDisplayId() will crash.
630     if (mPrimaryHwcDisplayId == hwcDisplayId) {
631         mPrimaryHwcDisplayId.reset();
632     }
633 }
634 
setOutputBuffer(HalVirtualDisplayId displayId,const sp<Fence> & acquireFence,const sp<GraphicBuffer> & buffer)635 status_t HWComposer::setOutputBuffer(HalVirtualDisplayId displayId, const sp<Fence>& acquireFence,
636                                      const sp<GraphicBuffer>& buffer) {
637     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
638     const auto& displayData = mDisplayData[displayId];
639 
640     auto error = displayData.hwcDisplay->setOutputBuffer(buffer, acquireFence);
641     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
642     return NO_ERROR;
643 }
644 
clearReleaseFences(HalDisplayId displayId)645 void HWComposer::clearReleaseFences(HalDisplayId displayId) {
646     RETURN_IF_INVALID_DISPLAY(displayId);
647     mDisplayData[displayId].releaseFences.clear();
648 }
649 
getHdrCapabilities(HalDisplayId displayId,HdrCapabilities * outCapabilities)650 status_t HWComposer::getHdrCapabilities(HalDisplayId displayId, HdrCapabilities* outCapabilities) {
651     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
652 
653     auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
654     auto error = hwcDisplay->getHdrCapabilities(outCapabilities);
655     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
656     return NO_ERROR;
657 }
658 
getSupportedPerFrameMetadata(HalDisplayId displayId) const659 int32_t HWComposer::getSupportedPerFrameMetadata(HalDisplayId displayId) const {
660     RETURN_IF_INVALID_DISPLAY(displayId, 0);
661     return mDisplayData.at(displayId).hwcDisplay->getSupportedPerFrameMetadata();
662 }
663 
getRenderIntents(HalDisplayId displayId,ui::ColorMode colorMode) const664 std::vector<ui::RenderIntent> HWComposer::getRenderIntents(HalDisplayId displayId,
665                                                            ui::ColorMode colorMode) const {
666     RETURN_IF_INVALID_DISPLAY(displayId, {});
667 
668     std::vector<ui::RenderIntent> renderIntents;
669     auto error = mDisplayData.at(displayId).hwcDisplay->getRenderIntents(colorMode, &renderIntents);
670     RETURN_IF_HWC_ERROR(error, displayId, {});
671     return renderIntents;
672 }
673 
getDataspaceSaturationMatrix(HalDisplayId displayId,ui::Dataspace dataspace)674 mat4 HWComposer::getDataspaceSaturationMatrix(HalDisplayId displayId, ui::Dataspace dataspace) {
675     RETURN_IF_INVALID_DISPLAY(displayId, {});
676 
677     mat4 matrix;
678     auto error = mDisplayData[displayId].hwcDisplay->getDataspaceSaturationMatrix(dataspace,
679             &matrix);
680     RETURN_IF_HWC_ERROR(error, displayId, {});
681     return matrix;
682 }
683 
getDisplayedContentSamplingAttributes(HalDisplayId displayId,ui::PixelFormat * outFormat,ui::Dataspace * outDataspace,uint8_t * outComponentMask)684 status_t HWComposer::getDisplayedContentSamplingAttributes(HalDisplayId displayId,
685                                                            ui::PixelFormat* outFormat,
686                                                            ui::Dataspace* outDataspace,
687                                                            uint8_t* outComponentMask) {
688     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
689     const auto error =
690             mDisplayData[displayId]
691                     .hwcDisplay->getDisplayedContentSamplingAttributes(outFormat, outDataspace,
692                                                                        outComponentMask);
693     if (error == hal::Error::UNSUPPORTED) RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
694     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
695     return NO_ERROR;
696 }
697 
setDisplayContentSamplingEnabled(HalDisplayId displayId,bool enabled,uint8_t componentMask,uint64_t maxFrames)698 status_t HWComposer::setDisplayContentSamplingEnabled(HalDisplayId displayId, bool enabled,
699                                                       uint8_t componentMask, uint64_t maxFrames) {
700     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
701     const auto error =
702             mDisplayData[displayId].hwcDisplay->setDisplayContentSamplingEnabled(enabled,
703                                                                                  componentMask,
704                                                                                  maxFrames);
705 
706     if (error == hal::Error::UNSUPPORTED) RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
707     if (error == hal::Error::BAD_PARAMETER) RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
708     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
709     return NO_ERROR;
710 }
711 
getDisplayedContentSample(HalDisplayId displayId,uint64_t maxFrames,uint64_t timestamp,DisplayedFrameStats * outStats)712 status_t HWComposer::getDisplayedContentSample(HalDisplayId displayId, uint64_t maxFrames,
713                                                uint64_t timestamp, DisplayedFrameStats* outStats) {
714     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
715     const auto error =
716             mDisplayData[displayId].hwcDisplay->getDisplayedContentSample(maxFrames, timestamp,
717                                                                           outStats);
718     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
719     return NO_ERROR;
720 }
721 
setDisplayBrightness(PhysicalDisplayId displayId,float brightness,float brightnessNits,const Hwc2::Composer::DisplayBrightnessOptions & options)722 ftl::Future<status_t> HWComposer::setDisplayBrightness(
723         PhysicalDisplayId displayId, float brightness, float brightnessNits,
724         const Hwc2::Composer::DisplayBrightnessOptions& options) {
725     RETURN_IF_INVALID_DISPLAY(displayId, ftl::yield<status_t>(BAD_INDEX));
726     auto& display = mDisplayData[displayId].hwcDisplay;
727 
728     return display->setDisplayBrightness(brightness, brightnessNits, options)
729             .then([displayId](hal::Error error) -> status_t {
730                 if (error == hal::Error::UNSUPPORTED) {
731                     RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
732                 }
733                 if (error == hal::Error::BAD_PARAMETER) {
734                     RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
735                 }
736                 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
737                 return NO_ERROR;
738             });
739 }
740 
getValidateSkipped(HalDisplayId displayId) const741 bool HWComposer::getValidateSkipped(HalDisplayId displayId) const {
742     if (mDisplayData.count(displayId) == 0) {
743         return false;
744     }
745     return mDisplayData.at(displayId).validateWasSkipped;
746 }
747 
setBootDisplayMode(PhysicalDisplayId displayId,hal::HWConfigId displayModeId)748 status_t HWComposer::setBootDisplayMode(PhysicalDisplayId displayId,
749                                         hal::HWConfigId displayModeId) {
750     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
751     const auto error = mDisplayData[displayId].hwcDisplay->setBootDisplayConfig(displayModeId);
752     if (error == hal::Error::UNSUPPORTED) {
753         RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
754     }
755     if (error == hal::Error::BAD_PARAMETER) {
756         RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
757     }
758     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
759     return NO_ERROR;
760 }
761 
clearBootDisplayMode(PhysicalDisplayId displayId)762 status_t HWComposer::clearBootDisplayMode(PhysicalDisplayId displayId) {
763     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
764     const auto error = mDisplayData[displayId].hwcDisplay->clearBootDisplayConfig();
765     if (error == hal::Error::UNSUPPORTED) {
766         RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
767     }
768     if (error == hal::Error::BAD_PARAMETER) {
769         RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
770     }
771     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
772     return NO_ERROR;
773 }
774 
getPreferredBootDisplayMode(PhysicalDisplayId displayId)775 std::optional<hal::HWConfigId> HWComposer::getPreferredBootDisplayMode(
776         PhysicalDisplayId displayId) {
777     RETURN_IF_INVALID_DISPLAY(displayId, std::nullopt);
778     hal::HWConfigId displayModeId;
779     const auto error =
780             mDisplayData[displayId].hwcDisplay->getPreferredBootDisplayConfig(&displayModeId);
781     if (error != hal::Error::NONE) {
782         LOG_DISPLAY_ERROR(displayId, to_string(error).c_str());
783         return std::nullopt;
784     }
785     return displayModeId;
786 }
787 
getDisplayDecorationSupport(PhysicalDisplayId displayId,std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport> * support)788 status_t HWComposer::getDisplayDecorationSupport(
789         PhysicalDisplayId displayId,
790         std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport>*
791                 support) {
792     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
793     const auto error = mDisplayData[displayId].hwcDisplay->getDisplayDecorationSupport(support);
794     if (error == hal::Error::UNSUPPORTED) {
795         RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
796     }
797     if (error == hal::Error::BAD_PARAMETER) {
798         RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
799     }
800     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
801     return NO_ERROR;
802 }
803 
setAutoLowLatencyMode(PhysicalDisplayId displayId,bool on)804 status_t HWComposer::setAutoLowLatencyMode(PhysicalDisplayId displayId, bool on) {
805     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
806     const auto error = mDisplayData[displayId].hwcDisplay->setAutoLowLatencyMode(on);
807     if (error == hal::Error::UNSUPPORTED) {
808         RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
809     }
810     if (error == hal::Error::BAD_PARAMETER) {
811         RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
812     }
813     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
814     return NO_ERROR;
815 }
816 
getSupportedContentTypes(PhysicalDisplayId displayId,std::vector<hal::ContentType> * outSupportedContentTypes) const817 status_t HWComposer::getSupportedContentTypes(
818         PhysicalDisplayId displayId,
819         std::vector<hal::ContentType>* outSupportedContentTypes) const {
820     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
821     const auto error = mDisplayData.at(displayId).hwcDisplay->getSupportedContentTypes(
822             outSupportedContentTypes);
823 
824     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
825 
826     return NO_ERROR;
827 }
828 
setContentType(PhysicalDisplayId displayId,hal::ContentType contentType)829 status_t HWComposer::setContentType(PhysicalDisplayId displayId, hal::ContentType contentType) {
830     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
831     const auto error = mDisplayData[displayId].hwcDisplay->setContentType(contentType);
832     if (error == hal::Error::UNSUPPORTED) {
833         RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
834     }
835     if (error == hal::Error::BAD_PARAMETER) {
836         RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
837     }
838     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
839 
840     return NO_ERROR;
841 }
842 
getSupportedLayerGenericMetadata() const843 const std::unordered_map<std::string, bool>& HWComposer::getSupportedLayerGenericMetadata() const {
844     return mSupportedLayerGenericMetadata;
845 }
846 
dump(std::string & result) const847 void HWComposer::dump(std::string& result) const {
848     result.append(mComposer->dumpDebugInfo());
849 }
850 
toPhysicalDisplayId(hal::HWDisplayId hwcDisplayId) const851 std::optional<PhysicalDisplayId> HWComposer::toPhysicalDisplayId(
852         hal::HWDisplayId hwcDisplayId) const {
853     if (const auto it = mPhysicalDisplayIdMap.find(hwcDisplayId);
854         it != mPhysicalDisplayIdMap.end()) {
855         return it->second;
856     }
857     return {};
858 }
859 
fromPhysicalDisplayId(PhysicalDisplayId displayId) const860 std::optional<hal::HWDisplayId> HWComposer::fromPhysicalDisplayId(
861         PhysicalDisplayId displayId) const {
862     if (const auto it = mDisplayData.find(displayId); it != mDisplayData.end()) {
863         return it->second.hwcDisplay->getId();
864     }
865     return {};
866 }
867 
shouldIgnoreHotplugConnect(hal::HWDisplayId hwcDisplayId,bool hasDisplayIdentificationData) const868 bool HWComposer::shouldIgnoreHotplugConnect(hal::HWDisplayId hwcDisplayId,
869                                             bool hasDisplayIdentificationData) const {
870     if (mHasMultiDisplaySupport && !hasDisplayIdentificationData) {
871         ALOGE("Ignoring connection of display %" PRIu64 " without identification data",
872               hwcDisplayId);
873         return true;
874     }
875 
876     // Legacy mode only supports IDs LEGACY_DISPLAY_TYPE_PRIMARY and LEGACY_DISPLAY_TYPE_EXTERNAL.
877     if (!mHasMultiDisplaySupport && mPhysicalDisplayIdMap.size() == 2) {
878         ALOGE("Ignoring connection of tertiary display %" PRIu64, hwcDisplayId);
879         return true;
880     }
881 
882     return false;
883 }
884 
onHotplugConnect(hal::HWDisplayId hwcDisplayId)885 std::optional<DisplayIdentificationInfo> HWComposer::onHotplugConnect(
886         hal::HWDisplayId hwcDisplayId) {
887     std::optional<DisplayIdentificationInfo> info;
888     if (const auto displayId = toPhysicalDisplayId(hwcDisplayId)) {
889         info = DisplayIdentificationInfo{.id = *displayId,
890                                          .name = std::string(),
891                                          .deviceProductInfo = std::nullopt};
892         if (mUpdateDeviceProductInfoOnHotplugReconnect) {
893             uint8_t port;
894             DisplayIdentificationData data;
895             getDisplayIdentificationData(hwcDisplayId, &port, &data);
896             if (auto newInfo = parseDisplayIdentificationData(port, data)) {
897                 info->deviceProductInfo = std::move(newInfo->deviceProductInfo);
898             } else {
899                 ALOGE("Failed to parse identification data for display %" PRIu64, hwcDisplayId);
900             }
901         }
902     } else {
903         uint8_t port;
904         DisplayIdentificationData data;
905         const bool hasDisplayIdentificationData =
906                 getDisplayIdentificationData(hwcDisplayId, &port, &data);
907         if (mPhysicalDisplayIdMap.empty()) {
908             mHasMultiDisplaySupport = hasDisplayIdentificationData;
909             ALOGI("Switching to %s multi-display mode",
910                   mHasMultiDisplaySupport ? "generalized" : "legacy");
911         }
912 
913         if (shouldIgnoreHotplugConnect(hwcDisplayId, hasDisplayIdentificationData)) {
914             return {};
915         }
916 
917         info = [this, hwcDisplayId, &port, &data, hasDisplayIdentificationData] {
918             const bool isPrimary = !mPrimaryHwcDisplayId;
919             if (mHasMultiDisplaySupport) {
920                 if (const auto info = parseDisplayIdentificationData(port, data)) {
921                     return *info;
922                 }
923                 ALOGE("Failed to parse identification data for display %" PRIu64, hwcDisplayId);
924             } else {
925                 ALOGW_IF(hasDisplayIdentificationData,
926                          "Ignoring identification data for display %" PRIu64, hwcDisplayId);
927                 port = isPrimary ? LEGACY_DISPLAY_TYPE_PRIMARY : LEGACY_DISPLAY_TYPE_EXTERNAL;
928             }
929 
930             return DisplayIdentificationInfo{.id = PhysicalDisplayId::fromPort(port),
931                                              .name = isPrimary ? "Primary display"
932                                                                : "Secondary display",
933                                              .deviceProductInfo = std::nullopt};
934         }();
935     }
936 
937     if (!isConnected(info->id)) {
938         allocatePhysicalDisplay(hwcDisplayId, info->id);
939     }
940     return info;
941 }
942 
onHotplugDisconnect(hal::HWDisplayId hwcDisplayId)943 std::optional<DisplayIdentificationInfo> HWComposer::onHotplugDisconnect(
944         hal::HWDisplayId hwcDisplayId) {
945     LOG_ALWAYS_FATAL_IF(hwcDisplayId == mPrimaryHwcDisplayId,
946                         "Primary display cannot be disconnected.");
947 
948     const auto displayId = toPhysicalDisplayId(hwcDisplayId);
949     if (!displayId) {
950         LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Invalid HWC display");
951         return {};
952     }
953 
954     // The display will later be destroyed by a call to
955     // destroyDisplay(). For now we just mark it disconnected.
956     if (isConnected(*displayId)) {
957         mDisplayData[*displayId].hwcDisplay->setConnected(false);
958     } else {
959         LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Already disconnected");
960     }
961     // The cleanup of Disconnect is handled through HWComposer::disconnectDisplay
962     // via SurfaceFlinger's onHotplugReceived callback handling
963     return DisplayIdentificationInfo{.id = *displayId,
964                                      .name = std::string(),
965                                      .deviceProductInfo = std::nullopt};
966 }
967 
loadCapabilities()968 void HWComposer::loadCapabilities() {
969     static_assert(sizeof(hal::Capability) == sizeof(int32_t), "Capability size has changed");
970     auto capabilities = mComposer->getCapabilities();
971     for (auto capability : capabilities) {
972         mCapabilities.emplace(capability);
973     }
974 }
975 
setIdleTimerEnabled(PhysicalDisplayId displayId,std::chrono::milliseconds timeout)976 status_t HWComposer::setIdleTimerEnabled(PhysicalDisplayId displayId,
977                                          std::chrono::milliseconds timeout) {
978     ATRACE_CALL();
979     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
980     const auto error = mDisplayData[displayId].hwcDisplay->setIdleTimerEnabled(timeout);
981     if (error == hal::Error::UNSUPPORTED) {
982         RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
983     }
984     if (error == hal::Error::BAD_PARAMETER) {
985         RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
986     }
987     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
988     return NO_ERROR;
989 }
990 
hasDisplayIdleTimerCapability(PhysicalDisplayId displayId) const991 bool HWComposer::hasDisplayIdleTimerCapability(PhysicalDisplayId displayId) const {
992     RETURN_IF_INVALID_DISPLAY(displayId, false);
993     return mDisplayData.at(displayId).hwcDisplay->hasDisplayIdleTimerCapability();
994 }
995 
getPhysicalDisplayOrientation(PhysicalDisplayId displayId) const996 Hwc2::AidlTransform HWComposer::getPhysicalDisplayOrientation(PhysicalDisplayId displayId) const {
997     ATRACE_CALL();
998     RETURN_IF_INVALID_DISPLAY(displayId, Hwc2::AidlTransform::NONE);
999     Hwc2::AidlTransform outTransform;
1000     const auto& hwcDisplay = mDisplayData.at(displayId).hwcDisplay;
1001     const auto error = hwcDisplay->getPhysicalDisplayOrientation(&outTransform);
1002     RETURN_IF_HWC_ERROR(error, displayId, Hwc2::AidlTransform::NONE);
1003     return outTransform;
1004 }
1005 
loadLayerMetadataSupport()1006 void HWComposer::loadLayerMetadataSupport() {
1007     mSupportedLayerGenericMetadata.clear();
1008 
1009     std::vector<Hwc2::IComposerClient::LayerGenericMetadataKey> supportedMetadataKeyInfo;
1010     const auto error = mComposer->getLayerGenericMetadataKeys(&supportedMetadataKeyInfo);
1011     if (error != hardware::graphics::composer::V2_4::Error::NONE) {
1012         if (error != hardware::graphics::composer::V2_4::Error::UNSUPPORTED) {
1013             ALOGE("%s: %s failed: %s (%d)", __FUNCTION__, "getLayerGenericMetadataKeys",
1014                   toString(error).c_str(), static_cast<int32_t>(error));
1015         }
1016         return;
1017     }
1018 
1019     for (const auto& [name, mandatory] : supportedMetadataKeyInfo) {
1020         mSupportedLayerGenericMetadata.emplace(name, mandatory);
1021     }
1022 }
1023 
1024 } // namespace impl
1025 } // namespace android
1026 
1027 // TODO(b/129481165): remove the #pragma below and fix conversion issues
1028 #pragma clang diagnostic pop // ignored "-Wconversion"
1029