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_REQUESTER_H
17 #define OHOS_HDI_DISPLAY_V1_0_DISPLAY_CMD_REQUESTER_H
18 
19 #include <fstream>
20 #include <poll.h>
21 #include <securec.h>
22 #include <sstream>
23 #include <string>
24 #include <sys/time.h>
25 #include <unistd.h>
26 #include <unordered_map>
27 #include <queue>
28 
29 #include "base/hdi_smq.h"
30 #include "buffer_handle_utils.h"
31 #include "command_pack/command_data_packer.h"
32 #include "command_pack/command_data_unpacker.h"
33 #include "display_cmd_utils.h"
34 #include "hdf_base.h"
35 #include "hdf_trace.h"
36 #include "hdifd_parcelable.h"
37 #include "hilog/log.h"
38 #include "idisplay_composer_vdi.h"
39 #include "parameter.h"
40 #include "v1_0/display_composer_type.h"
41 #include "v1_0/mapper_stub.h"
42 
43 #define DISPLAY_TRACE HdfTrace trace(__func__, "HDI:DISP:")
44 
45 namespace OHOS {
46 namespace HDI {
47 namespace Display {
48 namespace Composer {
49 namespace V1_0 {
50 using namespace OHOS::HDI::Base;
51 using namespace OHOS::HDI::Display::Composer::V1_0;
52 using namespace OHOS::HDI::Display::Buffer::V1_0;
53 using HdifdSet = std::vector<std::shared_ptr<HdifdParcelable>>;
54 
55 static constexpr uint32_t TIME_BUFFER_MAX_LEN = 15;
56 static constexpr uint32_t BUFFER_QUEUE_MAX_SIZE = 6;
57 static constexpr unsigned int REDUCE_COUNT = 50;
58 static constexpr int32_t ERROR_FENCE_COUNT = 500;
59 static sptr<IMapper> g_bufferServiceImpl = nullptr;
60 
61 static constexpr uint32_t COMMIT_PRINT_INTERVAL = 1200;
62 
63 template <typename Transfer, typename VdiImpl>
64 class DisplayCmdResponser {
65 public:
Create(VdiImpl * impl,std::shared_ptr<DeviceCacheManager> cacheMgr)66     static std::unique_ptr<DisplayCmdResponser> Create(VdiImpl* impl, std::shared_ptr<DeviceCacheManager> cacheMgr)
67     {
68         DISPLAY_CHK_RETURN(impl == nullptr, nullptr,
69             HDF_LOGE("%{public}s: error, VdiImpl is nullptr", __func__));
70         DISPLAY_CHK_RETURN(cacheMgr == nullptr, nullptr,
71             HDF_LOGE("%{public}s: error, VdiImpl is nullptr", __func__));
72         return std::make_unique<DisplayCmdResponser>(impl, cacheMgr);
73     }
74 
DisplayCmdResponser(VdiImpl * impl,std::shared_ptr<DeviceCacheManager> cacheMgr)75     DisplayCmdResponser(VdiImpl* impl, std::shared_ptr<DeviceCacheManager> cacheMgr)
76         : impl_(impl),
77         cacheMgr_(cacheMgr),
78         request_(nullptr),
79         isReplyUpdated_(false),
80         reply_(nullptr),
81         replyCommandCnt_(0) {}
82 
~DisplayCmdResponser()83     virtual ~DisplayCmdResponser()
84     {
85         while (delayFreeQueue_.size() > 0) {
86             BufferHandle *temp = delayFreeQueue_.front();
87             delayFreeQueue_.pop();
88             FreeBufferHandle(temp);
89             temp = nullptr;
90         }
91     }
92 
InitCmdRequest(const std::shared_ptr<Transfer> & request)93     int32_t InitCmdRequest(const std::shared_ptr<Transfer>& request)
94     {
95         DISPLAY_CHK_RETURN(request == nullptr, HDF_FAILURE,
96             HDF_LOGE("%{public}s: error, request is nullptr", __func__));
97         std::lock_guard<std::mutex> lock(requestMutex_);
98         if (request_ != nullptr) {
99             request_.reset();
100         }
101         request_ = request;
102 
103         return HDF_SUCCESS;
104     }
105 
GetCmdReply(std::shared_ptr<Transfer> & reply)106     int32_t GetCmdReply(std::shared_ptr<Transfer>& reply)
107     {
108         std::lock_guard<std::mutex> lock(replyMutex_);
109         int32_t ret = HDF_SUCCESS;
110         if (isReplyUpdated_ == false) {
111             ret = InitReply(CmdUtils::INIT_ELEMENT_COUNT);
112         }
113         if (ret == HDF_SUCCESS) {
114             if (reply_ != nullptr) {
115                 reply = reply_;
116             } else {
117                 ret = HDF_FAILURE;
118             }
119         }
120         isReplyUpdated_ = false;
121         if (ret != HDF_SUCCESS) {
122             HDF_LOGE("error: GetCmdReply failure");
123         }
124 
125         return ret;
126     }
127 
ProcessRequestCmd(CommandDataUnpacker & unpacker,int32_t cmd,const std::vector<HdifdInfo> & inFds,std::vector<HdifdInfo> & outFds)128     int32_t ProcessRequestCmd(CommandDataUnpacker& unpacker, int32_t cmd,
129         const std::vector<HdifdInfo>& inFds, std::vector<HdifdInfo>& outFds)
130     {
131         int32_t ret = HDF_SUCCESS;
132         switch (cmd) {
133             case REQUEST_CMD_PREPARE_DISPLAY_LAYERS: OnPrepareDisplayLayers(unpacker); break;
134             case REQUEST_CMD_SET_DISPLAY_CLIENT_BUFFER: OnSetDisplayClientBuffer(unpacker, inFds); break;
135             case REQUEST_CMD_SET_DISPLAY_CLIENT_DAMAGE: OnSetDisplayClientDamage(unpacker); break;
136             case REQUEST_CMD_COMMIT: OnCommit(unpacker, outFds); break;
137             case REQUEST_CMD_SET_LAYER_ALPHA: OnSetLayerAlpha(unpacker); break;
138             case REQUEST_CMD_SET_LAYER_REGION: OnSetLayerRegion(unpacker); break;
139             case REQUEST_CMD_SET_LAYER_CROP: OnSetLayerCrop(unpacker); break;
140             case REQUEST_CMD_SET_LAYER_ZORDER: OnSetLayerZorder(unpacker); break;
141             case REQUEST_CMD_SET_LAYER_PREMULTI: OnSetLayerPreMulti(unpacker); break;
142             case REQUEST_CMD_SET_LAYER_TRANSFORM_MODE: OnSetLayerTransformMode(unpacker); break;
143             case REQUEST_CMD_SET_LAYER_DIRTY_REGION: OnSetLayerDirtyRegion(unpacker); break;
144             case REQUEST_CMD_SET_LAYER_VISIBLE_REGION: OnSetLayerVisibleRegion(unpacker); break;
145             case REQUEST_CMD_SET_LAYER_BUFFER: OnSetLayerBuffer(unpacker, inFds); break;
146             case REQUEST_CMD_SET_LAYER_COMPOSITION_TYPE: OnSetLayerCompositionType(unpacker); break;
147             case REQUEST_CMD_SET_LAYER_BLEND_TYPE: OnSetLayerBlendType(unpacker); break;
148             case REQUEST_CMD_SET_LAYER_MASK_INFO: OnSetLayerMaskInfo(unpacker); break;
149             case CONTROL_CMD_REQUEST_END: ret = OnRequestEnd(unpacker); break;
150             case REQUEST_CMD_SET_LAYER_COLOR: OnSetLayerColor(unpacker); break;
151             default:
152                 HDF_LOGE("%{public}s: not support this cmd, unpacked cmd = %{public}d", __func__, cmd);
153                 ret = HDF_FAILURE;
154                 break;
155         }
156         return ret;
157     }
158 
CmdRequest(uint32_t inEleCnt,const std::vector<HdifdInfo> & inFds,uint32_t & outEleCnt,std::vector<HdifdInfo> & outFds)159     int32_t CmdRequest(uint32_t inEleCnt, const std::vector<HdifdInfo>& inFds, uint32_t& outEleCnt,
160         std::vector<HdifdInfo>& outFds)
161     {
162         if (inEleCnt > CmdUtils::MAX_ELE_COUNT) {
163             HDF_LOGE("%{public}s: inEleCnt:%{public}u is too large", __func__, inEleCnt);
164             return HDF_FAILURE;
165         }
166         std::shared_ptr<char> requestData(new char[inEleCnt * CmdUtils::ELEMENT_SIZE], std::default_delete<char[]>());
167         int32_t ret = HDF_SUCCESS;
168         {
169             std::lock_guard<std::mutex> lock(requestMutex_);
170             ret = request_->Read(reinterpret_cast<int32_t *>(requestData.get()), inEleCnt,
171                 CmdUtils::TRANSFER_WAIT_TIME);
172         }
173         CommandDataUnpacker unpacker;
174         unpacker.Init(requestData.get(), inEleCnt << CmdUtils::MOVE_SIZE);
175 #ifdef DEBUG_DISPLAY_CMD_RAW_DATA
176         unpacker.Dump();
177 #endif // DEBUG_DISPLAY_CMD_RAW_DATA
178 
179         int32_t unpackCmd = -1;
180         bool retBool = unpacker.PackBegin(unpackCmd);
181         DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE,
182             HDF_LOGE("%{public}s: error: Check RequestBegin failed", __func__));
183         DISPLAY_CHK_RETURN(unpackCmd != CONTROL_CMD_REQUEST_BEGIN, HDF_FAILURE,
184             HDF_LOGI("error: unpacker PackBegin cmd not match, cmd(%{public}d)=%{public}s.", unpackCmd,
185             CmdUtils::CommandToString(unpackCmd)));
186 
187         while (ret == HDF_SUCCESS && unpacker.NextSection()) {
188             if (!unpacker.BeginSection(unpackCmd)) {
189                 HDF_LOGE("error: PackSection failed, unpackCmd=%{public}s.", CmdUtils::CommandToString(unpackCmd));
190                 return HDF_FAILURE;
191             }
192             ret = ProcessRequestCmd(unpacker, unpackCmd, inFds, outFds);
193         }
194 
195         DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, HDF_LOGE("%{public}s:ProcessRequestCmd failed", __func__));
196         /* pack request end commands */
197         replyPacker_.PackEnd(CONTROL_CMD_REPLY_END);
198 
199 #ifdef DEBUG_DISPLAY_CMD_RAW_DATA
200         /* just for debug */
201         replyPacker_.Dump();
202         HDF_LOGI("CmdReply command cnt=%{public}d", replyCommandCnt_);
203 #endif // DEBUG_DISPLAY_CMD_RAW_DATA
204 
205         /*  Write reply pack */
206         outEleCnt = replyPacker_.ValidSize() >> CmdUtils::MOVE_SIZE;
207         {
208             std::lock_guard<std::mutex> lock(replyMutex_);
209             ret = reply_->Write(reinterpret_cast<int32_t *>(replyPacker_.GetDataPtr()), outEleCnt,
210                 CmdUtils::TRANSFER_WAIT_TIME);
211         }
212         if (ret != HDF_SUCCESS) {
213             HDF_LOGE("Reply write failure, ret=%{public}d", ret);
214             outEleCnt = 0;
215         }
216         int32_t ec = PeriodDataReset();
217         return (ret == HDF_SUCCESS ? ec : ret);
218     }
219 
220 protected:
InitReply(uint32_t size)221     int32_t InitReply(uint32_t size)
222     {
223         if (size > CmdUtils::MAX_MEMORY) {
224             HDF_LOGE("%{public}s: size:%{public}u is too large", __func__, size);
225             return HDF_FAILURE;
226         }
227         reply_ = std::make_shared<Transfer>(size, SmqType::SYNCED_SMQ);
228         DISPLAY_CHK_RETURN(reply_ == nullptr, HDF_FAILURE,
229             HDF_LOGE("%{public}s: reply_ construct failed", __func__));
230 
231         bool retBool = replyPacker_.Init(reply_->GetSize() << CmdUtils::MOVE_SIZE);
232         DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE,
233             HDF_LOGE("%{public}s: replyPacker_ init failed", __func__));
234 
235         return CmdUtils::StartPack(CONTROL_CMD_REPLY_BEGIN, replyPacker_);
236     }
237 
OnRequestEnd(CommandDataUnpacker & unpacker)238     int32_t OnRequestEnd(CommandDataUnpacker& unpacker)
239     {
240         DISPLAY_TRACE;
241 
242         size_t errCnt = errMaps_.size();
243         if (errCnt >= 0) {
244             int32_t ret = CmdUtils::StartSection(REPLY_CMD_SET_ERROR, replyPacker_);
245             DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret,
246                 HDF_LOGE("%{public}s: StartSection failed", __func__));
247 
248             bool result = replyPacker_.WriteUint32(errCnt);
249             DISPLAY_CHK_RETURN(result == false, HDF_FAILURE,
250                 HDF_LOGE("%{public}s: write errCnt failed", __func__));
251             for (auto it = errMaps_.begin(); it != errMaps_.end(); ++it) {
252                 result = replyPacker_.WriteInt32(it->first);
253                 DISPLAY_CHK_RETURN(result == false, HDF_FAILURE,
254                     HDF_LOGE("%{public}s: write err-cmd failed, cmdId:%{public}s",
255                     __func__, CmdUtils::CommandToString(it->first)));
256 
257                 result = replyPacker_.WriteInt32(it->second);
258                 DISPLAY_CHK_RETURN(result == false, HDF_FAILURE,
259                     HDF_LOGE("%{public}s: write errNo failed, errNo:%{public}d", __func__, it->second));
260             }
261             result = CmdUtils::EndSection(replyPacker_);
262             DISPLAY_CHK_RETURN(result == false, HDF_FAILURE,
263                 HDF_LOGE("%{public}s: write replyPacker_ EndSection failed", __func__));
264             replyCommandCnt_++;
265         }
266         return HDF_SUCCESS;
267     }
268 
OnPrepareDisplayLayers(CommandDataUnpacker & unpacker)269     void OnPrepareDisplayLayers(CommandDataUnpacker& unpacker)
270     {
271         DISPLAY_TRACE;
272 
273         uint32_t devId = 0;
274         bool needFlush = false;
275         uint32_t vectSize = 0;
276         std::vector<uint32_t> layers;
277         std::vector<int32_t> types;
278 
279         int32_t ret = unpacker.ReadUint32(devId) ? HDF_SUCCESS : HDF_FAILURE;
280         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
281         {
282             HdfTrace traceVdi("PrepareDisplayLayers", "HDI:DISP:HARDWARE");
283             ret = impl_->PrepareDisplayLayers(devId, needFlush);
284         }
285 
286         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
287         {
288             HdfTrace traceVdi("GetDisplayCompChange", "HDI:DISP:HARDWARE");
289             ret = impl_->GetDisplayCompChange(devId, layers, types);
290         }
291 
292         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
293 
294         ret = CmdUtils::StartSection(REPLY_CMD_PREPARE_DISPLAY_LAYERS, replyPacker_);
295         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
296 
297         DISPLAY_CHECK(replyPacker_.WriteUint32(devId) == false, goto EXIT);
298 
299         DISPLAY_CHECK(replyPacker_.WriteBool(needFlush) == false, goto EXIT);
300         // Write layers vector
301         vectSize = static_cast<uint32_t>(layers.size());
302         DISPLAY_CHECK(replyPacker_.WriteUint32(vectSize) == false, goto EXIT);
303 
304         for (uint32_t i = 0; i < vectSize; i++) {
305             DISPLAY_CHECK(replyPacker_.WriteUint32(layers[i]) == false, goto EXIT);
306         }
307         // Write composer types vector
308         vectSize = static_cast<uint32_t>(types.size());
309         DISPLAY_CHECK(replyPacker_.WriteUint32(vectSize) == false, goto EXIT);
310 
311         for (uint32_t i = 0; i < vectSize; i++) {
312             DISPLAY_CHECK(replyPacker_.WriteUint32(types[i]) == false, goto EXIT);
313         }
314         // End this cmd section
315         ret = CmdUtils::EndSection(replyPacker_);
316         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
317         replyCommandCnt_++;
318 EXIT:
319         if (ret != HDF_SUCCESS) {
320             errMaps_.emplace(REQUEST_CMD_PREPARE_DISPLAY_LAYERS, ret);
321         }
322         return;
323     }
324 
325     typedef struct ClientBufferData {
326         uint32_t devId;
327         uint32_t seqNo;
328         int32_t fence;
329         BufferHandle *buffer;
330         bool isValidBuffer;
331     } ClientBufferData;
332 
UnpackDisplayClientBufferInfo(CommandDataUnpacker & unpacker,const std::vector<HdifdInfo> & inFds,ClientBufferData & data)333     int32_t UnpackDisplayClientBufferInfo(CommandDataUnpacker& unpacker,
334         const std::vector<HdifdInfo>& inFds, ClientBufferData& data)
335     {
336         if (!unpacker.ReadUint32(data.devId)) {
337             return HDF_FAILURE;
338         }
339 
340         if (CmdUtils::BufferHandleUnpack(unpacker, inFds, data.buffer) != HDF_SUCCESS) {
341             data.isValidBuffer = false;
342             HDF_LOGE("%{public}s, read buffer handle error", __func__);
343             return HDF_FAILURE;
344         }
345         data.isValidBuffer = true;
346 
347         if (!unpacker.ReadUint32(data.seqNo)) {
348             HDF_LOGE("%{public}s, read seqNo error", __func__);
349             return HDF_FAILURE;
350         }
351 
352         if (CmdUtils::FileDescriptorUnpack(unpacker, inFds, data.fence) != HDF_SUCCESS) {
353             HDF_LOGE("%{public}s, FileDescriptorUnpack error", __func__);
354             return HDF_FAILURE;
355         }
356 
357         return HDF_SUCCESS;
358     }
359 
SetDisplayClientBuffer(ClientBufferData & data,bool & needFreeBuffer,bool & needMoveFd,int fd)360     int32_t SetDisplayClientBuffer(ClientBufferData& data, bool &needFreeBuffer, bool &needMoveFd, int fd)
361     {
362         if (cacheMgr_ == nullptr) {
363             HDF_LOGE("%{public}s, get cache manager error", __func__);
364             return HDF_FAILURE;
365         }
366         std::lock_guard<std::mutex> lock(cacheMgr_->GetCacheMgrMutex());
367 
368         DeviceCache* devCache = cacheMgr_->DeviceCacheInstance(data.devId);
369         if (devCache == nullptr) {
370             HDF_LOGE("%{public}s, get device cache error", __func__);
371             return HDF_FAILURE;
372         }
373 
374         int32_t ret = devCache->SetDisplayClientBuffer(data.buffer, data.seqNo, needFreeBuffer,
375             [&data, &needMoveFd, &fd, this](const BufferHandle& handle)->int32_t {
376 #ifdef DISPLAY_COMSPOER_DEBUG_DUMP
377             DumpLayerBuffer(data.devId, data.seqNo, data.fence, handle, "client_");
378 #endif
379             if (data.fence > ERROR_FENCE_COUNT) {
380                 HDF_LOGW("SetDisplayClientBuffer:%{public}s data.devId:%{public}d, data.buffer->fd:%{public}d, "
381                          "data.seqNo:%{public}d, fd:%{public}d",
382                     data.buffer == nullptr ? "data.buffer is nullptr!" : "",
383                     data.devId,
384                     data.buffer == nullptr ? -1 : data.buffer->fd,
385                     data.seqNo,
386                     fd);
387             }
388             needMoveFd = true;
389             HITRACE_METER_FMT(HITRACE_TAG_HDF,
390                 "SetDisplayClientBuffer:%s data.devId:%d, data.buffer->fd:%d, data.seqNo:%d, fd:%d",
391                 data.buffer == nullptr ? "data.buffer is nullptr!" : "",
392                 data.devId,
393                 data.buffer == nullptr ? -1 : data.buffer->fd,
394                 data.seqNo,
395                 fd);
396             int rc = impl_->SetDisplayClientBuffer(data.devId, handle, fd);
397             DISPLAY_CHK_RETURN(rc != HDF_SUCCESS, HDF_FAILURE, HDF_LOGE(" fail"));
398             return HDF_SUCCESS;
399         });
400         return ret;
401     }
402 
OnSetDisplayClientBuffer(CommandDataUnpacker & unpacker,const std::vector<HdifdInfo> & inFds)403     void OnSetDisplayClientBuffer(CommandDataUnpacker& unpacker, const std::vector<HdifdInfo>& inFds)
404     {
405         DISPLAY_TRACE;
406 
407         ClientBufferData data = {0};
408         data.fence = -1;
409         bool needFreeBuffer = false;
410         bool needMoveFd = false;
411         int32_t ret = UnpackDisplayClientBufferInfo(unpacker, inFds, data);
412         HdifdParcelable fdParcel(data.fence);
413         if (ret == HDF_SUCCESS) {
414             ret = SetDisplayClientBuffer(data, needFreeBuffer, needMoveFd, fdParcel.GetFd());
415         }
416 #ifndef DISPLAY_COMMUNITY
417         // fix fd leak
418         if (data.buffer != nullptr && needFreeBuffer) {
419             FreeBufferWithDelay(data.buffer);
420             data.buffer = nullptr;
421             data.isValidBuffer = false;
422         }
423         if (needMoveFd) {
424             fdParcel.Move();
425         }
426 #endif // DISPLAY_COMMUNITY
427         if (ret != HDF_SUCCESS) {
428             HDF_LOGE("%{public}s, SetDisplayClientBuffer error", __func__);
429             if (data.isValidBuffer && data.buffer != nullptr) {
430                 FreeBufferHandle(data.buffer);
431                 data.buffer = nullptr;
432             }
433             errMaps_.emplace(REQUEST_CMD_SET_DISPLAY_CLIENT_BUFFER, ret);
434         }
435     }
436 
OnSetDisplayClientDamage(CommandDataUnpacker & unpacker)437     void OnSetDisplayClientDamage(CommandDataUnpacker& unpacker)
438     {
439         DISPLAY_TRACE;
440 
441         uint32_t devId = 0;
442         uint32_t vectSize = 0;
443         bool retBool = true;
444         DISPLAY_CHK_CONDITION(retBool, true, unpacker.ReadUint32(devId),
445             HDF_LOGE("%{public}s, read devId error", __func__));
446 
447         DISPLAY_CHK_CONDITION(retBool, true, unpacker.ReadUint32(vectSize),
448             HDF_LOGE("%{public}s, read vectSize error", __func__));
449 
450         int32_t ret = (retBool ? HDF_SUCCESS : HDF_FAILURE);
451         std::vector<IRect> rects(vectSize);
452         if (ret == HDF_SUCCESS) {
453             for (uint32_t i = 0; i < vectSize; i++) {
454                 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::RectUnpack(unpacker, rects[i]),
455                     HDF_LOGE("%{public}s, read vect error at i = %{public}d", __func__, i));
456                 if (ret != HDF_SUCCESS) {
457                     break;
458                 }
459             }
460         }
461         if (ret == HDF_SUCCESS) {
462             HdfTrace traceVdi("SetDisplayClientDamage", "HDI:DISP:HARDWARE");
463             impl_->SetDisplayClientDamage(devId, rects);
464         } else {
465             HDF_LOGE("%{public}s, SetDisplayClientDamage error", __func__);
466             errMaps_.emplace(REQUEST_CMD_SET_DISPLAY_CLIENT_DAMAGE, ret);
467         }
468         return;
469     }
470 
OnCommit(CommandDataUnpacker & unpacker,std::vector<HdifdInfo> & outFds)471     void OnCommit(CommandDataUnpacker& unpacker, std::vector<HdifdInfo>& outFds)
472     {
473         DISPLAY_TRACE;
474 
475         uint32_t devId = 0;
476         int32_t fence = -1;
477 #ifdef DISPLAY_COMSPOER_DEBUG_DUMP
478         const std::string SWITCH_ON = "on";
479         const uint32_t DUMP_CACHE_SWITCH_LEN = 4;
480         char dumpSwitch[DUMP_CACHE_SWITCH_LEN] = {0};
481         GetParameter("hdi.composer.dumpcache", "off", dumpSwitch, DUMP_CACHE_SWITCH_LEN);
482 
483         if (SWITCH_ON.compare(dumpSwitch) == 0) {
484             cacheMgr_->Dump();
485         }
486 #endif
487         int32_t ret = HDF_SUCCESS;
488         if (!unpacker.ReadUint32(devId)) {
489             HDF_LOGE("%{public}s, read devId error", __func__);
490             ret = HDF_FAILURE;
491             goto REPLY;
492         }
493 
494         {
495             HdfTrace traceVdi("Commit", "HDI:DISP:HARDWARE");
496             ret = impl_->Commit(devId, fence);
497         }
498         static unsigned int count = 0;
499         if (ret == HDF_SUCCESS) {
500             count = 0;
501         } else {
502             if (++count > REDUCE_COUNT) {
503                 HDF_LOGE("%{public}s, commit failed with ret = %{public}d", __func__, ret);
504                 count = 0;
505             }
506         }
507 
508 REPLY:
509         HdifdParcelable fdParcel(fence);
510         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::StartSection(REPLY_CMD_COMMIT, replyPacker_),
511             HDF_LOGE("%{public}s, StartSection error", __func__));
512 
513         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::FileDescriptorPack(fdParcel.GetFd(), replyPacker_, outFds),
514             HDF_LOGE("%{public}s, FileDescriptorPack error", __func__));
515 
516         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::EndSection(replyPacker_),
517             HDF_LOGE("%{public}s, EndSection error", __func__));
518 
519         replyCommandCnt_++;
520 
521 #ifndef DISPLAY_COMMUNITY
522         fdParcel.Move();
523 #endif // DISPLAY_COMMUNITY
524 
525         if (ret != HDF_SUCCESS) {
526             errMaps_.emplace(REQUEST_CMD_COMMIT, ret);
527         }
528 
529         return;
530     }
531 
OnSetLayerAlpha(CommandDataUnpacker & unpacker)532     void OnSetLayerAlpha(CommandDataUnpacker& unpacker)
533     {
534         DISPLAY_TRACE;
535 
536         uint32_t devId = 0;
537         uint32_t layerId = 0;
538         LayerAlpha alpha = {0};
539         bool retBool = true;
540 
541         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
542         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
543 
544         retBool = unpacker.ReadBool(alpha.enGlobalAlpha);
545         DISPLAY_CHECK(retBool == false, goto EXIT);
546 
547         retBool = unpacker.ReadBool(alpha.enPixelAlpha);
548         DISPLAY_CHECK(retBool == false, goto EXIT);
549 
550         retBool = unpacker.ReadUint8(alpha.alpha0);
551         DISPLAY_CHECK(retBool == false, goto EXIT);
552 
553         retBool = unpacker.ReadUint8(alpha.alpha1);
554         DISPLAY_CHECK(retBool == false, goto EXIT);
555 
556         retBool = unpacker.ReadUint8(alpha.gAlpha);
557         DISPLAY_CHECK(retBool == false, goto EXIT);
558 
559         {
560             HdfTrace traceVdi("SetLayerAlpha", "HDI:DISP:HARDWARE");
561             ret = impl_->SetLayerAlpha(devId, layerId, alpha);
562         }
563         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
564 
565 EXIT:
566         if (ret != HDF_SUCCESS || retBool == false) {
567             errMaps_.emplace(REQUEST_CMD_SET_LAYER_ALPHA, ret);
568         }
569         return;
570     }
571 
OnSetLayerRegion(CommandDataUnpacker & unpacker)572     void OnSetLayerRegion(CommandDataUnpacker& unpacker)
573     {
574         DISPLAY_TRACE;
575 
576         uint32_t devId = 0;
577         uint32_t layerId = 0;
578         IRect rect = {0};
579 
580         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
581         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
582 
583         ret = CmdUtils::RectUnpack(unpacker, rect);
584         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
585 
586         {
587             HdfTrace traceVdi("SetLayerRegion", "HDI:DISP:HARDWARE");
588             ret = impl_->SetLayerRegion(devId, layerId, rect);
589         }
590         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
591 EXIT:
592         if (ret != HDF_SUCCESS) {
593             errMaps_.emplace(REQUEST_CMD_SET_LAYER_REGION, ret);
594         }
595         return;
596     }
597 
OnSetLayerCrop(CommandDataUnpacker & unpacker)598     void OnSetLayerCrop(CommandDataUnpacker& unpacker)
599     {
600         DISPLAY_TRACE;
601 
602         uint32_t devId = 0;
603         uint32_t layerId = 0;
604         IRect rect = {0};
605 
606         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
607         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
608 
609         ret = CmdUtils::RectUnpack(unpacker, rect);
610         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
611 
612         {
613             HdfTrace traceVdi("SetLayerCrop", "HDI:DISP:HARDWARE");
614             ret = impl_->SetLayerCrop(devId, layerId, rect);
615         }
616         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
617 EXIT:
618         if (ret != HDF_SUCCESS) {
619             errMaps_.emplace(REQUEST_CMD_SET_LAYER_CROP, ret);
620         }
621         return;
622     }
623 
OnSetLayerZorder(CommandDataUnpacker & unpacker)624     void OnSetLayerZorder(CommandDataUnpacker& unpacker)
625     {
626         DISPLAY_TRACE;
627 
628         uint32_t devId = 0;
629         uint32_t layerId = 0;
630         uint32_t zorder = 0;
631 
632         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
633         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
634 
635         ret = unpacker.ReadUint32(zorder) ? HDF_SUCCESS : HDF_FAILURE;
636         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
637 
638         {
639             HdfTrace traceVdi("SetLayerZorder", "HDI:DISP:HARDWARE");
640             ret = impl_->SetLayerZorder(devId, layerId, zorder);
641         }
642         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
643 EXIT:
644         if (ret != HDF_SUCCESS) {
645             errMaps_.emplace(REQUEST_CMD_SET_LAYER_ZORDER, ret);
646         }
647         return;
648     }
649 
OnSetLayerPreMulti(CommandDataUnpacker & unpacker)650     void OnSetLayerPreMulti(CommandDataUnpacker& unpacker)
651     {
652         DISPLAY_TRACE;
653 
654         uint32_t devId = 0;
655         uint32_t layerId = 0;
656         bool preMulti = false;
657 
658         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
659         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
660 
661         ret = unpacker.ReadBool(preMulti) ? HDF_SUCCESS : HDF_FAILURE;
662         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
663 
664         {
665             HdfTrace traceVdi("SetLayerPreMulti", "HDI:DISP:HARDWARE");
666             ret = impl_->SetLayerPreMulti(devId, layerId, preMulti);
667         }
668         DISPLAY_CHECK(ret != HDF_SUCCESS && ret != DISPLAY_NOT_SUPPORT && ret != HDF_ERR_NOT_SUPPORT, goto EXIT);
669 EXIT:
670         if (ret != HDF_SUCCESS) {
671             errMaps_.emplace(REQUEST_CMD_SET_LAYER_PREMULTI, ret);
672         }
673         return;
674     }
675 
OnSetLayerTransformMode(CommandDataUnpacker & unpacker)676     void OnSetLayerTransformMode(CommandDataUnpacker& unpacker)
677     {
678         DISPLAY_TRACE;
679 
680         uint32_t devId = 0;
681         uint32_t layerId = 0;
682         int32_t type = 0;
683 
684         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
685         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
686 
687         ret = unpacker.ReadInt32(type) ? HDF_SUCCESS : HDF_FAILURE;
688         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
689 
690         {
691             HdfTrace traceVdi("SetLayerTransformMode", "HDI:DISP:HARDWARE");
692             ret = impl_->SetLayerTransformMode(devId, layerId, static_cast<TransformType>(type));
693         }
694         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
695 EXIT:
696         if (ret != HDF_SUCCESS) {
697             errMaps_.emplace(REQUEST_CMD_SET_LAYER_TRANSFORM_MODE, ret);
698         }
699 
700         return;
701     }
702 
OnSetLayerDirtyRegion(CommandDataUnpacker & unpacker)703     void OnSetLayerDirtyRegion(CommandDataUnpacker& unpacker)
704     {
705         DISPLAY_TRACE;
706 
707         uint32_t devId = 0;
708         uint32_t layerId = 0;
709         uint32_t vectSize = 0;
710         int32_t ret = HDF_SUCCESS;
711 
712         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId),
713             HDF_LOGE("%{public}s, read devId error", __func__));
714 
715         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, unpacker.ReadUint32(vectSize) ? HDF_SUCCESS : HDF_FAILURE,
716             HDF_LOGE("%{public}s, read vectSize error", __func__));
717 
718         std::vector<IRect> rects(vectSize);
719         if (ret == HDF_SUCCESS) {
720             for (uint32_t i = 0; i < vectSize; i++) {
721                 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::RectUnpack(unpacker, rects[i]),
722                     HDF_LOGE("%{public}s, read vect error, at i = %{public}d", __func__, i));
723                 if (ret != HDF_SUCCESS) {
724                     break;
725                 }
726             }
727         }
728         if (ret == HDF_SUCCESS) {
729             HdfTrace traceVdi("SetLayerDirtyRegion", "HDI:DISP:HARDWARE");
730             impl_->SetLayerDirtyRegion(devId, layerId, rects);
731         } else {
732             HDF_LOGE("%{public}s, SetLayerDirtyRegion error", __func__);
733             errMaps_.emplace(REQUEST_CMD_SET_LAYER_DIRTY_REGION, ret);
734         }
735         return;
736     }
737 
OnSetLayerVisibleRegion(CommandDataUnpacker & unpacker)738     void OnSetLayerVisibleRegion(CommandDataUnpacker& unpacker)
739     {
740         DISPLAY_TRACE;
741 
742         uint32_t devId = 0;
743         uint32_t layerId = 0;
744         uint32_t vectSize = 0;
745         int32_t ret = HDF_SUCCESS;
746 
747         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId),
748             HDF_LOGE("%{public}s, read devId error", __func__));
749 
750         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, unpacker.ReadUint32(vectSize) ? HDF_SUCCESS : HDF_FAILURE,
751             HDF_LOGE("%{public}s, read vectSize error", __func__));
752 
753         std::vector<IRect> rects(vectSize);
754         if (ret == HDF_SUCCESS) {
755             for (uint32_t i = 0; i < vectSize; i++) {
756                 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::RectUnpack(unpacker, rects[i]),
757                     HDF_LOGE("%{public}s, read vect error, at i = %{public}d", __func__, i));
758                 if (ret != HDF_SUCCESS) {
759                     break;
760                 }
761             }
762         }
763         if (ret == HDF_SUCCESS) {
764             HdfTrace traceVdi("SetLayerVisibleRegion", "HDI:DISP:HARDWARE");
765             impl_->SetLayerVisibleRegion(devId, layerId, rects);
766         } else {
767             HDF_LOGE("%{public}s, SetLayerDirtyRegion error", __func__);
768             errMaps_.emplace(REQUEST_CMD_SET_LAYER_VISIBLE_REGION, ret);
769         }
770         return;
771     }
772 
773     typedef struct LayerBufferData {
774         bool isValidBuffer;
775         uint32_t devId;
776         uint32_t layerId;
777         uint32_t seqNo;
778         int32_t fence;
779         BufferHandle *buffer;
780     } LayerBufferData;
781 
UnPackLayerBufferInfo(CommandDataUnpacker & unpacker,const std::vector<HdifdInfo> & inFds,struct LayerBufferData * data,std::vector<uint32_t> & deletingList)782     int32_t UnPackLayerBufferInfo(CommandDataUnpacker& unpacker, const std::vector<HdifdInfo>& inFds,
783         struct LayerBufferData *data, std::vector<uint32_t> &deletingList)
784     {
785         DISPLAY_CHK_RETURN(HDF_SUCCESS != CmdUtils::SetupDeviceUnpack(unpacker, data->devId, data->layerId),
786             HDF_FAILURE, HDF_LOGE("%{public}s, read devId error", __func__));
787 
788         DISPLAY_CHK_RETURN(HDF_SUCCESS != CmdUtils::BufferHandleUnpack(unpacker, inFds, data->buffer), HDF_FAILURE,
789             HDF_LOGE("%{public}s, read BufferHandleUnpack error", __func__));
790 
791         data->isValidBuffer = true;
792 
793         DISPLAY_CHK_RETURN(true != unpacker.ReadUint32(data->seqNo), HDF_FAILURE,
794             HDF_LOGE("%{public}s, read seqNo error", __func__));
795 
796         DISPLAY_CHK_RETURN(HDF_SUCCESS != CmdUtils::FileDescriptorUnpack(unpacker, inFds, data->fence), HDF_FAILURE,
797             HDF_LOGE("%{public}s, FileDescriptorUnpack error", __func__));
798 
799         // unpack deletingList
800         uint32_t vectSize = 0;
801         DISPLAY_CHK_RETURN(true != unpacker.ReadUint32(vectSize), HDF_FAILURE,
802             HDF_LOGE("%{public}s, read vectSize error", __func__));
803         if (vectSize > CmdUtils::MAX_MEMORY) {
804             HDF_LOGE("%{public}s: vectSize:%{public}u is too large", __func__, vectSize);
805             return HDF_FAILURE;
806         }
807 
808         deletingList.resize(vectSize);
809         for (uint32_t i = 0; i < vectSize; i++) {
810             DISPLAY_CHK_RETURN(true != unpacker.ReadUint32(deletingList[i]), HDF_FAILURE,
811                 HDF_LOGE("%{public}s, read seqNo error, at i = %{public}d", __func__, i));
812         }
813         return HDF_SUCCESS;
814     }
815 
SetLayerBuffer(LayerBufferData & data,std::vector<uint32_t> & deletingList,bool & needFreeBuffer,bool & needMoveFd,int fd)816     int32_t SetLayerBuffer(LayerBufferData& data, std::vector<uint32_t> &deletingList,
817         bool &needFreeBuffer, bool &needMoveFd, int fd)
818     {
819         DISPLAY_CHECK(cacheMgr_ == nullptr, return HDF_FAILURE);
820         std::lock_guard<std::mutex> lock(cacheMgr_->GetCacheMgrMutex());
821         DeviceCache* devCache = nullptr;
822         LayerCache* layerCache = nullptr;
823         devCache = cacheMgr_->DeviceCacheInstance(data.devId);
824         DISPLAY_CHECK(devCache == nullptr, return HDF_FAILURE);
825         layerCache = devCache->LayerCacheInstance(data.layerId);
826         DISPLAY_CHECK(layerCache == nullptr, return HDF_FAILURE);
827 
828         int32_t ret = layerCache->SetLayerBuffer(data.buffer, data.seqNo, needFreeBuffer, deletingList,
829             [&data, &needMoveFd, &fd, this](const BufferHandle& handle)->int32_t {
830 #ifdef DISPLAY_COMSPOER_DEBUG_DUMP
831             DumpLayerBuffer(data.devId, data.layerId, data.fence, handle, "layer_");
832 #endif
833             if (data.fence > ERROR_FENCE_COUNT) {
834                 HDF_LOGW("SetLayerBuffer:%{public}s data.devId:%{public}d, data.layerId:%{public}d, "
835                          "data.buffer->fd:%{public}d, data.seqNo:%{public}d, fd:%{public}d",
836                     data.buffer == nullptr ? "data.buffer is nullptr!" : "",
837                     data.devId,
838                     data.layerId,
839                     data.buffer == nullptr ? -1 : data.buffer->fd,
840                     data.seqNo,
841                     fd);
842             }
843             needMoveFd = true;
844             HITRACE_METER_FMT(HITRACE_TAG_HDF,
845                 "SetLayerBuffer:%s data.devId:%d, data.layerId:%d, data.buffer->fd:%d, data.seqNo:%d, fd:%d",
846                 data.buffer == nullptr ? "data.buffer is nullptr!" : "",
847                 data.devId,
848                 data.layerId,
849                 data.buffer == nullptr ? -1 : data.buffer->fd,
850                 data.seqNo,
851                 fd);
852             int rc = impl_->SetLayerBuffer(data.devId, data.layerId, handle, fd);
853             DISPLAY_CHK_RETURN(rc != HDF_SUCCESS, HDF_FAILURE, HDF_LOGE(" fail"));
854             return HDF_SUCCESS;
855         });
856         return ret;
857     }
858 
OnSetLayerBuffer(CommandDataUnpacker & unpacker,const std::vector<HdifdInfo> & inFds)859     void OnSetLayerBuffer(CommandDataUnpacker& unpacker, const std::vector<HdifdInfo>& inFds)
860     {
861         DISPLAY_TRACE;
862 
863         struct LayerBufferData data;
864         std::vector<uint32_t> deletingList;
865 
866         int32_t ret = UnPackLayerBufferInfo(unpacker, inFds, &data, deletingList);
867         HdifdParcelable fdParcel(data.fence);
868         bool needFreeBuffer = false;
869         bool needMoveFd = false;
870 
871         if (ret == HDF_SUCCESS) {
872             ret = SetLayerBuffer(data, deletingList, needFreeBuffer, needMoveFd, fdParcel.GetFd());
873         }
874 #ifndef DISPLAY_COMMUNITY
875         // fix fd leak
876         if (data.buffer != nullptr && needFreeBuffer) {
877             FreeBufferWithDelay(data.buffer);
878             data.buffer = nullptr;
879             data.isValidBuffer = false;
880         }
881         if (needMoveFd) {
882             fdParcel.Move();
883         }
884 #endif // DISPLAY_COMMUNITY
885         if (ret != HDF_SUCCESS) {
886             HDF_LOGE("%{public}s, SetLayerBuffer error", __func__);
887             if (data.isValidBuffer && data.buffer != nullptr) {
888                 FreeBufferHandle(data.buffer);
889                 data.buffer = nullptr;
890             }
891             errMaps_.emplace(REQUEST_CMD_SET_DISPLAY_CLIENT_BUFFER, ret);
892         }
893 
894         return;
895     }
896 
OnSetLayerCompositionType(CommandDataUnpacker & unpacker)897     void OnSetLayerCompositionType(CommandDataUnpacker& unpacker)
898     {
899         DISPLAY_TRACE;
900 
901         uint32_t devId = 0;
902         uint32_t layerId = 0;
903         int32_t type;
904         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
905         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
906 
907         ret = unpacker.ReadInt32(type) ? HDF_SUCCESS : HDF_FAILURE;
908         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
909 
910         {
911             HdfTrace traceVdi("SetLayerCompositionType", "HDI:DISP:HARDWARE");
912             ret = impl_->SetLayerCompositionType(devId, layerId, static_cast<CompositionType>(type));
913         }
914         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
915 EXIT:
916         if (ret != HDF_SUCCESS) {
917             errMaps_.emplace(REQUEST_CMD_SET_LAYER_COMPOSITION_TYPE, ret);
918         }
919         return;
920     }
921 
OnSetLayerBlendType(CommandDataUnpacker & unpacker)922     void OnSetLayerBlendType(CommandDataUnpacker& unpacker)
923     {
924         DISPLAY_TRACE;
925 
926         uint32_t devId = 0;
927         uint32_t layerId = 0;
928         int32_t type;
929         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
930         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
931 
932         ret = unpacker.ReadInt32(type) ? HDF_SUCCESS : HDF_FAILURE;
933         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
934 
935         {
936             HdfTrace traceVdi("SetLayerBlendType", "HDI:DISP:HARDWARE");
937             ret = impl_->SetLayerBlendType(devId, layerId, static_cast<BlendType>(type));
938         }
939         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
940 EXIT:
941         if (ret != HDF_SUCCESS) {
942             errMaps_.emplace(REQUEST_CMD_SET_LAYER_BLEND_TYPE, ret);
943         }
944         return;
945     }
946 
OnSetLayerMaskInfo(CommandDataUnpacker & unpacker)947     void OnSetLayerMaskInfo(CommandDataUnpacker& unpacker)
948     {
949         DISPLAY_TRACE;
950 
951         uint32_t devId = 0;
952         uint32_t layerId = 0;
953         uint32_t maskInfo = 0;
954 
955         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
956         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
957 
958         ret = unpacker.ReadUint32(maskInfo) ? HDF_SUCCESS : HDF_FAILURE;
959         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
960 
961         {
962             HdfTrace traceVdi("SetLayerMaskInfo", "HDI:DISP:HARDWARE");
963             ret = impl_->SetLayerMaskInfo(devId, layerId, static_cast<MaskInfo>(maskInfo));
964         }
965         DISPLAY_CHECK(ret != HDF_SUCCESS && ret != DISPLAY_NOT_SUPPORT && ret != HDF_ERR_NOT_SUPPORT, goto EXIT);
966 EXIT:
967         if (ret != HDF_SUCCESS) {
968             errMaps_.emplace(REQUEST_CMD_SET_LAYER_MASK_INFO, ret);
969         }
970         return;
971     }
972 
OnSetLayerColor(CommandDataUnpacker & unpacker)973     void OnSetLayerColor(CommandDataUnpacker& unpacker)
974     {
975         DISPLAY_TRACE;
976 
977         uint32_t devId = 0;
978         uint32_t layerId = 0;
979         LayerColor layerColor = {0};
980 
981         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
982         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
983 
984         ret = CmdUtils::LayerColorUnpack(unpacker, layerColor);
985         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
986 
987         {
988             HdfTrace traceVdi("SetLayerColor", "HDI:DISP:HARDWARE");
989             ret = impl_->SetLayerColor(devId, layerId, layerColor);
990         }
991         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
992 EXIT:
993         if (ret != HDF_SUCCESS) {
994             errMaps_.emplace(REQUEST_CMD_SET_LAYER_COLOR, ret);
995         }
996         return;
997     }
998 
PeriodDataReset()999     int32_t PeriodDataReset()
1000     {
1001         replyCommandCnt_ = 0;
1002         errMaps_.clear();
1003 
1004         int32_t ret = CmdUtils::StartPack(CONTROL_CMD_REPLY_BEGIN, replyPacker_);
1005         if (ret != HDF_SUCCESS) {
1006             HDF_LOGE("PackBegin failure, ret=%{public}d", ret);
1007         }
1008         return ret;
1009     }
1010 
GetFileName(uint32_t devId,uint32_t layerId,const BufferHandle & buffer)1011     static std::string GetFileName(uint32_t devId, uint32_t layerId, const BufferHandle& buffer)
1012     {
1013         struct timeval tv;
1014         char nowStr[TIME_BUFFER_MAX_LEN] = {0};
1015 
1016         gettimeofday(&tv, nullptr);
1017         if (strftime(nowStr, sizeof(nowStr), "%m-%d-%H-%M-%S", localtime(&tv.tv_sec)) == 0) {
1018             HDF_LOGE("strftime failed");
1019             return "";
1020         };
1021 
1022         std::ostringstream strStream;
1023         const int32_t PIXEL_BYTES = 4;
1024         strStream << "hdi_layer_" << devId << "_" << layerId << "_" << buffer.stride / PIXEL_BYTES << "x" <<
1025             buffer.height << "_" << nowStr << "-" << tv.tv_usec;
1026         return strStream.str();
1027     }
1028 #ifdef DISPLAY_COMSPOER_DEBUG_DUMP
DumpLayerBuffer(uint32_t devId,uint32_t layerId,int32_t fence,const BufferHandle & buffer,std::string tag)1029     static void DumpLayerBuffer(uint32_t devId, uint32_t layerId, int32_t fence, const BufferHandle& buffer,
1030         std::string tag)
1031     {
1032         const std::string SWITCH_ON = "on";
1033         const uint32_t DUMP_BUFFER_SWITCH_LEN = 4;
1034         char dumpSwitch[DUMP_BUFFER_SWITCH_LEN] = {0};
1035         GetParameter("hdi.composer.dumpbuffer", "off", dumpSwitch, DUMP_BUFFER_SWITCH_LEN);
1036 
1037         if (SWITCH_ON.compare(dumpSwitch) != 0) {
1038             return;
1039         }
1040 
1041         const uint32_t FENCE_TIMEOUT = 3000;
1042         int32_t retCode = WaitFence(fence, FENCE_TIMEOUT);
1043         if (retCode != HDF_SUCCESS) {
1044             return;
1045         }
1046 
1047         if (g_bufferServiceImpl == nullptr) {
1048             g_bufferServiceImpl = IMapper::Get(true);
1049             DISPLAY_CHECK((g_bufferServiceImpl == nullptr), HDF_LOGE("get IMapper failed"));
1050         }
1051 
1052         std::string fileName = GetFileName(devId, layerId, buffer);
1053         DISPLAY_CHECK((fileName == ""), HDF_LOGE("GetFileName failed"));
1054         HDF_LOGI("fileName = %{public}s", fileName.c_str());
1055 
1056         const std::string PATH_PREFIX = "/data/local/traces/";
1057         std::stringstream filePath;
1058         filePath << PATH_PREFIX << tag << fileName;
1059         std::ofstream rawDataFile(filePath.str(), std::ofstream::binary);
1060         DISPLAY_CHECK((!rawDataFile.good()), HDF_LOGE("open file failed, %{public}s",
1061             std::strerror(errno)));
1062 
1063         sptr<NativeBuffer> hdiBuffer = new NativeBuffer();
1064         hdiBuffer->SetBufferHandle(const_cast<BufferHandle*>(&buffer));
1065 
1066         int32_t ret = 0;
1067         ret = g_bufferServiceImpl->Mmap(hdiBuffer);
1068         DISPLAY_CHECK((ret != HDF_SUCCESS), HDF_LOGE("Mmap buffer failed"));
1069 
1070         std::chrono::milliseconds time_before = std::chrono::duration_cast<std::chrono::milliseconds> (
1071             std::chrono::system_clock::now().time_since_epoch()
1072         );
1073         rawDataFile.write(static_cast<const char *>(buffer.virAddr), buffer.size);
1074         std::chrono::milliseconds time_after = std::chrono::duration_cast<std::chrono::milliseconds> (
1075             std::chrono::system_clock::now().time_since_epoch()
1076         );
1077         HDF_LOGI("wirte file take time %{public}lld", time_after.count() - time_before.count());
1078         rawDataFile.close();
1079 
1080         ret = g_bufferServiceImpl->Unmap(hdiBuffer);
1081         DISPLAY_CHECK((ret != HDF_SUCCESS), HDF_LOGE("Unmap buffer failed"));
1082     }
1083 #endif
1084 
WaitFence(int32_t fence,uint32_t timeout)1085     static int32_t WaitFence(int32_t fence, uint32_t timeout)
1086     {
1087         int retCode = -1;
1088         if (fence < 0) {
1089             HDF_LOGE("The fence id is invalid.");
1090             return retCode;
1091         }
1092 
1093         struct pollfd pollfds = {0};
1094         pollfds.fd = fence;
1095         pollfds.events = POLLIN;
1096 
1097         do {
1098             retCode = poll(&pollfds, 1, timeout);
1099         } while (retCode == -1 && (errno == EINTR || errno == EAGAIN));
1100 
1101         if (retCode == 0) {
1102             retCode = -1;
1103             errno = ETIME;
1104         } else if (retCode > 0) {
1105             retCode = 0;
1106             if (pollfds.revents & (POLLERR | POLLNVAL)) {
1107                 retCode = -1;
1108                 errno = EINVAL;
1109             }
1110         }
1111 
1112         return retCode < 0 ? -errno : HDF_SUCCESS;
1113     }
1114 
FreeBufferWithDelay(BufferHandle * handle)1115     void FreeBufferWithDelay(BufferHandle *handle)
1116     {
1117         delayFreeQueue_.push(handle);
1118         if (delayFreeQueue_.size() >= BUFFER_QUEUE_MAX_SIZE) {
1119             BufferHandle *temp = delayFreeQueue_.front();
1120             delayFreeQueue_.pop();
1121             FreeBufferHandle(temp);
1122             temp = nullptr;
1123         }
1124     }
1125 
1126 protected:
1127     VdiImpl* impl_ = nullptr;
1128     std::shared_ptr<DeviceCacheManager> cacheMgr_;
1129     std::shared_ptr<Transfer> request_;
1130     bool isReplyUpdated_;
1131     std::shared_ptr<Transfer> reply_;
1132     /* period data */
1133     uint32_t replyCommandCnt_;
1134     CommandDataPacker replyPacker_;
1135     std::unordered_map<int32_t, int32_t> errMaps_;
1136     /* fix fd leak */
1137     std::queue<BufferHandle *> delayFreeQueue_;
1138     std::mutex requestMutex_;
1139     std::mutex replyMutex_;
1140 };
1141 using HdiDisplayCmdResponser = DisplayCmdResponser<SharedMemQueue<int32_t>, IDisplayComposerVdi>;
1142 } // namespace V1_0
1143 } // namespace Composer
1144 } // namespace Display
1145 } // namespace HDI
1146 } // namespace OHOS
1147 #endif // OHOS_HDI_DISPLAY_V1_0_DISPLAY_CMD_REQUESTER_H