• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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