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