• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     const char *str = (const char*) descriptor.name.data();
101     bufferDescriptor.name = std::string(str);
102     return bufferDescriptor;
103 }
104 
allocate2(const AidlAllocator::BufferDescriptorInfo & descriptor,int32_t count,AidlAllocator::AllocationResult * result)105 ndk::ScopedAStatus GrallocAllocator::allocate2(
106         const AidlAllocator::BufferDescriptorInfo& descriptor, int32_t count,
107         AidlAllocator::AllocationResult* result) {
108     MALI_GRALLOC_LOGV("Allocation request from process: %lu", callingPid());
109 
110     buffer_descriptor_t bufferDescriptor = toInternalDescriptor(descriptor);
111 
112     HidlError error = HidlError::NONE;
113     auto hidl_cb = [&](HidlError _error, int _stride, hidl_vec<hidl_handle> _buffers) {
114         if (_error != HidlError::NONE) {
115             error = _error;
116             return;
117         }
118 
119         const uint32_t size = _buffers.size();
120 
121         result->stride = _stride;
122         result->buffers.resize(size);
123         for (uint32_t i = 0; i < size; i++) {
124             // Dup here is necessary. After this callback returns common::allocate
125             // will free the buffer which will destroy the older fd.
126             result->buffers[i] = android::dupToAidl(static_cast<const native_handle*>(_buffers[i]));
127         }
128     };
129 
130     arm::allocator::common::allocate(bufferDescriptor, count, hidl_cb);
131 
132     switch (error) {
133         case HidlError::NONE:
134             break;
135 
136         case HidlError::BAD_DESCRIPTOR:
137             return ndk::ScopedAStatus::fromServiceSpecificError(
138                     static_cast<int32_t>(AidlAllocator::AllocationError::BAD_DESCRIPTOR));
139 
140         case HidlError::NO_RESOURCES:
141             return ndk::ScopedAStatus::fromServiceSpecificError(
142                     static_cast<int32_t>(AidlAllocator::AllocationError::NO_RESOURCES));
143 
144         case HidlError::UNSUPPORTED:
145             return ndk::ScopedAStatus::fromServiceSpecificError(
146                     static_cast<int32_t>(AidlAllocator::AllocationError::UNSUPPORTED));
147 
148         default:
149             return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_ERROR);
150     }
151 
152     return ndk::ScopedAStatus::ok();
153 }
154 
155 // TODO(b/315883761): isSupported should return false for unknown-to-HAL usage
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