1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License.
5094332d3Sopenharmony_ci * You may obtain a copy of the License at
6094332d3Sopenharmony_ci *
7094332d3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8094332d3Sopenharmony_ci *
9094332d3Sopenharmony_ci * Unless required by law or agreed to in writing, software
10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and
13094332d3Sopenharmony_ci * limitations under the License.
14094332d3Sopenharmony_ci */
15094332d3Sopenharmony_ci
16094332d3Sopenharmony_ci#include <sys/mman.h>
17094332d3Sopenharmony_ci#include "ashmem.h"
18094332d3Sopenharmony_ci#include "buffer_helper.h"
19094332d3Sopenharmony_ci
20094332d3Sopenharmony_cinamespace OHOS::VDI::HEIF {
21094332d3Sopenharmony_ciusing namespace OHOS::HDI::Codec::Image::V2_0;
22094332d3Sopenharmony_ciusing namespace OHOS::HDI::Display::Buffer::V1_2;
23094332d3Sopenharmony_ciusing namespace OHOS::HDI::Display::Composer::V1_2;
24094332d3Sopenharmony_ciusing namespace std;
25094332d3Sopenharmony_ci
26094332d3Sopenharmony_cistatic size_t GetFileSizeInBytes(ifstream &ifs)
27094332d3Sopenharmony_ci{
28094332d3Sopenharmony_ci    ifs.seekg(0, ifstream::end);
29094332d3Sopenharmony_ci    auto len = ifs.tellg();
30094332d3Sopenharmony_ci    ifs.seekg(0, ifstream::beg);
31094332d3Sopenharmony_ci    return static_cast<size_t>(len);
32094332d3Sopenharmony_ci}
33094332d3Sopenharmony_ci
34094332d3Sopenharmony_ciBufferHelper::BufferHelper()
35094332d3Sopenharmony_ci{
36094332d3Sopenharmony_ci    bufferMgr_ = OHOS::HDI::Display::Buffer::V1_2::IDisplayBuffer::Get();
37094332d3Sopenharmony_ci}
38094332d3Sopenharmony_ci
39094332d3Sopenharmony_ciBufferHelper::~BufferHelper()
40094332d3Sopenharmony_ci{
41094332d3Sopenharmony_ci    bufferMgr_ = nullptr;
42094332d3Sopenharmony_ci    for (auto iter = allocatedFd_.begin(); iter != allocatedFd_.end(); ++iter) {
43094332d3Sopenharmony_ci        close(*iter);
44094332d3Sopenharmony_ci    }
45094332d3Sopenharmony_ci    allocatedFd_.clear();
46094332d3Sopenharmony_ci}
47094332d3Sopenharmony_ci
48094332d3Sopenharmony_cibool BufferHelper::ExtractPixelInfoFromFilePath(const string& filePath, PixelFileInfo& pixelInfo)
49094332d3Sopenharmony_ci{
50094332d3Sopenharmony_ci    size_t pos = filePath.find_last_of('/');
51094332d3Sopenharmony_ci    IF_TRUE_RETURN_VAL(pos == string::npos, false);
52094332d3Sopenharmony_ci    pos = filePath.find_first_of('[', pos);
53094332d3Sopenharmony_ci    IF_TRUE_RETURN_VAL(pos == string::npos, false);
54094332d3Sopenharmony_ci    int ret = sscanf_s(filePath.substr(pos).c_str(), "[%ux%u][%ux%u][fmt0x%x].yuv",
55094332d3Sopenharmony_ci                       &pixelInfo.displayWidth, &pixelInfo.displayHeight,
56094332d3Sopenharmony_ci                       &pixelInfo.alignedWidth, &pixelInfo.alignedHeight,
57094332d3Sopenharmony_ci                       &pixelInfo.pixFmt);
58094332d3Sopenharmony_ci    static constexpr int EXP_CNT = 5;
59094332d3Sopenharmony_ci    IF_TRUE_RETURN_VAL(ret != EXP_CNT, false);
60094332d3Sopenharmony_ci    HDF_LOGI("pixel info: display=[%{public}u x %{public}u], aligned=[%{public}u x %{public}u]",
61094332d3Sopenharmony_ci             pixelInfo.displayWidth, pixelInfo.displayHeight, pixelInfo.alignedWidth, pixelInfo.alignedHeight);
62094332d3Sopenharmony_ci    return true;
63094332d3Sopenharmony_ci}
64094332d3Sopenharmony_ci
65094332d3Sopenharmony_cibool BufferHelper::CopyYuvData(BufferHandle *handle, ifstream &ifs, PixelFileInfo& pixelInfo)
66094332d3Sopenharmony_ci{
67094332d3Sopenharmony_ci    static constexpr uint32_t BYTES_PER_PIXEL_YUV = 1;
68094332d3Sopenharmony_ci    // Y plane
69094332d3Sopenharmony_ci    char* dst = reinterpret_cast<char*>(handle->virAddr);
70094332d3Sopenharmony_ci    for (uint32_t i = 0; i < pixelInfo.displayHeight; i++) {
71094332d3Sopenharmony_ci        ifs.read(dst, pixelInfo.alignedWidth * BYTES_PER_PIXEL_YUV);
72094332d3Sopenharmony_ci        dst += handle->stride;
73094332d3Sopenharmony_ci    }
74094332d3Sopenharmony_ci    // skip aligned lines
75094332d3Sopenharmony_ci    for (uint32_t i = 0; i < (pixelInfo.alignedHeight - pixelInfo.displayHeight); i++) {
76094332d3Sopenharmony_ci        ifs.read(dst, pixelInfo.alignedWidth * BYTES_PER_PIXEL_YUV);
77094332d3Sopenharmony_ci    }
78094332d3Sopenharmony_ci    // UV plane
79094332d3Sopenharmony_ci    ImageLayout layout;
80094332d3Sopenharmony_ci    int32_t ret = bufferMgr_->GetImageLayout(*handle, layout);
81094332d3Sopenharmony_ci    IF_TRUE_RETURN_VAL_WITH_MSG(ret != HDF_SUCCESS, false,
82094332d3Sopenharmony_ci                                "failed to get uv start, err [%{public}d] !", ret);
83094332d3Sopenharmony_ci    static constexpr int PLANE_U = 1;
84094332d3Sopenharmony_ci    static constexpr int PLANE_V = 2;
85094332d3Sopenharmony_ci    static constexpr uint32_t UV_SAMPLE_RATE = 2;
86094332d3Sopenharmony_ci    uint64_t uvOffset = (pixelInfo.pixFmt == OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YCBCR_420_SP) ?
87094332d3Sopenharmony_ci                        layout.planes[PLANE_U].offset :
88094332d3Sopenharmony_ci                        layout.planes[PLANE_V].offset;
89094332d3Sopenharmony_ci    dst = reinterpret_cast<char*>(handle->virAddr) + uvOffset;
90094332d3Sopenharmony_ci    for (uint32_t i = 0; i < pixelInfo.displayHeight / UV_SAMPLE_RATE; i++) {
91094332d3Sopenharmony_ci        ifs.read(dst, pixelInfo.alignedWidth * BYTES_PER_PIXEL_YUV);
92094332d3Sopenharmony_ci        dst += handle->stride;
93094332d3Sopenharmony_ci    }
94094332d3Sopenharmony_ci    return true;
95094332d3Sopenharmony_ci}
96094332d3Sopenharmony_ci
97094332d3Sopenharmony_cibool BufferHelper::CopyRgbaData(BufferHandle *handle, ifstream &ifs, PixelFileInfo& pixelInfo)
98094332d3Sopenharmony_ci{
99094332d3Sopenharmony_ci    static constexpr uint32_t BYTES_PER_PIXEL_RBGA = 4;
100094332d3Sopenharmony_ci    char* dst = reinterpret_cast<char*>(handle->virAddr);
101094332d3Sopenharmony_ci    for (uint32_t i = 0; i < pixelInfo.displayHeight; i++) {
102094332d3Sopenharmony_ci        ifs.read(dst, pixelInfo.alignedWidth * BYTES_PER_PIXEL_RBGA);
103094332d3Sopenharmony_ci        dst += handle->stride;
104094332d3Sopenharmony_ci    }
105094332d3Sopenharmony_ci    return true;
106094332d3Sopenharmony_ci}
107094332d3Sopenharmony_ci
108094332d3Sopenharmony_ciuint32_t BufferHelper::GetPixelFmtFromFileSuffix(const string& imageFile)
109094332d3Sopenharmony_ci{
110094332d3Sopenharmony_ci    if (imageFile.rfind(".rgba") != string::npos) {
111094332d3Sopenharmony_ci        return OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_RGBA_8888;
112094332d3Sopenharmony_ci    }
113094332d3Sopenharmony_ci    if (imageFile.rfind(".nv21") != string::npos) {
114094332d3Sopenharmony_ci        return OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YCRCB_420_SP;
115094332d3Sopenharmony_ci    }
116094332d3Sopenharmony_ci    return OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YCBCR_420_SP;
117094332d3Sopenharmony_ci}
118094332d3Sopenharmony_ci
119094332d3Sopenharmony_cisptr<NativeBuffer> BufferHelper::CreateImgBuffer(const string& imageFile)
120094332d3Sopenharmony_ci{
121094332d3Sopenharmony_ci    IF_TRUE_RETURN_VAL(imageFile.length() <= 0, nullptr);
122094332d3Sopenharmony_ci    ifstream ifs(imageFile, ios::binary);
123094332d3Sopenharmony_ci    IF_TRUE_RETURN_VAL_WITH_MSG(!ifs.is_open(), nullptr, "cannot open %{public}s", imageFile.c_str());
124094332d3Sopenharmony_ci    PixelFileInfo pixelInfo;
125094332d3Sopenharmony_ci    IF_TRUE_RETURN_VAL_WITH_MSG(!ExtractPixelInfoFromFilePath(imageFile, pixelInfo), nullptr,
126094332d3Sopenharmony_ci                                "invalid file path format: %{public}s", imageFile.c_str());
127094332d3Sopenharmony_ci    uint64_t usage = OHOS::HDI::Display::Composer::V1_2::HBM_USE_CPU_READ |
128094332d3Sopenharmony_ci                     OHOS::HDI::Display::Composer::V1_2::HBM_USE_CPU_WRITE |
129094332d3Sopenharmony_ci                     OHOS::HDI::Display::Composer::V1_2::HBM_USE_MEM_DMA;
130094332d3Sopenharmony_ci    pixelInfo.pixFmt = GetPixelFmtFromFileSuffix(imageFile);
131094332d3Sopenharmony_ci    HDF_LOGI("pixelFmt=0x%{public}x", pixelInfo.pixFmt);
132094332d3Sopenharmony_ci    AllocInfo alloc = {
133094332d3Sopenharmony_ci        .width = pixelInfo.displayWidth,
134094332d3Sopenharmony_ci        .height = pixelInfo.displayHeight,
135094332d3Sopenharmony_ci        .usage =  usage,
136094332d3Sopenharmony_ci        .format = pixelInfo.pixFmt
137094332d3Sopenharmony_ci    };
138094332d3Sopenharmony_ci    BufferHandle *handle = nullptr;
139094332d3Sopenharmony_ci    int32_t ret = bufferMgr_->AllocMem(alloc, handle);
140094332d3Sopenharmony_ci    IF_TRUE_RETURN_VAL_WITH_MSG(ret != HDF_SUCCESS, nullptr,
141094332d3Sopenharmony_ci                                "failed to alloc buffer, err [%{public}d] !", ret);
142094332d3Sopenharmony_ci    bufferMgr_->Mmap(*handle);
143094332d3Sopenharmony_ci    bool flag = (pixelInfo.pixFmt == OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_RGBA_8888) ?
144094332d3Sopenharmony_ci                CopyRgbaData(handle, ifs, pixelInfo) :
145094332d3Sopenharmony_ci                CopyYuvData(handle, ifs, pixelInfo);
146094332d3Sopenharmony_ci    (void)bufferMgr_->Unmap(*handle);
147094332d3Sopenharmony_ci    if (!flag) {
148094332d3Sopenharmony_ci        bufferMgr_->FreeMem(*handle);
149094332d3Sopenharmony_ci        return nullptr;
150094332d3Sopenharmony_ci    }
151094332d3Sopenharmony_ci    sptr<NativeBuffer> imgBuffer = new NativeBuffer(handle);
152094332d3Sopenharmony_ci    return imgBuffer;
153094332d3Sopenharmony_ci}
154094332d3Sopenharmony_ci
155094332d3Sopenharmony_ciSharedBuffer BufferHelper::CreateSharedBuffer(map<PropertyType, string>& metaInfo)
156094332d3Sopenharmony_ci{
157094332d3Sopenharmony_ci    SharedBuffer buffer = {
158094332d3Sopenharmony_ci        .fd = -1,
159094332d3Sopenharmony_ci        .filledLen = 0,
160094332d3Sopenharmony_ci        .capacity = 0
161094332d3Sopenharmony_ci    };
162094332d3Sopenharmony_ci    ByteWriter bw;
163094332d3Sopenharmony_ci    bool flag = true;
164094332d3Sopenharmony_ci    for (auto iter = metaInfo.begin(); (iter != metaInfo.end()) && flag; ++iter) {
165094332d3Sopenharmony_ci        flag = bw.AddDataFromFile(iter->first, iter->second);
166094332d3Sopenharmony_ci    }
167094332d3Sopenharmony_ci    if (flag && bw.Finalize(buffer)) {
168094332d3Sopenharmony_ci        allocatedFd_.insert(buffer.fd);
169094332d3Sopenharmony_ci    }
170094332d3Sopenharmony_ci    return buffer;
171094332d3Sopenharmony_ci}
172094332d3Sopenharmony_ci
173094332d3Sopenharmony_ciSharedBuffer BufferHelper::CreateSharedBuffer(const string& metaFile)
174094332d3Sopenharmony_ci{
175094332d3Sopenharmony_ci    SharedBuffer buffer = {
176094332d3Sopenharmony_ci        .fd = -1,
177094332d3Sopenharmony_ci        .filledLen = 0,
178094332d3Sopenharmony_ci        .capacity = 0
179094332d3Sopenharmony_ci    };
180094332d3Sopenharmony_ci    IF_TRUE_RETURN_VAL_WITH_MSG(metaFile.length() <= 0, buffer, "no metaFile");
181094332d3Sopenharmony_ci    ifstream ifs(metaFile, ios::binary);
182094332d3Sopenharmony_ci    IF_TRUE_RETURN_VAL_WITH_MSG(!ifs.is_open(), buffer, "cannot open %{public}s", metaFile.c_str());
183094332d3Sopenharmony_ci    size_t totalSize = GetFileSizeInBytes(ifs);
184094332d3Sopenharmony_ci    int fd = AshmemCreate("ForMetaData", totalSize);
185094332d3Sopenharmony_ci    IF_TRUE_RETURN_VAL_WITH_MSG(fd < 0, buffer, "cannot create ashmem for meta data");
186094332d3Sopenharmony_ci    void *addr = mmap(nullptr, totalSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
187094332d3Sopenharmony_ci    if (addr == nullptr) {
188094332d3Sopenharmony_ci        HDF_LOGE("failed to map addr for meta buffer");
189094332d3Sopenharmony_ci        close(fd);
190094332d3Sopenharmony_ci        return buffer;
191094332d3Sopenharmony_ci    }
192094332d3Sopenharmony_ci    ifs.read(reinterpret_cast<char*>(addr), totalSize);
193094332d3Sopenharmony_ci    if (munmap(addr, totalSize) != 0) {
194094332d3Sopenharmony_ci        HDF_LOGW("failed to unmap addr for meta buffer");
195094332d3Sopenharmony_ci    }
196094332d3Sopenharmony_ci    buffer.fd = fd;
197094332d3Sopenharmony_ci    buffer.filledLen = static_cast<uint32_t>(totalSize);
198094332d3Sopenharmony_ci    buffer.capacity = static_cast<uint32_t>(AshmemGetSize(fd));
199094332d3Sopenharmony_ci    allocatedFd_.insert(fd);
200094332d3Sopenharmony_ci    return buffer;
201094332d3Sopenharmony_ci}
202094332d3Sopenharmony_ci
203094332d3Sopenharmony_civoid BufferHelper::DumpBuffer(const string& filePath, const SharedBuffer& buffer)
204094332d3Sopenharmony_ci{
205094332d3Sopenharmony_ci    IF_TRUE_RETURN_WITH_MSG(filePath.length() <= 0, "dump path is empty");
206094332d3Sopenharmony_ci    constexpr int maxPathLen = 256;
207094332d3Sopenharmony_ci    char outputFilePath[maxPathLen] = {0};
208094332d3Sopenharmony_ci    int ret = sprintf_s(outputFilePath, sizeof(outputFilePath), "%s/out.heic",
209094332d3Sopenharmony_ci                        filePath.c_str());
210094332d3Sopenharmony_ci    if (ret == -1) {
211094332d3Sopenharmony_ci        HDF_LOGE("failed to create dump file");
212094332d3Sopenharmony_ci        return;
213094332d3Sopenharmony_ci    }
214094332d3Sopenharmony_ci    HDF_LOGI("dump buffer to: %{public}s", outputFilePath);
215094332d3Sopenharmony_ci    ofstream ofs(outputFilePath, ios::binary);
216094332d3Sopenharmony_ci    IF_TRUE_RETURN_WITH_MSG(!ofs.is_open(), "cannot open %{public}s", outputFilePath);
217094332d3Sopenharmony_ci    void *addr = mmap(nullptr, buffer.filledLen, PROT_READ | PROT_WRITE, MAP_SHARED, buffer.fd, 0);
218094332d3Sopenharmony_ci    if (addr != nullptr) {
219094332d3Sopenharmony_ci        ofs.write(static_cast<char*>(addr), static_cast<streamsize>(buffer.filledLen));
220094332d3Sopenharmony_ci        ofs.close();
221094332d3Sopenharmony_ci        if (munmap(addr, buffer.filledLen) != 0) {
222094332d3Sopenharmony_ci            HDF_LOGW("failed to unmap addr for dump buffer");
223094332d3Sopenharmony_ci        }
224094332d3Sopenharmony_ci    } else {
225094332d3Sopenharmony_ci        HDF_LOGE("failed to map addr for dump buffer");
226094332d3Sopenharmony_ci    }
227094332d3Sopenharmony_ci}
228094332d3Sopenharmony_ci
229094332d3Sopenharmony_ciByteWriter::~ByteWriter()
230094332d3Sopenharmony_ci{
231094332d3Sopenharmony_ci    for (auto iter = data_.begin(); iter != data_.end(); ++iter) {
232094332d3Sopenharmony_ci        delete [] iter->data;
233094332d3Sopenharmony_ci    }
234094332d3Sopenharmony_ci    data_.clear();
235094332d3Sopenharmony_ci}
236094332d3Sopenharmony_ci
237094332d3Sopenharmony_cibool ByteWriter::CopyDataTo(uint8_t* dstStart)
238094332d3Sopenharmony_ci{
239094332d3Sopenharmony_ci    size_t offset = 0;
240094332d3Sopenharmony_ci    errno_t ret = EOK;
241094332d3Sopenharmony_ci    for (auto iter = data_.begin(); (iter != data_.end()) && (ret == EOK); ++iter) {
242094332d3Sopenharmony_ci        ret = memcpy_s(dstStart + offset, iter->len, iter->data, iter->len);
243094332d3Sopenharmony_ci        offset += iter->len;
244094332d3Sopenharmony_ci    }
245094332d3Sopenharmony_ci    return (ret == EOK);
246094332d3Sopenharmony_ci}
247094332d3Sopenharmony_ci
248094332d3Sopenharmony_cibool ByteWriter::Finalize(std::vector<uint8_t>& dst)
249094332d3Sopenharmony_ci{
250094332d3Sopenharmony_ci    dst.clear();
251094332d3Sopenharmony_ci    dst.resize(totalSize_);
252094332d3Sopenharmony_ci    return CopyDataTo(reinterpret_cast<uint8_t*>(dst.data()));
253094332d3Sopenharmony_ci}
254094332d3Sopenharmony_ci
255094332d3Sopenharmony_cibool ByteWriter::AddDataFromFile(PropertyType key, const string& filePath)
256094332d3Sopenharmony_ci{
257094332d3Sopenharmony_ci    IF_TRUE_RETURN_VAL_WITH_MSG(filePath.length() <= 0, false, "no prop file");
258094332d3Sopenharmony_ci    ifstream ifs(filePath, ios::binary);
259094332d3Sopenharmony_ci    IF_TRUE_RETURN_VAL_WITH_MSG(!ifs.is_open(), false, "cannot open %{public}s", filePath.c_str());
260094332d3Sopenharmony_ci    size_t fileSize = GetFileSizeInBytes(ifs);
261094332d3Sopenharmony_ci    static constexpr size_t BYTE_TO_STORE_BUFFER_SIZE = 4;
262094332d3Sopenharmony_ci    std::size_t dataSize = sizeof(key) + BYTE_TO_STORE_BUFFER_SIZE + fileSize;
263094332d3Sopenharmony_ci    uint8_t* p = new uint8_t[dataSize];
264094332d3Sopenharmony_ci    IF_TRUE_RETURN_VAL(p == nullptr, false);
265094332d3Sopenharmony_ci    data_.emplace_back(DataBlock {
266094332d3Sopenharmony_ci        .data = p,
267094332d3Sopenharmony_ci        .len = dataSize
268094332d3Sopenharmony_ci    });
269094332d3Sopenharmony_ci    totalSize_ += dataSize;
270094332d3Sopenharmony_ci    errno_t ret = memset_s(p, dataSize, 0, dataSize);
271094332d3Sopenharmony_ci    IF_TRUE_RETURN_VAL_WITH_MSG(ret != EOK, false, "failed to init mem");
272094332d3Sopenharmony_ci    size_t offset = 0;
273094332d3Sopenharmony_ci    ret = memcpy_s(p + offset, sizeof(key), reinterpret_cast<uint8_t*>(&key), sizeof(key));
274094332d3Sopenharmony_ci    IF_TRUE_RETURN_VAL_WITH_MSG(ret != EOK, false, "failed to copy key");
275094332d3Sopenharmony_ci    offset += sizeof(key);
276094332d3Sopenharmony_ci    ret = memcpy_s(p + offset, BYTE_TO_STORE_BUFFER_SIZE,
277094332d3Sopenharmony_ci                   reinterpret_cast<uint8_t*>(&fileSize), BYTE_TO_STORE_BUFFER_SIZE);
278094332d3Sopenharmony_ci    IF_TRUE_RETURN_VAL_WITH_MSG(ret != EOK, false, "failed to copy buffer size");
279094332d3Sopenharmony_ci    offset += BYTE_TO_STORE_BUFFER_SIZE;
280094332d3Sopenharmony_ci    ifs.read(reinterpret_cast<char*>(p) + offset, fileSize);
281094332d3Sopenharmony_ci    return true;
282094332d3Sopenharmony_ci}
283094332d3Sopenharmony_ci
284094332d3Sopenharmony_cibool ByteWriter::Finalize(SharedBuffer& buffer)
285094332d3Sopenharmony_ci{
286094332d3Sopenharmony_ci    int fd = AshmemCreate("ForMetaProp", totalSize_);
287094332d3Sopenharmony_ci    IF_TRUE_RETURN_VAL_WITH_MSG(fd < 0, false, "cannot create ashmem for meta prop");
288094332d3Sopenharmony_ci    void *addr = mmap(nullptr, totalSize_, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
289094332d3Sopenharmony_ci    if (addr == nullptr) {
290094332d3Sopenharmony_ci        HDF_LOGE("failed to map addr for meta prop");
291094332d3Sopenharmony_ci        close(fd);
292094332d3Sopenharmony_ci        return false;
293094332d3Sopenharmony_ci    }
294094332d3Sopenharmony_ci    bool flag = CopyDataTo(reinterpret_cast<uint8_t*>(addr));
295094332d3Sopenharmony_ci    if (munmap(addr, totalSize_) != 0) {
296094332d3Sopenharmony_ci        HDF_LOGW("failed to unmap addr for meta prop");
297094332d3Sopenharmony_ci    }
298094332d3Sopenharmony_ci    if (flag) {
299094332d3Sopenharmony_ci        buffer.fd = fd;
300094332d3Sopenharmony_ci        buffer.filledLen = static_cast<uint32_t>(totalSize_);
301094332d3Sopenharmony_ci        buffer.capacity = static_cast<uint32_t>(AshmemGetSize(fd));
302094332d3Sopenharmony_ci        return true;
303094332d3Sopenharmony_ci    }
304094332d3Sopenharmony_ci    return false;
305094332d3Sopenharmony_ci}
306094332d3Sopenharmony_ci}