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 "hdi_buffer_handle.h"
17 #include "hdf_log.h"
18 #include "hdi_buffer_handle_util.h"
19 #include <sstream>
20
21 #define HDF_LOG_TAG hdi_buffer_handle
22
23 namespace OHOS {
24 namespace HDI {
25 namespace Base {
HdiBufferHandle()26 HdiBufferHandle::HdiBufferHandle() : handle_(nullptr) {}
27
~HdiBufferHandle()28 HdiBufferHandle::~HdiBufferHandle()
29 {
30 if (handle_ != nullptr) {
31 FreeBufferHandle(handle_);
32 }
33 }
34
HdiBufferHandle(BufferHandle & handle)35 HdiBufferHandle::HdiBufferHandle(BufferHandle &handle) : HdiBufferHandle()
36 {
37 handle_ = CloneBufferHandle(&handle);
38 }
39
HdiBufferHandle(const HdiBufferHandle & other)40 HdiBufferHandle::HdiBufferHandle(const HdiBufferHandle &other) : HdiBufferHandle()
41 {
42 if (other.handle_ == nullptr) {
43 return;
44 }
45 handle_ = CloneBufferHandle(other.handle_);
46 }
47
HdiBufferHandle(HdiBufferHandle && other)48 HdiBufferHandle::HdiBufferHandle(HdiBufferHandle &&other) noexcept : HdiBufferHandle()
49 {
50 handle_ = other.handle_;
51 other.handle_ = nullptr;
52 }
53
operator =(const HdiBufferHandle & other)54 HdiBufferHandle &HdiBufferHandle::operator=(const HdiBufferHandle &other)
55 {
56 if (this != &other) {
57 if (handle_ != nullptr) {
58 FreeBufferHandle(handle_);
59 }
60 handle_ = CloneBufferHandle(other.handle_);
61 }
62 return *this;
63 }
64
operator =(HdiBufferHandle && other)65 HdiBufferHandle &HdiBufferHandle::operator=(HdiBufferHandle &&other) noexcept
66 {
67 if (this != &other) {
68 if (handle_ != nullptr) {
69 FreeBufferHandle(handle_);
70 }
71 handle_ = other.handle_;
72 other.handle_ = nullptr;
73 }
74 return *this;
75 }
76
Marshalling(Parcel & parcel) const77 bool HdiBufferHandle::Marshalling(Parcel &parcel) const
78 {
79 MessageParcel &messageParcel = static_cast<MessageParcel &>(parcel);
80 bool isValid = handle_ != nullptr ? true : false;
81 if (!messageParcel.WriteBool(isValid)) {
82 HDF_LOGI("%{public}s: failed to write valid flag of buffer handle", __func__);
83 return false;
84 }
85
86 if (!isValid) {
87 HDF_LOGD("%{public}s: write valid buffer handle", __func__);
88 return true;
89 }
90
91 if (!messageParcel.WriteUint32(handle_->reserveFds) || !messageParcel.WriteUint32(handle_->reserveInts) ||
92 !messageParcel.WriteInt32(handle_->width) || !messageParcel.WriteInt32(handle_->stride) ||
93 !messageParcel.WriteInt32(handle_->height) || !messageParcel.WriteInt32(handle_->size) ||
94 !messageParcel.WriteInt32(handle_->format) || !messageParcel.WriteInt64(handle_->usage) ||
95 !messageParcel.WriteUint64(handle_->phyAddr) || !messageParcel.WriteInt32(handle_->key)) {
96 HDF_LOGE("%{public}s: a lot failed", __func__);
97 return false;
98 }
99
100 bool validFd = (handle_->fd >= 0);
101 if (!messageParcel.WriteBool(validFd)) {
102 HDF_LOGE("%{public}s: failed to write valid flag of fd", __func__);
103 return false;
104 }
105 if (validFd && !messageParcel.WriteFileDescriptor(handle_->fd)) {
106 HDF_LOGE("%{public}s: failed to write fd", __func__);
107 return false;
108 }
109
110 if (!WriteReserveData(messageParcel, *handle_)) {
111 return false;
112 }
113
114 return true;
115 }
116
Unmarshalling(Parcel & parcel)117 sptr<HdiBufferHandle> HdiBufferHandle::Unmarshalling(Parcel &parcel)
118 {
119 sptr<HdiBufferHandle> newParcelable = new HdiBufferHandle();
120 if (!newParcelable->ExtractFromParcel(parcel)) {
121 return nullptr;
122 }
123 return newParcelable;
124 }
125
Move()126 BufferHandle *HdiBufferHandle::Move()
127 {
128 BufferHandle *handlePtr = handle_;
129 handle_ = nullptr;
130 return handlePtr;
131 }
132
Dump() const133 std::string HdiBufferHandle::Dump() const
134 {
135 std::stringstream os;
136 os << "{";
137 if (handle_ != nullptr) {
138 os << "fd:" << handle_->fd << ", ";
139 os << "width:" << handle_->width << ", ";
140 os << "stride:" << handle_->stride << ", ";
141 os << "height:" << handle_->height << ", ";
142 os << "size:" << handle_->size << ", ";
143 os << "format:" << handle_->format << ", ";
144 os << "usage:" << handle_->usage << ", ";
145 os << "phyAddr:" << handle_->phyAddr << ", ";
146 os << "key:" << handle_->key << ", ";
147 os << "}\nreserveFds[" << handle_->reserveFds << "]:{";
148
149 uint32_t i = 0;
150 for (; i < handle_->reserveFds; i++) {
151 os << handle_->reserve[i] << ", ";
152 }
153 os << "},\nreserveInts[" << handle_->reserveInts << "]:{";
154
155 uint32_t n = 0;
156 for (; n < handle_->reserveInts; n++) {
157 os << handle_->reserve[i + n] << ", ";
158 }
159 }
160 os << "}\n";
161 return os.str();
162 }
163
ExtractFromParcel(Parcel & parcel)164 bool HdiBufferHandle::ExtractFromParcel(Parcel &parcel)
165 {
166 MessageParcel &messageParcel = static_cast<MessageParcel &>(parcel);
167 if (!messageParcel.ReadBool()) {
168 HDF_LOGD("%{public}s: read invalid buffer handle", __func__);
169 return true;
170 }
171 uint32_t reserveFds = 0;
172 uint32_t reserveInts = 0;
173 if (!messageParcel.ReadUint32(reserveFds) || !messageParcel.ReadUint32(reserveInts)) {
174 HDF_LOGE("%{public}s: failed to read reserveFds or reserveInts", __func__);
175 return false;
176 }
177 if ((handle_ = AllocateBufferHandle(reserveFds, reserveInts)) == NULL) {
178 HDF_LOGE("%{public}s: failed to malloc BufferHandle", __func__);
179 return false;
180 }
181 bool validFd = false;
182 if (!messageParcel.ReadInt32(handle_->width) || !messageParcel.ReadInt32(handle_->stride) ||
183 !messageParcel.ReadInt32(handle_->height) || !messageParcel.ReadInt32(handle_->size) ||
184 !messageParcel.ReadInt32(handle_->format) || !messageParcel.ReadUint64(handle_->usage) ||
185 !messageParcel.ReadUint64(handle_->phyAddr) || !messageParcel.ReadInt32(handle_->key) ||
186 !messageParcel.ReadBool(validFd)) {
187 HDF_LOGE("%{public}s: failed to parcel read", __func__);
188 return false;
189 }
190 if (validFd) {
191 handle_->fd = messageParcel.ReadFileDescriptor();
192 if (handle_->fd == -1) {
193 FreeBufferHandle(handle_);
194 HDF_LOGE("%{public}s: failed to read fd", __func__);
195 return false;
196 }
197 }
198
199 if (!ReadReserveData(messageParcel, *handle_)) {
200 FreeBufferHandle(handle_);
201 return false;
202 }
203 return true;
204 }
205
WriteReserveData(MessageParcel & messageParcel,const BufferHandle & handle)206 bool HdiBufferHandle::WriteReserveData(MessageParcel &messageParcel, const BufferHandle &handle)
207 {
208 for (uint32_t i = 0; i < handle.reserveFds; i++) {
209 if (!messageParcel.WriteFileDescriptor(handle.reserve[i])) {
210 HDF_LOGE("%{public}s: failed to write reserved fd value", __func__);
211 return false;
212 }
213 }
214 for (uint32_t j = 0; j < handle.reserveInts; j++) {
215 if (!messageParcel.WriteInt32(handle.reserve[handle.reserveFds + j])) {
216 HDF_LOGE("%{public}s: failed to write reserved integer value", __func__);
217 return false;
218 }
219 }
220 return true;
221 }
222
ReadReserveData(MessageParcel & messageParcel,BufferHandle & handle)223 bool HdiBufferHandle::ReadReserveData(MessageParcel &messageParcel, BufferHandle &handle)
224 {
225 for (uint32_t i = 0; i < handle.reserveFds; i++) {
226 handle.reserve[i] = messageParcel.ReadFileDescriptor();
227 if (handle.reserve[i] == -1) {
228 HDF_LOGE("%{public}s: failed to read reserved fd value", __func__);
229 return false;
230 }
231 }
232 for (uint32_t j = 0; j < handle.reserveInts; j++) {
233 if (!messageParcel.ReadInt32(handle.reserve[handle.reserveFds + j])) {
234 HDF_LOGE("%{public}s: failed to read reserved integer value", __func__);
235 return false;
236 }
237 }
238 return true;
239 }
240 } // namespace Base
241 } // namespace HDI
242 } // namespace OHOS