1 /*
2 * Copyright (c) 2020-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 "surface_buffer_impl.h"
17 #include "securec.h"
18
19 namespace OHOS {
20 const uint16_t MAX_USER_DATA_COUNT = 1000;
21
SurfaceBufferImpl()22 SurfaceBufferImpl::SurfaceBufferImpl() : len_(0)
23 {
24 struct SurfaceBufferData bufferData = {{0}, 0, 0, 0, BUFFER_STATE_NONE, NULL};
25 bufferData_ = bufferData;
26 }
27
SetInt32(uint32_t key,int32_t value)28 int32_t SurfaceBufferImpl::SetInt32(uint32_t key, int32_t value)
29 {
30 return SetData(key, BUFFER_DATA_TYPE_INT_32, &value, sizeof(value));
31 }
32
GetInt32(uint32_t key,int32_t & value)33 int32_t SurfaceBufferImpl::GetInt32(uint32_t key, int32_t& value)
34 {
35 uint8_t type = BUFFER_DATA_TYPE_NONE;
36 void *data = nullptr;
37 uint8_t size;
38 if (GetData(key, &type, &data, &size) != SURFACE_ERROR_OK || type != BUFFER_DATA_TYPE_INT_32) {
39 return SURFACE_ERROR_INVALID_PARAM;
40 }
41 if (size != sizeof(value)) {
42 return SURFACE_ERROR_INVALID_PARAM;
43 }
44 value = *(reinterpret_cast<int32_t *>(data));
45 return SURFACE_ERROR_OK;
46 }
47
SetInt64(uint32_t key,int64_t value)48 int32_t SurfaceBufferImpl::SetInt64(uint32_t key, int64_t value)
49 {
50 return SetData(key, BUFFER_DATA_TYPE_INT_64, &value, sizeof(value));
51 }
52
GetInt64(uint32_t key,int64_t & value)53 int32_t SurfaceBufferImpl::GetInt64(uint32_t key, int64_t& value)
54 {
55 uint8_t type = BUFFER_DATA_TYPE_NONE;
56 void *data = nullptr;
57 uint8_t size;
58 if (GetData(key, &type, &data, &size) != SURFACE_ERROR_OK || type != BUFFER_DATA_TYPE_INT_64) {
59 return SURFACE_ERROR_INVALID_PARAM;
60 }
61 if (size != sizeof(value)) {
62 return SURFACE_ERROR_INVALID_PARAM;
63 }
64 value = *(reinterpret_cast<int64_t *>(data));
65 return SURFACE_ERROR_OK;
66 }
67
SetData(uint32_t key,uint8_t type,const void * data,uint8_t size)68 int32_t SurfaceBufferImpl::SetData(uint32_t key, uint8_t type, const void* data, uint8_t size)
69 {
70 if (type <= BUFFER_DATA_TYPE_NONE ||
71 type >= BUFFER_DATA_TYPE_MAX ||
72 size <= 0 ||
73 size > sizeof(int64_t)) {
74 GRAPHIC_LOGI("Invalid Param");
75 return SURFACE_ERROR_INVALID_PARAM;
76 }
77 if (extDatas_.size() > MAX_USER_DATA_COUNT) {
78 GRAPHIC_LOGI("No more data can be saved because the storage space is full.");
79 return SURFACE_ERROR_SYSTEM_ERROR;
80 }
81 ExtraData extData = {0};
82 std::map<uint32_t, ExtraData>::iterator iter = extDatas_.find(key);
83 if (iter != extDatas_.end()) {
84 extData = iter->second;
85 if (size != extData.size) {
86 free(extData.value);
87 extData.value = nullptr;
88 }
89 }
90 if (extData.value == nullptr) {
91 extData.value = malloc(size);
92 if (extData.value == nullptr) {
93 GRAPHIC_LOGE("Couldn't allocate %zu bytes for ext data", size);
94 return SURFACE_ERROR_SYSTEM_ERROR;
95 }
96 }
97 if (memcpy_s(extData.value, size, data, size) != EOK) {
98 free(extData.value);
99 GRAPHIC_LOGW("Couldn't copy %zu bytes for ext data", size);
100 return SURFACE_ERROR_SYSTEM_ERROR;
101 }
102 extData.size = size;
103 extData.type = type;
104 extDatas_[key] = extData;
105 return SURFACE_ERROR_OK;
106 }
107
GetData(uint32_t key,uint8_t * type,void ** data,uint8_t * size)108 int32_t SurfaceBufferImpl::GetData(uint32_t key, uint8_t* type, void** data, uint8_t* size)
109 {
110 if ((type == nullptr) || (data == nullptr) || (size == nullptr)) {
111 return SURFACE_ERROR_INVALID_PARAM;
112 }
113
114 std::map<uint32_t, ExtraData>::iterator iter = extDatas_.find(key);
115 if (iter == extDatas_.end()) {
116 return SURFACE_ERROR_INVALID_PARAM;
117 }
118 ExtraData extData = extDatas_[key];
119 *data = extData.value;
120 *size = extData.size;
121 *type = extData.type;
122 return SURFACE_ERROR_OK;
123 }
124
ReadFromIpcIo(IpcIo & io)125 void SurfaceBufferImpl::ReadFromIpcIo(IpcIo& io)
126 {
127 ReadInt32(&io, &(bufferData_.handle.key));
128 ReadUint64(&io, &(bufferData_.handle.phyAddr));
129 ReadUint32(&io, &(bufferData_.handle.reserveFds));
130 ReadUint32(&io, &(bufferData_.handle.reserveInts));
131 ReadUint32(&io, &(bufferData_.size));
132 ReadUint32(&io, &(bufferData_.usage));
133 ReadUint32(&io, &len_);
134 uint32_t extDataSize;
135 ReadUint32(&io, &extDataSize);
136 if (extDataSize > 0 && extDataSize < MAX_USER_DATA_COUNT) {
137 for (uint32_t i = 0; i < extDataSize; i++) {
138 uint32_t key;
139 ReadUint32(&io, &key);
140 uint32_t type;
141 ReadUint32(&io, &type);
142 switch (type) {
143 case BUFFER_DATA_TYPE_INT_32: {
144 int32_t value;
145 ReadInt32(&io, &value);
146 SetInt32(key, value);
147 break;
148 }
149 case BUFFER_DATA_TYPE_INT_64: {
150 int64_t value;
151 ReadInt64(&io, &value);
152 SetInt64(key, value);
153 break;
154 }
155 default:
156 break;
157 }
158 }
159 }
160 }
WriteToIpcIo(IpcIo & io)161 void SurfaceBufferImpl::WriteToIpcIo(IpcIo& io)
162 {
163 WriteInt32(&io, bufferData_.handle.key);
164 WriteUint64(&io, bufferData_.handle.phyAddr);
165 WriteUint32(&io, bufferData_.handle.reserveFds);
166 WriteUint32(&io, bufferData_.handle.reserveInts);
167 WriteUint32(&io, bufferData_.size);
168 WriteUint32(&io, bufferData_.usage);
169 WriteUint32(&io, len_);
170 WriteUint32(&io, extDatas_.size());
171 if (!extDatas_.empty()) {
172 std::map<uint32_t, ExtraData>::iterator iter;
173 for (iter = extDatas_.begin(); iter != extDatas_.end(); ++iter) {
174 uint32_t key = iter->first;
175 ExtraData value = iter->second;
176 WriteUint32(&io, key);
177 WriteUint32(&io, value.type);
178 switch (value.type) {
179 case BUFFER_DATA_TYPE_INT_32:
180 WriteInt32(&io, *(reinterpret_cast<int32_t *>(value.value)));
181 break;
182 case BUFFER_DATA_TYPE_INT_64:
183 WriteInt64(&io, *(reinterpret_cast<int64_t *>(value.value)));
184 break;
185 default:
186 break;
187 }
188 }
189 }
190 }
191
CopyExtraData(SurfaceBufferImpl & buffer)192 void SurfaceBufferImpl::CopyExtraData(SurfaceBufferImpl& buffer)
193 {
194 len_ = buffer.len_;
195 extDatas_ = buffer.extDatas_;
196 buffer.extDatas_.clear();
197 }
198
ClearExtraData()199 void SurfaceBufferImpl::ClearExtraData()
200 {
201 if (!extDatas_.empty()) {
202 std::map<uint32_t, ExtraData>::iterator iter;
203 for (iter = extDatas_.begin(); iter != extDatas_.end(); ++iter) {
204 ExtraData value = iter->second;
205 free(value.value);
206 value.value = nullptr;
207 }
208 extDatas_.clear();
209 }
210 }
211
~SurfaceBufferImpl()212 SurfaceBufferImpl::~SurfaceBufferImpl()
213 {
214 ClearExtraData();
215 struct SurfaceBufferData bufferData = {{0}, 0, 0, 0, BUFFER_STATE_NONE, NULL};
216 bufferData_ = bufferData;
217 }
218 }
219