1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "base/native_buffer.h"
17 #include <sstream>
18 #include "base/buffer_util.h"
19 #include "hdf_log.h"
20
21 #define HDF_LOG_TAG native_buffer
22
23 namespace OHOS {
24 namespace HDI {
25 namespace Base {
NativeBuffer()26 NativeBuffer::NativeBuffer() : handle_(nullptr), isOwner_(true), bufferDestructor_(nullptr) {}
27
~NativeBuffer()28 NativeBuffer::~NativeBuffer()
29 {
30 DestroyBuffer();
31 }
32
NativeBuffer(const BufferHandle * handle)33 NativeBuffer::NativeBuffer(const BufferHandle *handle) : NativeBuffer()
34 {
35 handle_ = CloneNativeBufferHandle(handle);
36 }
37
NativeBuffer(const NativeBuffer & other)38 NativeBuffer::NativeBuffer(const NativeBuffer &other) : NativeBuffer()
39 {
40 if (other.handle_ == nullptr) {
41 return;
42 }
43 handle_ = CloneNativeBufferHandle(other.handle_);
44 }
45
NativeBuffer(NativeBuffer && other)46 NativeBuffer::NativeBuffer(NativeBuffer &&other) noexcept : NativeBuffer()
47 {
48 handle_ = other.handle_;
49 isOwner_ = other.isOwner_;
50 bufferDestructor_ = other.bufferDestructor_;
51 other.handle_ = nullptr;
52 }
53
operator =(const NativeBuffer & other)54 NativeBuffer &NativeBuffer::operator=(const NativeBuffer &other)
55 {
56 if (this != &other) {
57 DestroyBuffer();
58 handle_ = CloneNativeBufferHandle(other.handle_);
59 isOwner_ = true;
60 }
61 return *this;
62 }
63
operator =(NativeBuffer && other)64 NativeBuffer &NativeBuffer::operator=(NativeBuffer &&other) noexcept
65 {
66 if (this != &other) {
67 DestroyBuffer();
68 handle_ = other.handle_;
69 isOwner_ = other.isOwner_;
70 bufferDestructor_ = other.bufferDestructor_;
71 other.handle_ = nullptr;
72 }
73 return *this;
74 }
75
Marshalling(Parcel & parcel) const76 bool NativeBuffer::Marshalling(Parcel &parcel) const
77 {
78 MessageParcel &messageParcel = static_cast<MessageParcel &>(parcel);
79 bool isValid = handle_ != nullptr ? true : false;
80 if (!messageParcel.WriteBool(isValid)) {
81 HDF_LOGI("%{public}s: failed to write valid flag of buffer handle", __func__);
82 return false;
83 }
84
85 if (!isValid) {
86 HDF_LOGD("%{public}s: write valid buffer handle", __func__);
87 return true;
88 }
89
90 if (!messageParcel.WriteUint32(handle_->reserveFds) || !messageParcel.WriteUint32(handle_->reserveInts) ||
91 !messageParcel.WriteInt32(handle_->width) || !messageParcel.WriteInt32(handle_->stride) ||
92 !messageParcel.WriteInt32(handle_->height) || !messageParcel.WriteInt32(handle_->size) ||
93 !messageParcel.WriteInt32(handle_->format) || !messageParcel.WriteUint64(handle_->usage)) {
94 HDF_LOGE("%{public}s: a lot failed", __func__);
95 return false;
96 }
97
98 bool validFd = (handle_->fd >= 0);
99 if (!messageParcel.WriteBool(validFd)) {
100 HDF_LOGE("%{public}s: failed to write valid flag of fd", __func__);
101 return false;
102 }
103 if (validFd && !messageParcel.WriteFileDescriptor(handle_->fd)) {
104 HDF_LOGE("%{public}s: failed to write fd", __func__);
105 return false;
106 }
107
108 if (!WriteReserveData(messageParcel, *handle_)) {
109 return false;
110 }
111
112 return true;
113 }
114
Unmarshalling(Parcel & parcel)115 sptr<NativeBuffer> NativeBuffer::Unmarshalling(Parcel &parcel)
116 {
117 sptr<NativeBuffer> newParcelable = new NativeBuffer();
118 if (!newParcelable->ExtractFromParcel(parcel)) {
119 return nullptr;
120 }
121 return newParcelable;
122 }
123
Clone()124 BufferHandle *NativeBuffer::Clone()
125 {
126 return CloneNativeBufferHandle(handle_);
127 }
128
Move()129 BufferHandle *NativeBuffer::Move() noexcept
130 {
131 if (isOwner_ == false) {
132 HDF_LOGE("%{public}s@%{public}d: isOwner_ is false, Cannot be moved", __func__, __LINE__);
133 return nullptr;
134 }
135 BufferHandle *handlePtr = handle_;
136 handle_ = nullptr;
137 return handlePtr;
138 }
139
SetBufferHandle(BufferHandle * handle,bool isOwner,std::function<void (BufferHandle *)> destructor)140 void NativeBuffer::SetBufferHandle(BufferHandle *handle, bool isOwner, std::function<void(BufferHandle *)> destructor)
141 {
142 DestroyBuffer();
143 isOwner_ = isOwner;
144 handle_ = handle;
145 bufferDestructor_ = destructor;
146 }
147
DestroyBuffer()148 void NativeBuffer::DestroyBuffer()
149 {
150 if (handle_ != nullptr && isOwner_ == true) {
151 if (bufferDestructor_ == nullptr) {
152 FreeNativeBufferHandle(handle_);
153 } else {
154 bufferDestructor_(handle_);
155 }
156 handle_ = nullptr;
157 }
158 }
159
GetBufferHandle()160 BufferHandle *NativeBuffer::GetBufferHandle() noexcept
161 {
162 return handle_;
163 }
164
Dump() const165 std::string NativeBuffer::Dump() const
166 {
167 std::stringstream os;
168 os << "{";
169 if (handle_ == nullptr) {
170 os << "}\n";
171 return os.str();
172 }
173
174 os << "fd:" << handle_->fd << ", ";
175 os << "width:" << handle_->width << ", ";
176 os << "stride:" << handle_->stride << ", ";
177 os << "height:" << handle_->height << ", ";
178 os << "size:" << handle_->size << ", ";
179 os << "format:" << handle_->format << ", ";
180 os << "reserveFds:" << handle_->reserveFds << ", ";
181 os << "reserveInts:" << handle_->reserveInts << ", ";
182 os << "reserve: [";
183
184 if (UINT32_MAX - handle_->reserveFds >= handle_->reserveInts) {
185 uint32_t reserveSize = handle_->reserveFds + handle_->reserveInts;
186 for (uint32_t i = 0; i < reserveSize; ++i) {
187 os << handle_->reserve[i];
188 if (i + 1 < reserveSize) {
189 os << ", ";
190 }
191 }
192 }
193 os << "]";
194 os << "}\n";
195 return os.str();
196 }
197
ExtractFromParcel(Parcel & parcel)198 bool NativeBuffer::ExtractFromParcel(Parcel &parcel)
199 {
200 MessageParcel &messageParcel = static_cast<MessageParcel &>(parcel);
201 if (!messageParcel.ReadBool()) {
202 HDF_LOGD("%{public}s: read invalid buffer handle", __func__);
203 return true;
204 }
205 uint32_t reserveFds = 0;
206 uint32_t reserveInts = 0;
207 if (!messageParcel.ReadUint32(reserveFds) || !messageParcel.ReadUint32(reserveInts)) {
208 HDF_LOGE("%{public}s: failed to read reserveFds or reserveInts", __func__);
209 return false;
210 }
211 if ((handle_ = AllocateNativeBufferHandle(reserveFds, reserveInts)) == nullptr) {
212 HDF_LOGE("%{public}s: failed to malloc BufferHandle", __func__);
213 return false;
214 }
215 bool validFd = false;
216 if (!messageParcel.ReadInt32(handle_->width) || !messageParcel.ReadInt32(handle_->stride) ||
217 !messageParcel.ReadInt32(handle_->height) || !messageParcel.ReadInt32(handle_->size) ||
218 !messageParcel.ReadInt32(handle_->format) || !messageParcel.ReadUint64(handle_->usage) ||
219 !messageParcel.ReadBool(validFd)) {
220 HDF_LOGE("%{public}s: failed to parcel read", __func__);
221 return false;
222 }
223 if (validFd) {
224 handle_->fd = messageParcel.ReadFileDescriptor();
225 if (handle_->fd == -1) {
226 DestroyBuffer();
227 HDF_LOGE("%{public}s: failed to read fd", __func__);
228 return false;
229 }
230 }
231
232 if (!ReadReserveData(messageParcel, *handle_)) {
233 DestroyBuffer();
234 return false;
235 }
236 return true;
237 }
238
WriteReserveData(MessageParcel & messageParcel,const BufferHandle & handle)239 bool NativeBuffer::WriteReserveData(MessageParcel &messageParcel, const BufferHandle &handle)
240 {
241 for (uint32_t i = 0; i < handle.reserveFds; i++) {
242 if (!messageParcel.WriteFileDescriptor(handle.reserve[i])) {
243 HDF_LOGE("%{public}s: failed to write reserved fd value", __func__);
244 return false;
245 }
246 }
247 for (uint32_t j = 0; j < handle.reserveInts; j++) {
248 if (!messageParcel.WriteInt32(handle.reserve[handle.reserveFds + j])) {
249 HDF_LOGE("%{public}s: failed to write reserved integer value", __func__);
250 return false;
251 }
252 }
253 return true;
254 }
255
ReadReserveData(MessageParcel & messageParcel,BufferHandle & handle)256 bool NativeBuffer::ReadReserveData(MessageParcel &messageParcel, BufferHandle &handle)
257 {
258 for (uint32_t i = 0; i < handle.reserveFds; i++) {
259 handle.reserve[i] = messageParcel.ReadFileDescriptor();
260 if (handle.reserve[i] == -1) {
261 HDF_LOGE("%{public}s: failed to read reserved fd value", __func__);
262 return false;
263 }
264 }
265 for (uint32_t j = 0; j < handle.reserveInts; j++) {
266 if (!messageParcel.ReadInt32(handle.reserve[handle.reserveFds + j])) {
267 HDF_LOGE("%{public}s: failed to read reserved integer value", __func__);
268 return false;
269 }
270 }
271 return true;
272 }
273 } // namespace Base
274 } // namespace HDI
275 } // namespace OHOS
276