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