• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
3  * Not a Contribution.
4  *
5  * Copyright (C) 2017 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #include <vector>
21 #include <string>
22 
23 #include "QtiComposerClient.h"
24 
25 namespace vendor {
26 namespace qti {
27 namespace hardware {
28 namespace display {
29 namespace composer {
30 namespace V3_0 {
31 namespace implementation {
32 
33 ComposerHandleImporter mHandleImporter;
34 
BufferCacheEntry()35 BufferCacheEntry::BufferCacheEntry() : mHandle(nullptr) {}
36 
BufferCacheEntry(BufferCacheEntry && other)37 BufferCacheEntry::BufferCacheEntry(BufferCacheEntry&& other) {
38   mHandle = other.mHandle;
39   other.mHandle = nullptr;
40 }
41 
operator =(buffer_handle_t handle)42 BufferCacheEntry& BufferCacheEntry::operator=(buffer_handle_t handle) {
43   clear();
44   mHandle = handle;
45   return *this;
46 }
47 
~BufferCacheEntry()48 BufferCacheEntry::~BufferCacheEntry() {
49   clear();
50 }
51 
clear()52 void BufferCacheEntry::clear() {
53   if (mHandle) {
54     mHandleImporter.freeBuffer(mHandle);
55   }
56 }
57 
QtiComposerClient()58 QtiComposerClient::QtiComposerClient() : mWriter(kWriterInitialSize), mReader(*this) {
59   hwc_session_ = HWCSession::GetInstance();
60   mHandleImporter.initialize();
61 }
62 
~QtiComposerClient()63 QtiComposerClient::~QtiComposerClient() {
64   // We want to call hwc2_close here (and move hwc2_open to the
65   // constructor), with the assumption that hwc2_close would
66   //
67   //  - clean up all resources owned by the client
68   //  - make sure all displays are blank (since there is no layer)
69   //
70   // But since SF used to crash at this point, different hwcomposer2
71   // implementations behave differently on hwc2_close.  Our only portable
72   // choice really is to abort().  But that is not an option anymore
73   // because we might also have VTS or VR as clients that can come and go.
74   //
75   // Below we manually clean all resources (layers and virtual
76   // displays), and perform a presentDisplay afterwards.
77   ALOGW("destroying composer client");
78 
79   enableCallback(false);
80 
81   // no need to grab the mutex as any in-flight hwbinder call would have
82   // kept the client alive
83   for (const auto& dpy : mDisplayData) {
84     ALOGW("destroying client resources for display %" PRIu64, dpy.first);
85 
86     for (const auto& ly : dpy.second.Layers) {
87       hwc_session_->DestroyLayer(dpy.first, ly.first);
88     }
89 
90     if (dpy.second.IsVirtual) {
91       destroyVirtualDisplay(dpy.first);
92     } else {
93       ALOGW("performing a final presentDisplay");
94 
95       std::vector<Layer> changedLayers;
96       std::vector<IComposerClient::Composition> compositionTypes;
97       uint32_t displayRequestMask = 0;
98       std::vector<Layer> requestedLayers;
99       std::vector<uint32_t> requestMasks;
100       IComposerClient::ClientTargetProperty clientTargetProperty;
101       mReader.validateDisplay(dpy.first, changedLayers, compositionTypes, displayRequestMask,
102                               requestedLayers, requestMasks, clientTargetProperty);
103 
104       hwc_session_->AcceptDisplayChanges(dpy.first);
105 
106       shared_ptr<Fence> presentFence = nullptr;
107       std::vector<Layer> releasedLayers;
108       std::vector<shared_ptr<Fence>> releaseFences;
109       mReader.presentDisplay(dpy.first, &presentFence, releasedLayers, releaseFences);
110     }
111   }
112 
113   mDisplayData.clear();
114 
115   mHandleImporter.cleanup();
116 
117   ALOGW("removed composer client");
118 }
119 
onHotplug(hwc2_callback_data_t callbackData,hwc2_display_t display,int32_t connected)120 void QtiComposerClient::onHotplug(hwc2_callback_data_t callbackData, hwc2_display_t display,
121                                     int32_t connected) {
122   auto client = reinterpret_cast<QtiComposerClient*>(callbackData);
123   auto connect = static_cast<composer_V2_4::IComposerCallback::Connection>(connected);
124   if (connect == composer_V2_4::IComposerCallback::Connection::CONNECTED) {
125     std::lock_guard<std::mutex> lock_d(client->mDisplayDataMutex);
126     client->mDisplayData.emplace(display, DisplayData(false));
127   }
128 
129   auto ret = client->callback_->onHotplug(display, connect);
130   ALOGW_IF(!ret.isOk(), "failed to send onHotplug: %s. SF likely unavailable.",
131            ret.description().c_str());
132 
133   if (connect == composer_V2_4::IComposerCallback::Connection::DISCONNECTED) {
134     // Trigger refresh to make sure disconnect event received/updated properly by SurfaceFlinger.
135     client->hwc_session_->Refresh(HWC_DISPLAY_PRIMARY);
136     // Wait for sufficient time to ensure sufficient resources are available to process connection.
137     uint32_t vsync_period;
138     client->hwc_session_->GetVsyncPeriod(HWC_DISPLAY_PRIMARY, &vsync_period);
139     usleep(vsync_period * 2 / 1000);
140 
141     // Wait for the input command message queue to process before destroying the local display data.
142     std::lock_guard<std::mutex> lock(client->mCommandMutex);
143     std::lock_guard<std::mutex> lock_d(client->mDisplayDataMutex);
144     client->mDisplayData.erase(display);
145   }
146 }
147 
onRefresh(hwc2_callback_data_t callbackData,hwc2_display_t display)148 void QtiComposerClient::onRefresh(hwc2_callback_data_t callbackData, hwc2_display_t display) {
149   auto client = reinterpret_cast<QtiComposerClient*>(callbackData);
150   auto ret = client->callback_->onRefresh(display);
151   ALOGW_IF(!ret.isOk(), "failed to send onRefresh: %s. SF likely unavailable.",
152            ret.description().c_str());
153 }
154 
onVsync(hwc2_callback_data_t callbackData,hwc2_display_t display,int64_t timestamp)155 void QtiComposerClient::onVsync(hwc2_callback_data_t callbackData, hwc2_display_t display,
156                                 int64_t timestamp) {
157   auto client = reinterpret_cast<QtiComposerClient*>(callbackData);
158   auto ret = client->callback_->onVsync(display, timestamp);
159   ALOGW_IF(!ret.isOk(), "failed to send onVsync: %s. SF likely unavailable.",
160            ret.description().c_str());
161 }
162 
onVsync_2_4(hwc2_callback_data_t callbackData,hwc2_display_t display,int64_t timestamp,VsyncPeriodNanos vsyncPeriodNanos)163 void QtiComposerClient::onVsync_2_4(hwc2_callback_data_t callbackData, hwc2_display_t display,
164                                     int64_t timestamp, VsyncPeriodNanos vsyncPeriodNanos) {
165   auto client = reinterpret_cast<QtiComposerClient*>(callbackData);
166   auto ret = client->callback24_->onVsync_2_4(display, timestamp, vsyncPeriodNanos);
167   ALOGW_IF(!ret.isOk(), "failed to send onVsync_2_4: %s. SF likely unavailable.",
168            ret.description().c_str());
169 }
170 
onVsyncPeriodTimingChanged(hwc2_callback_data_t callbackData,hwc2_display_t display,hwc_vsync_period_change_timeline_t * updatedTimeline)171 void QtiComposerClient::onVsyncPeriodTimingChanged(hwc2_callback_data_t callbackData,
172       hwc2_display_t display, hwc_vsync_period_change_timeline_t *updatedTimeline) {
173    VsyncPeriodChangeTimeline timeline =
174                                    {updatedTimeline->newVsyncAppliedTimeNanos,
175                                     static_cast<bool>(updatedTimeline->refreshRequired),
176                                     updatedTimeline->refreshTimeNanos};
177 
178   auto client = reinterpret_cast<QtiComposerClient*>(callbackData);
179   auto ret = client->callback24_->onVsyncPeriodTimingChanged(display, timeline);
180   ALOGW_IF(!ret.isOk(), "failed to send onVsyncPeriodTimingChanged: %s. SF likely unavailable.",
181           ret.description().c_str());
182 }
183 
onSeamlessPossible(hwc2_callback_data_t callbackData,hwc2_display_t display)184 void QtiComposerClient::onSeamlessPossible(hwc2_callback_data_t callbackData,
185                                            hwc2_display_t display) {
186   auto client = reinterpret_cast<QtiComposerClient*>(callbackData);
187   auto ret = client->callback24_->onSeamlessPossible(display);
188   ALOGW_IF(!ret.isOk(), "failed to send onSeamlessPossible: %s. SF likely unavailable.",
189            ret.description().c_str());
190 }
191 
192 // convert fenceFd to or from hidl_handle
193 // Handle would still own original fence. Hence create a Fence object on duped fd.
getFence(const hidl_handle & fenceHandle,shared_ptr<Fence> * outFence,const string & name)194 Error QtiComposerClient::getFence(const hidl_handle& fenceHandle, shared_ptr<Fence>* outFence,
195                                   const string& name) {
196   auto handle = fenceHandle.getNativeHandle();
197   if (handle && handle->numFds > 1) {
198     ALOGE("invalid fence handle with %d fds", handle->numFds);
199     return Error::BAD_PARAMETER;
200   }
201 
202   int fenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1;
203   *outFence = Fence::Create(dup(fenceFd), name);
204 
205   return Error::NONE;
206 }
207 
208 // Handle would own fence hereafter. Hence provide a dupped fd.
getFenceHandle(const shared_ptr<Fence> & fence,char * handleStorage)209 hidl_handle QtiComposerClient::getFenceHandle(const shared_ptr<Fence>& fence,
210                                               char* handleStorage) {
211   native_handle_t* handle = nullptr;
212   if (fence) {
213     handle = native_handle_init(handleStorage, 1, 0);
214     if (handle) {
215       handle->data[0] = Fence::Dup(fence);
216     }
217   }
218 
219   return hidl_handle(handle);
220 }
221 
getDisplayReadbackBuffer(Display display,const native_handle_t * rawHandle,const native_handle_t ** outHandle)222 Error QtiComposerClient::getDisplayReadbackBuffer(Display display,
223                                                   const native_handle_t* rawHandle,
224                                                   const native_handle_t** outHandle) {
225   // TODO(user): revisit for caching and freeBuffer in success case.
226   if (!mHandleImporter.importBuffer(rawHandle)) {
227     ALOGE("%s: importBuffer failed: ", __FUNCTION__);
228     return Error::NO_RESOURCES;
229   }
230 
231   std::lock_guard<std::mutex> lock(mDisplayDataMutex);
232   auto iter = mDisplayData.find(display);
233   if (iter == mDisplayData.end()) {
234     mHandleImporter.freeBuffer(rawHandle);
235     return Error::BAD_DISPLAY;
236   }
237 
238   *outHandle = rawHandle;
239   return Error::NONE;
240 }
241 
getCapabilities()242 void QtiComposerClient::getCapabilities() {
243   uint32_t count = 0;
244   hwc_session_->GetCapabilities(&count, nullptr);
245 
246   std::vector<int32_t> composer_caps(count);
247   hwc_session_->GetCapabilities(&count, composer_caps.data());
248   composer_caps.resize(count);
249 
250   mCapabilities.reserve(count);
251   for (auto cap : composer_caps) {
252     mCapabilities.insert(static_cast<hwc2_capability_t>(cap));
253   }
254 }
255 
enableCallback(bool enable)256 void QtiComposerClient::enableCallback(bool enable) {
257   if (enable) {
258     hwc_session_->RegisterCallback(HWC2_CALLBACK_HOTPLUG, this,
259                                    reinterpret_cast<hwc2_function_pointer_t>(onHotplug));
260     hwc_session_->RegisterCallback(HWC2_CALLBACK_REFRESH, this,
261                                    reinterpret_cast<hwc2_function_pointer_t>(onRefresh));
262     if (!mUseCallback24_) {
263       hwc_session_->RegisterCallback(HWC2_CALLBACK_VSYNC, this,
264                                      reinterpret_cast<hwc2_function_pointer_t>(onVsync));
265     } else {
266       hwc_session_->RegisterCallback(HWC2_CALLBACK_VSYNC_2_4, this,
267                                      reinterpret_cast<hwc2_function_pointer_t>(onVsync_2_4));
268       hwc_session_->RegisterCallback(HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED, this,
269                              reinterpret_cast<hwc2_function_pointer_t>(onVsyncPeriodTimingChanged));
270       hwc_session_->RegisterCallback(HWC2_CALLBACK_SEAMLESS_POSSIBLE, this,
271                                      reinterpret_cast<hwc2_function_pointer_t>(onSeamlessPossible));
272     }
273   } else {
274     hwc_session_->RegisterCallback(HWC2_CALLBACK_HOTPLUG, this, nullptr);
275     hwc_session_->RegisterCallback(HWC2_CALLBACK_REFRESH, this, nullptr);
276     if (!mUseCallback24_) {
277       hwc_session_->RegisterCallback(HWC2_CALLBACK_VSYNC, this, nullptr);
278     } else {
279       hwc_session_->RegisterCallback(HWC2_CALLBACK_VSYNC_2_4, this, nullptr);
280       hwc_session_->RegisterCallback(HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED, this, nullptr);
281       hwc_session_->RegisterCallback(HWC2_CALLBACK_SEAMLESS_POSSIBLE, this, nullptr);
282     }
283   }
284 }
285 
286 // Methods from ::android::hardware::graphics::composer::V2_1::IComposerClient follow.
registerCallback(const sp<composer_V2_1::IComposerCallback> & callback)287 Return<void> QtiComposerClient::registerCallback(
288                                             const sp<composer_V2_1::IComposerCallback>& callback) {
289   callback_ = callback;
290   enableCallback(callback != nullptr);
291   return Void();
292 }
293 
getMaxVirtualDisplayCount()294 Return<uint32_t> QtiComposerClient::getMaxVirtualDisplayCount() {
295   return hwc_session_->GetMaxVirtualDisplayCount();
296 }
297 
createVirtualDisplay(uint32_t width,uint32_t height,common_V1_0::PixelFormat formatHint,uint32_t outputBufferSlotCount,createVirtualDisplay_cb _hidl_cb)298 Return<void> QtiComposerClient::createVirtualDisplay(uint32_t width, uint32_t height,
299                                                      common_V1_0::PixelFormat formatHint,
300                                                      uint32_t outputBufferSlotCount,
301                                                      createVirtualDisplay_cb _hidl_cb) {
302   // TODO(user): Implement combinedly w.r.t createVirtualDisplay_2_2
303   int32_t format = static_cast<int32_t>(formatHint);
304   uint64_t display;
305   auto error = hwc_session_->CreateVirtualDisplay(width, height, &format, &display);
306 
307   if (static_cast<Error>(error) == Error::NONE) {
308     std::lock_guard<std::mutex> lock(mDisplayDataMutex);
309 
310     auto dpy = mDisplayData.emplace(static_cast<Display>(display), DisplayData(true)).first;
311     dpy->second.OutputBuffers.resize(outputBufferSlotCount);
312   }
313 
314   _hidl_cb(static_cast<Error>(error), display, static_cast<common_V1_0::PixelFormat>(format));
315   return Void();
316 }
317 
destroyVirtualDisplay(uint64_t display)318 Return<composer_V2_1::Error> QtiComposerClient::destroyVirtualDisplay(uint64_t display) {
319   auto error = hwc_session_->DestroyVirtualDisplay(display);
320   if (static_cast<Error>(error) == Error::NONE) {
321     std::lock_guard<std::mutex> lock(mDisplayDataMutex);
322 
323     mDisplayData.erase(display);
324   }
325 
326   return static_cast<Error>(error);
327 }
328 
createLayer(uint64_t display,uint32_t bufferSlotCount,createLayer_cb _hidl_cb)329 Return<void> QtiComposerClient::createLayer(uint64_t display, uint32_t bufferSlotCount,
330                                             createLayer_cb _hidl_cb) {
331   composer_V2_1::Layer layer = 0;
332   auto error = hwc_session_->CreateLayer(display, &layer);
333   Error err = static_cast<Error>(error);
334   if (err == Error::NONE) {
335     std::lock_guard<std::mutex> lock(mDisplayDataMutex);
336     auto dpy = mDisplayData.find(display);
337     // The display entry may have already been removed by onHotplug.
338     if (dpy != mDisplayData.end()) {
339       auto ly = dpy->second.Layers.emplace(layer, LayerBuffers()).first;
340       ly->second.Buffers.resize(bufferSlotCount);
341     } else {
342       err = Error::BAD_DISPLAY;
343       // Note: We do not destroy the layer on this error as the hotplug
344       // disconnect invalidates the display id. The implementation should
345       // ensure all layers for the display are destroyed.
346     }
347   }
348 
349   _hidl_cb(err, layer);
350   return Void();
351 }
352 
destroyLayer(uint64_t display,uint64_t layer)353 Return<Error> QtiComposerClient::destroyLayer(uint64_t display, uint64_t layer) {
354   auto error = hwc_session_->DestroyLayer(display, layer);
355   Error err = static_cast<Error>(error);
356   if (err == Error::NONE) {
357     std::lock_guard<std::mutex> lock(mDisplayDataMutex);
358 
359     auto dpy = mDisplayData.find(display);
360     // The display entry may have already been removed by onHotplug.
361     if (dpy != mDisplayData.end()) {
362       dpy->second.Layers.erase(layer);
363     }
364   }
365 
366   return static_cast<Error>(error);
367 }
368 
getActiveConfig(uint64_t display,getActiveConfig_cb _hidl_cb)369 Return<void> QtiComposerClient::getActiveConfig(uint64_t display, getActiveConfig_cb _hidl_cb) {
370   uint32_t config = 0;
371   auto error = hwc_session_->GetActiveConfig(display, &config);
372 
373   _hidl_cb(static_cast<Error>(error), config);
374 
375   return Void();
376 }
377 
getClientTargetSupport(uint64_t display,uint32_t width,uint32_t height,common_V1_0::PixelFormat format,common_V1_0::Dataspace dataspace)378 Return<Error> QtiComposerClient::getClientTargetSupport(uint64_t display, uint32_t width,
379                                                         uint32_t height,
380                                                         common_V1_0::PixelFormat format,
381                                                         common_V1_0::Dataspace dataspace) {
382   auto error = hwc_session_->GetClientTargetSupport(display, width, height,
383                                                     static_cast<int32_t>(format),
384                                                     static_cast<int32_t>(dataspace));
385 
386   return static_cast<Error>(error);
387 }
388 
getColorModes(uint64_t display,getColorModes_cb _hidl_cb)389 Return<void> QtiComposerClient::getColorModes(uint64_t display, getColorModes_cb _hidl_cb) {
390   // TODO(user): Implement combinedly w.r.t getColorModes_2_3
391   hidl_vec<common_V1_0::ColorMode> modes;
392   uint32_t count = 0;
393 
394   auto error = hwc_session_->GetColorModes(display, &count, nullptr);
395   if (error != HWC2_ERROR_NONE) {
396     _hidl_cb(static_cast<Error>(error), modes);
397     return Void();
398   }
399 
400   modes.resize(count);
401   error = hwc_session_->GetColorModes(display, &count,
402               reinterpret_cast<std::underlying_type<common_V1_0::ColorMode>::type*>(modes.data()));
403 
404   _hidl_cb(static_cast<Error>(error), modes);
405   return Void();
406 }
407 
getDisplayAttribute(uint64_t display,uint32_t config,composer_V2_1::IComposerClient::Attribute attribute,getDisplayAttribute_cb _hidl_cb)408 Return<void> QtiComposerClient::getDisplayAttribute(uint64_t display, uint32_t config,
409                                                composer_V2_1::IComposerClient::Attribute attribute,
410                                                getDisplayAttribute_cb _hidl_cb) {
411   int32_t value = 0;
412   auto error = hwc_session_->GetDisplayAttribute(
413       display, config, static_cast<composer_V2_4::IComposerClient::Attribute>(attribute), &value);
414 
415   _hidl_cb(static_cast<Error>(error), value);
416   return Void();
417 }
418 
getDisplayConfigs(uint64_t display,getDisplayConfigs_cb _hidl_cb)419 Return<void> QtiComposerClient::getDisplayConfigs(uint64_t display,
420                                                   getDisplayConfigs_cb _hidl_cb) {
421   hidl_vec<uint32_t> configs;
422   uint32_t count = 0;
423 
424   auto error = hwc_session_->GetDisplayConfigs(display, &count, nullptr);
425   if (error != HWC2_ERROR_NONE) {
426     _hidl_cb(static_cast<Error>(error), configs);
427     return Void();
428   }
429 
430   configs.resize(count);
431   error = hwc_session_->GetDisplayConfigs(display, &count, configs.data());
432 
433   _hidl_cb(static_cast<Error>(error), configs);
434   return Void();
435 }
436 
getDisplayName(uint64_t display,getDisplayName_cb _hidl_cb)437 Return<void> QtiComposerClient::getDisplayName(uint64_t display, getDisplayName_cb _hidl_cb) {
438   uint32_t count = 0;
439   hidl_string name_reply;
440   std::vector<char> name;
441 
442   auto error = hwc_session_->GetDisplayName(display, &count, nullptr);
443   if (error != HWC2_ERROR_NONE) {
444     _hidl_cb(static_cast<Error>(error), name_reply);
445     return Void();
446   }
447 
448   name.resize(count + 1);
449   error = hwc_session_->GetDisplayName(display, &count, name.data());
450   if (error != HWC2_ERROR_NONE) {
451     _hidl_cb(static_cast<Error>(error), name_reply);
452     return Void();
453   }
454 
455   name.resize(count + 1);
456   name[count] = '\0';
457   name_reply.setToExternal(name.data(), count);
458 
459   _hidl_cb(static_cast<Error>(error), name_reply);
460   return Void();
461 }
462 
getDisplayType(uint64_t display,getDisplayType_cb _hidl_cb)463 Return<void> QtiComposerClient::getDisplayType(uint64_t display, getDisplayType_cb _hidl_cb) {
464   int32_t hwc_type;
465   auto error = hwc_session_->GetDisplayType(display, &hwc_type);
466 
467   _hidl_cb(static_cast<Error>(error), static_cast<IComposerClient::DisplayType>(hwc_type));
468   return Void();
469 }
470 
getDozeSupport(uint64_t display,getDozeSupport_cb _hidl_cb)471 Return<void> QtiComposerClient::getDozeSupport(uint64_t display, getDozeSupport_cb _hidl_cb) {
472   int32_t hwc_support = 0;
473   auto error = hwc_session_->GetDozeSupport(display, &hwc_support);
474 
475   _hidl_cb(static_cast<Error>(error), hwc_support);
476   return Void();
477 }
478 
getHdrCapabilities(uint64_t display,getHdrCapabilities_cb _hidl_cb)479 Return<void> QtiComposerClient::getHdrCapabilities(uint64_t display,
480                                                    getHdrCapabilities_cb _hidl_cb) {
481   // TODO(user): Implement combinedly w.r.t getHdrCapabilities_2_3
482   uint32_t count = 0;
483   hidl_vec<common_V1_0::Hdr> types;
484   float max_lumi = 0.0f;
485   float max_avg_lumi = 0.0f;
486   float min_lumi = 0.0f;
487 
488   auto error = hwc_session_->GetHdrCapabilities(display, &count, nullptr, &max_lumi,
489                                                 &max_avg_lumi, &min_lumi);
490   if (error != HWC2_ERROR_NONE) {
491     _hidl_cb(static_cast<Error>(error), types, max_lumi, max_avg_lumi, min_lumi);
492     return Void();
493   }
494 
495   types.resize(count);
496   error = hwc_session_->GetHdrCapabilities(display, &count,
497            reinterpret_cast<std::underlying_type<common_V1_2::Hdr>::type*>(types.data()),
498            &max_lumi, &max_avg_lumi, &min_lumi);
499 
500   _hidl_cb(static_cast<Error>(error), types, max_lumi, max_avg_lumi, min_lumi);
501   return Void();
502 }
503 
setClientTargetSlotCount(uint64_t display,uint32_t clientTargetSlotCount)504 Return<Error> QtiComposerClient::setClientTargetSlotCount(uint64_t display,
505                                                           uint32_t clientTargetSlotCount) {
506   std::lock_guard<std::mutex> lock(mDisplayDataMutex);
507 
508   auto dpy = mDisplayData.find(display);
509   if (dpy == mDisplayData.end()) {
510     return Error::BAD_DISPLAY;
511   }
512   dpy->second.ClientTargets.resize(clientTargetSlotCount);
513 
514   return Error::NONE;
515 }
516 
setActiveConfig(uint64_t display,uint32_t config)517 Return<Error> QtiComposerClient::setActiveConfig(uint64_t display, uint32_t config) {
518   auto error = hwc_session_->SetActiveConfig(display, config);
519 
520   return static_cast<Error>(error);
521 }
522 
setColorMode(uint64_t display,common_V1_0::ColorMode mode)523 Return<Error> QtiComposerClient::setColorMode(uint64_t display, common_V1_0::ColorMode mode) {
524   auto error = hwc_session_->SetColorMode(display, static_cast<int32_t>(mode));
525 
526   return static_cast<Error>(error);
527 }
528 
setPowerMode(uint64_t display,composer_V2_1::IComposerClient::PowerMode mode)529 Return<Error> QtiComposerClient::setPowerMode(uint64_t display,
530                                               composer_V2_1::IComposerClient::PowerMode mode) {
531   // TODO(user): Implement combinedly w.r.t setPowerMode_2_2
532   auto error = hwc_session_->SetPowerMode(display, static_cast<int32_t>(mode));
533 
534   return static_cast<Error>(error);
535 }
536 
setVsyncEnabled(uint64_t display,composer_V2_1::IComposerClient::Vsync enabled)537 Return<Error> QtiComposerClient::setVsyncEnabled(uint64_t display,
538                                                  composer_V2_1::IComposerClient::Vsync enabled) {
539   auto error = hwc_session_->SetVsyncEnabled(display, static_cast<int32_t>(enabled));
540 
541   return static_cast<Error>(error);
542 }
543 
setInputCommandQueue(const MQDescriptorSync<uint32_t> & descriptor)544 Return<Error> QtiComposerClient::setInputCommandQueue(
545                                                     const MQDescriptorSync<uint32_t>& descriptor) {
546   std::lock_guard<std::mutex> lock(mCommandMutex);
547   return mReader.setMQDescriptor(descriptor) ? Error::NONE : Error::NO_RESOURCES;
548 }
549 
getOutputCommandQueue(getOutputCommandQueue_cb _hidl_cb)550 Return<void> QtiComposerClient::getOutputCommandQueue(getOutputCommandQueue_cb _hidl_cb) {
551   // no locking as we require this function to be called inside
552   // executeCommands_cb
553 
554   auto outDescriptor = mWriter.getMQDescriptor();
555   if (outDescriptor) {
556     _hidl_cb(Error::NONE, *outDescriptor);
557   } else {
558     _hidl_cb(Error::NO_RESOURCES, MQDescriptorSync<uint32_t>());
559   }
560 
561   return Void();
562 }
563 
executeCommands(uint32_t inLength,const hidl_vec<hidl_handle> & inHandles,executeCommands_cb _hidl_cb)564 Return<void> QtiComposerClient::executeCommands(uint32_t inLength,
565                                                 const hidl_vec<hidl_handle>& inHandles,
566                                                 executeCommands_cb _hidl_cb) {
567   std::lock_guard<std::mutex> lock(mCommandMutex);
568 
569   bool outChanged = false;
570   uint32_t outLength = 0;
571   hidl_vec<hidl_handle> outHandles;
572 
573   if (!mReader.readQueue(inLength, inHandles)) {
574     _hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
575     return Void();
576   }
577 
578   Error err = mReader.parse();
579   if (err == Error::NONE &&
580       !mWriter.writeQueue(outChanged, outLength, outHandles)) {
581     err = Error::NO_RESOURCES;
582   }
583 
584   _hidl_cb(Error::NONE, outChanged, outLength, outHandles);
585 
586   mReader.reset();
587   mWriter.reset();
588 
589   return Void();
590 }
591 
592 
593 // Methods from ::android::hardware::graphics::composer::V2_2::IComposerClient follow.
getPerFrameMetadataKeys(uint64_t display,getPerFrameMetadataKeys_cb _hidl_cb)594 Return<void> QtiComposerClient::getPerFrameMetadataKeys(uint64_t display,
595                                                         getPerFrameMetadataKeys_cb _hidl_cb) {
596   // TODO(user): Implement combinedly w.r.t getPerFrameMetadataKeys_2_3
597   std::vector<PerFrameMetadataKey_V2> keys;
598   uint32_t count = 0;
599 
600   auto error = hwc_session_->GetPerFrameMetadataKeys(display, &count, nullptr);
601   if (error != HWC2_ERROR_NONE) {
602     _hidl_cb(static_cast<Error>(error), keys);
603     return Void();
604   }
605 
606   keys.resize(count);
607   error = hwc_session_->GetPerFrameMetadataKeys(display, &count,
608                reinterpret_cast<std::underlying_type<PerFrameMetadataKey_V2>::type*>(keys.data()));
609 
610   _hidl_cb(static_cast<Error>(error), keys);
611   return Void();
612 }
613 
getReadbackBufferAttributes(uint64_t display,getReadbackBufferAttributes_cb _hidl_cb)614 Return<void> QtiComposerClient::getReadbackBufferAttributes(uint64_t display,
615                                                          getReadbackBufferAttributes_cb _hidl_cb) {
616   // TODO(user): Implement combinedly w.r.t getReadbackBufferAttributes_2_3
617   int32_t format = 0;
618   int32_t dataspace = 0;
619 
620   auto error = hwc_session_->GetReadbackBufferAttributes(display, &format, &dataspace);
621 
622   if (error != HWC2_ERROR_NONE) {
623     format = 0;
624     dataspace = 0;
625   }
626 
627   _hidl_cb(static_cast<Error>(error), static_cast<common_V1_1::PixelFormat>(format),
628            static_cast<common_V1_1::Dataspace>(dataspace));
629   return Void();
630 }
631 
getReadbackBufferFence(uint64_t display,getReadbackBufferFence_cb _hidl_cb)632 Return<void> QtiComposerClient::getReadbackBufferFence(uint64_t display,
633                                                        getReadbackBufferFence_cb _hidl_cb) {
634   shared_ptr<Fence> fence = nullptr;
635   auto error = hwc_session_->GetReadbackBufferFence(display, &fence);
636   if (static_cast<Error>(error) != Error::NONE) {
637     _hidl_cb(static_cast<Error>(error), nullptr);
638     return Void();
639   }
640 
641   NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0);
642 
643   _hidl_cb(static_cast<Error>(error), getFenceHandle(fence, fenceStorage));
644   return Void();
645 }
646 
setReadbackBuffer(uint64_t display,const hidl_handle & buffer,const hidl_handle & releaseFence)647 Return<Error> QtiComposerClient::setReadbackBuffer(uint64_t display, const hidl_handle& buffer,
648                                                    const hidl_handle& releaseFence) {
649   shared_ptr<Fence> fence = nullptr;
650   Error error = getFence(releaseFence, &fence, "read_back");
651   if (error != Error::NONE) {
652     return error;
653   }
654 
655   const native_handle_t* readbackBuffer;
656   error = getDisplayReadbackBuffer(display, buffer.getNativeHandle(), &readbackBuffer);
657   if (error != Error::NONE) {
658     return error;
659   }
660 
661   auto err = hwc_session_->SetReadbackBuffer(display, readbackBuffer, fence);
662   return static_cast<Error>(err);
663 }
664 
createVirtualDisplay_2_2(uint32_t width,uint32_t height,common_V1_1::PixelFormat formatHint,uint32_t outputBufferSlotCount,createVirtualDisplay_2_2_cb _hidl_cb)665 Return<void> QtiComposerClient::createVirtualDisplay_2_2(uint32_t width, uint32_t height,
666                                                          common_V1_1::PixelFormat formatHint,
667                                                          uint32_t outputBufferSlotCount,
668                                                          createVirtualDisplay_2_2_cb _hidl_cb) {
669   int32_t format = static_cast<int32_t>(formatHint);
670   uint64_t display;
671   auto error = hwc_session_->CreateVirtualDisplay(width, height, &format, &display);
672 
673   if (static_cast<Error>(error) == Error::NONE) {
674     std::lock_guard<std::mutex> lock(mDisplayDataMutex);
675 
676     auto dpy = mDisplayData.emplace(static_cast<Display>(display), DisplayData(true)).first;
677     dpy->second.OutputBuffers.resize(outputBufferSlotCount);
678   }
679 
680   _hidl_cb(static_cast<Error>(error), display, static_cast<common_V1_1::PixelFormat>(format));
681   return Void();
682 }
683 
getClientTargetSupport_2_2(uint64_t display,uint32_t width,uint32_t height,common_V1_1::PixelFormat format,common_V1_1::Dataspace dataspace)684 Return<Error> QtiComposerClient::getClientTargetSupport_2_2(uint64_t display, uint32_t width,
685                                                             uint32_t height,
686                                                             common_V1_1::PixelFormat format,
687                                                             common_V1_1::Dataspace dataspace) {
688   auto error = hwc_session_->GetClientTargetSupport(display, width, height,
689                                                     static_cast<int32_t>(format),
690                                                     static_cast<int32_t>(dataspace));
691 
692   return static_cast<Error>(error);
693 }
694 
setPowerMode_2_2(uint64_t display,composer_V2_2::IComposerClient::PowerMode mode)695 Return<Error> QtiComposerClient::setPowerMode_2_2(uint64_t display,
696                                                   composer_V2_2::IComposerClient::PowerMode mode) {
697   if (mode == IComposerClient::PowerMode::ON_SUSPEND) {
698     return Error::UNSUPPORTED;
699   }
700   auto error = hwc_session_->SetPowerMode(display, static_cast<int32_t>(mode));
701 
702   return static_cast<Error>(error);
703 }
704 
getColorModes_2_2(uint64_t display,getColorModes_2_2_cb _hidl_cb)705 Return<void> QtiComposerClient::getColorModes_2_2(uint64_t display,
706                                                   getColorModes_2_2_cb _hidl_cb) {
707   // TODO(user): Implement combinedly w.r.t getColorModes_2_3
708   hidl_vec<common_V1_1::ColorMode> modes;
709   uint32_t count = 0;
710 
711   auto error = hwc_session_->GetColorModes(display, &count, nullptr);
712   if (error != HWC2_ERROR_NONE) {
713     _hidl_cb(static_cast<Error>(error), modes);
714     return Void();
715   }
716 
717   modes.resize(count);
718   error = hwc_session_->GetColorModes(display, &count,
719               reinterpret_cast<std::underlying_type<common_V1_1::ColorMode>::type*>(modes.data()));
720 
721   _hidl_cb(static_cast<Error>(error), modes);
722   return Void();
723 }
724 
getRenderIntents(uint64_t display,common_V1_1::ColorMode mode,getRenderIntents_cb _hidl_cb)725 Return<void> QtiComposerClient::getRenderIntents(uint64_t display, common_V1_1::ColorMode mode,
726                                                  getRenderIntents_cb _hidl_cb) {
727   // TODO(user): Implement combinedly w.r.t getRenderIntents_2_3
728   uint32_t count = 0;
729   std::vector<RenderIntent> intents;
730 
731   auto error = hwc_session_->GetRenderIntents(display, int32_t(mode), &count, nullptr);
732   if (error != HWC2_ERROR_NONE) {
733     _hidl_cb(static_cast<Error>(error), intents);
734     return Void();
735   }
736 
737   intents.resize(count);
738   error = hwc_session_->GetRenderIntents(display, int32_t(mode), &count,
739   reinterpret_cast<std::underlying_type<RenderIntent>::type*>(intents.data()));
740 
741   _hidl_cb(static_cast<Error>(error), intents);
742   return Void();
743 }
744 
setColorMode_2_2(uint64_t display,common_V1_1::ColorMode mode,common_V1_1::RenderIntent intent)745 Return<Error> QtiComposerClient::setColorMode_2_2(uint64_t display, common_V1_1::ColorMode mode,
746                                                   common_V1_1::RenderIntent intent) {
747   auto error = hwc_session_->SetColorModeWithRenderIntent(display, static_cast<int32_t>(mode),
748                                                           static_cast<int32_t>(intent));
749 
750   return static_cast<Error>(error);
751 }
752 
getDataspaceSaturationMatrix(common_V1_1::Dataspace dataspace,getDataspaceSaturationMatrix_cb _hidl_cb)753 Return<void> QtiComposerClient::getDataspaceSaturationMatrix(common_V1_1::Dataspace dataspace,
754                                                         getDataspaceSaturationMatrix_cb _hidl_cb) {
755   if (dataspace != common_V1_1::Dataspace::SRGB_LINEAR) {
756     _hidl_cb(Error::BAD_PARAMETER, std::array<float, 16>{0.0f}.data());
757     return Void();
758   }
759 
760   std::array<float, 16> matrix;
761   int32_t error = HWC2_ERROR_UNSUPPORTED;
762   error = hwc_session_->GetDataspaceSaturationMatrix(static_cast<int32_t>(dataspace),
763                                                      matrix.data());
764   if (error != HWC2_ERROR_NONE) {
765     matrix = {
766       1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
767       0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
768     };
769   }
770   _hidl_cb(Error::NONE, matrix.data());
771   return Void();
772 }
773 
executeCommands_2_2(uint32_t inLength,const hidl_vec<hidl_handle> & inHandles,executeCommands_2_2_cb _hidl_cb)774 Return<void> QtiComposerClient::executeCommands_2_2(uint32_t inLength,
775                                                     const hidl_vec<hidl_handle>& inHandles,
776                                                     executeCommands_2_2_cb _hidl_cb) {
777   std::lock_guard<std::mutex> lock(mCommandMutex);
778 
779   bool outChanged = false;
780   uint32_t outLength = 0;
781   hidl_vec<hidl_handle> outHandles;
782 
783   if (!mReader.readQueue(inLength, inHandles)) {
784     _hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
785     return Void();
786   }
787 
788   Error err = mReader.parse();
789   if (err == Error::NONE &&
790       !mWriter.writeQueue(outChanged, outLength, outHandles)) {
791       err = Error::NO_RESOURCES;
792   }
793 
794   _hidl_cb(Error::NONE, outChanged, outLength, outHandles);
795 
796   mReader.reset();
797   mWriter.reset();
798 
799   return Void();
800 }
801 
802 
803 // Methods from ::android::hardware::graphics::composer::V2_3::IComposerClient follow.
getDisplayIdentificationData(uint64_t display,getDisplayIdentificationData_cb _hidl_cb)804 Return<void> QtiComposerClient::getDisplayIdentificationData(uint64_t display,
805                                                         getDisplayIdentificationData_cb _hidl_cb) {
806   uint8_t port = 0;
807   uint32_t size = 0;
808   std::vector<uint8_t> data(size);
809 
810   auto error = hwc_session_->GetDisplayIdentificationData(display, &port, &size, nullptr);
811   if (error != HWC2_ERROR_NONE) {
812     _hidl_cb(static_cast<Error>(error), port, data);
813     return Void();
814   }
815 
816   data.resize(size);
817   error = hwc_session_->GetDisplayIdentificationData(display, &port, &size, data.data());
818 
819   _hidl_cb(static_cast<Error>(error), port, data);
820   return Void();
821 }
822 
getReadbackBufferAttributes_2_3(uint64_t display,getReadbackBufferAttributes_2_3_cb _hidl_cb)823 Return<void> QtiComposerClient::getReadbackBufferAttributes_2_3(uint64_t display,
824                                                      getReadbackBufferAttributes_2_3_cb _hidl_cb) {
825   int32_t format = 0;
826   int32_t dataspace = 0;
827 
828   auto error = hwc_session_->GetReadbackBufferAttributes(display, &format, &dataspace);
829 
830   if (error != HWC2_ERROR_NONE) {
831     format = 0;
832     dataspace = 0;
833   }
834 
835   _hidl_cb(static_cast<Error>(error), static_cast<common_V1_2::PixelFormat>(format),
836            static_cast<common_V1_2::Dataspace>(dataspace));
837   return Void();
838 }
839 
getClientTargetSupport_2_3(uint64_t display,uint32_t width,uint32_t height,common_V1_2::PixelFormat format,common_V1_2::Dataspace dataspace)840 Return<Error> QtiComposerClient::getClientTargetSupport_2_3(uint64_t display, uint32_t width,
841                                                             uint32_t height,
842                                                             common_V1_2::PixelFormat format,
843                                                             common_V1_2::Dataspace dataspace) {
844   auto error = hwc_session_->GetClientTargetSupport(display, width, height,
845                                                     static_cast<int32_t>(format),
846                                                     static_cast<int32_t>(dataspace));
847 
848   return static_cast<Error>(error);
849 }
850 
getDisplayedContentSamplingAttributes(uint64_t display,getDisplayedContentSamplingAttributes_cb _hidl_cb)851 Return<void> QtiComposerClient::getDisplayedContentSamplingAttributes(uint64_t display,
852                                                getDisplayedContentSamplingAttributes_cb _hidl_cb) {
853   // getDisplayedContentSamplingAttributes is not supported
854   int constexpr invalid = -1;
855   auto error = Error::UNSUPPORTED;
856   common_V1_2::PixelFormat format = static_cast<common_V1_2::PixelFormat>(invalid);
857   common_V1_2::Dataspace dataspace = static_cast<common_V1_2::Dataspace>(invalid);
858   hidl_bitfield<IComposerClient::FormatColorComponent> componentMask =
859     static_cast<hidl_bitfield<IComposerClient::FormatColorComponent>>(invalid);
860 
861   _hidl_cb(error, format, dataspace, componentMask);
862   return Void();
863 }
864 
setDisplayedContentSamplingEnabled(uint64_t display,composer_V2_3::IComposerClient::DisplayedContentSampling enable,hidl_bitfield<FormatColorComponent> componentMask,uint64_t maxFrames)865 Return<Error> QtiComposerClient::setDisplayedContentSamplingEnabled(uint64_t display,
866                                    composer_V2_3::IComposerClient::DisplayedContentSampling enable,
867                                    hidl_bitfield<FormatColorComponent> componentMask,
868                                    uint64_t maxFrames) {
869   // setDisplayedContentSamplingEnabled is not supported
870   return Error::UNSUPPORTED;
871 }
872 
getDisplayedContentSample(uint64_t display,uint64_t maxFrames,uint64_t timestamp,getDisplayedContentSample_cb _hidl_cb)873 Return<void> QtiComposerClient::getDisplayedContentSample(uint64_t display, uint64_t maxFrames,
874                                                           uint64_t timestamp,
875                                                           getDisplayedContentSample_cb _hidl_cb) {
876   // getDisplayedContentSample is not supported
877   auto error = Error::UNSUPPORTED;
878   uint64_t frameCount = 0;
879   hidl_vec<uint64_t> sampleComponent0 = 0;
880   hidl_vec<uint64_t> sampleComponent1 = 0;
881   hidl_vec<uint64_t> sampleComponent2 = 0;
882   hidl_vec<uint64_t> sampleComponent3 = 0;
883 
884   _hidl_cb(error, frameCount, sampleComponent0, sampleComponent1, sampleComponent2,
885            sampleComponent3);
886   return Void();
887 }
888 
executeCommands_2_3(uint32_t inLength,const hidl_vec<hidl_handle> & inHandles,executeCommands_2_3_cb _hidl_cb)889 Return<void> QtiComposerClient::executeCommands_2_3(uint32_t inLength,
890                                                     const hidl_vec<hidl_handle>& inHandles,
891                                                     executeCommands_2_3_cb _hidl_cb) {
892   // TODO(user): Implement combinedly w.r.t executeCommands_2_2
893   std::lock_guard<std::mutex> lock(mCommandMutex);
894 
895   bool outChanged = false;
896   uint32_t outLength = 0;
897   hidl_vec<hidl_handle> outHandles;
898 
899   if (!mReader.readQueue(inLength, inHandles)) {
900     _hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
901     return Void();
902   }
903 
904   Error err = mReader.parse();
905   if (err == Error::NONE &&
906       !mWriter.writeQueue(outChanged, outLength, outHandles)) {
907       err = Error::NO_RESOURCES;
908   }
909 
910   _hidl_cb(Error::NONE, outChanged, outLength, outHandles);
911 
912   mReader.reset();
913   mWriter.reset();
914 
915   return Void();
916 }
917 
getRenderIntents_2_3(uint64_t display,common_V1_2::ColorMode mode,getRenderIntents_2_3_cb _hidl_cb)918 Return<void> QtiComposerClient::getRenderIntents_2_3(uint64_t display, common_V1_2::ColorMode mode,
919                                                      getRenderIntents_2_3_cb _hidl_cb) {
920   uint32_t count = 0;
921   std::vector<RenderIntent> intents;
922 
923   auto error = hwc_session_->GetRenderIntents(display, int32_t(mode), &count, nullptr);
924   if (error != HWC2_ERROR_NONE) {
925     _hidl_cb(static_cast<Error>(error), intents);
926     return Void();
927   }
928 
929   intents.resize(count);
930   error = hwc_session_->GetRenderIntents(display, int32_t(mode), &count,
931   reinterpret_cast<std::underlying_type<RenderIntent>::type*>(intents.data()));
932 
933   _hidl_cb(static_cast<Error>(error), intents);
934   return Void();
935 }
936 
getColorModes_2_3(uint64_t display,getColorModes_2_3_cb _hidl_cb)937 Return<void> QtiComposerClient::getColorModes_2_3(uint64_t display,
938                                                   getColorModes_2_3_cb _hidl_cb) {
939   hidl_vec<common_V1_2::ColorMode> modes;
940   uint32_t count = 0;
941 
942   auto error = hwc_session_->GetColorModes(display, &count, nullptr);
943   if (error != HWC2_ERROR_NONE) {
944     _hidl_cb(static_cast<Error>(error), modes);
945     return Void();
946   }
947 
948   modes.resize(count);
949   error = hwc_session_->GetColorModes(display, &count,
950               reinterpret_cast<std::underlying_type<common_V1_2::ColorMode>::type*>(modes.data()));
951 
952   _hidl_cb(static_cast<Error>(error), modes);
953   return Void();
954 }
955 
setColorMode_2_3(uint64_t display,common_V1_2::ColorMode mode,common_V1_1::RenderIntent intent)956 Return<Error> QtiComposerClient::setColorMode_2_3(uint64_t display, common_V1_2::ColorMode mode,
957                                                   common_V1_1::RenderIntent intent) {
958   auto error = hwc_session_->SetColorModeWithRenderIntent(display, static_cast<int32_t>(mode),
959                                                           static_cast<int32_t>(intent));
960 
961   return static_cast<Error>(error);
962 }
963 
getDisplayCapabilities(uint64_t display,getDisplayCapabilities_cb _hidl_cb)964 Return<void> QtiComposerClient::getDisplayCapabilities(uint64_t display,
965                                                        getDisplayCapabilities_cb _hidl_cb) {
966   hidl_vec<composer_V2_3::IComposerClient::DisplayCapability> capabilities;
967   uint32_t count = 0;
968   auto error = hwc_session_->GetDisplayCapabilities(display, &count, nullptr);
969   if (error != HWC2_ERROR_NONE) {
970     _hidl_cb(static_cast<Error>(error), capabilities);
971     return Void();
972   }
973 
974   capabilities.resize(count);
975   error = hwc_session_->GetDisplayCapabilities(
976       display, &count,
977       reinterpret_cast<std::underlying_type<composer_V2_3::IComposerClient::DisplayCapability>::type
978                            *>(capabilities.data()));
979 
980   _hidl_cb(static_cast<Error>(error), capabilities);
981   return Void();
982 }
983 
getPerFrameMetadataKeys_2_3(uint64_t display,getPerFrameMetadataKeys_2_3_cb _hidl_cb)984 Return<void> QtiComposerClient::getPerFrameMetadataKeys_2_3(uint64_t display,
985                                                          getPerFrameMetadataKeys_2_3_cb _hidl_cb) {
986   std::vector<PerFrameMetadataKey> keys;
987   uint32_t count = 0;
988 
989   auto error = hwc_session_->GetPerFrameMetadataKeys(display, &count, nullptr);
990   if (error != HWC2_ERROR_NONE) {
991     _hidl_cb(static_cast<Error>(error), keys);
992     return Void();
993   }
994 
995   keys.resize(count);
996   error = hwc_session_->GetPerFrameMetadataKeys(display, &count,
997                   reinterpret_cast<std::underlying_type<PerFrameMetadataKey>::type*>(keys.data()));
998 
999   _hidl_cb(static_cast<Error>(error), keys);
1000   return Void();
1001 }
1002 
getHdrCapabilities_2_3(uint64_t display,getHdrCapabilities_2_3_cb _hidl_cb)1003 Return<void> QtiComposerClient::getHdrCapabilities_2_3(uint64_t display,
1004                                                        getHdrCapabilities_2_3_cb _hidl_cb) {
1005   uint32_t count = 0;
1006   hidl_vec<common_V1_2::Hdr> types;
1007   float max_lumi = 0.0f;
1008   float max_avg_lumi = 0.0f;
1009   float min_lumi = 0.0f;
1010 
1011   auto error = hwc_session_->GetHdrCapabilities(display, &count, nullptr, &max_lumi,
1012                                                 &max_avg_lumi, &min_lumi);
1013   if (error != HWC2_ERROR_NONE) {
1014     _hidl_cb(static_cast<Error>(error), types, max_lumi, max_avg_lumi, min_lumi);
1015     return Void();
1016   }
1017 
1018   types.resize(count);
1019   error = hwc_session_->GetHdrCapabilities(display, &count,
1020            reinterpret_cast<std::underlying_type<common_V1_2::Hdr>::type*>(types.data()),
1021            &max_lumi, &max_avg_lumi, &min_lumi);
1022 
1023   _hidl_cb(static_cast<Error>(error), types, max_lumi, max_avg_lumi, min_lumi);
1024   return Void();
1025 }
1026 
getDisplayBrightnessSupport(uint64_t display,getDisplayBrightnessSupport_cb _hidl_cb)1027 Return<void> QtiComposerClient::getDisplayBrightnessSupport(uint64_t display,
1028                                                          getDisplayBrightnessSupport_cb _hidl_cb) {
1029   bool support = false;
1030   auto error = hwc_session_->GetDisplayBrightnessSupport(display, &support);
1031 
1032   _hidl_cb(static_cast<Error>(error), support);
1033   return Void();
1034 }
1035 
setDisplayBrightness(uint64_t display,float brightness)1036 Return<Error> QtiComposerClient::setDisplayBrightness(uint64_t display, float brightness) {
1037   if (std::isnan(brightness) || brightness > 1.0f || (brightness < 0.0f && brightness != -1.0f)) {
1038     return Error::BAD_PARAMETER;
1039   }
1040 
1041   auto error = hwc_session_->SetDisplayBrightness(display, brightness);
1042   return static_cast<Error>(error);
1043 }
1044 
1045 // Methods from ::android::hardware::graphics::composer::V2_4::IComposerClient follow.
registerCallback_2_4(const sp<composer_V2_4::IComposerCallback> & callback)1046 Return<void> QtiComposerClient::registerCallback_2_4(
1047     const sp<composer_V2_4::IComposerCallback> &callback) {
1048   callback_ = sp<composer_V2_1::IComposerCallback>(callback.get());
1049   callback24_ = callback;
1050   mUseCallback24_ = true;
1051   enableCallback(callback != nullptr);
1052   return Void();
1053 }
1054 
getDisplayCapabilities_2_4(uint64_t display,getDisplayCapabilities_2_4_cb _hidl_cb)1055 Return<void> QtiComposerClient::getDisplayCapabilities_2_4(uint64_t display,
1056                                                            getDisplayCapabilities_2_4_cb _hidl_cb) {
1057   hidl_vec<HwcDisplayCapability> capabilities;
1058   uint32_t count = 0;
1059   auto error = hwc_session_->GetDisplayCapabilities(display, &count, nullptr);
1060   if (error != HWC2_ERROR_NONE) {
1061     _hidl_cb(static_cast<composer_V2_4::Error>(error), capabilities);
1062     return Void();
1063   }
1064 
1065   uint32_t count_2_4 = 0;
1066   error = hwc_session_->GetDisplayCapabilities_2_4(display, &count_2_4, nullptr);
1067   if (error != HWC2_ERROR_NONE) {
1068     _hidl_cb(static_cast<composer_V2_4::Error>(error), capabilities);
1069     return Void();
1070   }
1071 
1072   capabilities.resize(count + count_2_4);
1073   error = hwc_session_->GetDisplayCapabilities(
1074       display, &count,
1075       reinterpret_cast<std::underlying_type<HwcDisplayCapability>::type *>(capabilities.data()));
1076   if (error != HWC2_ERROR_NONE) {
1077     _hidl_cb(static_cast<composer_V2_4::Error>(error), {});
1078     return Void();
1079   }
1080 
1081   error = hwc_session_->GetDisplayCapabilities_2_4(
1082       display, &count_2_4,
1083       reinterpret_cast<std::underlying_type<HwcDisplayCapability>::type *>(capabilities.data() +
1084                                                                            count));
1085   if (error != HWC2_ERROR_NONE) {
1086     _hidl_cb(static_cast<composer_V2_4::Error>(error), {});
1087     return Void();
1088   }
1089 
1090   _hidl_cb(static_cast<composer_V2_4::Error>(error), capabilities);
1091   return Void();
1092 }
1093 
getDisplayConnectionType(uint64_t display,getDisplayConnectionType_cb _hidl_cb)1094 Return<void> QtiComposerClient::getDisplayConnectionType(uint64_t display,
1095                                                          getDisplayConnectionType_cb _hidl_cb) {
1096   HwcDisplayConnectionType type;
1097   auto error = hwc_session_->GetDisplayConnectionType(display, &type);
1098   _hidl_cb(static_cast<composer_V2_4::Error>(error), type);
1099   return Void();
1100 }
1101 
getDisplayAttribute_2_4(uint64_t display,uint32_t config,composer_V2_4::IComposerClient::Attribute attribute,getDisplayAttribute_2_4_cb _hidl_cb)1102 Return<void> QtiComposerClient::getDisplayAttribute_2_4(
1103     uint64_t display, uint32_t config, composer_V2_4::IComposerClient::Attribute attribute,
1104     getDisplayAttribute_2_4_cb _hidl_cb) {
1105   int32_t value = 0;
1106   auto error = hwc_session_->GetDisplayAttribute(display, config, attribute, &value);
1107   _hidl_cb(static_cast<composer_V2_4::Error>(error), value);
1108   return Void();
1109 }
1110 
getDisplayVsyncPeriod(uint64_t display,getDisplayVsyncPeriod_cb _hidl_cb)1111 Return<void> QtiComposerClient::getDisplayVsyncPeriod(uint64_t display,
1112                                                       getDisplayVsyncPeriod_cb _hidl_cb) {
1113   VsyncPeriodNanos vsync_period;
1114   auto error = hwc_session_->GetDisplayVsyncPeriod(display, &vsync_period);
1115   _hidl_cb(static_cast<composer_V2_4::Error>(error), vsync_period);
1116   return Void();
1117 }
1118 
setActiveConfigWithConstraints(uint64_t display,uint32_t config,const VsyncPeriodChangeConstraints & vsyncPeriodChangeConstraints,setActiveConfigWithConstraints_cb _hidl_cb)1119 Return<void> QtiComposerClient::setActiveConfigWithConstraints(
1120     uint64_t display, uint32_t config,
1121     const VsyncPeriodChangeConstraints &vsyncPeriodChangeConstraints,
1122     setActiveConfigWithConstraints_cb _hidl_cb) {
1123   VsyncPeriodChangeTimeline timeline;
1124   timeline.newVsyncAppliedTimeNanos = systemTime();
1125   timeline.refreshRequired = false;
1126   timeline.refreshTimeNanos = 0;
1127 
1128   auto error = hwc_session_->SetActiveConfigWithConstraints(
1129       display, config, &vsyncPeriodChangeConstraints, &timeline);
1130   _hidl_cb(static_cast<composer_V2_4::Error>(error), timeline);
1131   return Void();
1132 }
1133 
setAutoLowLatencyMode(uint64_t display,bool on)1134 Return<composer_V2_4::Error> QtiComposerClient::setAutoLowLatencyMode(uint64_t display, bool on) {
1135   if (mDisplayData.find(display) == mDisplayData.end()) {
1136     return composer_V2_4::Error::BAD_DISPLAY;
1137   }
1138 
1139   auto error = hwc_session_->SetAutoLowLatencyMode(display, on);
1140 
1141   return static_cast<composer_V2_4::Error>(error);
1142 }
1143 
getSupportedContentTypes(uint64_t display,getSupportedContentTypes_cb _hidl_cb)1144 Return<void> QtiComposerClient::getSupportedContentTypes(uint64_t display,
1145                                                          getSupportedContentTypes_cb _hidl_cb) {
1146   hidl_vec<composer_V2_4::IComposerClient::ContentType> types;
1147   if (mDisplayData.find(display) == mDisplayData.end()) {
1148     _hidl_cb(composer_V2_4::Error::BAD_DISPLAY, types);
1149     return Void();
1150   }
1151   auto error = hwc_session_->GetSupportedContentTypes(display, &types);
1152   _hidl_cb(static_cast<composer_V2_4::Error>(error), types);
1153   return Void();
1154 }
1155 
setContentType(uint64_t display,composer_V2_4::IComposerClient::ContentType type)1156 Return<composer_V2_4::Error> QtiComposerClient::setContentType(
1157     uint64_t display, composer_V2_4::IComposerClient::ContentType type) {
1158   if (mDisplayData.find(display) == mDisplayData.end()) {
1159     return composer_V2_4::Error::BAD_DISPLAY;
1160   }
1161   if (type == composer_V2_4::IComposerClient::ContentType::NONE) {
1162     return composer_V2_4::Error::NONE;
1163   }
1164   auto error = hwc_session_->SetContentType(display, type);
1165 
1166   return static_cast<composer_V2_4::Error>(error);
1167 }
1168 
getLayerGenericMetadataKeys(getLayerGenericMetadataKeys_cb _hidl_cb)1169 Return<void> QtiComposerClient::getLayerGenericMetadataKeys(
1170     getLayerGenericMetadataKeys_cb _hidl_cb) {
1171   hidl_vec<composer_V2_4::IComposerClient::LayerGenericMetadataKey> keys = {};
1172   _hidl_cb(composer_V2_4::Error::NONE, keys);
1173   return Void();
1174 }
1175 
CommandReader(QtiComposerClient & client)1176 QtiComposerClient::CommandReader::CommandReader(QtiComposerClient& client)
1177   : mClient(client), mWriter(client.mWriter) {
1178 }
1179 
parseCommonCmd(IComposerClient::Command command,uint16_t length)1180 bool QtiComposerClient::CommandReader::parseCommonCmd(
1181     IComposerClient::Command command, uint16_t length) {
1182   bool parsed = false;
1183 
1184   switch (command) {
1185   // Commands from ::android::hardware::graphics::composer::V2_1::IComposerClient follow.
1186   case IComposerClient::Command::SELECT_DISPLAY:
1187     parsed = parseSelectDisplay(length);
1188     // Displays will not be removed while processing the command queue.
1189     if (parsed && mClient.mDisplayData.find(mDisplay) == mClient.mDisplayData.end()) {
1190       ALOGW("Command::SELECT_DISPLAY: Display %" PRId64 "not found. Dropping commands.", mDisplay);
1191       mDisplay = sdm::HWCCallbacks::kNumDisplays;
1192     }
1193     break;
1194   case IComposerClient::Command::SELECT_LAYER:
1195     parsed = parseSelectLayer(length);
1196     break;
1197   case IComposerClient::Command::SET_COLOR_TRANSFORM:
1198     parsed = parseSetColorTransform(length);
1199     break;
1200   case IComposerClient::Command::SET_CLIENT_TARGET:
1201     parsed = parseSetClientTarget(length);
1202     break;
1203   case IComposerClient::Command::SET_OUTPUT_BUFFER:
1204     parsed = parseSetOutputBuffer(length);
1205     break;
1206   case IComposerClient::Command::VALIDATE_DISPLAY:
1207     parsed = parseValidateDisplay(length);
1208     break;
1209   case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
1210     parsed = parseAcceptDisplayChanges(length);
1211     break;
1212   case IComposerClient::Command::PRESENT_DISPLAY:
1213     parsed = parsePresentDisplay(length);
1214     break;
1215   case IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY:
1216     parsed = parsePresentOrValidateDisplay(length);
1217     break;
1218   case IComposerClient::Command::SET_LAYER_CURSOR_POSITION:
1219     parsed = parseSetLayerCursorPosition(length);
1220     break;
1221   case IComposerClient::Command::SET_LAYER_BUFFER:
1222     parsed = parseSetLayerBuffer(length);
1223     break;
1224   case IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE:
1225     parsed = parseSetLayerSurfaceDamage(length);
1226     break;
1227   case IComposerClient::Command::SET_LAYER_BLEND_MODE:
1228     parsed = parseSetLayerBlendMode(length);
1229     break;
1230   case IComposerClient::Command::SET_LAYER_COLOR:
1231     parsed = parseSetLayerColor(length);
1232     break;
1233   case IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE:
1234     parsed = parseSetLayerCompositionType(length);
1235     break;
1236   case IComposerClient::Command::SET_LAYER_DATASPACE:
1237     parsed = parseSetLayerDataspace(length);
1238     break;
1239   case IComposerClient::Command::SET_LAYER_DISPLAY_FRAME:
1240     parsed = parseSetLayerDisplayFrame(length);
1241     break;
1242   case IComposerClient::Command::SET_LAYER_PLANE_ALPHA:
1243     parsed = parseSetLayerPlaneAlpha(length);
1244     break;
1245   case IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM:
1246     parsed = parseSetLayerSidebandStream(length);
1247     break;
1248   case IComposerClient::Command::SET_LAYER_SOURCE_CROP:
1249     parsed = parseSetLayerSourceCrop(length);
1250     break;
1251   case IComposerClient::Command::SET_LAYER_TRANSFORM:
1252     parsed = parseSetLayerTransform(length);
1253     break;
1254   case IComposerClient::Command::SET_LAYER_VISIBLE_REGION:
1255     parsed = parseSetLayerVisibleRegion(length);
1256     break;
1257   case IComposerClient::Command::SET_LAYER_Z_ORDER:
1258     parsed = parseSetLayerZOrder(length);
1259     break;
1260   // Commands from ::android::hardware::graphics::composer::V2_2::IComposerClient follow.
1261   case IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA:
1262     parsed = parseSetLayerPerFrameMetadata(length);
1263     break;
1264   case IComposerClient::Command::SET_LAYER_FLOAT_COLOR:
1265     parsed = parseSetLayerFloatColor(length);
1266     break;
1267   // Commands from ::android::hardware::graphics::composer::V2_3::IComposerClient follow.
1268   case IComposerClient::Command::SET_LAYER_COLOR_TRANSFORM:
1269     parsed = parseSetLayerColorTransform(length);
1270     break;
1271   case IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA_BLOBS:
1272     parsed = parseSetLayerPerFrameMetadataBlobs(length);
1273     break;
1274   default:
1275     parsed = false;
1276     break;
1277   }
1278 
1279   return parsed;
1280 }
1281 
parse()1282 Error QtiComposerClient::CommandReader::parse() {
1283   IQtiComposerClient::Command qticommand;
1284   uint16_t length;
1285 
1286   while (!isEmpty()) {
1287     if (!beginCommand(qticommand, length)) {
1288       break;
1289     }
1290 
1291     bool parsed = false;
1292     switch (qticommand) {
1293       case IQtiComposerClient::Command::SET_LAYER_TYPE:
1294         parsed = parseSetLayerType(length);
1295         break;
1296       case IQtiComposerClient::Command::SET_DISPLAY_ELAPSE_TIME:
1297         parsed = parseSetDisplayElapseTime(length);
1298         break;
1299       default:
1300         parsed = parseCommonCmd(static_cast<IComposerClient::Command>(qticommand), length);
1301         break;
1302     }
1303 
1304     endCommand();
1305 
1306     if (!parsed) {
1307       ALOGE("failed to parse command 0x%x, length %" PRIu16,
1308           qticommand, length);
1309       break;
1310     }
1311   }
1312 
1313   return (isEmpty()) ? Error::NONE : Error::BAD_PARAMETER;
1314 }
1315 
parseSelectDisplay(uint16_t length)1316 bool QtiComposerClient::CommandReader::parseSelectDisplay(uint16_t length) {
1317   if (length != CommandWriter::kSelectDisplayLength) {
1318     return false;
1319   }
1320 
1321   mDisplay = read64();
1322   mWriter.selectDisplay(mDisplay);
1323 
1324   return true;
1325 }
1326 
parseSelectLayer(uint16_t length)1327 bool QtiComposerClient::CommandReader::parseSelectLayer(uint16_t length) {
1328   if (length != CommandWriter::kSelectLayerLength) {
1329     return false;
1330   }
1331 
1332   mLayer = read64();
1333 
1334   return true;
1335 }
1336 
parseSetColorTransform(uint16_t length)1337 bool QtiComposerClient::CommandReader::parseSetColorTransform(uint16_t length) {
1338   if (length != CommandWriter::kSetColorTransformLength) {
1339     return false;
1340   }
1341 
1342   float matrix[16];
1343   for (int i = 0; i < 16; i++) {
1344     matrix[i] = readFloat();
1345   }
1346   auto transform = readSigned();
1347 
1348   auto err = mClient.hwc_session_->SetColorTransform(mDisplay, matrix, transform);
1349   if (static_cast<Error>(err) != Error::NONE) {
1350     mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1351   }
1352 
1353   return true;
1354 }
1355 
parseSetClientTarget(uint16_t length)1356 bool QtiComposerClient::CommandReader::parseSetClientTarget(uint16_t length) {
1357   // 4 parameters followed by N rectangles
1358   if ((length - 4) % 4 != 0) {
1359     return false;
1360   }
1361 
1362   bool useCache = false;
1363   auto slot = read();
1364   auto clientTarget = readHandle(useCache);
1365   shared_ptr<Fence> fence = nullptr;
1366   readFence(&fence, "fbt");
1367   auto dataspace = readSigned();
1368   auto damage = readRegion((length - 4) / 4);
1369   hwc_region region = {damage.size(), damage.data()};
1370   auto err = lookupBuffer(BufferCache::CLIENT_TARGETS, slot, useCache, clientTarget, &clientTarget);
1371   if (err == Error::NONE) {
1372     auto error = mClient.hwc_session_->SetClientTarget(mDisplay, clientTarget, fence,
1373         dataspace, region);
1374     err = static_cast<Error>(error);
1375     auto updateBufErr = updateBuffer(BufferCache::CLIENT_TARGETS, slot,
1376         useCache, clientTarget);
1377     if (err == Error::NONE) {
1378       err = updateBufErr;
1379     }
1380   }
1381   if (err != Error::NONE) {
1382     mWriter.setError(getCommandLoc(), err);
1383   }
1384 
1385   return true;
1386 }
1387 
parseSetOutputBuffer(uint16_t length)1388 bool QtiComposerClient::CommandReader::parseSetOutputBuffer(uint16_t length) {
1389   if (length != CommandWriter::kSetOutputBufferLength) {
1390     return false;
1391   }
1392 
1393   bool useCache;
1394   auto slot = read();
1395   auto outputBuffer = readHandle(useCache);
1396   shared_ptr<Fence> fence = nullptr;
1397   readFence(&fence, "outbuf");
1398   auto err = lookupBuffer(BufferCache::OUTPUT_BUFFERS, slot, useCache, outputBuffer, &outputBuffer);
1399   if (err == Error::NONE) {
1400     auto error = mClient.hwc_session_->SetOutputBuffer(mDisplay, outputBuffer, fence);
1401     err = static_cast<Error>(error);
1402     auto updateBufErr = updateBuffer(BufferCache::OUTPUT_BUFFERS, slot, useCache, outputBuffer);
1403     if (err == Error::NONE) {
1404       err = updateBufErr;
1405     }
1406   }
1407 
1408   if (err != Error::NONE) {
1409     mWriter.setError(getCommandLoc(), err);
1410   }
1411 
1412   return true;
1413 }
1414 
validateDisplay(Display display,std::vector<Layer> & changedLayers,std::vector<IComposerClient::Composition> & compositionTypes,uint32_t & displayRequestMask,std::vector<Layer> & requestedLayers,std::vector<uint32_t> & requestMasks,IComposerClient::ClientTargetProperty & clientTargetProperty)1415 Error QtiComposerClient::CommandReader::validateDisplay(Display display,
1416                                        std::vector<Layer>& changedLayers,
1417                                        std::vector<IComposerClient::Composition>& compositionTypes,
1418                                        uint32_t& displayRequestMask,
1419                                        std::vector<Layer>& requestedLayers,
1420                                        std::vector<uint32_t>& requestMasks,
1421                                        IComposerClient::ClientTargetProperty& clientTargetProperty) {
1422   uint32_t types_count = 0;
1423   uint32_t reqs_count = 0;
1424 
1425   auto err = mClient.hwc_session_->ValidateDisplay(mDisplay, &types_count, &reqs_count);
1426   if (err != HWC2_ERROR_NONE && err != HWC2_ERROR_HAS_CHANGES) {
1427     return static_cast<Error>(err);
1428   }
1429 
1430   err = mClient.hwc_session_->GetChangedCompositionTypes(mDisplay, &types_count, nullptr, nullptr);
1431   if (err != HWC2_ERROR_NONE) {
1432     return static_cast<Error>(err);
1433   }
1434 
1435   changedLayers.resize(types_count);
1436   compositionTypes.resize(types_count);
1437   err = mClient.hwc_session_->GetChangedCompositionTypes(mDisplay, &types_count,
1438                         changedLayers.data(),
1439                         reinterpret_cast<std::underlying_type<IComposerClient::Composition>::type*>(
1440                         compositionTypes.data()));
1441 
1442   if (err != HWC2_ERROR_NONE) {
1443     changedLayers.clear();
1444     compositionTypes.clear();
1445     return static_cast<Error>(err);
1446   }
1447 
1448   int32_t display_reqs = 0;
1449   err = mClient.hwc_session_->GetDisplayRequests(mDisplay, &display_reqs, &reqs_count, nullptr,
1450                                                  nullptr);
1451   if (err != HWC2_ERROR_NONE) {
1452     changedLayers.clear();
1453     compositionTypes.clear();
1454     return static_cast<Error>(err);
1455   }
1456 
1457   requestedLayers.resize(reqs_count);
1458   requestMasks.resize(reqs_count);
1459   err = mClient.hwc_session_->GetDisplayRequests(mDisplay, &display_reqs, &reqs_count,
1460                                                  requestedLayers.data(),
1461                                                  reinterpret_cast<int32_t*>(requestMasks.data()));
1462   if (err != HWC2_ERROR_NONE) {
1463     changedLayers.clear();
1464     compositionTypes.clear();
1465 
1466     requestedLayers.clear();
1467     requestMasks.clear();
1468     return static_cast<Error>(err);
1469   }
1470 
1471   displayRequestMask = display_reqs;
1472 
1473   err = mClient.hwc_session_->GetClientTargetProperty(mDisplay, &clientTargetProperty);
1474   if (err != HWC2_ERROR_NONE) {
1475     // todo: reset to default values
1476     return static_cast<Error>(err);
1477   }
1478 
1479   return static_cast<Error>(err);
1480 }
1481 
parseValidateDisplay(uint16_t length)1482 bool QtiComposerClient::CommandReader::parseValidateDisplay(uint16_t length) {
1483   if (length != CommandWriter::kValidateDisplayLength) {
1484     return false;
1485   }
1486 
1487   std::vector<Layer> changedLayers;
1488   std::vector<IComposerClient::Composition> compositionTypes;
1489   uint32_t displayRequestMask;
1490   std::vector<Layer> requestedLayers;
1491   std::vector<uint32_t> requestMasks;
1492   IComposerClient::ClientTargetProperty clientTargetProperty;
1493 
1494   auto err = validateDisplay(mDisplay, changedLayers, compositionTypes, displayRequestMask,
1495                              requestedLayers, requestMasks, clientTargetProperty);
1496 
1497   if (static_cast<Error>(err) == Error::NONE) {
1498     mWriter.setChangedCompositionTypes(changedLayers, compositionTypes);
1499     mWriter.setDisplayRequests(displayRequestMask, requestedLayers, requestMasks);
1500     if (mClient.mUseCallback24_) {
1501       mWriter.setClientTargetProperty(clientTargetProperty);
1502     }
1503   } else {
1504     mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1505   }
1506 
1507   return true;
1508 }
1509 
parseAcceptDisplayChanges(uint16_t length)1510 bool QtiComposerClient::CommandReader::parseAcceptDisplayChanges(uint16_t length) {
1511   if (length != CommandWriter::kAcceptDisplayChangesLength) {
1512     return false;
1513   }
1514 
1515   auto err = mClient.hwc_session_->AcceptDisplayChanges(mDisplay);
1516   if (static_cast<Error>(err) != Error::NONE) {
1517     mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1518   }
1519 
1520   return true;
1521 }
1522 
presentDisplay(Display display,shared_ptr<Fence> * presentFence,std::vector<Layer> & layers,std::vector<shared_ptr<Fence>> & releaseFences)1523 Error QtiComposerClient::CommandReader::presentDisplay(Display display,
1524                                                   shared_ptr<Fence>* presentFence,
1525                                                   std::vector<Layer>& layers,
1526                                                   std::vector<shared_ptr<Fence>>& releaseFences) {
1527   int32_t err = mClient.hwc_session_->PresentDisplay(display, presentFence);
1528   if (err != HWC2_ERROR_NONE) {
1529     return static_cast<Error>(err);
1530   }
1531 
1532   uint32_t count = 0;
1533   err = mClient.hwc_session_->GetReleaseFences(display, &count, nullptr, nullptr);
1534   if (err != HWC2_ERROR_NONE) {
1535     ALOGW("failed to get release fences");
1536     return Error::NONE;
1537   }
1538 
1539   layers.resize(count);
1540   releaseFences.resize(count);
1541   err = mClient.hwc_session_->GetReleaseFences(display, &count, layers.data(), &releaseFences);
1542   if (err != HWC2_ERROR_NONE) {
1543     ALOGW("failed to get release fences");
1544     layers.clear();
1545     releaseFences.clear();
1546     return Error::NONE;
1547   }
1548 
1549   return static_cast<Error>(err);
1550 }
1551 
parsePresentDisplay(uint16_t length)1552 bool QtiComposerClient::CommandReader::parsePresentDisplay(uint16_t length) {
1553   if (length != CommandWriter::kPresentDisplayLength) {
1554     return false;
1555   }
1556 
1557   shared_ptr<Fence> presentFence = nullptr;
1558   std::vector<Layer> layers;
1559   std::vector<shared_ptr<Fence>> fences;
1560 
1561   auto err = presentDisplay(mDisplay, &presentFence, layers, fences);
1562   if (err == Error::NONE) {
1563     mWriter.setPresentFence(presentFence);
1564     mWriter.setReleaseFences(layers, fences);
1565   } else {
1566     mWriter.setError(getCommandLoc(), err);
1567   }
1568 
1569   return true;
1570 }
1571 
parsePresentOrValidateDisplay(uint16_t length)1572 bool QtiComposerClient::CommandReader::parsePresentOrValidateDisplay(uint16_t length) {
1573   if (length != CommandWriter::kPresentOrValidateDisplayLength) {
1574      return false;
1575   }
1576 
1577   // First try to Present as is.
1578   mClient.getCapabilities();
1579   if (mClient.hasCapability(HWC2_CAPABILITY_SKIP_VALIDATE)) {
1580     shared_ptr<Fence> presentFence = nullptr;
1581     std::vector<Layer> layers;
1582     std::vector<shared_ptr<Fence>> fences;
1583     auto err = presentDisplay(mDisplay, &presentFence, layers, fences);
1584     if (err == Error::NONE) {
1585       mWriter.setPresentOrValidateResult(1);
1586       mWriter.setPresentFence(presentFence);
1587       mWriter.setReleaseFences(layers, fences);
1588       return true;
1589     }
1590   }
1591 
1592   // Present has failed. We need to fallback to validate
1593   std::vector<Layer> changedLayers;
1594   std::vector<IComposerClient::Composition> compositionTypes;
1595   uint32_t displayRequestMask = 0x0;
1596   std::vector<Layer> requestedLayers;
1597   std::vector<uint32_t> requestMasks;
1598   IComposerClient::ClientTargetProperty clientTargetProperty;
1599 
1600   auto err = validateDisplay(mDisplay, changedLayers, compositionTypes, displayRequestMask,
1601                              requestedLayers, requestMasks, clientTargetProperty);
1602   // mResources->setDisplayMustValidateState(mDisplay, false);
1603   if (err == Error::NONE) {
1604     mWriter.setPresentOrValidateResult(0);
1605     mWriter.setChangedCompositionTypes(changedLayers, compositionTypes);
1606     mWriter.setDisplayRequests(displayRequestMask, requestedLayers, requestMasks);
1607     if (mClient.mUseCallback24_) {
1608       mWriter.setClientTargetProperty(clientTargetProperty);
1609     }
1610   } else {
1611     mWriter.setError(getCommandLoc(), err);
1612   }
1613 
1614   return true;
1615 }
1616 
parseSetLayerCursorPosition(uint16_t length)1617 bool QtiComposerClient::CommandReader::parseSetLayerCursorPosition(uint16_t length) {
1618   if (length != CommandWriter::kSetLayerCursorPositionLength) {
1619     return false;
1620   }
1621 
1622   auto err = mClient.hwc_session_->SetCursorPosition(mDisplay, mLayer, readSigned(), readSigned());
1623   if (static_cast<Error>(err) != Error::NONE) {
1624     mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1625   }
1626 
1627   return true;
1628 }
1629 
parseSetLayerBuffer(uint16_t length)1630 bool QtiComposerClient::CommandReader::parseSetLayerBuffer(uint16_t length) {
1631   if (length != CommandWriter::kSetLayerBufferLength) {
1632     return false;
1633   }
1634 
1635   bool useCache;
1636   auto slot = read();
1637   auto buffer = readHandle(useCache);
1638   shared_ptr<Fence> fence = nullptr;
1639   readFence(&fence, "layer");
1640   auto error = lookupBuffer(BufferCache::LAYER_BUFFERS, slot, useCache, buffer, &buffer);
1641   if (error == Error::NONE) {
1642     auto err = mClient.hwc_session_->SetLayerBuffer(mDisplay, mLayer, buffer, fence);
1643     error = static_cast<Error>(err);
1644     auto updateBufErr = updateBuffer(BufferCache::LAYER_BUFFERS, slot, useCache, buffer);
1645     if (static_cast<Error>(error) == Error::NONE) {
1646       error = updateBufErr;
1647     }
1648   }
1649   if (static_cast<Error>(error) != Error::NONE) {
1650     mWriter.setError(getCommandLoc(), static_cast<Error>(error));
1651   }
1652 
1653   return true;
1654 }
1655 
parseSetLayerSurfaceDamage(uint16_t length)1656 bool QtiComposerClient::CommandReader::parseSetLayerSurfaceDamage(uint16_t length) {
1657   // N rectangles
1658   if (length % 4 != 0) {
1659     return false;
1660   }
1661 
1662   auto damage = readRegion(length / 4);
1663   hwc_region region = {damage.size(), damage.data()};
1664   auto err = mClient.hwc_session_->SetLayerSurfaceDamage(mDisplay, mLayer, region);
1665   if (static_cast<Error>(err) != Error::NONE) {
1666     mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1667   }
1668 
1669   return true;
1670 }
1671 
parseSetLayerBlendMode(uint16_t length)1672 bool QtiComposerClient::CommandReader::parseSetLayerBlendMode(uint16_t length) {
1673   if (length != CommandWriter::kSetLayerBlendModeLength) {
1674     return false;
1675   }
1676 
1677   auto err = mClient.hwc_session_->SetLayerBlendMode(mDisplay, mLayer, readSigned());
1678   if (static_cast<Error>(err) != Error::NONE) {
1679     mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1680   }
1681 
1682   return true;
1683 }
1684 
parseSetLayerColor(uint16_t length)1685 bool QtiComposerClient::CommandReader::parseSetLayerColor(uint16_t length) {
1686   if (length != CommandWriter::kSetLayerColorLength) {
1687     return false;
1688   }
1689   auto color = readColor();
1690   hwc_color_t hwc_color{color.r, color.g, color.b, color.a};
1691   auto err = mClient.hwc_session_->SetLayerColor(mDisplay, mLayer, hwc_color);
1692   if (static_cast<Error>(err) != Error::NONE) {
1693     mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1694   }
1695 
1696   return true;
1697 }
1698 
parseSetLayerCompositionType(uint16_t length)1699 bool QtiComposerClient::CommandReader::parseSetLayerCompositionType(uint16_t length) {
1700   if (length != CommandWriter::kSetLayerCompositionTypeLength) {
1701     return false;
1702   }
1703 
1704   auto err = mClient.hwc_session_->SetLayerCompositionType(mDisplay, mLayer, readSigned());
1705   if (static_cast<Error>(err) != Error::NONE) {
1706     mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1707   }
1708 
1709   return true;
1710 }
1711 
parseSetLayerDataspace(uint16_t length)1712 bool QtiComposerClient::CommandReader::parseSetLayerDataspace(uint16_t length) {
1713   if (length != CommandWriter::kSetLayerDataspaceLength) {
1714     return false;
1715   }
1716 
1717   auto err = mClient.hwc_session_->SetLayerDataspace(mDisplay, mLayer, readSigned());
1718   if (static_cast<Error>(err) != Error::NONE) {
1719     mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1720   }
1721 
1722   return true;
1723 }
1724 
parseSetLayerDisplayFrame(uint16_t length)1725 bool QtiComposerClient::CommandReader::parseSetLayerDisplayFrame(uint16_t length) {
1726   if (length != CommandWriter::kSetLayerDisplayFrameLength) {
1727     return false;
1728   }
1729 
1730   auto err = mClient.hwc_session_->SetLayerDisplayFrame(mDisplay, mLayer, readRect());
1731   if (static_cast<Error>(err) != Error::NONE) {
1732     mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1733   }
1734 
1735   return true;
1736 }
1737 
parseSetLayerPlaneAlpha(uint16_t length)1738 bool QtiComposerClient::CommandReader::parseSetLayerPlaneAlpha(uint16_t length) {
1739   if (length != CommandWriter::kSetLayerPlaneAlphaLength) {
1740     return false;
1741   }
1742 
1743   auto err = mClient.hwc_session_->SetLayerPlaneAlpha(mDisplay, mLayer, readFloat());
1744   if (static_cast<Error>(err) != Error::NONE) {
1745     mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1746   }
1747 
1748   return true;
1749 }
1750 
parseSetLayerSidebandStream(uint16_t length)1751 bool QtiComposerClient::CommandReader::parseSetLayerSidebandStream(uint16_t length) {
1752   if (length != CommandWriter::kSetLayerSidebandStreamLength) {
1753     return false;
1754   }
1755 
1756   // Sideband stream is not supported
1757   return true;
1758 }
1759 
parseSetLayerSourceCrop(uint16_t length)1760 bool QtiComposerClient::CommandReader::parseSetLayerSourceCrop(uint16_t length) {
1761   if (length != CommandWriter::kSetLayerSourceCropLength) {
1762     return false;
1763   }
1764 
1765   auto err = mClient.hwc_session_->SetLayerSourceCrop(mDisplay, mLayer, readFRect());
1766   if (static_cast<Error>(err) != Error::NONE) {
1767     mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1768   }
1769 
1770   return true;
1771 }
1772 
parseSetLayerTransform(uint16_t length)1773 bool QtiComposerClient::CommandReader::parseSetLayerTransform(uint16_t length) {
1774   if (length != CommandWriter::kSetLayerTransformLength) {
1775     return false;
1776   }
1777 
1778   auto err = mClient.hwc_session_->SetLayerTransform(mDisplay, mLayer, readSigned());
1779   if (static_cast<Error>(err) != Error::NONE) {
1780     mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1781   }
1782 
1783   return true;
1784 }
1785 
parseSetLayerVisibleRegion(uint16_t length)1786 bool QtiComposerClient::CommandReader::parseSetLayerVisibleRegion(uint16_t length) {
1787   // N rectangles
1788   if (length % 4 != 0) {
1789     return false;
1790   }
1791 
1792   auto region = readRegion(length / 4);
1793   hwc_region visibleRegion = {region.size(), region.data()};
1794   auto err = mClient.hwc_session_->SetLayerVisibleRegion(mDisplay, mLayer, visibleRegion);
1795   if (static_cast<Error>(err) != Error::NONE) {
1796     mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1797   }
1798 
1799   return true;
1800 }
1801 
parseSetLayerZOrder(uint16_t length)1802 bool QtiComposerClient::CommandReader::parseSetLayerZOrder(uint16_t length) {
1803   if (length != CommandWriter::kSetLayerZOrderLength) {
1804     return false;
1805   }
1806 
1807   auto err = mClient.hwc_session_->SetLayerZOrder(mDisplay, mLayer, read());
1808   if (static_cast<Error>(err) != Error::NONE) {
1809     mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1810   }
1811 
1812   return true;
1813 }
1814 
parseSetLayerType(uint16_t length)1815 bool QtiComposerClient::CommandReader::parseSetLayerType(uint16_t length) {
1816   if (length != CommandWriter::kSetLayerTypeLength) {
1817     return false;
1818   }
1819 
1820   auto err = mClient.hwc_session_->SetLayerType(mDisplay, mLayer,
1821             static_cast<IQtiComposerClient::LayerType>(read()));
1822   if (static_cast<Error>(err) != Error::NONE) {
1823     mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1824   }
1825 
1826   return true;
1827 }
1828 
parseSetLayerPerFrameMetadata(uint16_t length)1829 bool QtiComposerClient::CommandReader::parseSetLayerPerFrameMetadata(uint16_t length) {
1830   // (key, value) pairs
1831   if (length % 2 != 0) {
1832     return false;
1833   }
1834 
1835   std::vector<IComposerClient::PerFrameMetadata> metadata;
1836   metadata.reserve(length / 2);
1837   while (length > 0) {
1838     metadata.emplace_back(IComposerClient::PerFrameMetadata{
1839                           static_cast<IComposerClient::PerFrameMetadataKey>(readSigned()),
1840                           readFloat()});
1841     length -= 2;
1842   }
1843 
1844   std::vector<int32_t> keys;
1845   std::vector<float> values;
1846   keys.reserve(metadata.size());
1847   values.reserve(metadata.size());
1848   for (const auto& m : metadata) {
1849     keys.push_back(static_cast<int32_t>(m.key));
1850     values.push_back(m.value);
1851   }
1852 
1853   auto err = mClient.hwc_session_->SetLayerPerFrameMetadata(mDisplay, mLayer, metadata.size(),
1854                                                             keys.data(), values.data());
1855   if (static_cast<Error>(err) != Error::NONE) {
1856     mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1857   }
1858 
1859   return true;
1860 }
1861 
parseSetLayerFloatColor(uint16_t length)1862 bool QtiComposerClient::CommandReader::parseSetLayerFloatColor(uint16_t length) {
1863   if (length != CommandWriter::kSetLayerFloatColorLength) {
1864     return false;
1865   }
1866 
1867   // setLayerFloatColor is not supported
1868   auto err = Error::UNSUPPORTED;
1869   mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1870 
1871   return true;
1872 }
1873 
parseSetLayerColorTransform(uint16_t length)1874 bool QtiComposerClient::CommandReader::parseSetLayerColorTransform(uint16_t length) {
1875   if (length != CommandWriter::kSetLayerColorTransformLength) {
1876     return false;
1877   }
1878 
1879   float matrix[16];
1880   for (int i = 0; i < 16; i++) {
1881     matrix[i] = readFloat();
1882   }
1883 
1884   auto error = mClient.hwc_session_->SetLayerColorTransform(mDisplay, mLayer, matrix);
1885   if (static_cast<Error>(error) != Error::NONE) {
1886     mWriter.setError(getCommandLoc(), static_cast<Error>(error));
1887   }
1888 
1889   return true;
1890 }
1891 
parseSetLayerPerFrameMetadataBlobs(uint16_t length)1892 bool QtiComposerClient::CommandReader::parseSetLayerPerFrameMetadataBlobs(uint16_t length) {
1893   // must have at least one metadata blob
1894   // of at least size 1 in queue (i.e {/*numBlobs=*/1, key, size, blob})
1895   if (length < 4) {
1896     return false;
1897   }
1898 
1899   uint32_t numBlobs = read();
1900   length--;
1901   std::vector<IComposerClient::PerFrameMetadataBlob> metadata;
1902 
1903   for (size_t i = 0; i < numBlobs; i++) {
1904     IComposerClient::PerFrameMetadataKey key =
1905       static_cast<IComposerClient::PerFrameMetadataKey>(readSigned());
1906     uint32_t blobSize = read();
1907     length -= 2;
1908 
1909     if (length * sizeof(uint32_t) < blobSize) {
1910       return false;
1911     }
1912 
1913     metadata.push_back({key, std::vector<uint8_t>()});
1914     IComposerClient::PerFrameMetadataBlob& metadataBlob = metadata.back();
1915     metadataBlob.blob.resize(blobSize);
1916     readBlob(blobSize, metadataBlob.blob.data());
1917   }
1918 
1919   std::vector<int32_t> keys;
1920   std::vector<uint32_t> sizes_of_metablob_;
1921   std::vector<uint8_t> blob_of_data_;
1922   keys.reserve(metadata.size());
1923   sizes_of_metablob_.reserve(metadata.size());
1924   for (const auto& m : metadata) {
1925     keys.push_back(static_cast<int32_t>(m.key));
1926     sizes_of_metablob_.push_back(m.blob.size());
1927     for (size_t i = 0; i < m.blob.size(); i++) {
1928       blob_of_data_.push_back(m.blob[i]);
1929     }
1930   }
1931   auto err = mClient.hwc_session_->SetLayerPerFrameMetadataBlobs(mDisplay, mLayer, metadata.size(),
1932                                                                  keys.data(),
1933                                                                  sizes_of_metablob_.data(),
1934                                                                  blob_of_data_.data());
1935   if (static_cast<Error>(err) != Error::NONE) {
1936     mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1937   }
1938   return true;
1939 }
1940 
parseSetDisplayElapseTime(uint16_t length)1941 bool QtiComposerClient::CommandReader::parseSetDisplayElapseTime(uint16_t length) {
1942   if (length < CommandWriter::kSetDisplayElapseTime) {
1943     return false;
1944   }
1945   uint64_t time = read64();
1946 
1947   auto err = mClient.hwc_session_->SetDisplayElapseTime(mDisplay, time);
1948   if (static_cast<Error>(err) != Error::NONE) {
1949     mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1950   }
1951 
1952   return true;
1953 }
1954 
readRect()1955 hwc_rect_t QtiComposerClient::CommandReader::readRect() {
1956   return hwc_rect_t{
1957     readSigned(),
1958     readSigned(),
1959     readSigned(),
1960     readSigned(),
1961   };
1962 }
1963 
readRegion(size_t count)1964 std::vector<hwc_rect_t> QtiComposerClient::CommandReader::readRegion(size_t count) {
1965   std::vector<hwc_rect_t> region;
1966   region.reserve(count);
1967   while (count > 0) {
1968     region.emplace_back(readRect());
1969     count--;
1970   }
1971 
1972   return region;
1973 }
1974 
readFRect()1975 hwc_frect_t QtiComposerClient::CommandReader::readFRect() {
1976   return hwc_frect_t{
1977     readFloat(),
1978     readFloat(),
1979     readFloat(),
1980     readFloat(),
1981   };
1982 }
1983 
lookupBufferCacheEntryLocked(BufferCache cache,uint32_t slot,BufferCacheEntry ** outEntry)1984 Error QtiComposerClient::CommandReader::lookupBufferCacheEntryLocked(BufferCache cache,
1985                                                                      uint32_t slot,
1986                                                                      BufferCacheEntry** outEntry) {
1987   auto dpy = mClient.mDisplayData.find(mDisplay);
1988   if (dpy == mClient.mDisplayData.end()) {
1989     return Error::BAD_DISPLAY;
1990   }
1991 
1992   BufferCacheEntry* entry = nullptr;
1993   switch (cache) {
1994   case BufferCache::CLIENT_TARGETS:
1995     if (slot < dpy->second.ClientTargets.size()) {
1996       entry = &dpy->second.ClientTargets[slot];
1997     }
1998     break;
1999   case BufferCache::OUTPUT_BUFFERS:
2000     if (slot < dpy->second.OutputBuffers.size()) {
2001       entry = &dpy->second.OutputBuffers[slot];
2002     }
2003     break;
2004   case BufferCache::LAYER_BUFFERS:
2005     {
2006       auto ly = dpy->second.Layers.find(mLayer);
2007       if (ly == dpy->second.Layers.end()) {
2008         return Error::BAD_LAYER;
2009       }
2010       if (slot < ly->second.Buffers.size()) {
2011         entry = &ly->second.Buffers[slot];
2012       }
2013     }
2014     break;
2015   case BufferCache::LAYER_SIDEBAND_STREAMS:
2016     {
2017       auto ly = dpy->second.Layers.find(mLayer);
2018       if (ly == dpy->second.Layers.end()) {
2019         return Error::BAD_LAYER;
2020       }
2021       if (slot == 0) {
2022         entry = &ly->second.SidebandStream;
2023       }
2024     }
2025     break;
2026   default:
2027     break;
2028   }
2029 
2030   if (!entry) {
2031     ALOGW("invalid buffer slot %" PRIu32, slot);
2032     return Error::BAD_PARAMETER;
2033   }
2034 
2035   *outEntry = entry;
2036 
2037   return Error::NONE;
2038 }
2039 
lookupBuffer(BufferCache cache,uint32_t slot,bool useCache,buffer_handle_t handle,buffer_handle_t * outHandle)2040 Error QtiComposerClient::CommandReader::lookupBuffer(BufferCache cache, uint32_t slot,
2041                                                      bool useCache, buffer_handle_t handle,
2042                                                      buffer_handle_t* outHandle) {
2043   if (useCache) {
2044     std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
2045 
2046     BufferCacheEntry* entry;
2047     Error error = lookupBufferCacheEntryLocked(cache, slot, &entry);
2048     if (error != Error::NONE) {
2049       return error;
2050     }
2051 
2052     // input handle is ignored
2053     *outHandle = entry->getHandle();
2054   } else if (cache == BufferCache::LAYER_SIDEBAND_STREAMS) {
2055     if (handle) {
2056       *outHandle = native_handle_clone(handle);
2057       if (*outHandle == nullptr) {
2058         return Error::NO_RESOURCES;
2059       }
2060     }
2061   } else {
2062     if (!mHandleImporter.importBuffer(handle)) {
2063       return Error::NO_RESOURCES;
2064     }
2065 
2066     *outHandle = handle;
2067   }
2068 
2069   return Error::NONE;
2070 }
2071 
updateBuffer(BufferCache cache,uint32_t slot,bool useCache,buffer_handle_t handle)2072 Error QtiComposerClient::CommandReader::updateBuffer(BufferCache cache, uint32_t slot,
2073                                                      bool useCache, buffer_handle_t handle) {
2074   // handle was looked up from cache
2075   if (useCache) {
2076     return Error::NONE;
2077   }
2078 
2079   std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
2080 
2081   BufferCacheEntry* entry = nullptr;
2082   Error error = lookupBufferCacheEntryLocked(cache, slot, &entry);
2083   if (error != Error::NONE) {
2084     return error;
2085   }
2086 
2087   *entry = handle;
2088   return Error::NONE;
2089 }
2090 // Methods from ::android::hidl::base::V1_0::IBase follow.
2091 
HIDL_FETCH_IQtiComposerClient(const char *)2092 IQtiComposerClient* HIDL_FETCH_IQtiComposerClient(const char* /* name */) {
2093   return QtiComposerClient::CreateQtiComposerClientInstance();
2094 }
2095 
2096 }  // namespace implementation
2097 }  // namespace V3_0
2098 }  // namespace composer
2099 }  // namespace display
2100 }  // namespace hardware
2101 }  // namespace qti
2102 }  // namespace vendor
2103