1 #include "GrallocAllocator2.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 #include "hidl_common/Allocator.h"
10 
11 namespace pixel::allocator {
12 
13 namespace AidlAllocator = aidl::android::hardware::graphics::allocator;
14 
15 using android::hardware::hidl_handle;
16 using android::hardware::hidl_vec;
17 using HidlError = android::hardware::graphics::mapper::V4_0::Error;
18 
callingPid()19 unsigned long callingPid() {
20     return static_cast<unsigned long>(AIBinder_getCallingPid());
21 }
22 
callingUid()23 unsigned long callingUid() {
24     return static_cast<unsigned long>(AIBinder_getCallingUid());
25 }
26 
GrallocAllocator()27 GrallocAllocator::GrallocAllocator() {}
28 
~GrallocAllocator()29 GrallocAllocator::~GrallocAllocator() {}
30 
allocate(const std::vector<uint8_t> & descriptor,int32_t count,AidlAllocator::AllocationResult * result)31 ndk::ScopedAStatus GrallocAllocator::allocate(const std::vector<uint8_t>& descriptor, int32_t count,
32                                               AidlAllocator::AllocationResult* result) {
33     MALI_GRALLOC_LOGV("Allocation request from process: %lu", callingPid());
34 
35     buffer_descriptor_t bufferDescriptor;
36     if (!arm::mapper::common::grallocDecodeBufferDescriptor(hidl_vec(descriptor),
37                                                             bufferDescriptor)) {
38         return ndk::ScopedAStatus::fromServiceSpecificError(
39                 static_cast<int32_t>(AidlAllocator::AllocationError::BAD_DESCRIPTOR));
40     }
41 
42     // TODO(layog@): This dependency between AIDL and HIDL backends is not good.
43     // Ideally common::allocate should return the result and it should be encoded
44     // by this interface into HIDL or AIDL.
45     HidlError error = HidlError::NONE;
46     auto hidl_cb = [&](HidlError _error, int _stride, hidl_vec<hidl_handle> _buffers) {
47         if (_error != HidlError::NONE) {
48             error = _error;
49             return;
50         }
51 
52         const uint32_t size = _buffers.size();
53 
54         result->stride = _stride;
55         result->buffers.resize(size);
56         for (uint32_t i = 0; i < size; i++) {
57             // Dup here is necessary. After this callback returns common::allocate
58             // will free the buffer which will destroy the older fd.
59             result->buffers[i] = android::dupToAidl(static_cast<const native_handle*>(_buffers[i]));
60         }
61     };
62 
63     arm::allocator::common::allocate(bufferDescriptor, count, hidl_cb);
64 
65     switch (error) {
66         case HidlError::NONE:
67             break;
68 
69         case HidlError::BAD_DESCRIPTOR:
70             return ndk::ScopedAStatus::fromServiceSpecificError(
71                     static_cast<int32_t>(AidlAllocator::AllocationError::BAD_DESCRIPTOR));
72 
73         case HidlError::NO_RESOURCES:
74             return ndk::ScopedAStatus::fromServiceSpecificError(
75                     static_cast<int32_t>(AidlAllocator::AllocationError::NO_RESOURCES));
76 
77         case HidlError::UNSUPPORTED:
78             return ndk::ScopedAStatus::fromServiceSpecificError(
79                     static_cast<int32_t>(AidlAllocator::AllocationError::UNSUPPORTED));
80 
81         default:
82             return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_ERROR);
83     }
84 
85     return ndk::ScopedAStatus::ok();
86 }
87 
toInternalDescriptor(const AidlAllocator::BufferDescriptorInfo & descriptor)88 buffer_descriptor_t toInternalDescriptor(
89         const AidlAllocator::BufferDescriptorInfo& descriptor) {
90     buffer_descriptor_t bufferDescriptor;
91     bufferDescriptor.width = descriptor.width;
92     bufferDescriptor.height = descriptor.height;
93     bufferDescriptor.layer_count = descriptor.layerCount;
94     bufferDescriptor.hal_format = static_cast<uint64_t>(descriptor.format);
95     bufferDescriptor.producer_usage = static_cast<uint64_t>(descriptor.usage);
96     bufferDescriptor.consumer_usage = bufferDescriptor.producer_usage;
97     bufferDescriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE;
98     bufferDescriptor.signature = sizeof(buffer_descriptor_t);
99     bufferDescriptor.reserved_size = descriptor.reservedSize;
100     bufferDescriptor.additional_options = descriptor.additionalOptions;
101     const char *str = (const char*) descriptor.name.data();
102     bufferDescriptor.name = std::string(str);
103     return bufferDescriptor;
104 }
105 
allocate2(const AidlAllocator::BufferDescriptorInfo & descriptor,int32_t count,AidlAllocator::AllocationResult * result)106 ndk::ScopedAStatus GrallocAllocator::allocate2(
107         const AidlAllocator::BufferDescriptorInfo& descriptor, int32_t count,
108         AidlAllocator::AllocationResult* result) {
109     MALI_GRALLOC_LOGV("Allocation request from process: %lu", callingPid());
110 
111     buffer_descriptor_t bufferDescriptor = toInternalDescriptor(descriptor);
112 
113     HidlError error = HidlError::NONE;
114     auto hidl_cb = [&](HidlError _error, int _stride, hidl_vec<hidl_handle> _buffers) {
115         if (_error != HidlError::NONE) {
116             error = _error;
117             return;
118         }
119 
120         const uint32_t size = _buffers.size();
121 
122         result->stride = _stride;
123         result->buffers.resize(size);
124         for (uint32_t i = 0; i < size; i++) {
125             // Dup here is necessary. After this callback returns common::allocate
126             // will free the buffer which will destroy the older fd.
127             result->buffers[i] = android::dupToAidl(static_cast<const native_handle*>(_buffers[i]));
128         }
129     };
130 
131     arm::allocator::common::allocate(bufferDescriptor, count, hidl_cb);
132 
133     switch (error) {
134         case HidlError::NONE:
135             break;
136 
137         case HidlError::BAD_DESCRIPTOR:
138             return ndk::ScopedAStatus::fromServiceSpecificError(
139                     static_cast<int32_t>(AidlAllocator::AllocationError::BAD_DESCRIPTOR));
140 
141         case HidlError::NO_RESOURCES:
142             return ndk::ScopedAStatus::fromServiceSpecificError(
143                     static_cast<int32_t>(AidlAllocator::AllocationError::NO_RESOURCES));
144 
145         case HidlError::UNSUPPORTED:
146             return ndk::ScopedAStatus::fromServiceSpecificError(
147                     static_cast<int32_t>(AidlAllocator::AllocationError::UNSUPPORTED));
148 
149         default:
150             return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_ERROR);
151     }
152 
153     return ndk::ScopedAStatus::ok();
154 }
155 
isSupported(const AidlAllocator::BufferDescriptorInfo & descriptor,bool * result)156 ndk::ScopedAStatus GrallocAllocator::isSupported(
157         const AidlAllocator::BufferDescriptorInfo& descriptor, bool* result) {
158     buffer_descriptor_t bufferDescriptor = toInternalDescriptor(descriptor);
159 
160     bool isBufferDescriptorSupported = arm::allocator::common::isSupported(&bufferDescriptor);
161     *result = isBufferDescriptorSupported;
162 
163     if (isBufferDescriptorSupported) {
164         MALI_GRALLOC_LOGV("Allocation for the given description will not succeed");
165     }
166     return ndk::ScopedAStatus::ok();
167 }
168 
getIMapperLibrarySuffix(std::string * result)169 ndk::ScopedAStatus GrallocAllocator::getIMapperLibrarySuffix(std::string* result) {
170     *result = "pixel";
171     return ndk::ScopedAStatus::ok();
172 }
173 
dump(int fd,const char **,uint32_t numArgs)174 binder_status_t GrallocAllocator::dump(int fd, const char** /* args */, uint32_t numArgs) {
175     if (callingUid() != AID_ROOT) {
176         const std::string permission_denied = "Permission Denied\n";
177         write(fd, permission_denied.c_str(), permission_denied.size());
178         return STATUS_PERMISSION_DENIED;
179     }
180 
181     if (numArgs != 0) {
182         const std::string argument_error = "No argument expected\n";
183         write(fd, argument_error.c_str(), argument_error.size());
184         return STATUS_BAD_VALUE;
185     }
186 
187     const std::string dump_info = arm::allocator::common::dump();
188     write(fd, dump_info.c_str(), dump_info.size());
189     return STATUS_OK;
190 }
191 
192 } // namespace pixel::allocator
193 
194