132a6e48fSopenharmony_ci/*
232a6e48fSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
332a6e48fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
432a6e48fSopenharmony_ci * you may not use this file except in compliance with the License.
532a6e48fSopenharmony_ci * You may obtain a copy of the License at
632a6e48fSopenharmony_ci *
732a6e48fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
832a6e48fSopenharmony_ci *
932a6e48fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1032a6e48fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1132a6e48fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1232a6e48fSopenharmony_ci * See the License for the specific language governing permissions and
1332a6e48fSopenharmony_ci * limitations under the License.
1432a6e48fSopenharmony_ci */
1532a6e48fSopenharmony_ci
1632a6e48fSopenharmony_ci#include "buffer_handle.h"
1732a6e48fSopenharmony_ci#include "buffer_handle_utils.h"
1832a6e48fSopenharmony_ci
1932a6e48fSopenharmony_ci#include <cstdlib>
2032a6e48fSopenharmony_ci#include <securec.h>
2132a6e48fSopenharmony_ci
2232a6e48fSopenharmony_ci#include <hilog/log.h>
2332a6e48fSopenharmony_ci#include <message_parcel.h>
2432a6e48fSopenharmony_ci#include <unistd.h>
2532a6e48fSopenharmony_ci
2632a6e48fSopenharmony_ci#undef LOG_DOMAIN
2732a6e48fSopenharmony_ci#define LOG_DOMAIN 0xD001400
2832a6e48fSopenharmony_ci#undef LOG_TAG
2932a6e48fSopenharmony_ci#define LOG_TAG "graphicutils"
3032a6e48fSopenharmony_ci#define UTILS_LOGF(...) (void)HILOG_FATAL(LOG_CORE, __VA_ARGS__)
3132a6e48fSopenharmony_ci#define UTILS_LOGE(...) (void)HILOG_ERROR(LOG_CORE, __VA_ARGS__)
3232a6e48fSopenharmony_ci#define UTILS_LOGW(...) (void)HILOG_WARN(LOG_CORE, __VA_ARGS__)
3332a6e48fSopenharmony_ci#define UTILS_LOGI(...) (void)HILOG_INFO(LOG_CORE, __VA_ARGS__)
3432a6e48fSopenharmony_ci#define UTILS_LOGD(...) (void)HILOG_DEBUG(LOG_CORE, __VA_ARGS__)
3532a6e48fSopenharmony_ci#define BUFFER_HANDLE_RESERVE_MAX_SIZE 1024
3632a6e48fSopenharmony_ci
3732a6e48fSopenharmony_ciBufferHandle *AllocateBufferHandle(uint32_t reserveFds, uint32_t reserveInts)
3832a6e48fSopenharmony_ci{
3932a6e48fSopenharmony_ci    if (reserveFds > BUFFER_HANDLE_RESERVE_MAX_SIZE || reserveInts > BUFFER_HANDLE_RESERVE_MAX_SIZE) {
4032a6e48fSopenharmony_ci        UTILS_LOGE("AllocateBufferHandle reserveFds or reserveInts too lager");
4132a6e48fSopenharmony_ci        return nullptr;
4232a6e48fSopenharmony_ci    }
4332a6e48fSopenharmony_ci    size_t handleSize = sizeof(BufferHandle) + (sizeof(int32_t) * (reserveFds + reserveInts));
4432a6e48fSopenharmony_ci    BufferHandle *handle = static_cast<BufferHandle *>(malloc(handleSize));
4532a6e48fSopenharmony_ci    if (handle != nullptr) {
4632a6e48fSopenharmony_ci        errno_t ret = memset_s(handle, handleSize, 0, handleSize);
4732a6e48fSopenharmony_ci        if (ret != 0) {
4832a6e48fSopenharmony_ci            UTILS_LOGE("memset_s error, ret is %{public}d", ret);
4932a6e48fSopenharmony_ci            free(handle);
5032a6e48fSopenharmony_ci            return nullptr;
5132a6e48fSopenharmony_ci        }
5232a6e48fSopenharmony_ci        handle->fd = -1;
5332a6e48fSopenharmony_ci        for (uint32_t i = 0; i < reserveFds; i++) {
5432a6e48fSopenharmony_ci            handle->reserve[i] = -1;
5532a6e48fSopenharmony_ci        }
5632a6e48fSopenharmony_ci        handle->reserveFds = reserveFds;
5732a6e48fSopenharmony_ci        handle->reserveInts = reserveInts;
5832a6e48fSopenharmony_ci    } else {
5932a6e48fSopenharmony_ci        UTILS_LOGE("AllocateBufferHandle malloc %{public}zu failed", handleSize);
6032a6e48fSopenharmony_ci    }
6132a6e48fSopenharmony_ci    return handle;
6232a6e48fSopenharmony_ci}
6332a6e48fSopenharmony_ci
6432a6e48fSopenharmony_ciint32_t FreeBufferHandle(BufferHandle *handle)
6532a6e48fSopenharmony_ci{
6632a6e48fSopenharmony_ci    if (handle == nullptr) {
6732a6e48fSopenharmony_ci        UTILS_LOGW("FreeBufferHandle with nullptr handle");
6832a6e48fSopenharmony_ci        return 0;
6932a6e48fSopenharmony_ci    }
7032a6e48fSopenharmony_ci    if (handle->fd >= 0) {
7132a6e48fSopenharmony_ci        close(handle->fd);
7232a6e48fSopenharmony_ci        handle->fd = -1;
7332a6e48fSopenharmony_ci    }
7432a6e48fSopenharmony_ci    const uint32_t reserveFds = handle->reserveFds;
7532a6e48fSopenharmony_ci    for (uint32_t i = 0; i < reserveFds; i++) {
7632a6e48fSopenharmony_ci        if (handle->reserve[i] >= 0) {
7732a6e48fSopenharmony_ci            close(handle->reserve[i]);
7832a6e48fSopenharmony_ci            handle->reserve[i] = -1;
7932a6e48fSopenharmony_ci        }
8032a6e48fSopenharmony_ci    }
8132a6e48fSopenharmony_ci    free(handle);
8232a6e48fSopenharmony_ci    return 0;
8332a6e48fSopenharmony_ci}
8432a6e48fSopenharmony_ci
8532a6e48fSopenharmony_cinamespace OHOS {
8632a6e48fSopenharmony_cibool WriteBufferHandle(MessageParcel &parcel, const BufferHandle &handle)
8732a6e48fSopenharmony_ci{
8832a6e48fSopenharmony_ci    if (!parcel.WriteUint32(handle.reserveFds) || !parcel.WriteUint32(handle.reserveInts) ||
8932a6e48fSopenharmony_ci        !parcel.WriteInt32(handle.width) || !parcel.WriteInt32(handle.stride) || !parcel.WriteInt32(handle.height) ||
9032a6e48fSopenharmony_ci        !parcel.WriteInt32(handle.size) || !parcel.WriteInt32(handle.format) || !parcel.WriteInt64(handle.usage) ||
9132a6e48fSopenharmony_ci        !parcel.WriteUint64(handle.phyAddr)) {
9232a6e48fSopenharmony_ci        UTILS_LOGE("%{public}s a lot failed", __func__);
9332a6e48fSopenharmony_ci        return false;
9432a6e48fSopenharmony_ci    }
9532a6e48fSopenharmony_ci    bool validFd = (handle.fd >= 0);
9632a6e48fSopenharmony_ci    if (!parcel.WriteBool(validFd)) {
9732a6e48fSopenharmony_ci        UTILS_LOGE("%{public}s parcel.WriteBool failed", __func__);
9832a6e48fSopenharmony_ci        return false;
9932a6e48fSopenharmony_ci    }
10032a6e48fSopenharmony_ci    if (validFd && !parcel.WriteFileDescriptor(handle.fd)) {
10132a6e48fSopenharmony_ci        UTILS_LOGE("%{public}s parcel.WriteFileDescriptor fd failed", __func__);
10232a6e48fSopenharmony_ci        return false;
10332a6e48fSopenharmony_ci    }
10432a6e48fSopenharmony_ci
10532a6e48fSopenharmony_ci    for (uint32_t i = 0; i < handle.reserveFds; i++) {
10632a6e48fSopenharmony_ci        if (!parcel.WriteFileDescriptor(handle.reserve[i])) {
10732a6e48fSopenharmony_ci            UTILS_LOGE("%{public}s parcel.WriteFileDescriptor reserveFds failed", __func__);
10832a6e48fSopenharmony_ci            return false;
10932a6e48fSopenharmony_ci        }
11032a6e48fSopenharmony_ci    }
11132a6e48fSopenharmony_ci    for (uint32_t j = 0; j < handle.reserveInts; j++) {
11232a6e48fSopenharmony_ci        if (!parcel.WriteInt32(handle.reserve[handle.reserveFds + j])) {
11332a6e48fSopenharmony_ci            UTILS_LOGE("%{public}s parcel.WriteInt32 reserve failed", __func__);
11432a6e48fSopenharmony_ci            return false;
11532a6e48fSopenharmony_ci        }
11632a6e48fSopenharmony_ci    }
11732a6e48fSopenharmony_ci    return true;
11832a6e48fSopenharmony_ci}
11932a6e48fSopenharmony_ci
12032a6e48fSopenharmony_ciBufferHandle *ReadBufferHandle(MessageParcel &parcel)
12132a6e48fSopenharmony_ci{
12232a6e48fSopenharmony_ci    uint32_t reserveFds = 0;
12332a6e48fSopenharmony_ci    uint32_t reserveInts = 0;
12432a6e48fSopenharmony_ci    if (!parcel.ReadUint32(reserveFds) || !parcel.ReadUint32(reserveInts)) {
12532a6e48fSopenharmony_ci        UTILS_LOGE("%{public}s parcel.ReadUint32 reserveFds failed", __func__);
12632a6e48fSopenharmony_ci        return nullptr;
12732a6e48fSopenharmony_ci    }
12832a6e48fSopenharmony_ci
12932a6e48fSopenharmony_ci    BufferHandle *handle = AllocateBufferHandle(reserveFds, reserveInts);
13032a6e48fSopenharmony_ci    if (handle == nullptr) {
13132a6e48fSopenharmony_ci        UTILS_LOGE("%{public}s AllocateBufferHandle failed", __func__);
13232a6e48fSopenharmony_ci        return nullptr;
13332a6e48fSopenharmony_ci    }
13432a6e48fSopenharmony_ci
13532a6e48fSopenharmony_ci    if (!parcel.ReadInt32(handle->width) || !parcel.ReadInt32(handle->stride) || !parcel.ReadInt32(handle->height) ||
13632a6e48fSopenharmony_ci        !parcel.ReadInt32(handle->size) || !parcel.ReadInt32(handle->format) || !parcel.ReadUint64(handle->usage) ||
13732a6e48fSopenharmony_ci        !parcel.ReadUint64(handle->phyAddr)) {
13832a6e48fSopenharmony_ci        UTILS_LOGE("%{public}s a lot failed", __func__);
13932a6e48fSopenharmony_ci        FreeBufferHandle(handle);
14032a6e48fSopenharmony_ci        return nullptr;
14132a6e48fSopenharmony_ci    }
14232a6e48fSopenharmony_ci
14332a6e48fSopenharmony_ci    bool validFd = false;
14432a6e48fSopenharmony_ci    if (!parcel.ReadBool(validFd)) {
14532a6e48fSopenharmony_ci        UTILS_LOGE("%{public}s ReadBool validFd failed", __func__);
14632a6e48fSopenharmony_ci        FreeBufferHandle(handle);
14732a6e48fSopenharmony_ci        return nullptr;
14832a6e48fSopenharmony_ci    }
14932a6e48fSopenharmony_ci    if (validFd) {
15032a6e48fSopenharmony_ci        handle->fd = parcel.ReadFileDescriptor();
15132a6e48fSopenharmony_ci        if (handle->fd == -1) {
15232a6e48fSopenharmony_ci            UTILS_LOGE("%{public}s ReadFileDescriptor fd failed", __func__);
15332a6e48fSopenharmony_ci            FreeBufferHandle(handle);
15432a6e48fSopenharmony_ci            return nullptr;
15532a6e48fSopenharmony_ci        }
15632a6e48fSopenharmony_ci    }
15732a6e48fSopenharmony_ci
15832a6e48fSopenharmony_ci    for (uint32_t i = 0; i < handle->reserveFds; i++) {
15932a6e48fSopenharmony_ci        handle->reserve[i] = parcel.ReadFileDescriptor();
16032a6e48fSopenharmony_ci        if (handle->reserve[i] == -1) {
16132a6e48fSopenharmony_ci            UTILS_LOGE("%{public}s ReadFileDescriptor reserve failed", __func__);
16232a6e48fSopenharmony_ci            FreeBufferHandle(handle);
16332a6e48fSopenharmony_ci            return nullptr;
16432a6e48fSopenharmony_ci        }
16532a6e48fSopenharmony_ci    }
16632a6e48fSopenharmony_ci    for (uint32_t j = 0; j < handle->reserveInts; j++) {
16732a6e48fSopenharmony_ci        if (!parcel.ReadInt32(handle->reserve[reserveFds + j])) {
16832a6e48fSopenharmony_ci            UTILS_LOGE("%{public}s ReadInt32 reserve failed", __func__);
16932a6e48fSopenharmony_ci            FreeBufferHandle(handle);
17032a6e48fSopenharmony_ci            return nullptr;
17132a6e48fSopenharmony_ci        }
17232a6e48fSopenharmony_ci    }
17332a6e48fSopenharmony_ci    return handle;
17432a6e48fSopenharmony_ci}
17532a6e48fSopenharmony_ci} // namespace OHOS
176