• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 The Chromium OS Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6 
7 #include "cros_gralloc/gralloc4/CrosGralloc4Mapper.h"
8 
9 #include <aidl/android/hardware/graphics/common/BlendMode.h>
10 #include <aidl/android/hardware/graphics/common/Dataspace.h>
11 #include <aidl/android/hardware/graphics/common/PlaneLayout.h>
12 #include <aidl/android/hardware/graphics/common/Rect.h>
13 #include <cutils/native_handle.h>
14 #include <gralloctypes/Gralloc4.h>
15 
16 #include "cros_gralloc/cros_gralloc_helpers.h"
17 #include "cros_gralloc/gralloc4/CrosGralloc4Utils.h"
18 
19 using aidl::android::hardware::graphics::common::BlendMode;
20 using aidl::android::hardware::graphics::common::Dataspace;
21 using aidl::android::hardware::graphics::common::PlaneLayout;
22 using aidl::android::hardware::graphics::common::Rect;
23 using android::hardware::hidl_handle;
24 using android::hardware::hidl_vec;
25 using android::hardware::Return;
26 using android::hardware::Void;
27 using android::hardware::graphics::common::V1_2::BufferUsage;
28 using android::hardware::graphics::common::V1_2::PixelFormat;
29 using android::hardware::graphics::mapper::V4_0::Error;
30 using android::hardware::graphics::mapper::V4_0::IMapper;
31 
createDescriptor(const BufferDescriptorInfo & description,createDescriptor_cb hidlCb)32 Return<void> CrosGralloc4Mapper::createDescriptor(const BufferDescriptorInfo& description,
33                                                   createDescriptor_cb hidlCb) {
34     hidl_vec<uint8_t> descriptor;
35 
36     if (description.width == 0) {
37         ALOGE("Failed to createDescriptor. Bad width: %d.", description.width);
38         hidlCb(Error::BAD_VALUE, descriptor);
39         return Void();
40     }
41 
42     if (description.height == 0) {
43         ALOGE("Failed to createDescriptor. Bad height: %d.", description.height);
44         hidlCb(Error::BAD_VALUE, descriptor);
45         return Void();
46     }
47 
48     if (description.layerCount == 0) {
49         ALOGE("Failed to createDescriptor. Bad layer count: %d.", description.layerCount);
50         hidlCb(Error::BAD_VALUE, descriptor);
51         return Void();
52     }
53 
54     int ret = android::gralloc4::encodeBufferDescriptorInfo(description, &descriptor);
55     if (ret) {
56         ALOGE("Failed to createDescriptor. Failed to encode: %d.", ret);
57         hidlCb(Error::BAD_VALUE, descriptor);
58         return Void();
59     }
60 
61     hidlCb(Error::NONE, descriptor);
62     return Void();
63 }
64 
importBuffer(const hidl_handle & handle,importBuffer_cb hidlCb)65 Return<void> CrosGralloc4Mapper::importBuffer(const hidl_handle& handle, importBuffer_cb hidlCb) {
66     if (!mDriver) {
67         ALOGE("Failed to import buffer. Driver is uninitialized.");
68         hidlCb(Error::NO_RESOURCES, nullptr);
69         return Void();
70     }
71 
72     const native_handle_t* bufferHandle = handle.getNativeHandle();
73     if (!bufferHandle || bufferHandle->numFds == 0) {
74         ALOGE("Failed to importBuffer. Bad handle.");
75         hidlCb(Error::BAD_BUFFER, nullptr);
76         return Void();
77     }
78 
79     native_handle_t* importedBufferHandle = native_handle_clone(bufferHandle);
80     if (!importedBufferHandle) {
81         ALOGE("Failed to importBuffer. Handle clone failed: %s.", strerror(errno));
82         hidlCb(Error::NO_RESOURCES, nullptr);
83         return Void();
84     }
85 
86     int ret = mDriver->retain(importedBufferHandle);
87     if (ret) {
88         native_handle_close(importedBufferHandle);
89         native_handle_delete(importedBufferHandle);
90         hidlCb(Error::NO_RESOURCES, nullptr);
91         return Void();
92     }
93 
94     hidlCb(Error::NONE, importedBufferHandle);
95     return Void();
96 }
97 
freeBuffer(void * rawHandle)98 Return<Error> CrosGralloc4Mapper::freeBuffer(void* rawHandle) {
99     if (!mDriver) {
100         ALOGE("Failed to freeBuffer. Driver is uninitialized.");
101         return Error::NO_RESOURCES;
102     }
103 
104     native_handle_t* bufferHandle = reinterpret_cast<native_handle_t*>(rawHandle);
105     if (!bufferHandle) {
106         ALOGE("Failed to freeBuffer. Empty handle.");
107         return Error::BAD_BUFFER;
108     }
109 
110     int ret = mDriver->release(bufferHandle);
111     if (ret) {
112         return Error::BAD_BUFFER;
113     }
114 
115     native_handle_close(bufferHandle);
116     native_handle_delete(bufferHandle);
117     return Error::NONE;
118 }
119 
validateBufferSize(void * rawHandle,const BufferDescriptorInfo & descriptor,uint32_t stride)120 Return<Error> CrosGralloc4Mapper::validateBufferSize(void* rawHandle,
121                                                      const BufferDescriptorInfo& descriptor,
122                                                      uint32_t stride) {
123     if (!mDriver) {
124         ALOGE("Failed to validateBufferSize. Driver is uninitialized.");
125         return Error::NO_RESOURCES;
126     }
127 
128     native_handle_t* bufferHandle = reinterpret_cast<native_handle_t*>(rawHandle);
129     if (!bufferHandle) {
130         ALOGE("Failed to validateBufferSize. Empty handle.");
131         return Error::BAD_BUFFER;
132     }
133 
134     cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
135     if (!crosHandle) {
136         ALOGE("Failed to validateBufferSize. Invalid handle.");
137         return Error::BAD_BUFFER;
138     }
139 
140     PixelFormat crosHandleFormat = static_cast<PixelFormat>(crosHandle->droid_format);
141     if (descriptor.format != crosHandleFormat) {
142         ALOGE("Failed to validateBufferSize. Format mismatch.");
143         return Error::BAD_BUFFER;
144     }
145 
146     if (descriptor.width != crosHandle->width) {
147         ALOGE("Failed to validateBufferSize. Width mismatch (%d vs %d).", descriptor.width,
148               crosHandle->width);
149         return Error::BAD_VALUE;
150     }
151 
152     if (descriptor.height != crosHandle->height) {
153         ALOGE("Failed to validateBufferSize. Height mismatch (%d vs %d).", descriptor.height,
154               crosHandle->height);
155         return Error::BAD_VALUE;
156     }
157 
158     if (crosHandle->droid_format == HAL_PIXEL_FORMAT_BLOB) {
159         if (stride > crosHandle->pixel_stride) {
160             ALOGE("Failed to validateBufferSize. Oversized stride (%d vs %d).", stride,
161                   crosHandle->pixel_stride);
162             return Error::BAD_VALUE;
163         }
164     } else if (stride != crosHandle->pixel_stride) {
165         ALOGE("Failed to validateBufferSize. Stride mismatch (%d vs %d).", stride,
166               crosHandle->pixel_stride);
167         return Error::BAD_VALUE;
168     }
169 
170     return Error::NONE;
171 }
172 
getTransportSize(void * rawHandle,getTransportSize_cb hidlCb)173 Return<void> CrosGralloc4Mapper::getTransportSize(void* rawHandle, getTransportSize_cb hidlCb) {
174     if (!mDriver) {
175         ALOGE("Failed to getTransportSize. Driver is uninitialized.");
176         hidlCb(Error::BAD_BUFFER, 0, 0);
177         return Void();
178     }
179 
180     native_handle_t* bufferHandle = reinterpret_cast<native_handle_t*>(rawHandle);
181     if (!bufferHandle) {
182         ALOGE("Failed to getTransportSize. Bad handle.");
183         hidlCb(Error::BAD_BUFFER, 0, 0);
184         return Void();
185     }
186 
187     // No local process data is currently stored on the native handle.
188     hidlCb(Error::NONE, bufferHandle->numFds, bufferHandle->numInts);
189     return Void();
190 }
191 
lock(void * rawBuffer,uint64_t cpuUsage,const Rect & region,const hidl_handle & acquireFence,lock_cb hidlCb)192 Return<void> CrosGralloc4Mapper::lock(void* rawBuffer, uint64_t cpuUsage, const Rect& region,
193                                       const hidl_handle& acquireFence, lock_cb hidlCb) {
194     if (!mDriver) {
195         ALOGE("Failed to lock. Driver is uninitialized.");
196         hidlCb(Error::NO_RESOURCES, nullptr);
197         return Void();
198     }
199 
200     buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawBuffer);
201     if (!bufferHandle) {
202         ALOGE("Failed to lock. Empty handle.");
203         hidlCb(Error::BAD_BUFFER, nullptr);
204         return Void();
205     }
206 
207     if (cpuUsage == 0) {
208         ALOGE("Failed to lock. Bad cpu usage: %" PRIu64 ".", cpuUsage);
209         hidlCb(Error::BAD_VALUE, nullptr);
210         return Void();
211     }
212 
213     uint32_t mapUsage = 0;
214     int ret = convertToMapUsage(cpuUsage, &mapUsage);
215     if (ret) {
216         ALOGE("Failed to lock. Convert usage failed.");
217         hidlCb(Error::BAD_VALUE, nullptr);
218         return Void();
219     }
220 
221     cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
222     if (crosHandle == nullptr) {
223         ALOGE("Failed to lock. Invalid handle.");
224         hidlCb(Error::BAD_VALUE, nullptr);
225         return Void();
226     }
227 
228     if (region.left < 0) {
229         ALOGE("Failed to lock. Invalid region: negative left value %d.", region.left);
230         hidlCb(Error::BAD_VALUE, nullptr);
231         return Void();
232     }
233 
234     if (region.top < 0) {
235         ALOGE("Failed to lock. Invalid region: negative top value %d.", region.top);
236         hidlCb(Error::BAD_VALUE, nullptr);
237         return Void();
238     }
239 
240     if (region.width < 0) {
241         ALOGE("Failed to lock. Invalid region: negative width value %d.", region.width);
242         hidlCb(Error::BAD_VALUE, nullptr);
243         return Void();
244     }
245 
246     if (region.height < 0) {
247         ALOGE("Failed to lock. Invalid region: negative height value %d.", region.height);
248         hidlCb(Error::BAD_VALUE, nullptr);
249         return Void();
250     }
251 
252     if (region.width > crosHandle->width) {
253         ALOGE("Failed to lock. Invalid region: width greater than buffer width (%d vs %d).",
254               region.width, crosHandle->width);
255         hidlCb(Error::BAD_VALUE, nullptr);
256         return Void();
257     }
258 
259     if (region.height > crosHandle->height) {
260         ALOGE("Failed to lock. Invalid region: height greater than buffer height (%d vs %d).",
261               region.height, crosHandle->height);
262         hidlCb(Error::BAD_VALUE, nullptr);
263         return Void();
264     }
265 
266     struct rectangle rect = {static_cast<uint32_t>(region.left), static_cast<uint32_t>(region.top),
267                              static_cast<uint32_t>(region.width),
268                              static_cast<uint32_t>(region.height)};
269 
270     // An access region of all zeros means the entire buffer.
271     if (rect.x == 0 && rect.y == 0 && rect.width == 0 && rect.height == 0) {
272         rect.width = crosHandle->width;
273         rect.height = crosHandle->height;
274     }
275 
276     int acquireFenceFd = -1;
277     ret = convertToFenceFd(acquireFence, &acquireFenceFd);
278     if (ret) {
279         ALOGE("Failed to lock. Bad acquire fence.");
280         hidlCb(Error::BAD_VALUE, nullptr);
281         return Void();
282     }
283 
284     uint8_t* addr[DRV_MAX_PLANES];
285     ret = mDriver->lock(bufferHandle, acquireFenceFd, /*close_acquire_fence=*/false, &rect,
286                         mapUsage, addr);
287     if (ret) {
288         hidlCb(Error::BAD_VALUE, nullptr);
289         return Void();
290     }
291 
292     hidlCb(Error::NONE, addr[0]);
293     return Void();
294 }
295 
unlock(void * rawHandle,unlock_cb hidlCb)296 Return<void> CrosGralloc4Mapper::unlock(void* rawHandle, unlock_cb hidlCb) {
297     if (!mDriver) {
298         ALOGE("Failed to unlock. Driver is uninitialized.");
299         hidlCb(Error::BAD_BUFFER, nullptr);
300         return Void();
301     }
302 
303     buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
304     if (!bufferHandle) {
305         ALOGE("Failed to unlock. Empty handle.");
306         hidlCb(Error::BAD_BUFFER, nullptr);
307         return Void();
308     }
309 
310     int releaseFenceFd = -1;
311     int ret = mDriver->unlock(bufferHandle, &releaseFenceFd);
312     if (ret) {
313         ALOGE("Failed to unlock.");
314         hidlCb(Error::BAD_BUFFER, nullptr);
315         return Void();
316     }
317 
318     hidl_handle releaseFenceHandle;
319     ret = convertToFenceHandle(releaseFenceFd, &releaseFenceHandle);
320     if (ret) {
321         ALOGE("Failed to unlock. Failed to convert release fence to handle.");
322         hidlCb(Error::BAD_BUFFER, nullptr);
323         return Void();
324     }
325 
326     hidlCb(Error::NONE, releaseFenceHandle);
327     return Void();
328 }
329 
flushLockedBuffer(void * rawHandle,flushLockedBuffer_cb hidlCb)330 Return<void> CrosGralloc4Mapper::flushLockedBuffer(void* rawHandle, flushLockedBuffer_cb hidlCb) {
331     if (!mDriver) {
332         ALOGE("Failed to flushLockedBuffer. Driver is uninitialized.");
333         hidlCb(Error::NO_RESOURCES, nullptr);
334         return Void();
335     }
336 
337     buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
338     if (!bufferHandle) {
339         ALOGE("Failed to flushLockedBuffer. Empty handle.");
340         hidlCb(Error::BAD_BUFFER, nullptr);
341         return Void();
342     }
343 
344     /*
345      * From the ANativeWindow::dequeueBuffer documentation:
346      *
347      * "A value of -1 indicates that the caller may access the buffer immediately without
348      * waiting on a fence."
349      */
350     int releaseFenceFd = -1;
351     int ret = mDriver->flush(bufferHandle);
352     if (ret) {
353         ALOGE("Failed to flushLockedBuffer. Flush failed.");
354         hidlCb(Error::BAD_BUFFER, nullptr);
355         return Void();
356     }
357 
358     hidl_handle releaseFenceHandle;
359     ret = convertToFenceHandle(releaseFenceFd, &releaseFenceHandle);
360     if (ret) {
361         ALOGE("Failed to flushLockedBuffer. Failed to convert release fence to handle.");
362         hidlCb(Error::BAD_BUFFER, nullptr);
363         return Void();
364     }
365 
366     hidlCb(Error::NONE, releaseFenceHandle);
367     return Void();
368 }
369 
rereadLockedBuffer(void * rawHandle)370 Return<Error> CrosGralloc4Mapper::rereadLockedBuffer(void* rawHandle) {
371     if (!mDriver) {
372         ALOGE("Failed to rereadLockedBuffer. Driver is uninitialized.");
373         return Error::NO_RESOURCES;
374     }
375 
376     buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
377     if (!bufferHandle) {
378         ALOGE("Failed to rereadLockedBuffer. Empty handle.");
379         return Error::BAD_BUFFER;
380     }
381 
382     int ret = mDriver->invalidate(bufferHandle);
383     if (ret) {
384         ALOGE("Failed to rereadLockedBuffer. Failed to invalidate.");
385         return Error::BAD_BUFFER;
386     }
387 
388     return Error::NONE;
389 }
390 
isSupported(const BufferDescriptorInfo & descriptor,isSupported_cb hidlCb)391 Return<void> CrosGralloc4Mapper::isSupported(const BufferDescriptorInfo& descriptor,
392                                              isSupported_cb hidlCb) {
393     if (!mDriver) {
394         ALOGE("Failed to isSupported. Driver is uninitialized.");
395         hidlCb(Error::BAD_VALUE, false);
396         return Void();
397     }
398 
399     struct cros_gralloc_buffer_descriptor crosDescriptor;
400     if (convertToCrosDescriptor(descriptor, &crosDescriptor)) {
401         hidlCb(Error::NONE, false);
402         return Void();
403     }
404 
405     hidlCb(Error::NONE, mDriver->is_supported(&crosDescriptor));
406     return Void();
407 }
408 
get(void * rawHandle,const MetadataType & metadataType,get_cb hidlCb)409 Return<void> CrosGralloc4Mapper::get(void* rawHandle, const MetadataType& metadataType,
410                                      get_cb hidlCb) {
411     hidl_vec<uint8_t> encodedMetadata;
412 
413     if (!mDriver) {
414         ALOGE("Failed to get. Driver is uninitialized.");
415         hidlCb(Error::NO_RESOURCES, encodedMetadata);
416         return Void();
417     }
418 
419     buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
420     if (!bufferHandle) {
421         ALOGE("Failed to get. Empty handle.");
422         hidlCb(Error::BAD_BUFFER, encodedMetadata);
423         return Void();
424     }
425 
426     cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
427     if (!crosHandle) {
428         ALOGE("Failed to get. Invalid handle.");
429         hidlCb(Error::BAD_BUFFER, encodedMetadata);
430         return Void();
431     }
432 
433     mDriver->with_buffer(crosHandle, [&, this](cros_gralloc_buffer* crosBuffer) {
434         get(crosBuffer, metadataType, hidlCb);
435     });
436     return Void();
437 }
438 
get(const cros_gralloc_buffer * crosBuffer,const MetadataType & metadataType,get_cb hidlCb)439 Return<void> CrosGralloc4Mapper::get(const cros_gralloc_buffer* crosBuffer,
440                                      const MetadataType& metadataType, get_cb hidlCb) {
441     hidl_vec<uint8_t> encodedMetadata;
442 
443     if (!mDriver) {
444         ALOGE("Failed to get. Driver is uninitialized.");
445         hidlCb(Error::NO_RESOURCES, encodedMetadata);
446         return Void();
447     }
448 
449     if (!crosBuffer) {
450         ALOGE("Failed to get. Invalid buffer.");
451         hidlCb(Error::BAD_BUFFER, encodedMetadata);
452         return Void();
453     }
454 
455     const CrosGralloc4Metadata* crosMetadata = nullptr;
456     if (metadataType == android::gralloc4::MetadataType_BlendMode ||
457         metadataType == android::gralloc4::MetadataType_Cta861_3 ||
458         metadataType == android::gralloc4::MetadataType_Dataspace ||
459         metadataType == android::gralloc4::MetadataType_Name ||
460         metadataType == android::gralloc4::MetadataType_Smpte2086) {
461         Error error = getMetadata(crosBuffer, &crosMetadata);
462         if (error != Error::NONE) {
463             ALOGE("Failed to get. Failed to get buffer metadata.");
464             hidlCb(Error::NO_RESOURCES, encodedMetadata);
465             return Void();
466         }
467     }
468 
469     android::status_t status = android::NO_ERROR;
470     if (metadataType == android::gralloc4::MetadataType_BufferId) {
471         status = android::gralloc4::encodeBufferId(crosBuffer->get_id(), &encodedMetadata);
472     } else if (metadataType == android::gralloc4::MetadataType_Name) {
473         status = android::gralloc4::encodeName(crosMetadata->name, &encodedMetadata);
474     } else if (metadataType == android::gralloc4::MetadataType_Width) {
475         status = android::gralloc4::encodeWidth(crosBuffer->get_width(), &encodedMetadata);
476     } else if (metadataType == android::gralloc4::MetadataType_Height) {
477         status = android::gralloc4::encodeHeight(crosBuffer->get_height(), &encodedMetadata);
478     } else if (metadataType == android::gralloc4::MetadataType_LayerCount) {
479         status = android::gralloc4::encodeLayerCount(1, &encodedMetadata);
480     } else if (metadataType == android::gralloc4::MetadataType_PixelFormatRequested) {
481         PixelFormat pixelFormat = static_cast<PixelFormat>(crosBuffer->get_android_format());
482         status = android::gralloc4::encodePixelFormatRequested(pixelFormat, &encodedMetadata);
483     } else if (metadataType == android::gralloc4::MetadataType_PixelFormatFourCC) {
484         status = android::gralloc4::encodePixelFormatFourCC(
485                 drv_get_standard_fourcc(crosBuffer->get_format()), &encodedMetadata);
486     } else if (metadataType == android::gralloc4::MetadataType_PixelFormatModifier) {
487         status = android::gralloc4::encodePixelFormatModifier(crosBuffer->get_format_modifier(),
488                                                               &encodedMetadata);
489     } else if (metadataType == android::gralloc4::MetadataType_Usage) {
490         status = android::gralloc4::encodeUsage(crosBuffer->get_android_usage(), &encodedMetadata);
491     } else if (metadataType == android::gralloc4::MetadataType_AllocationSize) {
492         status = android::gralloc4::encodeAllocationSize(crosBuffer->get_total_size(),
493                                                          &encodedMetadata);
494     } else if (metadataType == android::gralloc4::MetadataType_ProtectedContent) {
495         uint64_t hasProtectedContent =
496                 crosBuffer->get_android_usage() & BufferUsage::PROTECTED ? 1 : 0;
497         status = android::gralloc4::encodeProtectedContent(hasProtectedContent, &encodedMetadata);
498     } else if (metadataType == android::gralloc4::MetadataType_Compression) {
499         status = android::gralloc4::encodeCompression(android::gralloc4::Compression_None,
500                                                       &encodedMetadata);
501     } else if (metadataType == android::gralloc4::MetadataType_Interlaced) {
502         status = android::gralloc4::encodeInterlaced(android::gralloc4::Interlaced_None,
503                                                      &encodedMetadata);
504     } else if (metadataType == android::gralloc4::MetadataType_ChromaSiting) {
505         status = android::gralloc4::encodeChromaSiting(android::gralloc4::ChromaSiting_None,
506                                                        &encodedMetadata);
507     } else if (metadataType == android::gralloc4::MetadataType_PlaneLayouts) {
508         std::vector<PlaneLayout> planeLayouts;
509         getPlaneLayouts(crosBuffer->get_format(), &planeLayouts);
510 
511         for (size_t plane = 0; plane < planeLayouts.size(); plane++) {
512             PlaneLayout& planeLayout = planeLayouts[plane];
513             planeLayout.offsetInBytes = crosBuffer->get_plane_offset(plane);
514             planeLayout.strideInBytes = crosBuffer->get_plane_stride(plane);
515             planeLayout.totalSizeInBytes = crosBuffer->get_plane_size(plane);
516             planeLayout.widthInSamples =
517                     crosBuffer->get_width() / planeLayout.horizontalSubsampling;
518             planeLayout.heightInSamples =
519                     crosBuffer->get_height() / planeLayout.verticalSubsampling;
520         }
521 
522         status = android::gralloc4::encodePlaneLayouts(planeLayouts, &encodedMetadata);
523     } else if (metadataType == android::gralloc4::MetadataType_Crop) {
524         const uint32_t numPlanes = crosBuffer->get_num_planes();
525         const uint32_t w = crosBuffer->get_width();
526         const uint32_t h = crosBuffer->get_height();
527         std::vector<aidl::android::hardware::graphics::common::Rect> crops;
528         for (uint32_t plane = 0; plane < numPlanes; plane++) {
529             aidl::android::hardware::graphics::common::Rect crop;
530             crop.left = 0;
531             crop.top = 0;
532             crop.right = w;
533             crop.bottom = h;
534             crops.push_back(crop);
535         }
536 
537         status = android::gralloc4::encodeCrop(crops, &encodedMetadata);
538     } else if (metadataType == android::gralloc4::MetadataType_Dataspace) {
539         status = android::gralloc4::encodeDataspace(crosMetadata->dataspace, &encodedMetadata);
540     } else if (metadataType == android::gralloc4::MetadataType_BlendMode) {
541         status = android::gralloc4::encodeBlendMode(crosMetadata->blendMode, &encodedMetadata);
542     } else if (metadataType == android::gralloc4::MetadataType_Smpte2086) {
543         status = android::gralloc4::encodeSmpte2086(crosMetadata->smpte2086, &encodedMetadata);
544     } else if (metadataType == android::gralloc4::MetadataType_Cta861_3) {
545         status = android::gralloc4::encodeCta861_3(crosMetadata->cta861_3, &encodedMetadata);
546     } else if (metadataType == android::gralloc4::MetadataType_Smpte2094_40) {
547         status = android::gralloc4::encodeSmpte2094_40(std::nullopt, &encodedMetadata);
548     } else {
549         hidlCb(Error::UNSUPPORTED, encodedMetadata);
550         return Void();
551     }
552 
553     if (status != android::NO_ERROR) {
554         hidlCb(Error::NO_RESOURCES, encodedMetadata);
555         ALOGE("Failed to get. Failed to encode metadata.");
556         return Void();
557     }
558 
559     hidlCb(Error::NONE, encodedMetadata);
560     return Void();
561 }
562 
set(void * rawHandle,const MetadataType & metadataType,const hidl_vec<uint8_t> & encodedMetadata)563 Return<Error> CrosGralloc4Mapper::set(void* rawHandle, const MetadataType& metadataType,
564                                       const hidl_vec<uint8_t>& encodedMetadata) {
565     if (!mDriver) {
566         ALOGE("Failed to set. Driver is uninitialized.");
567         return Error::NO_RESOURCES;
568     }
569 
570     buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
571     if (!bufferHandle) {
572         ALOGE("Failed to set. Empty handle.");
573         return Error::BAD_BUFFER;
574     }
575 
576     cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
577     if (!crosHandle) {
578         ALOGE("Failed to set. Invalid handle.");
579         return Error::BAD_BUFFER;
580     }
581 
582     if (metadataType == android::gralloc4::MetadataType_BufferId) {
583         return Error::BAD_VALUE;
584     } else if (metadataType == android::gralloc4::MetadataType_Name) {
585         return Error::BAD_VALUE;
586     } else if (metadataType == android::gralloc4::MetadataType_Width) {
587         return Error::BAD_VALUE;
588     } else if (metadataType == android::gralloc4::MetadataType_Height) {
589         return Error::BAD_VALUE;
590     } else if (metadataType == android::gralloc4::MetadataType_LayerCount) {
591         return Error::BAD_VALUE;
592     } else if (metadataType == android::gralloc4::MetadataType_PixelFormatRequested) {
593         return Error::BAD_VALUE;
594     } else if (metadataType == android::gralloc4::MetadataType_Usage) {
595         return Error::BAD_VALUE;
596     }
597 
598     if (metadataType != android::gralloc4::MetadataType_BlendMode &&
599         metadataType != android::gralloc4::MetadataType_Cta861_3 &&
600         metadataType != android::gralloc4::MetadataType_Dataspace &&
601         metadataType != android::gralloc4::MetadataType_Smpte2086) {
602         return Error::UNSUPPORTED;
603     }
604 
605     Error error = Error::NONE;
606     mDriver->with_buffer(crosHandle, [&, this](cros_gralloc_buffer* crosBuffer) {
607         error = set(crosBuffer, metadataType, encodedMetadata);
608     });
609 
610     return error;
611 }
612 
set(cros_gralloc_buffer * crosBuffer,const MetadataType & metadataType,const android::hardware::hidl_vec<uint8_t> & encodedMetadata)613 Error CrosGralloc4Mapper::set(cros_gralloc_buffer* crosBuffer, const MetadataType& metadataType,
614                               const android::hardware::hidl_vec<uint8_t>& encodedMetadata) {
615     if (!mDriver) {
616         ALOGE("Failed to set. Driver is uninitialized.");
617         return Error::NO_RESOURCES;
618     }
619 
620     if (!crosBuffer) {
621         ALOGE("Failed to set. Invalid buffer.");
622         return Error::BAD_BUFFER;
623     }
624 
625     CrosGralloc4Metadata* crosMetadata = nullptr;
626 
627     Error error = getMutableMetadata(crosBuffer, &crosMetadata);
628     if (error != Error::NONE) {
629         ALOGE("Failed to set. Failed to get buffer metadata.");
630         return Error::UNSUPPORTED;
631     }
632 
633     if (metadataType == android::gralloc4::MetadataType_BlendMode) {
634         auto status = android::gralloc4::decodeBlendMode(encodedMetadata, &crosMetadata->blendMode);
635         if (status != android::NO_ERROR) {
636             ALOGE("Failed to set. Failed to decode blend mode.");
637             return Error::UNSUPPORTED;
638         }
639     } else if (metadataType == android::gralloc4::MetadataType_Cta861_3) {
640         auto status = android::gralloc4::decodeCta861_3(encodedMetadata, &crosMetadata->cta861_3);
641         if (status != android::NO_ERROR) {
642             ALOGE("Failed to set. Failed to decode cta861_3.");
643             return Error::UNSUPPORTED;
644         }
645     } else if (metadataType == android::gralloc4::MetadataType_Dataspace) {
646         auto status = android::gralloc4::decodeDataspace(encodedMetadata, &crosMetadata->dataspace);
647         if (status != android::NO_ERROR) {
648             ALOGE("Failed to set. Failed to decode dataspace.");
649             return Error::UNSUPPORTED;
650         }
651     } else if (metadataType == android::gralloc4::MetadataType_Smpte2086) {
652         auto status = android::gralloc4::decodeSmpte2086(encodedMetadata, &crosMetadata->smpte2086);
653         if (status != android::NO_ERROR) {
654             ALOGE("Failed to set. Failed to decode smpte2086.");
655             return Error::UNSUPPORTED;
656         }
657     }
658 
659     return Error::NONE;
660 }
661 
getResolvedDrmFormat(PixelFormat pixelFormat,uint64_t bufferUsage,uint32_t * outDrmFormat)662 int CrosGralloc4Mapper::getResolvedDrmFormat(PixelFormat pixelFormat, uint64_t bufferUsage,
663                                              uint32_t* outDrmFormat) {
664     uint32_t drmFormat;
665     if (convertToDrmFormat(pixelFormat, &drmFormat)) {
666         std::string pixelFormatString = getPixelFormatString(pixelFormat);
667         ALOGE("Failed to getResolvedDrmFormat. Failed to convert format %s",
668               pixelFormatString.c_str());
669         return -EINVAL;
670     }
671 
672     uint64_t usage;
673     if (convertToBufferUsage(bufferUsage, &usage)) {
674         std::string usageString = getUsageString(bufferUsage);
675         ALOGE("Failed to getResolvedDrmFormat. Failed to convert usage %s", usageString.c_str());
676         return -EINVAL;
677     }
678 
679     uint32_t resolvedDrmFormat = mDriver->get_resolved_drm_format(drmFormat, usage);
680     if (resolvedDrmFormat == DRM_FORMAT_INVALID) {
681         std::string drmFormatString = get_drm_format_string(drmFormat);
682         ALOGE("Failed to getResolvedDrmFormat. Failed to resolve drm format %s",
683               drmFormatString.c_str());
684         return -EINVAL;
685     }
686 
687     *outDrmFormat = resolvedDrmFormat;
688 
689     return 0;
690 }
691 
getFromBufferDescriptorInfo(const BufferDescriptorInfo & descriptor,const MetadataType & metadataType,getFromBufferDescriptorInfo_cb hidlCb)692 Return<void> CrosGralloc4Mapper::getFromBufferDescriptorInfo(
693         const BufferDescriptorInfo& descriptor, const MetadataType& metadataType,
694         getFromBufferDescriptorInfo_cb hidlCb) {
695     hidl_vec<uint8_t> encodedMetadata;
696 
697     if (!mDriver) {
698         ALOGE("Failed to getFromBufferDescriptorInfo. Driver is uninitialized.");
699         hidlCb(Error::NO_RESOURCES, encodedMetadata);
700         return Void();
701     }
702 
703     android::status_t status = android::NO_ERROR;
704     if (metadataType == android::gralloc4::MetadataType_Name) {
705         status = android::gralloc4::encodeName(descriptor.name, &encodedMetadata);
706     } else if (metadataType == android::gralloc4::MetadataType_Width) {
707         status = android::gralloc4::encodeWidth(descriptor.width, &encodedMetadata);
708     } else if (metadataType == android::gralloc4::MetadataType_Height) {
709         status = android::gralloc4::encodeHeight(descriptor.height, &encodedMetadata);
710     } else if (metadataType == android::gralloc4::MetadataType_LayerCount) {
711         status = android::gralloc4::encodeLayerCount(1, &encodedMetadata);
712     } else if (metadataType == android::gralloc4::MetadataType_PixelFormatRequested) {
713         status = android::gralloc4::encodePixelFormatRequested(descriptor.format, &encodedMetadata);
714     } else if (metadataType == android::gralloc4::MetadataType_PixelFormatFourCC) {
715         uint32_t drmFormat;
716         if (getResolvedDrmFormat(descriptor.format, descriptor.usage, &drmFormat)) {
717             hidlCb(Error::BAD_VALUE, encodedMetadata);
718             return Void();
719         }
720         status = android::gralloc4::encodePixelFormatFourCC(drv_get_standard_fourcc(drmFormat),
721                                                             &encodedMetadata);
722     } else if (metadataType == android::gralloc4::MetadataType_Usage) {
723         status = android::gralloc4::encodeUsage(descriptor.usage, &encodedMetadata);
724     } else if (metadataType == android::gralloc4::MetadataType_ProtectedContent) {
725         uint64_t hasProtectedContent = descriptor.usage & BufferUsage::PROTECTED ? 1 : 0;
726         status = android::gralloc4::encodeProtectedContent(hasProtectedContent, &encodedMetadata);
727     } else if (metadataType == android::gralloc4::MetadataType_Compression) {
728         status = android::gralloc4::encodeCompression(android::gralloc4::Compression_None,
729                                                       &encodedMetadata);
730     } else if (metadataType == android::gralloc4::MetadataType_Interlaced) {
731         status = android::gralloc4::encodeInterlaced(android::gralloc4::Interlaced_None,
732                                                      &encodedMetadata);
733     } else if (metadataType == android::gralloc4::MetadataType_ChromaSiting) {
734         status = android::gralloc4::encodeChromaSiting(android::gralloc4::ChromaSiting_None,
735                                                        &encodedMetadata);
736     } else if (metadataType == android::gralloc4::MetadataType_Crop) {
737         uint32_t drmFormat;
738         if (getResolvedDrmFormat(descriptor.format, descriptor.usage, &drmFormat)) {
739             hidlCb(Error::BAD_VALUE, encodedMetadata);
740             return Void();
741         }
742 
743         size_t numPlanes = drv_num_planes_from_format(drmFormat);
744 
745         std::vector<aidl::android::hardware::graphics::common::Rect> crops;
746         for (size_t plane = 0; plane < numPlanes; plane++) {
747             aidl::android::hardware::graphics::common::Rect crop;
748             crop.left = 0;
749             crop.top = 0;
750             crop.right = descriptor.width;
751             crop.bottom = descriptor.height;
752             crops.push_back(crop);
753         }
754         status = android::gralloc4::encodeCrop(crops, &encodedMetadata);
755     } else if (metadataType == android::gralloc4::MetadataType_Dataspace) {
756         status = android::gralloc4::encodeDataspace(Dataspace::UNKNOWN, &encodedMetadata);
757     } else if (metadataType == android::gralloc4::MetadataType_BlendMode) {
758         status = android::gralloc4::encodeBlendMode(BlendMode::INVALID, &encodedMetadata);
759     } else if (metadataType == android::gralloc4::MetadataType_Smpte2086) {
760         status = android::gralloc4::encodeSmpte2086(std::nullopt, &encodedMetadata);
761     } else if (metadataType == android::gralloc4::MetadataType_Cta861_3) {
762         status = android::gralloc4::encodeCta861_3(std::nullopt, &encodedMetadata);
763     } else if (metadataType == android::gralloc4::MetadataType_Smpte2094_40) {
764         status = android::gralloc4::encodeSmpte2094_40(std::nullopt, &encodedMetadata);
765     } else {
766         hidlCb(Error::UNSUPPORTED, encodedMetadata);
767         return Void();
768     }
769 
770     if (status != android::NO_ERROR) {
771         hidlCb(Error::NO_RESOURCES, encodedMetadata);
772         return Void();
773     }
774 
775     hidlCb(Error::NONE, encodedMetadata);
776     return Void();
777 }
778 
listSupportedMetadataTypes(listSupportedMetadataTypes_cb hidlCb)779 Return<void> CrosGralloc4Mapper::listSupportedMetadataTypes(listSupportedMetadataTypes_cb hidlCb) {
780     hidl_vec<MetadataTypeDescription> supported;
781 
782     if (!mDriver) {
783         ALOGE("Failed to listSupportedMetadataTypes. Driver is uninitialized.");
784         hidlCb(Error::NO_RESOURCES, supported);
785         return Void();
786     }
787 
788     supported = hidl_vec<IMapper::MetadataTypeDescription>({
789             {
790                     android::gralloc4::MetadataType_BufferId,
791                     "",
792                     /*isGettable=*/true,
793                     /*isSettable=*/false,
794             },
795             {
796                     android::gralloc4::MetadataType_Name,
797                     "",
798                     /*isGettable=*/true,
799                     /*isSettable=*/false,
800             },
801             {
802                     android::gralloc4::MetadataType_Width,
803                     "",
804                     /*isGettable=*/true,
805                     /*isSettable=*/false,
806             },
807             {
808                     android::gralloc4::MetadataType_Height,
809                     "",
810                     /*isGettable=*/true,
811                     /*isSettable=*/false,
812             },
813             {
814                     android::gralloc4::MetadataType_LayerCount,
815                     "",
816                     /*isGettable=*/true,
817                     /*isSettable=*/false,
818             },
819             {
820                     android::gralloc4::MetadataType_PixelFormatRequested,
821                     "",
822                     /*isGettable=*/true,
823                     /*isSettable=*/false,
824             },
825             {
826                     android::gralloc4::MetadataType_PixelFormatFourCC,
827                     "",
828                     /*isGettable=*/true,
829                     /*isSettable=*/false,
830             },
831             {
832                     android::gralloc4::MetadataType_PixelFormatModifier,
833                     "",
834                     /*isGettable=*/true,
835                     /*isSettable=*/false,
836             },
837             {
838                     android::gralloc4::MetadataType_Usage,
839                     "",
840                     /*isGettable=*/true,
841                     /*isSettable=*/false,
842             },
843             {
844                     android::gralloc4::MetadataType_AllocationSize,
845                     "",
846                     /*isGettable=*/true,
847                     /*isSettable=*/false,
848             },
849             {
850                     android::gralloc4::MetadataType_ProtectedContent,
851                     "",
852                     /*isGettable=*/true,
853                     /*isSettable=*/false,
854             },
855             {
856                     android::gralloc4::MetadataType_Compression,
857                     "",
858                     /*isGettable=*/true,
859                     /*isSettable=*/false,
860             },
861             {
862                     android::gralloc4::MetadataType_Interlaced,
863                     "",
864                     /*isGettable=*/true,
865                     /*isSettable=*/false,
866             },
867             {
868                     android::gralloc4::MetadataType_ChromaSiting,
869                     "",
870                     /*isGettable=*/true,
871                     /*isSettable=*/false,
872             },
873             {
874                     android::gralloc4::MetadataType_PlaneLayouts,
875                     "",
876                     /*isGettable=*/true,
877                     /*isSettable=*/false,
878             },
879             {
880                     android::gralloc4::MetadataType_Crop,
881                     "",
882                     /*isGettable=*/true,
883                     /*isSettable=*/false,
884             },
885             {
886                     android::gralloc4::MetadataType_Dataspace,
887                     "",
888                     /*isGettable=*/true,
889                     /*isSettable=*/true,
890             },
891             {
892                     android::gralloc4::MetadataType_BlendMode,
893                     "",
894                     /*isGettable=*/true,
895                     /*isSettable=*/true,
896             },
897             {
898                     android::gralloc4::MetadataType_Smpte2086,
899                     "",
900                     /*isGettable=*/true,
901                     /*isSettable=*/true,
902             },
903             {
904                     android::gralloc4::MetadataType_Cta861_3,
905                     "",
906                     /*isGettable=*/true,
907                     /*isSettable=*/true,
908             },
909             {
910                     android::gralloc4::MetadataType_Smpte2094_40,
911                     "",
912                     /*isGettable=*/true,
913                     /*isSettable=*/false,
914             },
915     });
916 
917     hidlCb(Error::NONE, supported);
918     return Void();
919 }
920 
dumpBuffer(void * rawHandle,dumpBuffer_cb hidlCb)921 Return<void> CrosGralloc4Mapper::dumpBuffer(void* rawHandle, dumpBuffer_cb hidlCb) {
922     BufferDump bufferDump;
923 
924     if (!mDriver) {
925         ALOGE("Failed to dumpBuffer. Driver is uninitialized.");
926         hidlCb(Error::NO_RESOURCES, bufferDump);
927         return Void();
928     }
929 
930     buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
931     if (!bufferHandle) {
932         ALOGE("Failed to dumpBuffer. Empty handle.");
933         hidlCb(Error::BAD_BUFFER, bufferDump);
934         return Void();
935     }
936 
937     cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
938     if (!crosHandle) {
939         ALOGE("Failed to dumpBuffer. Invalid handle.");
940         hidlCb(Error::BAD_BUFFER, bufferDump);
941         return Void();
942     }
943 
944     mDriver->with_buffer(crosHandle, [&, this](cros_gralloc_buffer* crosBuffer) {
945         dumpBuffer(crosBuffer, hidlCb);
946     });
947     return Void();
948 }
949 
dumpBuffer(const cros_gralloc_buffer * crosBuffer,dumpBuffer_cb hidlCb)950 Return<void> CrosGralloc4Mapper::dumpBuffer(const cros_gralloc_buffer* crosBuffer,
951                                             dumpBuffer_cb hidlCb) {
952     BufferDump bufferDump;
953 
954     if (!mDriver) {
955         ALOGE("Failed to dumpBuffer. Driver is uninitialized.");
956         hidlCb(Error::NO_RESOURCES, bufferDump);
957         return Void();
958     }
959 
960     std::vector<MetadataDump> metadataDumps;
961 
962     MetadataType metadataType = android::gralloc4::MetadataType_BufferId;
963     auto metadata_get_callback = [&](Error, hidl_vec<uint8_t> metadata) {
964         MetadataDump metadataDump;
965         metadataDump.metadataType = metadataType;
966         metadataDump.metadata = metadata;
967         metadataDumps.push_back(metadataDump);
968     };
969 
970     metadataType = android::gralloc4::MetadataType_BufferId;
971     get(crosBuffer, metadataType, metadata_get_callback);
972 
973     metadataType = android::gralloc4::MetadataType_Name;
974     get(crosBuffer, metadataType, metadata_get_callback);
975 
976     metadataType = android::gralloc4::MetadataType_Width;
977     get(crosBuffer, metadataType, metadata_get_callback);
978 
979     metadataType = android::gralloc4::MetadataType_Height;
980     get(crosBuffer, metadataType, metadata_get_callback);
981 
982     metadataType = android::gralloc4::MetadataType_LayerCount;
983     get(crosBuffer, metadataType, metadata_get_callback);
984 
985     metadataType = android::gralloc4::MetadataType_PixelFormatRequested;
986     get(crosBuffer, metadataType, metadata_get_callback);
987 
988     metadataType = android::gralloc4::MetadataType_PixelFormatFourCC;
989     get(crosBuffer, metadataType, metadata_get_callback);
990 
991     metadataType = android::gralloc4::MetadataType_PixelFormatModifier;
992     get(crosBuffer, metadataType, metadata_get_callback);
993 
994     metadataType = android::gralloc4::MetadataType_Usage;
995     get(crosBuffer, metadataType, metadata_get_callback);
996 
997     metadataType = android::gralloc4::MetadataType_AllocationSize;
998     get(crosBuffer, metadataType, metadata_get_callback);
999 
1000     metadataType = android::gralloc4::MetadataType_ProtectedContent;
1001     get(crosBuffer, metadataType, metadata_get_callback);
1002 
1003     metadataType = android::gralloc4::MetadataType_Compression;
1004     get(crosBuffer, metadataType, metadata_get_callback);
1005 
1006     metadataType = android::gralloc4::MetadataType_Interlaced;
1007     get(crosBuffer, metadataType, metadata_get_callback);
1008 
1009     metadataType = android::gralloc4::MetadataType_ChromaSiting;
1010     get(crosBuffer, metadataType, metadata_get_callback);
1011 
1012     metadataType = android::gralloc4::MetadataType_PlaneLayouts;
1013     get(crosBuffer, metadataType, metadata_get_callback);
1014 
1015     metadataType = android::gralloc4::MetadataType_Dataspace;
1016     get(crosBuffer, metadataType, metadata_get_callback);
1017 
1018     metadataType = android::gralloc4::MetadataType_BlendMode;
1019     get(crosBuffer, metadataType, metadata_get_callback);
1020 
1021     bufferDump.metadataDump = metadataDumps;
1022     hidlCb(Error::NONE, bufferDump);
1023     return Void();
1024 }
1025 
dumpBuffers(dumpBuffers_cb hidlCb)1026 Return<void> CrosGralloc4Mapper::dumpBuffers(dumpBuffers_cb hidlCb) {
1027     std::vector<BufferDump> bufferDumps;
1028 
1029     if (!mDriver) {
1030         ALOGE("Failed to dumpBuffers. Driver is uninitialized.");
1031         hidlCb(Error::NO_RESOURCES, bufferDumps);
1032         return Void();
1033     }
1034 
1035     Error error = Error::NONE;
1036 
1037     const auto dumpBufferCallback = [&](Error err, BufferDump bufferDump) {
1038         error = err;
1039         if (error == Error::NONE) {
1040             bufferDumps.push_back(bufferDump);
1041         }
1042     };
1043 
1044     mDriver->with_each_buffer(
1045             [&](cros_gralloc_buffer* crosBuffer) { dumpBuffer(crosBuffer, dumpBufferCallback); });
1046 
1047     hidlCb(error, bufferDumps);
1048     return Void();
1049 }
1050 
getReservedRegionArea(const cros_gralloc_buffer * crosBuffer,ReservedRegionArea area,void ** outAddr,uint64_t * outSize)1051 Error CrosGralloc4Mapper::getReservedRegionArea(const cros_gralloc_buffer* crosBuffer,
1052                                                 ReservedRegionArea area, void** outAddr,
1053                                                 uint64_t* outSize) {
1054     if (!mDriver) {
1055         ALOGE("Failed to getReservedRegionArea. Driver is uninitialized.");
1056         return Error::NO_RESOURCES;
1057     }
1058 
1059     if (!crosBuffer) {
1060         ALOGE("Failed to getReservedRegionArea. Invalid buffer.");
1061         return Error::BAD_BUFFER;
1062     }
1063 
1064     int ret = crosBuffer->get_reserved_region(outAddr, outSize);
1065     if (ret) {
1066         ALOGE("Failed to getReservedRegionArea.");
1067         *outAddr = nullptr;
1068         *outSize = 0;
1069         return Error::NO_RESOURCES;
1070     }
1071 
1072     switch (area) {
1073         case ReservedRegionArea::MAPPER4_METADATA: {
1074             // CrosGralloc4Metadata resides at the beginning reserved region.
1075             *outSize = sizeof(CrosGralloc4Metadata);
1076             break;
1077         }
1078         case ReservedRegionArea::USER_METADATA: {
1079             // User metadata resides after the CrosGralloc4Metadata.
1080             *outAddr = reinterpret_cast<void*>(reinterpret_cast<char*>(*outAddr) +
1081                                                sizeof(CrosGralloc4Metadata));
1082             *outSize = *outSize - sizeof(CrosGralloc4Metadata);
1083             break;
1084         }
1085     }
1086 
1087     return Error::NONE;
1088 }
1089 
getMetadata(const cros_gralloc_buffer * crosBuffer,const CrosGralloc4Metadata ** outMetadata)1090 Error CrosGralloc4Mapper::getMetadata(const cros_gralloc_buffer* crosBuffer,
1091                                       const CrosGralloc4Metadata** outMetadata) {
1092     void* addr = nullptr;
1093     uint64_t size;
1094 
1095     Error error =
1096             getReservedRegionArea(crosBuffer, ReservedRegionArea::MAPPER4_METADATA, &addr, &size);
1097     if (error != Error::NONE) {
1098         return error;
1099     }
1100 
1101     *outMetadata = reinterpret_cast<const CrosGralloc4Metadata*>(addr);
1102     return Error::NONE;
1103 }
1104 
getMutableMetadata(cros_gralloc_buffer * crosBuffer,CrosGralloc4Metadata ** outMetadata)1105 Error CrosGralloc4Mapper::getMutableMetadata(cros_gralloc_buffer* crosBuffer,
1106                                              CrosGralloc4Metadata** outMetadata) {
1107     void* addr = nullptr;
1108     uint64_t size;
1109 
1110     Error error =
1111             getReservedRegionArea(crosBuffer, ReservedRegionArea::MAPPER4_METADATA, &addr, &size);
1112     if (error != Error::NONE) {
1113         return error;
1114     }
1115 
1116     *outMetadata = reinterpret_cast<CrosGralloc4Metadata*>(addr);
1117     return Error::NONE;
1118 }
1119 
getReservedRegion(void * rawHandle,getReservedRegion_cb hidlCb)1120 Return<void> CrosGralloc4Mapper::getReservedRegion(void* rawHandle, getReservedRegion_cb hidlCb) {
1121     if (!mDriver) {
1122         ALOGE("Failed to getReservedRegion. Driver is uninitialized.");
1123         hidlCb(Error::NO_RESOURCES, nullptr, 0);
1124         return Void();
1125     }
1126 
1127     buffer_handle_t bufferHandle = reinterpret_cast<buffer_handle_t>(rawHandle);
1128     if (!bufferHandle) {
1129         ALOGE("Failed to getReservedRegion. Empty handle.");
1130         hidlCb(Error::BAD_BUFFER, nullptr, 0);
1131         return Void();
1132     }
1133 
1134     cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
1135     if (!crosHandle) {
1136         ALOGE("Failed to getReservedRegion. Invalid handle.");
1137         hidlCb(Error::BAD_BUFFER, nullptr, 0);
1138         return Void();
1139     }
1140 
1141     void* reservedRegionAddr = nullptr;
1142     uint64_t reservedRegionSize = 0;
1143 
1144     Error error = Error::NONE;
1145     mDriver->with_buffer(crosHandle, [&, this](cros_gralloc_buffer* crosBuffer) {
1146         error = getReservedRegionArea(crosBuffer, ReservedRegionArea::USER_METADATA,
1147                                       &reservedRegionAddr, &reservedRegionSize);
1148     });
1149 
1150     if (error != Error::NONE) {
1151         ALOGE("Failed to getReservedRegion. Failed to getReservedRegionArea.");
1152         hidlCb(Error::BAD_BUFFER, nullptr, 0);
1153         return Void();
1154     }
1155 
1156     hidlCb(Error::NONE, reservedRegionAddr, reservedRegionSize);
1157     return Void();
1158 }
1159 
HIDL_FETCH_IMapper(const char *)1160 android::hardware::graphics::mapper::V4_0::IMapper* HIDL_FETCH_IMapper(const char* /*name*/) {
1161     return static_cast<android::hardware::graphics::mapper::V4_0::IMapper*>(new CrosGralloc4Mapper);
1162 }
1163