1 /* 2 * Copyright 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /** 18 * @file hardware_buffer_aidl.h 19 * @brief HardwareBuffer NDK AIDL glue code 20 */ 21 22 /** 23 * @addtogroup AHardwareBuffer 24 * 25 * Parcelable support for AHardwareBuffer. Can be used with libbinder_ndk 26 * 27 * @{ 28 */ 29 30 #ifndef ANDROID_HARDWARE_BUFFER_AIDL_H 31 #define ANDROID_HARDWARE_BUFFER_AIDL_H 32 33 #include <android/binder_parcel.h> 34 #include <android/hardware_buffer.h> 35 #include <sys/cdefs.h> 36 37 #ifdef __cplusplus 38 #include <string> 39 #endif 40 41 __BEGIN_DECLS 42 43 /** 44 * Read an AHardwareBuffer from a AParcel. The output buffer will have an 45 * initial reference acquired and will need to be released with 46 * AHardwareBuffer_release. 47 * 48 * Available since API level 34. 49 * 50 * \return STATUS_OK on success 51 * STATUS_BAD_VALUE if the parcel or outBuffer is null, or if there's an 52 * issue deserializing (eg, corrupted parcel) 53 * STATUS_BAD_TYPE if the parcel's current data position is not that of 54 * an AHardwareBuffer type 55 * STATUS_NO_MEMORY if an allocation fails 56 */ 57 binder_status_t AHardwareBuffer_readFromParcel(const AParcel* _Nonnull parcel, 58 AHardwareBuffer* _Nullable* _Nonnull outBuffer) __INTRODUCED_IN(34); 59 60 /** 61 * Write an AHardwareBuffer to an AParcel. 62 * 63 * Available since API level 34. 64 * 65 * \return STATUS_OK on success. 66 * STATUS_BAD_VALUE if either buffer or parcel is null, or if the AHardwareBuffer* 67 * fails to serialize (eg, internally corrupted) 68 * STATUS_NO_MEMORY if the parcel runs out of space to store the buffer & is 69 * unable to allocate more 70 * STATUS_FDS_NOT_ALLOWED if the parcel does not allow storing FDs 71 */ 72 binder_status_t AHardwareBuffer_writeToParcel(const AHardwareBuffer* _Nonnull buffer, 73 AParcel* _Nonnull parcel) __INTRODUCED_IN(34); 74 75 __END_DECLS 76 77 // Only enable the AIDL glue helper if this is C++ 78 #ifdef __cplusplus 79 80 namespace aidl::android::hardware { 81 82 /** 83 * Wrapper class that enables interop with AIDL NDK generation 84 * Takes ownership of the AHardwareBuffer* given to it in reset() and will automatically 85 * destroy it in the destructor, similar to a smart pointer container 86 */ 87 class HardwareBuffer { 88 public: HardwareBuffer()89 HardwareBuffer() noexcept {} HardwareBuffer(HardwareBuffer && other)90 HardwareBuffer(HardwareBuffer&& other) noexcept : mBuffer(other.release()) {} 91 ~HardwareBuffer()92 ~HardwareBuffer() { 93 reset(); 94 } 95 readFromParcel(const AParcel * _Nonnull parcel)96 binder_status_t readFromParcel(const AParcel* _Nonnull parcel) { 97 reset(); 98 return AHardwareBuffer_readFromParcel(parcel, &mBuffer); 99 } 100 writeToParcel(AParcel * _Nonnull parcel)101 binder_status_t writeToParcel(AParcel* _Nonnull parcel) const { 102 if (!mBuffer) { 103 return STATUS_BAD_VALUE; 104 } 105 return AHardwareBuffer_writeToParcel(mBuffer, parcel); 106 } 107 108 /** 109 * Destroys any currently owned AHardwareBuffer* and takes ownership of the given 110 * AHardwareBuffer* 111 * 112 * @param buffer The buffer to take ownership of 113 */ 114 void reset(AHardwareBuffer* _Nullable buffer = nullptr) noexcept { 115 if (mBuffer) { 116 AHardwareBuffer_release(mBuffer); 117 mBuffer = nullptr; 118 } 119 mBuffer = buffer; 120 } 121 122 inline AHardwareBuffer* _Nullable operator-> () const { return mBuffer; } get()123 inline AHardwareBuffer* _Nullable get() const { return mBuffer; } 124 inline explicit operator bool () const { return mBuffer != nullptr; } 125 126 inline bool operator!=(const HardwareBuffer& rhs) const { return get() != rhs.get(); } 127 inline bool operator<(const HardwareBuffer& rhs) const { return get() < rhs.get(); } 128 inline bool operator<=(const HardwareBuffer& rhs) const { return get() <= rhs.get(); } 129 inline bool operator==(const HardwareBuffer& rhs) const { return get() == rhs.get(); } 130 inline bool operator>(const HardwareBuffer& rhs) const { return get() > rhs.get(); } 131 inline bool operator>=(const HardwareBuffer& rhs) const { return get() >= rhs.get(); } 132 133 HardwareBuffer& operator=(HardwareBuffer&& other) noexcept { 134 reset(other.release()); 135 return *this; 136 } 137 138 /** 139 * Stops managing any contained AHardwareBuffer*, returning it to the caller. Ownership 140 * is released. 141 * @return AHardwareBuffer* or null if this was empty 142 */ release()143 [[nodiscard]] AHardwareBuffer* _Nullable release() noexcept { 144 AHardwareBuffer* _Nullable ret = mBuffer; 145 mBuffer = nullptr; 146 return ret; 147 } 148 toString()149 inline std::string toString() const { 150 if (!mBuffer) { 151 return "<HardwareBuffer: Invalid>"; 152 } 153 uint64_t id = 0; 154 AHardwareBuffer_getId(mBuffer, &id); 155 return "<HardwareBuffer " + std::to_string(id) + ">"; 156 } 157 158 private: 159 HardwareBuffer(const HardwareBuffer& other) = delete; 160 HardwareBuffer& operator=(const HardwareBuffer& other) = delete; 161 162 AHardwareBuffer* _Nullable mBuffer = nullptr; 163 }; 164 165 } // aidl::android::hardware 166 167 #endif // __cplusplus 168 169 #endif // ANDROID_HARDWARE_BUFFER_AIDL_H 170 171 /** @} */ 172