1 #include "GrallocAllocator.h"
2
3 #include <aidl/android/hardware/graphics/allocator/AllocationError.h>
4 #include <aidlcommonsupport/NativeHandle.h>
5 #include <android/binder_ibinder.h>
6 #include <android/binder_status.h>
7 #include <cutils/android_filesystem_config.h>
8 #include <hidl/HidlSupport.h>
9
10 #include "allocator/mali_gralloc_ion.h"
11 #include "hidl_common/Allocator.h"
12
13 namespace pixel::allocator {
14
15 namespace AidlAllocator = aidl::android::hardware::graphics::allocator;
16 namespace HidlAllocator = android::hardware::graphics::allocator::V4_0;
17
18 using android::hardware::hidl_handle;
19 using android::hardware::hidl_vec;
20 using HidlError = android::hardware::graphics::mapper::V4_0::Error;
21
callingPid()22 unsigned long callingPid() {
23 return static_cast<unsigned long>(AIBinder_getCallingPid());
24 }
25
callingUid()26 unsigned long callingUid() {
27 return static_cast<unsigned long>(AIBinder_getCallingUid());
28 }
29
GrallocAllocator()30 GrallocAllocator::GrallocAllocator() {}
31
~GrallocAllocator()32 GrallocAllocator::~GrallocAllocator() {}
33
allocate(const std::vector<uint8_t> & descriptor,int32_t count,AidlAllocator::AllocationResult * result)34 ndk::ScopedAStatus GrallocAllocator::allocate(const std::vector<uint8_t>& descriptor, int32_t count,
35 AidlAllocator::AllocationResult* result) {
36 MALI_GRALLOC_LOGV("Allocation request from process: %lu", callingPid());
37
38 buffer_descriptor_t bufferDescriptor;
39 if (!arm::mapper::common::grallocDecodeBufferDescriptor(hidl_vec(descriptor),
40 bufferDescriptor)) {
41 return ndk::ScopedAStatus::fromServiceSpecificError(
42 static_cast<int32_t>(AidlAllocator::AllocationError::BAD_DESCRIPTOR));
43 }
44
45 // TODO(layog@): This dependency between AIDL and HIDL backends is not good.
46 // Ideally common::allocate should return the result and it should be encoded
47 // by this interface into HIDL or AIDL.
48 HidlError error = HidlError::NONE;
49 auto hidl_cb = [&](HidlError _error, int _stride, hidl_vec<hidl_handle> _buffers) {
50 if (_error != HidlError::NONE) {
51 error = _error;
52 return;
53 }
54
55 const uint32_t size = _buffers.size();
56
57 result->stride = _stride;
58 result->buffers.resize(size);
59 for (uint32_t i = 0; i < size; i++) {
60 // Dup here is necessary. After this callback returns common::allocate
61 // will free the buffer which will destroy the older fd.
62 result->buffers[i] = android::dupToAidl(static_cast<const native_handle*>(_buffers[i]));
63 }
64 };
65
66 arm::allocator::common::allocate(bufferDescriptor, count, hidl_cb);
67
68 switch (error) {
69 case HidlError::NONE:
70 break;
71
72 case HidlError::BAD_DESCRIPTOR:
73 return ndk::ScopedAStatus::fromServiceSpecificError(
74 static_cast<int32_t>(AidlAllocator::AllocationError::BAD_DESCRIPTOR));
75
76 case HidlError::NO_RESOURCES:
77 return ndk::ScopedAStatus::fromServiceSpecificError(
78 static_cast<int32_t>(AidlAllocator::AllocationError::NO_RESOURCES));
79
80 case HidlError::UNSUPPORTED:
81 return ndk::ScopedAStatus::fromServiceSpecificError(
82 static_cast<int32_t>(AidlAllocator::AllocationError::UNSUPPORTED));
83
84 default:
85 return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_ERROR);
86 }
87
88 return ndk::ScopedAStatus::ok();
89 }
90
dump(int fd,const char **,uint32_t numArgs)91 binder_status_t GrallocAllocator::dump(int fd, const char** /* args */, uint32_t numArgs) {
92 if (callingUid() != AID_ROOT) {
93 const std::string permission_denied = "Permission Denied\n";
94 write(fd, permission_denied.c_str(), permission_denied.size());
95 return STATUS_PERMISSION_DENIED;
96 }
97
98 if (numArgs != 0) {
99 const std::string argument_error = "No argument expected\n";
100 write(fd, argument_error.c_str(), argument_error.size());
101 return STATUS_BAD_VALUE;
102 }
103
104 const std::string dump_info = arm::allocator::common::dump();
105 write(fd, dump_info.c_str(), dump_info.size());
106 return STATUS_OK;
107 }
108
109 } // namespace pixel::allocator
110