1 /*
2  * Copyright (C) 2021 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 #define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
18 
19 #include "ComposerClient.h"
20 
21 #include <android-base/logging.h>
22 #include <android/binder_ibinder_platform.h>
23 #include <hardware/hwcomposer2.h>
24 
25 #include "Util.h"
26 
27 namespace aidl::android::hardware::graphics::composer3::impl {
28 
init()29 bool ComposerClient::init() {
30     DEBUG_FUNC();
31     mResources = IResourceManager::create();
32     if (!mResources) {
33         LOG(ERROR) << "failed to create composer resources";
34         return false;
35     }
36 
37     return true;
38 }
39 
~ComposerClient()40 ComposerClient::~ComposerClient() {
41     DEBUG_FUNC();
42     LOG(DEBUG) << "destroying composer client";
43 
44     mHal->unregisterEventCallback();
45     destroyResources();
46 
47     if (mOnClientDestroyed) {
48         mOnClientDestroyed();
49     }
50 
51     LOG(DEBUG) << "removed composer client";
52 }
53 
54 // no need to check nullptr for output parameter, the aidl stub code won't pass nullptr
createLayer(int64_t display,int32_t bufferSlotCount,int64_t * layer)55 ndk::ScopedAStatus ComposerClient::createLayer(int64_t display, int32_t bufferSlotCount,
56                                                int64_t* layer) {
57     DEBUG_DISPLAY_FUNC(display);
58     auto err = mHal->createLayer(display, layer);
59     if (!err) {
60         err = mResources->addLayer(display, *layer, bufferSlotCount);
61         if (err) {
62             layer = 0;
63         }
64     }
65     return TO_BINDER_STATUS(err);
66 }
67 
createVirtualDisplay(int32_t width,int32_t height,AidlPixelFormat formatHint,int32_t outputBufferSlotCount,VirtualDisplay * display)68 ndk::ScopedAStatus ComposerClient::createVirtualDisplay(int32_t width, int32_t height,
69                                                         AidlPixelFormat formatHint,
70                                                         int32_t outputBufferSlotCount,
71                                                         VirtualDisplay* display) {
72     DEBUG_FUNC();
73     auto err = mHal->createVirtualDisplay(width, height, formatHint, display);
74     if (!err) {
75         err = mResources->addVirtualDisplay(display->display, outputBufferSlotCount);
76     }
77     return TO_BINDER_STATUS(err);
78 }
79 
getDisplayConfigurations(int64_t display,int32_t maxFrameIntervalNs,std::vector<DisplayConfiguration> * configs)80 ndk::ScopedAStatus ComposerClient::getDisplayConfigurations(
81         int64_t display, int32_t maxFrameIntervalNs, std::vector<DisplayConfiguration>* configs) {
82     DEBUG_DISPLAY_FUNC(display);
83     auto err = mHal->getDisplayConfigurations(display, maxFrameIntervalNs, configs);
84     return TO_BINDER_STATUS(err);
85 }
86 
notifyExpectedPresent(int64_t display,const ClockMonotonicTimestamp & expectedPresentTime,int32_t frameIntervalNs)87 ndk::ScopedAStatus ComposerClient::notifyExpectedPresent(
88         int64_t display, const ClockMonotonicTimestamp& expectedPresentTime,
89         int32_t frameIntervalNs) {
90     DEBUG_DISPLAY_FUNC(display);
91     auto err = mHal->notifyExpectedPresent(display, expectedPresentTime, frameIntervalNs);
92     return TO_BINDER_STATUS(err);
93 }
94 
getMaxLayerPictureProfiles(int64_t display,int32_t * outMaxProfiles)95 ndk::ScopedAStatus ComposerClient::getMaxLayerPictureProfiles(int64_t display,
96                                                               int32_t* outMaxProfiles) {
97     DEBUG_DISPLAY_FUNC(display);
98     auto err = mHal->getMaxLayerPictureProfiles(display, outMaxProfiles);
99     return TO_BINDER_STATUS(err);
100 }
101 
getLuts(int64_t display,const std::vector<Buffer> &,std::vector<Luts> *)102 ndk::ScopedAStatus ComposerClient::getLuts(int64_t display, const std::vector<Buffer>& /*buffers*/,
103                                            std::vector<Luts>* /*luts*/) {
104     DEBUG_DISPLAY_FUNC(display);
105     LOG(ERROR) << "not implemented";
106     return ndk::ScopedAStatus::fromStatus(EX_UNSUPPORTED_OPERATION);
107 }
108 
destroyLayer(int64_t display,int64_t layer)109 ndk::ScopedAStatus ComposerClient::destroyLayer(int64_t display, int64_t layer) {
110     DEBUG_DISPLAY_FUNC(display);
111     auto err = mHal->destroyLayer(display, layer);
112     if (!err) {
113         err = mResources->removeLayer(display, layer);
114     }
115     return TO_BINDER_STATUS(err);
116 }
117 
destroyVirtualDisplay(int64_t display)118 ndk::ScopedAStatus ComposerClient::destroyVirtualDisplay(int64_t display) {
119     DEBUG_DISPLAY_FUNC(display);
120     auto err = mHal->destroyVirtualDisplay(display);
121     if (!err) {
122         err = mResources->removeDisplay(display);
123     }
124     return TO_BINDER_STATUS(err);
125 }
126 
executeCommands(const std::vector<DisplayCommand> & commands,std::vector<CommandResultPayload> * results)127 ndk::ScopedAStatus ComposerClient::executeCommands(const std::vector<DisplayCommand>& commands,
128                                                    std::vector<CommandResultPayload>* results) {
129     int64_t display = commands.empty() ? -1 : commands[0].display;
130     DEBUG_DISPLAY_FUNC(display);
131     ComposerCommandEngine engine(mHal, mResources.get());
132 
133     auto err = engine.init();
134     if (err != ::android::NO_ERROR) {
135         LOG(ERROR) << "executeCommands(): init ComposerCommandEngine failed " << err;
136         return TO_BINDER_STATUS(err);
137     }
138 
139     err = engine.execute(commands, results);
140     if (err != ::android::NO_ERROR) {
141         LOG(ERROR) << "executeCommands(): execute failed " << err;
142         return TO_BINDER_STATUS(err);
143     }
144     return TO_BINDER_STATUS(err);
145 }
146 
getActiveConfig(int64_t display,int32_t * config)147 ndk::ScopedAStatus ComposerClient::getActiveConfig(int64_t display, int32_t* config) {
148     DEBUG_DISPLAY_FUNC(display);
149     auto err = mHal->getActiveConfig(display, config);
150     return TO_BINDER_STATUS(err);
151 }
152 
getColorModes(int64_t display,std::vector<ColorMode> * colorModes)153 ndk::ScopedAStatus ComposerClient::getColorModes(int64_t display,
154                                                  std::vector<ColorMode>* colorModes) {
155     DEBUG_DISPLAY_FUNC(display);
156     auto err = mHal->getColorModes(display, colorModes);
157     return TO_BINDER_STATUS(err);
158 }
159 
getDataspaceSaturationMatrix(common::Dataspace dataspace,std::vector<float> * matrix)160 ndk::ScopedAStatus ComposerClient::getDataspaceSaturationMatrix(common::Dataspace dataspace,
161                                                                 std::vector<float>* matrix) {
162     DEBUG_FUNC();
163     if (dataspace != common::Dataspace::SRGB_LINEAR) {
164         return TO_BINDER_STATUS(EX_BAD_PARAMETER);
165     }
166 
167     auto err = mHal->getDataspaceSaturationMatrix(dataspace, matrix);
168     if (err) {
169         constexpr std::array<float, 16> unit {
170                 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
171                 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
172         };
173         matrix->clear();
174         matrix->insert(matrix->begin(), unit.begin(), unit.end());
175     }
176     return TO_BINDER_STATUS(err);
177 }
178 
getDisplayAttribute(int64_t display,int32_t config,DisplayAttribute attribute,int32_t * value)179 ndk::ScopedAStatus ComposerClient::getDisplayAttribute(int64_t display, int32_t config,
180                                                        DisplayAttribute attribute, int32_t* value) {
181     DEBUG_DISPLAY_FUNC(display);
182     auto err = mHal->getDisplayAttribute(display, config, attribute, value);
183     return TO_BINDER_STATUS(err);
184 }
185 
getDisplayCapabilities(int64_t display,std::vector<DisplayCapability> * caps)186 ndk::ScopedAStatus ComposerClient::getDisplayCapabilities(int64_t display,
187                                                           std::vector<DisplayCapability>* caps) {
188     DEBUG_DISPLAY_FUNC(display);
189     auto err = mHal->getDisplayCapabilities(display, caps);
190     if (err) {
191         return TO_BINDER_STATUS(err);
192     }
193 
194     bool support = false;
195     err = mHal->getDisplayIdleTimerSupport(display, support);
196     if (err != ::android::OK) {
197         LOG(ERROR) << "failed to getDisplayIdleTimerSupport: " << err;
198     }
199 
200     if (support) {
201         caps->push_back(DisplayCapability::DISPLAY_IDLE_TIMER);
202     }
203 
204     err = mHal->getDisplayMultiThreadedPresentSupport(display, support);
205     if (err != ::android::OK) {
206         LOG(ERROR) << "failed to getDisplayMultiThreadedPresentSupport: " << err;
207         return TO_BINDER_STATUS(err);
208     }
209 
210     if (support) {
211         caps->push_back(DisplayCapability::MULTI_THREADED_PRESENT);
212     }
213 
214     return TO_BINDER_STATUS(err);
215 }
216 
getDisplayConfigs(int64_t display,std::vector<int32_t> * configs)217 ndk::ScopedAStatus ComposerClient::getDisplayConfigs(int64_t display,
218                                                      std::vector<int32_t>* configs) {
219     DEBUG_DISPLAY_FUNC(display);
220     auto err = mHal->getDisplayConfigs(display, configs);
221     return TO_BINDER_STATUS(err);
222 }
223 
getDisplayConnectionType(int64_t display,DisplayConnectionType * type)224 ndk::ScopedAStatus ComposerClient::getDisplayConnectionType(int64_t display,
225                                                             DisplayConnectionType* type) {
226     DEBUG_DISPLAY_FUNC(display);
227     auto err = mHal->getDisplayConnectionType(display, type);
228     return TO_BINDER_STATUS(err);
229 }
230 
getDisplayIdentificationData(int64_t display,DisplayIdentification * id)231 ndk::ScopedAStatus ComposerClient::getDisplayIdentificationData(int64_t display,
232                                                                 DisplayIdentification* id) {
233     DEBUG_DISPLAY_FUNC(display);
234     auto err = mHal->getDisplayIdentificationData(display, id);
235     return TO_BINDER_STATUS(err);
236 }
237 
getDisplayName(int64_t display,std::string * name)238 ndk::ScopedAStatus ComposerClient::getDisplayName(int64_t display, std::string* name) {
239     DEBUG_DISPLAY_FUNC(display);
240     auto err = mHal->getDisplayName(display, name);
241     return TO_BINDER_STATUS(err);
242 }
243 
getDisplayVsyncPeriod(int64_t display,int32_t * vsyncPeriod)244 ndk::ScopedAStatus ComposerClient::getDisplayVsyncPeriod(int64_t display, int32_t* vsyncPeriod) {
245     DEBUG_DISPLAY_FUNC(display);
246     auto err = mHal->getDisplayVsyncPeriod(display, vsyncPeriod);
247     return TO_BINDER_STATUS(err);
248 }
249 
getDisplayedContentSample(int64_t display,int64_t maxFrames,int64_t timestamp,DisplayContentSample * samples)250 ndk::ScopedAStatus ComposerClient::getDisplayedContentSample(int64_t display, int64_t maxFrames,
251                                                              int64_t timestamp,
252                                                              DisplayContentSample* samples) {
253     DEBUG_DISPLAY_FUNC(display);
254     auto err = mHal->getDisplayedContentSample(display, maxFrames, timestamp, samples);
255     return TO_BINDER_STATUS(err);
256 }
257 
getDisplayedContentSamplingAttributes(int64_t display,DisplayContentSamplingAttributes * attrs)258 ndk::ScopedAStatus ComposerClient::getDisplayedContentSamplingAttributes(
259         int64_t display, DisplayContentSamplingAttributes* attrs) {
260     DEBUG_DISPLAY_FUNC(display);
261     auto err = mHal->getDisplayedContentSamplingAttributes(display, attrs);
262     return TO_BINDER_STATUS(err);
263 }
264 
getDisplayPhysicalOrientation(int64_t display,common::Transform * orientation)265 ndk::ScopedAStatus ComposerClient::getDisplayPhysicalOrientation(int64_t display,
266                                                                  common::Transform* orientation) {
267     DEBUG_DISPLAY_FUNC(display);
268     auto err = mHal->getDisplayPhysicalOrientation(display, orientation);
269     return TO_BINDER_STATUS(err);
270 }
271 
getHdrCapabilities(int64_t display,HdrCapabilities * caps)272 ndk::ScopedAStatus ComposerClient::getHdrCapabilities(int64_t display, HdrCapabilities* caps) {
273     DEBUG_DISPLAY_FUNC(display);
274     auto err = mHal->getHdrCapabilities(display, caps);
275     return TO_BINDER_STATUS(err);
276 }
277 
getOverlaySupport(OverlayProperties * caps)278 ndk::ScopedAStatus ComposerClient::getOverlaySupport(OverlayProperties* caps) {
279     DEBUG_FUNC();
280     auto err = mHal->getOverlaySupport(caps);
281     return TO_BINDER_STATUS(err);
282 }
283 
getMaxVirtualDisplayCount(int32_t * count)284 ndk::ScopedAStatus ComposerClient::getMaxVirtualDisplayCount(int32_t* count) {
285     DEBUG_FUNC();
286     auto err = mHal->getMaxVirtualDisplayCount(count);
287     return TO_BINDER_STATUS(err);
288 }
289 
getPerFrameMetadataKeys(int64_t display,std::vector<PerFrameMetadataKey> * keys)290 ndk::ScopedAStatus ComposerClient::getPerFrameMetadataKeys(int64_t display,
291                                                            std::vector<PerFrameMetadataKey>* keys) {
292     DEBUG_DISPLAY_FUNC(display);
293     auto err = mHal->getPerFrameMetadataKeys(display, keys);
294     return TO_BINDER_STATUS(err);
295 }
296 
getReadbackBufferAttributes(int64_t display,ReadbackBufferAttributes * attrs)297 ndk::ScopedAStatus ComposerClient::getReadbackBufferAttributes(int64_t display,
298                                                                ReadbackBufferAttributes* attrs) {
299     DEBUG_DISPLAY_FUNC(display);
300     auto err = mHal->getReadbackBufferAttributes(display, attrs);
301     return TO_BINDER_STATUS(err);
302 }
303 
getReadbackBufferFence(int64_t display,ndk::ScopedFileDescriptor * acquireFence)304 ndk::ScopedAStatus ComposerClient::getReadbackBufferFence(int64_t display,
305                                                           ndk::ScopedFileDescriptor* acquireFence) {
306     DEBUG_DISPLAY_FUNC(display);
307     auto err = mHal->getReadbackBufferFence(display, acquireFence);
308     return TO_BINDER_STATUS(err);
309 }
310 
getRenderIntents(int64_t display,ColorMode mode,std::vector<RenderIntent> * intents)311 ndk::ScopedAStatus ComposerClient::getRenderIntents(int64_t display, ColorMode mode,
312                                                     std::vector<RenderIntent>* intents) {
313     DEBUG_DISPLAY_FUNC(display);
314     auto err = mHal->getRenderIntents(display, mode, intents);
315     return TO_BINDER_STATUS(err);
316 }
317 
getSupportedContentTypes(int64_t display,std::vector<ContentType> * types)318 ndk::ScopedAStatus ComposerClient::getSupportedContentTypes(int64_t display,
319                                                             std::vector<ContentType>* types) {
320     DEBUG_DISPLAY_FUNC(display);
321     auto err = mHal->getSupportedContentTypes(display, types);
322     return TO_BINDER_STATUS(err);
323 }
324 
getDisplayDecorationSupport(int64_t display,std::optional<common::DisplayDecorationSupport> * supportStruct)325 ndk::ScopedAStatus ComposerClient::getDisplayDecorationSupport(
326         int64_t display, std::optional<common::DisplayDecorationSupport>* supportStruct) {
327     DEBUG_DISPLAY_FUNC(display);
328     bool support = false;
329     auto err = mHal->getRCDLayerSupport(display, support);
330     if (err != ::android::OK) {
331         LOG(ERROR) << "failed to getRCDLayerSupport: " << err;
332     }
333     if (support) {
334         // TODO (b/218499393): determine from mHal instead of hard coding.
335         auto& s = supportStruct->emplace();
336         s.format = common::PixelFormat::R_8;
337         s.alphaInterpretation = common::AlphaInterpretation::COVERAGE;
338     } else {
339         supportStruct->reset();
340     }
341     return TO_BINDER_STATUS(err);
342 }
343 
registerCallback(const std::shared_ptr<IComposerCallback> & callback)344 ndk::ScopedAStatus ComposerClient::registerCallback(
345         const std::shared_ptr<IComposerCallback>& callback) {
346     DEBUG_FUNC();
347     // no locking as we require this function to be called only once
348     mHalEventCallback = std::make_unique<HalEventCallback>(mHal, mResources.get(), callback);
349     mHal->registerEventCallback(mHalEventCallback.get());
350     return ndk::ScopedAStatus::ok();
351 }
352 
setActiveConfig(int64_t display,int32_t config)353 ndk::ScopedAStatus ComposerClient::setActiveConfig(int64_t display, int32_t config) {
354     DEBUG_DISPLAY_FUNC(display);
355     auto err = mHal->setActiveConfig(display, config);
356     return TO_BINDER_STATUS(err);
357 }
358 
setActiveConfigWithConstraints(int64_t display,int32_t config,const VsyncPeriodChangeConstraints & constraints,VsyncPeriodChangeTimeline * timeline)359 ndk::ScopedAStatus ComposerClient::setActiveConfigWithConstraints(
360         int64_t display, int32_t config, const VsyncPeriodChangeConstraints& constraints,
361         VsyncPeriodChangeTimeline* timeline) {
362     DEBUG_DISPLAY_FUNC(display);
363     auto err = mHal->setActiveConfigWithConstraints(display, config, constraints, timeline);
364     return TO_BINDER_STATUS(err);
365 }
366 
setBootDisplayConfig(int64_t display,int32_t config)367 ndk::ScopedAStatus ComposerClient::setBootDisplayConfig(int64_t display, int32_t config) {
368     DEBUG_DISPLAY_FUNC(display);
369     auto err = mHal->setBootDisplayConfig(display, config);
370     return TO_BINDER_STATUS(err);
371 }
372 
clearBootDisplayConfig(int64_t display)373 ndk::ScopedAStatus ComposerClient::clearBootDisplayConfig(int64_t display) {
374     DEBUG_DISPLAY_FUNC(display);
375     auto err = mHal->clearBootDisplayConfig(display);
376     return TO_BINDER_STATUS(err);
377 }
378 
getPreferredBootDisplayConfig(int64_t display,int32_t * config)379 ndk::ScopedAStatus ComposerClient::getPreferredBootDisplayConfig(int64_t display, int32_t* config) {
380     DEBUG_DISPLAY_FUNC(display);
381     auto err = mHal->getPreferredBootDisplayConfig(display, config);
382     return TO_BINDER_STATUS(err);
383 }
384 
getHdrConversionCapabilities(std::vector<common::HdrConversionCapability> * hdrConversionCapabilities)385 ndk::ScopedAStatus ComposerClient::getHdrConversionCapabilities(
386         std::vector<common::HdrConversionCapability>* hdrConversionCapabilities) {
387     DEBUG_FUNC();
388     auto err = mHal->getHdrConversionCapabilities(hdrConversionCapabilities);
389     return TO_BINDER_STATUS(err);
390 }
391 
setHdrConversionStrategy(const common::HdrConversionStrategy & hdrConversionStrategy,common::Hdr * preferredHdrOutputType)392 ndk::ScopedAStatus ComposerClient::setHdrConversionStrategy(
393         const common::HdrConversionStrategy& hdrConversionStrategy,
394         common::Hdr* preferredHdrOutputType) {
395     DEBUG_FUNC();
396     auto err = mHal->setHdrConversionStrategy(hdrConversionStrategy, preferredHdrOutputType);
397     return TO_BINDER_STATUS(err);
398 }
399 
setAutoLowLatencyMode(int64_t display,bool on)400 ndk::ScopedAStatus ComposerClient::setAutoLowLatencyMode(int64_t display, bool on) {
401     DEBUG_DISPLAY_FUNC(display);
402     auto err = mHal->setAutoLowLatencyMode(display, on);
403     return TO_BINDER_STATUS(err);
404 }
405 
setClientTargetSlotCount(int64_t display,int32_t count)406 ndk::ScopedAStatus ComposerClient::setClientTargetSlotCount(int64_t display, int32_t count) {
407     DEBUG_DISPLAY_FUNC(display);
408     auto err = mResources->setDisplayClientTargetCacheSize(display, count);
409     return TO_BINDER_STATUS(err);
410 }
411 
setColorMode(int64_t display,ColorMode mode,RenderIntent intent)412 ndk::ScopedAStatus ComposerClient::setColorMode(int64_t display, ColorMode mode,
413                                                 RenderIntent intent) {
414     DEBUG_DISPLAY_FUNC(display);
415     auto err = mHal->setColorMode(display, mode, intent);
416     return TO_BINDER_STATUS(err);
417 }
418 
setContentType(int64_t display,ContentType type)419 ndk::ScopedAStatus ComposerClient::setContentType(int64_t display, ContentType type) {
420     DEBUG_DISPLAY_FUNC(display);
421     auto err = mHal->setContentType(display, type);
422     return TO_BINDER_STATUS(err);
423 }
424 
setDisplayedContentSamplingEnabled(int64_t display,bool enable,FormatColorComponent componentMask,int64_t maxFrames)425 ndk::ScopedAStatus ComposerClient::setDisplayedContentSamplingEnabled(
426         int64_t display, bool enable, FormatColorComponent componentMask, int64_t maxFrames) {
427     DEBUG_DISPLAY_FUNC(display);
428     auto err = mHal->setDisplayedContentSamplingEnabled(display, enable, componentMask, maxFrames);
429     return TO_BINDER_STATUS(err);
430 }
431 
setPowerMode(int64_t display,PowerMode mode)432 ndk::ScopedAStatus ComposerClient::setPowerMode(int64_t display, PowerMode mode) {
433     DEBUG_DISPLAY_FUNC(display);
434     auto err = mHal->setPowerMode(display, mode);
435     return TO_BINDER_STATUS(err);
436 }
437 
setReadbackBuffer(int64_t display,const AidlNativeHandle & aidlBuffer,const ndk::ScopedFileDescriptor & releaseFence)438 ndk::ScopedAStatus ComposerClient::setReadbackBuffer(
439         int64_t display, const AidlNativeHandle& aidlBuffer,
440         const ndk::ScopedFileDescriptor& releaseFence) {
441     DEBUG_DISPLAY_FUNC(display);
442     buffer_handle_t readbackBuffer;
443     // Note ownership of the buffer is not passed to resource manager.
444     buffer_handle_t buffer = ::android::makeFromAidl(aidlBuffer);
445     auto bufReleaser = mResources->createReleaser(true /* isBuffer */);
446     auto err = mResources->getDisplayReadbackBuffer(display, buffer,
447                                                     readbackBuffer, bufReleaser.get());
448     if (!err) {
449         err = mHal->setReadbackBuffer(display, readbackBuffer, releaseFence);
450     }
451     return TO_BINDER_STATUS(err);
452 }
453 
setVsyncEnabled(int64_t display,bool enabled)454 ndk::ScopedAStatus ComposerClient::setVsyncEnabled(int64_t display, bool enabled) {
455     DEBUG_DISPLAY_FUNC(display);
456     auto err = mHal->setVsyncEnabled(display, enabled);
457     return TO_BINDER_STATUS(err);
458 }
459 
setIdleTimerEnabled(int64_t display,int32_t timeout)460 ndk::ScopedAStatus ComposerClient::setIdleTimerEnabled(int64_t display, int32_t timeout) {
461     DEBUG_DISPLAY_FUNC(display);
462     auto err = mHal->setIdleTimerEnabled(display, timeout);
463     return TO_BINDER_STATUS(err);
464 }
465 
setRefreshRateChangedCallbackDebugEnabled(int64_t display,bool enabled)466 ndk::ScopedAStatus ComposerClient::setRefreshRateChangedCallbackDebugEnabled(int64_t display,
467                                                                              bool enabled) {
468     DEBUG_DISPLAY_FUNC(display);
469     auto err = mHal->setRefreshRateChangedCallbackDebugEnabled(display, enabled);
470     return TO_BINDER_STATUS(err);
471 }
472 
startHdcpNegotiation(int64_t display,const drm::HdcpLevels &)473 ndk::ScopedAStatus ComposerClient::startHdcpNegotiation(int64_t display,
474                                                         const drm::HdcpLevels& /*levels*/) {
475     DEBUG_DISPLAY_FUNC(display);
476     LOG(ERROR) << "not implemented";
477     return ndk::ScopedAStatus::fromStatus(EX_UNSUPPORTED_OPERATION);
478 }
479 
onRefreshRateChangedDebug(const RefreshRateChangedDebugData & data)480 void ComposerClient::HalEventCallback::onRefreshRateChangedDebug(
481         const RefreshRateChangedDebugData& data) {
482     DEBUG_DISPLAY_FUNC(data.display);
483     auto ret = mCallback->onRefreshRateChangedDebug(data);
484     if (!ret.isOk()) {
485         LOG(ERROR) << "failed to send onRefreshRateChangedDebug:" << ret.getDescription();
486     }
487 }
488 
onHotplug(int64_t display,bool connected)489 void ComposerClient::HalEventCallback::onHotplug(int64_t display, bool connected) {
490     DEBUG_DISPLAY_FUNC(display);
491     processDisplayResources(display, connected);
492     auto ret = mCallback->onHotplug(display, connected);
493     if (!ret.isOk()) {
494         LOG(ERROR) << "failed to send onHotplug:" << ret.getDescription();
495     }
496 }
497 
onRefresh(int64_t display)498 void ComposerClient::HalEventCallback::onRefresh(int64_t display) {
499     DEBUG_DISPLAY_FUNC(display);
500     mResources->setDisplayMustValidateState(display, true);
501     auto ret = mCallback->onRefresh(display);
502     if (!ret.isOk()) {
503         LOG(ERROR) << "failed to send onRefresh:" << ret.getDescription();
504     }
505 }
506 
onVsync(int64_t display,int64_t timestamp,int32_t vsyncPeriodNanos)507 void ComposerClient::HalEventCallback::onVsync(int64_t display, int64_t timestamp,
508                                                int32_t vsyncPeriodNanos) {
509     DEBUG_DISPLAY_FUNC(display);
510     auto ret = mCallback->onVsync(display, timestamp, vsyncPeriodNanos);
511     if (!ret.isOk()) {
512         LOG(ERROR) << "failed to send onVsync:" << ret.getDescription();
513     }
514 }
515 
onVsyncPeriodTimingChanged(int64_t display,const VsyncPeriodChangeTimeline & timeline)516 void ComposerClient::HalEventCallback::onVsyncPeriodTimingChanged(
517         int64_t display, const VsyncPeriodChangeTimeline& timeline) {
518     DEBUG_DISPLAY_FUNC(display);
519     auto ret = mCallback->onVsyncPeriodTimingChanged(display, timeline);
520     if (!ret.isOk()) {
521         LOG(ERROR) << "failed to send onVsyncPeriodTimingChanged:" << ret.getDescription();
522     }
523 }
524 
onVsyncIdle(int64_t display)525 void ComposerClient::HalEventCallback::onVsyncIdle(int64_t display) {
526     DEBUG_DISPLAY_FUNC(display);
527     auto ret = mCallback->onVsyncIdle(display);
528     if (!ret.isOk()) {
529         LOG(ERROR) << "failed to send onVsyncIdle:" << ret.getDescription();
530     }
531 }
532 
onSeamlessPossible(int64_t display)533 void ComposerClient::HalEventCallback::onSeamlessPossible(int64_t display) {
534     DEBUG_DISPLAY_FUNC(display);
535     auto ret = mCallback->onSeamlessPossible(display);
536     if (!ret.isOk()) {
537         LOG(ERROR) << "failed to send onSealmessPossible:" << ret.getDescription();
538     }
539 }
540 
onHotplugEvent(int64_t display,common::DisplayHotplugEvent event)541 void ComposerClient::HalEventCallback::onHotplugEvent(int64_t display,
542                                                       common::DisplayHotplugEvent event) {
543     DEBUG_DISPLAY_FUNC(display);
544     processDisplayResources(display, event == common::DisplayHotplugEvent::CONNECTED);
545     auto ret = mCallback->onHotplugEvent(display, event);
546     if (!ret.isOk()) {
547         LOG(ERROR) << "failed to send onHotplugEvent:" << ret.getDescription();
548     }
549 }
550 
onHdcpLevelsChanged(int64_t display,drm::HdcpLevels levels)551 void ComposerClient::HalEventCallback::onHdcpLevelsChanged(int64_t display,
552                                                            drm::HdcpLevels levels) {
553     DEBUG_DISPLAY_FUNC(display);
554     auto ret = mCallback->onHdcpLevelsChanged(display, levels);
555     if (!ret.isOk()) {
556         LOG(ERROR) << "failed to send onHdcpLevelsChanged:" << ret.getDescription();
557     }
558 }
559 
processDisplayResources(int64_t display,bool connected)560 void ComposerClient::HalEventCallback::processDisplayResources(int64_t display, bool connected) {
561     if (connected) {
562         if (mResources->hasDisplay(display)) {
563             // This is a subsequent hotplug "connected" for a display. This signals a
564             // display change and thus the framework may want to reallocate buffers. We
565             // need to free all cached handles, since they are holding a strong reference
566             // to the underlying buffers.
567             cleanDisplayResources(display);
568             mResources->removeDisplay(display);
569         }
570         mResources->addPhysicalDisplay(display);
571     } else {
572         mResources->removeDisplay(display);
573     }
574 }
575 
cleanDisplayResources(int64_t display)576 void ComposerClient::HalEventCallback::cleanDisplayResources(int64_t display) {
577     DEBUG_DISPLAY_FUNC(display);
578     size_t cacheSize;
579     auto err = mResources->getDisplayClientTargetCacheSize(display, &cacheSize);
580     if (!err) {
581         for (int slot = 0; slot < cacheSize; slot++) {
582             // Replace the buffer slots with NULLs. Keep the old handle until it is
583             // replaced in ComposerHal, otherwise we risk leaving a dangling pointer.
584             buffer_handle_t outHandle;
585             auto bufReleaser = mResources->createReleaser(true /* isBuffer */);
586             err = mResources->getDisplayClientTarget(display, slot, /*useCache*/ true,
587                                                     /*rawHandle*/ nullptr, outHandle,
588                                                     bufReleaser.get());
589             if (err) {
590                 continue;
591             }
592             const std::vector<common::Rect> damage;
593             ndk::ScopedFileDescriptor fence; // empty fence
594             common::Dataspace dataspace = common::Dataspace::UNKNOWN;
595             err = mHal->setClientTarget(display, outHandle, fence, dataspace, damage);
596             if (err) {
597                 LOG(ERROR) << "Can't clean slot " << slot
598                            << " of the client target buffer cache for display" << display;
599             }
600         }
601     } else {
602         LOG(ERROR) << "Can't clean client target cache for display " << display;
603     }
604 
605     err = mResources->getDisplayOutputBufferCacheSize(display, &cacheSize);
606     if (!err) {
607         for (int slot = 0; slot < cacheSize; slot++) {
608             // Replace the buffer slots with NULLs. Keep the old handle until it is
609             // replaced in ComposerHal, otherwise we risk leaving a dangling pointer.
610             buffer_handle_t outputBuffer;
611             auto bufReleaser = mResources->createReleaser(true /* isBuffer */);
612             err = mResources->getDisplayOutputBuffer(display, slot, /*useCache*/ true,
613                                                     /*rawHandle*/ nullptr, outputBuffer,
614                                                     bufReleaser.get());
615             if (err) {
616                 continue;
617             }
618             ndk::ScopedFileDescriptor emptyFd;
619             err = mHal->setOutputBuffer(display, outputBuffer, /*fence*/ emptyFd);
620             if (err) {
621                 LOG(ERROR) << "Can't clean slot " << slot
622                            << " of the output buffer cache for display " << display;
623             }
624         }
625     } else {
626         LOG(ERROR) << "Can't clean output buffer cache for display " << display;
627     }
628 }
629 
destroyResources()630 void ComposerClient::destroyResources() {
631     DEBUG_FUNC();
632     // We want to call hwc2_close here (and move hwc2_open to the
633     // constructor), with the assumption that hwc2_close would
634     //
635     //  - clean up all resources owned by the client
636     //  - make sure all displays are blank (since there is no layer)
637     //
638     // But since SF used to crash at this point, different hwcomposer2
639     // implementations behave differently on hwc2_close.  Our only portable
640     // choice really is to abort().  But that is not an option anymore
641     // because we might also have VTS or VR as clients that can come and go.
642     //
643     // Below we manually clean all resources (layers and virtual
644     // displays), and perform a presentDisplay afterwards.
645     mResources->clear([this](int64_t display, bool isVirtual, const std::vector<int64_t> layers) {
646         LOG(WARNING) << "destroying client resources for display " << display;
647         for (auto layer : layers) {
648             mHal->destroyLayer(display, layer);
649         }
650 
651         if (isVirtual) {
652             mHal->destroyVirtualDisplay(display);
653         } else {
654             LOG(WARNING) << "performing a final presentDisplay";
655             std::vector<int64_t> changedLayers;
656             std::vector<Composition> compositionTypes;
657             uint32_t displayRequestMask = 0;
658             std::vector<int64_t> requestedLayers;
659             std::vector<int32_t> requestMasks;
660             ClientTargetProperty clientTargetProperty;
661             DimmingStage dimmingStage;
662             mHal->validateDisplay(display, &changedLayers, &compositionTypes, &displayRequestMask,
663                                   &requestedLayers, &requestMasks, &clientTargetProperty,
664                                   &dimmingStage);
665             mHal->acceptDisplayChanges(display);
666 
667             ndk::ScopedFileDescriptor presentFence;
668             std::vector<int64_t> releasedLayers;
669             std::vector<ndk::ScopedFileDescriptor> releaseFences;
670             mHal->presentDisplay(display, presentFence, &releasedLayers, &releaseFences);
671         }
672     });
673     mResources.reset();
674 }
675 
createBinder()676 ::ndk::SpAIBinder ComposerClient::createBinder() {
677     auto binder = BnComposerClient::createBinder();
678     AIBinder_setInheritRt(binder.get(), true);
679     return binder;
680 }
681 
682 } // namespace aidl::android::hardware::graphics::composer3::impl
683