• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #ifndef OHOS_HDI_DISPLAY_V1_0_DISPLAY_CMD_UTILS_H
17 #define OHOS_HDI_DISPLAY_V1_0_DISPLAY_CMD_UTILS_H
18 
19 #include "buffer_handle_utils.h"
20 #include "command_pack/command_data_packer.h"
21 #include "command_pack/command_data_unpacker.h"
22 #include "common/include/display_interface_utils.h"
23 #include "v1_0/display_composer_type.h"
24 
25 #undef LOG_TAG
26 #define LOG_TAG "DISP_CMD"
27 #undef LOG_DOMAIN
28 #define LOG_DOMAIN 0xD002515
29 
30 #define INVALID_FD (-1)
31 
32 namespace OHOS {
33 namespace HDI {
34 namespace Display {
35 namespace Composer {
36 namespace V1_0 {
37 using namespace OHOS::HDI::Display::Composer::V1_0;
38 
39 class DisplayCmdUtils {
40 public:
41     static constexpr int32_t MAX_INT = 0x7fffffff;
42     static constexpr uint32_t ELEMENT_SIZE = sizeof(int32_t);
43     static constexpr uint32_t MOVE_SIZE = sizeof(int) / 2;
44     static constexpr uint32_t TRANSFER_WAIT_TIME = 100000000; // ms
45     static constexpr uint32_t INIT_ELEMENT_COUNT = 32 * 1024;
46     static constexpr uint32_t MAX_MEMORY = 10485760; // 10M
47     static constexpr uint32_t MAX_ELE_COUNT = 100000;
48 
49     #define SWITCHCASE(x) case (x): {return #x;}
CommandToString(int32_t cmdId)50     static const char *CommandToString(int32_t cmdId)
51     {
52         switch (cmdId) {
53             /* request cmd */
54             SWITCHCASE(REQUEST_CMD_PREPARE_DISPLAY_LAYERS);
55             SWITCHCASE(REQUEST_CMD_SET_DISPLAY_CLIENT_BUFFER);
56             SWITCHCASE(REQUEST_CMD_SET_DISPLAY_CLIENT_DAMAGE);
57             SWITCHCASE(REQUEST_CMD_COMMIT);
58             SWITCHCASE(REQUEST_CMD_SET_LAYER_ALPHA);
59             SWITCHCASE(REQUEST_CMD_SET_LAYER_REGION);
60             SWITCHCASE(REQUEST_CMD_SET_LAYER_CROP);
61             SWITCHCASE(REQUEST_CMD_SET_LAYER_ZORDER);
62             SWITCHCASE(REQUEST_CMD_SET_LAYER_PREMULTI);
63             SWITCHCASE(REQUEST_CMD_SET_LAYER_TRANSFORM_MODE);
64             SWITCHCASE(REQUEST_CMD_SET_LAYER_DIRTY_REGION);
65             SWITCHCASE(REQUEST_CMD_SET_LAYER_VISIBLE_REGION);
66             SWITCHCASE(REQUEST_CMD_SET_LAYER_BUFFER);
67             SWITCHCASE(REQUEST_CMD_SET_LAYER_COMPOSITION_TYPE);
68             SWITCHCASE(REQUEST_CMD_SET_LAYER_BLEND_TYPE);
69             SWITCHCASE(REQUEST_CMD_SET_LAYER_VISIBLE);
70             SWITCHCASE(REQUEST_CMD_SET_LAYER_MASK_INFO);
71             SWITCHCASE(REQUEST_CMD_SET_LAYER_COLOR);
72             /* reply cmd */
73             SWITCHCASE(REPLY_CMD_SET_ERROR);
74             SWITCHCASE(REPLY_CMD_PREPARE_DISPLAY_LAYERS);
75             SWITCHCASE(REPLY_CMD_COMMIT);
76             /* pack control cmd */
77             SWITCHCASE(CONTROL_CMD_REQUEST_BEGIN);
78             SWITCHCASE(CONTROL_CMD_REPLY_BEGIN);
79             SWITCHCASE(CONTROL_CMD_REQUEST_END);
80             SWITCHCASE(CONTROL_CMD_REPLY_END);
81             default:
82                 return "unknow command id.";
83         }
84     }
85 
StartPack(int32_t cmdId,CommandDataPacker & packer)86     static int32_t StartPack(int32_t cmdId, CommandDataPacker& packer)
87     {
88         return packer.PackBegin(cmdId) ? HDF_SUCCESS : HDF_FAILURE;
89     }
90 
EndPack(CommandDataPacker & packer)91     static int32_t EndPack(CommandDataPacker& packer)
92     {
93         return packer.PackEnd(CONTROL_CMD_REQUEST_END) ? HDF_SUCCESS : HDF_FAILURE;
94     }
95 
StartSection(int32_t cmdId,CommandDataPacker & packer)96     static int32_t StartSection(int32_t cmdId, CommandDataPacker& packer)
97     {
98         return packer.BeginSection(cmdId) ? HDF_SUCCESS : HDF_FAILURE;
99     }
100 
SetupDevice(uint32_t devId,uint32_t layerId,CommandDataPacker & packer)101     static int32_t SetupDevice(uint32_t devId, uint32_t layerId, CommandDataPacker& packer)
102     {
103         DISPLAY_CHK_RETURN(packer.WriteUint32(devId) == false, HDF_FAILURE,
104             HDF_LOGE("%{public}s, write devId error", __func__));
105         DISPLAY_CHK_RETURN(packer.WriteUint32(layerId) == false, HDF_FAILURE,
106             HDF_LOGE("%{public}s, write layerId error", __func__));
107         return HDF_SUCCESS;
108     }
109 
EndSection(CommandDataPacker & packer)110     static int32_t EndSection(CommandDataPacker& packer)
111     {
112         return packer.EndSection() ? HDF_SUCCESS : HDF_FAILURE;
113     }
114 
GenerateHdifdSeqid()115     static int32_t GenerateHdifdSeqid()
116     {
117         static int32_t HdifdSeqidCursor = 0;
118 
119         if (HdifdSeqidCursor <= MAX_INT) {
120             ++HdifdSeqidCursor;
121             return HdifdSeqidCursor;
122         } else {
123             return 0;
124         }
125     }
126 
MatchHdiFd(int32_t id,std::vector<HdifdInfo> hdiFds,int32_t & fd)127     static bool MatchHdiFd(int32_t id, std::vector<HdifdInfo> hdiFds, int32_t& fd)
128     {
129         for (uint32_t i = 0; i < hdiFds.size(); ++i) {
130             if (hdiFds[i].hdiFd == nullptr) {
131                 HDF_LOGE("%{public}s, hdiFd is nullptr", __func__);
132                 continue;
133             }
134             if (hdiFds[i].id == id) {
135                 fd = hdiFds[i].hdiFd->Move();
136                 return true;
137             }
138         }
139         return false;
140     }
141 
RectPack(const IRect & rect,CommandDataPacker & packer)142     static int32_t RectPack(const IRect& rect, CommandDataPacker& packer)
143     {
144         DISPLAY_CHK_RETURN(packer.WriteInt32(rect.x) == false, HDF_FAILURE,
145             HDF_LOGE("%{public}s, write rect.x error", __func__));
146         DISPLAY_CHK_RETURN(packer.WriteInt32(rect.y) == false, HDF_FAILURE,
147             HDF_LOGE("%{public}s, write rect.y error", __func__));
148         DISPLAY_CHK_RETURN(packer.WriteInt32(rect.w) == false, HDF_FAILURE,
149             HDF_LOGE("%{public}s, write rect.w error", __func__));
150         DISPLAY_CHK_RETURN(packer.WriteInt32(rect.h) == false, HDF_FAILURE,
151             HDF_LOGE("%{public}s, write rect.h error", __func__));
152         return HDF_SUCCESS;
153     }
154 
LayerColorPack(const LayerColor & layerColor,CommandDataPacker & packer)155     static int32_t LayerColorPack(const LayerColor& layerColor, CommandDataPacker& packer)
156     {
157         DISPLAY_CHK_RETURN(packer.WriteUint8(layerColor.r) == false, HDF_FAILURE,
158             HDF_LOGE("%{public}s, write layerColor.r error", __func__));
159         DISPLAY_CHK_RETURN(packer.WriteUint8(layerColor.g) == false, HDF_FAILURE,
160             HDF_LOGE("%{public}s, write layerColor.g error", __func__));
161         DISPLAY_CHK_RETURN(packer.WriteUint8(layerColor.b) == false, HDF_FAILURE,
162             HDF_LOGE("%{public}s, write layerColor.b error", __func__));
163         DISPLAY_CHK_RETURN(packer.WriteUint8(layerColor.a) == false, HDF_FAILURE,
164             HDF_LOGE("%{public}s, write layerColor.a error", __func__));
165         return HDF_SUCCESS;
166     }
167 
168     static int32_t FileDescriptorPack(
169         const int32_t fd, CommandDataPacker& packer, std::vector<HdifdInfo>& hdiFds, bool dupFd = true)
170     {
171         if (fd < 0) {
172             DISPLAY_CHK_RETURN(packer.WriteInt32(fd) == false, HDF_FAILURE,
173                 HDF_LOGE("%{public}s, write fd error", __func__));
174             return HDF_SUCCESS;
175         }
176 
177         HdifdInfo hdifdInfo;
178         hdifdInfo.id = GenerateHdifdSeqid();
179         if (dupFd) {
180             hdifdInfo.hdiFd = new HdifdParcelable();
181             DISPLAY_CHK_RETURN(hdifdInfo.hdiFd == nullptr, HDF_FAILURE,
182                 HDF_LOGE("%{public}s, new HdifdParcelable failed", __func__));
183             // A normal fd is transfered by binder, here just write id for unpacking to match fd.
184             DISPLAY_CHK_RETURN(hdifdInfo.hdiFd->Init(fd) == false, HDF_FAILURE,
185                 HDF_LOGE("%{public}s, hdiFd init failed, fd:%{public}d", __func__, fd));
186         } else {
187             hdifdInfo.hdiFd = new HdifdParcelable(fd);
188             DISPLAY_CHK_RETURN(hdifdInfo.hdiFd == nullptr, HDF_FAILURE,
189                 HDF_LOGE("%{public}s, new HdifdParcelable failed", __func__));
190             hdifdInfo.hdiFd->Move();
191         }
192 
193         hdiFds.push_back(hdifdInfo);
194         DISPLAY_CHK_RETURN(packer.WriteInt32(hdifdInfo.id) == false, HDF_FAILURE,
195             HDF_LOGE("%{public}s, write hdifdInfo.id failed", __func__));
196 
197         return HDF_SUCCESS;
198     }
199 
BufferHandlePack(const BufferHandle * buffer,CommandDataPacker & packer,std::vector<HdifdInfo> & hdiFds)200     static int32_t BufferHandlePack(const BufferHandle* buffer, CommandDataPacker& packer,
201         std::vector<HdifdInfo>& hdiFds)
202     {
203         if (buffer == nullptr) {
204             DISPLAY_CHK_RETURN(packer.WriteUint32(UINT32_MAX) == false, HDF_FAILURE,
205                 HDF_LOGE("%{public}s, write null buffer reserveFds error", __func__));
206             DISPLAY_CHK_RETURN(packer.WriteUint32(UINT32_MAX) == false, HDF_FAILURE,
207                 HDF_LOGE("%{public}s, write null buffer reservceInts error", __func__));
208             return HDF_SUCCESS;
209         } else {
210             DISPLAY_CHK_RETURN(packer.WriteUint32(buffer->reserveFds) == false, HDF_FAILURE,
211                 HDF_LOGE("%{public}s, write buffer->reserveFds error", __func__));
212             DISPLAY_CHK_RETURN(packer.WriteUint32(buffer->reserveInts) == false, HDF_FAILURE,
213                 HDF_LOGE("%{public}s, write buffer->reserveInts error", __func__));
214         }
215         int32_t ret = FileDescriptorPack(buffer->fd, packer, hdiFds);
216         if (ret != HDF_SUCCESS) {
217             return ret;
218         }
219         DISPLAY_CHK_RETURN(packer.WriteInt32(buffer->width) == false, HDF_FAILURE,
220             HDF_LOGE("%{public}s, write buffer->width failed", __func__));
221         DISPLAY_CHK_RETURN(packer.WriteInt32(buffer->stride) == false, HDF_FAILURE,
222             HDF_LOGE("%{public}s, write buffer->stride failed", __func__));
223         DISPLAY_CHK_RETURN(packer.WriteInt32(buffer->height) == false, HDF_FAILURE,
224             HDF_LOGE("%{public}s, write buffer->height failed", __func__));
225         DISPLAY_CHK_RETURN(packer.WriteInt32(buffer->size) == false, HDF_FAILURE,
226             HDF_LOGE("%{public}s, write buffer->size failed", __func__));
227         DISPLAY_CHK_RETURN(packer.WriteInt32(buffer->format) == false, HDF_FAILURE,
228             HDF_LOGE("%{public}s, write buffer->format failed", __func__));
229         DISPLAY_CHK_RETURN(packer.WriteUint64(buffer->usage) == false, HDF_FAILURE,
230             HDF_LOGE("%{public}s, write buffer->usage failed", __func__));
231         DISPLAY_CHK_RETURN(packer.WriteUint64(buffer->phyAddr) == false, HDF_FAILURE,
232             HDF_LOGE("%{public}s, write buffer->phyAddr failed", __func__));
233         uint32_t i = 0;
234         for (i = 0; i < buffer->reserveFds; i++) {
235             ret = FileDescriptorPack(buffer->reserve[i], packer, hdiFds);
236             if (ret != HDF_SUCCESS) {
237                 return ret;
238             }
239         }
240         for (uint32_t j = 0; j < buffer->reserveInts; j++) {
241             DISPLAY_CHK_RETURN(packer.WriteInt32(buffer->reserve[i++]) == false, HDF_FAILURE,
242                 HDF_LOGE("%{public}s, write buffer->reserve failed", __func__));
243         }
244         return HDF_SUCCESS;
245     }
246 
SetupDeviceUnpack(CommandDataUnpacker & unpacker,uint32_t & devId,uint32_t & layerId)247     static int32_t SetupDeviceUnpack(CommandDataUnpacker& unpacker, uint32_t& devId, uint32_t& layerId)
248     {
249         DISPLAY_CHK_RETURN(unpacker.ReadUint32(devId) == false, HDF_FAILURE,
250             HDF_LOGE("%{public}s, read devId failed", __func__));
251         DISPLAY_CHK_RETURN(unpacker.ReadUint32(layerId) == false, HDF_FAILURE,
252             HDF_LOGE("%{public}s, read layerId failed", __func__));
253         return HDF_SUCCESS;
254     }
255 
RectUnpack(CommandDataUnpacker & unpacker,IRect & rect)256     static int32_t RectUnpack(CommandDataUnpacker& unpacker, IRect& rect)
257     {
258         DISPLAY_CHK_RETURN(unpacker.ReadInt32(rect.x) == false, HDF_FAILURE,
259             HDF_LOGE("%{public}s, read rect.x failed", __func__));
260         DISPLAY_CHK_RETURN(unpacker.ReadInt32(rect.y) == false, HDF_FAILURE,
261             HDF_LOGE("%{public}s, read rect.y failed", __func__));
262         DISPLAY_CHK_RETURN(unpacker.ReadInt32(rect.w) == false, HDF_FAILURE,
263             HDF_LOGE("%{public}s, read rect.w failed", __func__));
264         DISPLAY_CHK_RETURN(unpacker.ReadInt32(rect.h) == false, HDF_FAILURE,
265             HDF_LOGE("%{public}s, read rect.h failed", __func__));
266         return HDF_SUCCESS;
267     }
268 
FileDescriptorUnpack(CommandDataUnpacker & unpacker,const std::vector<HdifdInfo> & hdiFds,int32_t & fd)269     static int32_t FileDescriptorUnpack(
270         CommandDataUnpacker& unpacker, const std::vector<HdifdInfo>& hdiFds, int32_t& fd)
271     {
272         int32_t fdId = -1;
273         DISPLAY_CHK_RETURN(unpacker.ReadInt32(fdId) == false, HDF_FAILURE,
274             HDF_LOGE("%{public}s, read fdId failed", __func__));
275         if (fdId < 0) {
276             fd = INVALID_FD;
277             return HDF_SUCCESS;
278         }
279         if (!(MatchHdiFd(fdId, hdiFds, fd))) {
280             // If matching failure, the illegal fd is transfered by smq directly, not by binder IPC.
281             HDF_LOGE("%{public}s, matching failure, fd %{public}d, fdId %{public}d, hdiFds.size %{public}zu",
282                      __func__, fd, fdId, hdiFds.size());
283             fd = INVALID_FD;
284             return HDF_FAILURE;
285         }
286         return HDF_SUCCESS;
287     }
288 
UnpackBasicInfo(CommandDataUnpacker & unpacker,const std::vector<HdifdInfo> & hdiFds,BufferHandle * handle)289     static bool UnpackBasicInfo(CommandDataUnpacker& unpacker, const std::vector<HdifdInfo>& hdiFds,
290         BufferHandle *handle)
291     {
292         int32_t ret = FileDescriptorUnpack(unpacker, hdiFds, handle->fd);
293         bool retVal = (ret == HDF_SUCCESS ? true : false);
294         DISPLAY_CHK_CONDITION(retVal, true, unpacker.ReadInt32(handle->width),
295             HDF_LOGE("%{public}s, read handle->width error", __func__));
296         DISPLAY_CHK_CONDITION(retVal, true, unpacker.ReadInt32(handle->stride),
297             HDF_LOGE("%{public}s, read handle->stride error", __func__));
298         DISPLAY_CHK_CONDITION(retVal, true, unpacker.ReadInt32(handle->height),
299             HDF_LOGE("%{public}s, read handle->height error", __func__));
300         DISPLAY_CHK_CONDITION(retVal, true, unpacker.ReadInt32(handle->size),
301             HDF_LOGE("%{public}s, read handle->size error", __func__));
302         DISPLAY_CHK_CONDITION(retVal, true, unpacker.ReadInt32(handle->format),
303             HDF_LOGE("%{public}s, read handle->format error", __func__));
304         DISPLAY_CHK_CONDITION(retVal, true, unpacker.ReadUint64(handle->usage),
305             HDF_LOGE("%{public}s, read handle->usage error", __func__));
306         DISPLAY_CHK_CONDITION(retVal, true, unpacker.ReadUint64(handle->phyAddr),
307             HDF_LOGE("%{public}s, read handle->phyAddr error", __func__));
308         return retVal;
309     }
310 
UnpackExtraInfo(CommandDataUnpacker & unpacker,const std::vector<HdifdInfo> & hdiFds,BufferHandle * handle)311     static bool UnpackExtraInfo(CommandDataUnpacker& unpacker, const std::vector<HdifdInfo>& hdiFds,
312         BufferHandle *handle)
313     {
314         bool retVal = true;
315         uint32_t i = 0;
316         for (i = 0; i < handle->reserveFds; i++) {
317             int32_t ret = FileDescriptorUnpack(unpacker, hdiFds, handle->reserve[i]);
318             if (ret != HDF_SUCCESS) {
319                 retVal = false;
320                 break;
321             }
322         }
323         for (uint32_t j = 0; j < handle->reserveInts; j++) {
324             retVal = unpacker.ReadInt32(handle->reserve[i++]);
325             if (!retVal) {
326                 HDF_LOGE("%{public}s, get reserve data error, i:%{public}u, j:%{public}u",
327                     __func__, i, j);
328                 break;
329             }
330         }
331         return retVal;
332     }
333 
BufferHandleUnpack(CommandDataUnpacker & unpacker,const std::vector<HdifdInfo> & hdiFds,BufferHandle * & buffer)334     static int32_t BufferHandleUnpack(CommandDataUnpacker& unpacker,
335         const std::vector<HdifdInfo>& hdiFds, BufferHandle*& buffer)
336     {
337         uint32_t fdsNum = 0;
338         uint32_t intsNum = 0;
339         DISPLAY_CHK_RETURN(unpacker.ReadUint32(fdsNum) == false, HDF_FAILURE,
340             HDF_LOGE("%{public}s, read fdsNum error", __func__));
341         DISPLAY_CHK_RETURN(unpacker.ReadUint32(intsNum) == false, HDF_FAILURE,
342             HDF_LOGE("%{public}s, read intsNum error", __func__));
343         if (fdsNum == UINT32_MAX && intsNum == UINT32_MAX) {
344             buffer = nullptr;
345             return HDF_SUCCESS;
346         }
347         BufferHandle *handle = AllocateBufferHandle(fdsNum, intsNum);
348         if (handle == nullptr) {
349             return HDF_FAILURE;
350         }
351         bool retVal = UnpackBasicInfo(unpacker, hdiFds, handle);
352         if (retVal) {
353             retVal = UnpackExtraInfo(unpacker, hdiFds, handle);
354         }
355         if (!retVal) {
356             if (handle != nullptr) {
357                 FreeBufferHandle(handle);
358                 handle = nullptr;
359             }
360             HDF_LOGE("%{public}s: buffer handle unpack failed", __func__);
361         }
362         buffer = handle;
363         return retVal ? HDF_SUCCESS : HDF_FAILURE;
364     }
365 
LayerColorUnpack(CommandDataUnpacker & unpacker,LayerColor & layerColor)366     static int32_t LayerColorUnpack(CommandDataUnpacker& unpacker, LayerColor& layerColor)
367     {
368         DISPLAY_CHK_RETURN(unpacker.ReadUint8(layerColor.r) == false, HDF_FAILURE,
369             HDF_LOGE("%{public}s, read layerColor.r failed", __func__));
370         DISPLAY_CHK_RETURN(unpacker.ReadUint8(layerColor.g) == false, HDF_FAILURE,
371             HDF_LOGE("%{public}s, read layerColor.g failed", __func__));
372         DISPLAY_CHK_RETURN(unpacker.ReadUint8(layerColor.b) == false, HDF_FAILURE,
373             HDF_LOGE("%{public}s, read layerColor.b failed", __func__));
374         DISPLAY_CHK_RETURN(unpacker.ReadUint8(layerColor.a) == false, HDF_FAILURE,
375             HDF_LOGE("%{public}s, read layerColor.a failed", __func__));
376         return HDF_SUCCESS;
377     }
378 };
379 using CmdUtils = DisplayCmdUtils;
380 } // namespace V1_0
381 } // namespace Composer
382 } // namespace Display
383 } // namespace HDI
384 } // namespace OHOS
385 #endif // OHOS_HDI_DISPLAY_V1_0_DISPLAY_CMD_UTILS_H