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