1c5e268c6Sopenharmony_ci/*
2c5e268c6Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3c5e268c6Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4c5e268c6Sopenharmony_ci * you may not use this file except in compliance with the License.
5c5e268c6Sopenharmony_ci * You may obtain a copy of the License at
6c5e268c6Sopenharmony_ci *
7c5e268c6Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8c5e268c6Sopenharmony_ci *
9c5e268c6Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10c5e268c6Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11c5e268c6Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12c5e268c6Sopenharmony_ci * See the License for the specific language governing permissions and
13c5e268c6Sopenharmony_ci * limitations under the License.
14c5e268c6Sopenharmony_ci */
15c5e268c6Sopenharmony_ci
16c5e268c6Sopenharmony_ci#include "hdifd_parcelable.h"
17c5e268c6Sopenharmony_ci#include <unistd.h>
18c5e268c6Sopenharmony_ci#include <sstream>
19c5e268c6Sopenharmony_ci#include "securec.h"
20c5e268c6Sopenharmony_ci#include "hdf_log.h"
21c5e268c6Sopenharmony_ci#include "hilog/log.h"
22c5e268c6Sopenharmony_ci#include "ipc_file_descriptor.h"
23c5e268c6Sopenharmony_ci
24c5e268c6Sopenharmony_ci#undef LOG_TAG
25c5e268c6Sopenharmony_ci#define LOG_TAG "DISP_HDIFD"
26c5e268c6Sopenharmony_ci#undef LOG_DOMAIN
27c5e268c6Sopenharmony_ci#define LOG_DOMAIN 0xD002515
28c5e268c6Sopenharmony_ci
29c5e268c6Sopenharmony_cinamespace OHOS {
30c5e268c6Sopenharmony_cinamespace HDI {
31c5e268c6Sopenharmony_cinamespace Display {
32c5e268c6Sopenharmony_ciHdifdParcelable::HdifdParcelable()
33c5e268c6Sopenharmony_ci    : isOwner_(false), hdiFd_(-1)
34c5e268c6Sopenharmony_ci{
35c5e268c6Sopenharmony_ci}
36c5e268c6Sopenharmony_ci
37c5e268c6Sopenharmony_ciHdifdParcelable::HdifdParcelable(int32_t fd)
38c5e268c6Sopenharmony_ci    : isOwner_(true), hdiFd_(fd)
39c5e268c6Sopenharmony_ci{
40c5e268c6Sopenharmony_ci}
41c5e268c6Sopenharmony_ci
42c5e268c6Sopenharmony_ciHdifdParcelable::~HdifdParcelable()
43c5e268c6Sopenharmony_ci{
44c5e268c6Sopenharmony_ci    if (isOwner_ && (hdiFd_ >= 0)) {
45c5e268c6Sopenharmony_ci        close(hdiFd_);
46c5e268c6Sopenharmony_ci    }
47c5e268c6Sopenharmony_ci}
48c5e268c6Sopenharmony_ci
49c5e268c6Sopenharmony_cibool HdifdParcelable::Init(int32_t fd)
50c5e268c6Sopenharmony_ci{
51c5e268c6Sopenharmony_ci    bool ret = true;
52c5e268c6Sopenharmony_ci
53c5e268c6Sopenharmony_ci    if (isOwner_) {
54c5e268c6Sopenharmony_ci        HDF_LOGI("%{public}s: fd parcelable have been initialized", __func__);
55c5e268c6Sopenharmony_ci        ret = false;
56c5e268c6Sopenharmony_ci    } else {
57c5e268c6Sopenharmony_ci        if (fd < 0) {
58c5e268c6Sopenharmony_ci            hdiFd_ = -1;
59c5e268c6Sopenharmony_ci        } else {
60c5e268c6Sopenharmony_ci            hdiFd_ = dup(fd);
61c5e268c6Sopenharmony_ci            ret = (hdiFd_ < 0) ? false : true;
62c5e268c6Sopenharmony_ci        }
63c5e268c6Sopenharmony_ci        if (!ret) {
64c5e268c6Sopenharmony_ci            return ret;
65c5e268c6Sopenharmony_ci        }
66c5e268c6Sopenharmony_ci        isOwner_ = true;
67c5e268c6Sopenharmony_ci    }
68c5e268c6Sopenharmony_ci    return ret;
69c5e268c6Sopenharmony_ci}
70c5e268c6Sopenharmony_ci
71c5e268c6Sopenharmony_cibool HdifdParcelable::WriteFileDescriptor(const int fd, Parcel& parcel)
72c5e268c6Sopenharmony_ci{
73c5e268c6Sopenharmony_ci    if (fd < 0) {
74c5e268c6Sopenharmony_ci        return false;
75c5e268c6Sopenharmony_ci    }
76c5e268c6Sopenharmony_ci    int dupFd = dup(fd);
77c5e268c6Sopenharmony_ci    if (dupFd < 0) {
78c5e268c6Sopenharmony_ci        return false;
79c5e268c6Sopenharmony_ci    }
80c5e268c6Sopenharmony_ci
81c5e268c6Sopenharmony_ci    sptr<IPCFileDescriptor> descriptor(new (std::nothrow) IPCFileDescriptor(dupFd));
82c5e268c6Sopenharmony_ci    if (descriptor == nullptr) {
83c5e268c6Sopenharmony_ci        HDF_LOGE("%{public}s: create IPCFileDescriptor object failed", __func__);
84c5e268c6Sopenharmony_ci        close(dupFd);
85c5e268c6Sopenharmony_ci        return false;
86c5e268c6Sopenharmony_ci    }
87c5e268c6Sopenharmony_ci    bool ret = parcel.WriteObject<IPCFileDescriptor>(descriptor);
88c5e268c6Sopenharmony_ci    if (!ret) {
89c5e268c6Sopenharmony_ci        HDF_LOGE("%{public}s: WriteObject IPCFileDescriptor failed", __func__);
90c5e268c6Sopenharmony_ci        close(dupFd);
91c5e268c6Sopenharmony_ci        return false;
92c5e268c6Sopenharmony_ci    }
93c5e268c6Sopenharmony_ci    return ret;
94c5e268c6Sopenharmony_ci}
95c5e268c6Sopenharmony_ci
96c5e268c6Sopenharmony_ciint HdifdParcelable::ReadFileDescriptor(Parcel& parcel)
97c5e268c6Sopenharmony_ci{
98c5e268c6Sopenharmony_ci    sptr<IPCFileDescriptor> descriptor = parcel.ReadObject<IPCFileDescriptor>();
99c5e268c6Sopenharmony_ci    if (descriptor == nullptr) {
100c5e268c6Sopenharmony_ci        return -1;
101c5e268c6Sopenharmony_ci    }
102c5e268c6Sopenharmony_ci    int fd = descriptor->GetFd();
103c5e268c6Sopenharmony_ci    if (fd < 0) {
104c5e268c6Sopenharmony_ci        return -1;
105c5e268c6Sopenharmony_ci    }
106c5e268c6Sopenharmony_ci    return dup(fd);
107c5e268c6Sopenharmony_ci}
108c5e268c6Sopenharmony_ci
109c5e268c6Sopenharmony_cibool HdifdParcelable::Marshalling(Parcel& parcel) const
110c5e268c6Sopenharmony_ci{
111c5e268c6Sopenharmony_ci    bool validFlag = (hdiFd_ >= 0);
112c5e268c6Sopenharmony_ci    if (!parcel.WriteBool(validFlag)) {
113c5e268c6Sopenharmony_ci        HDF_LOGE("%{public}s: parcel.WriteBool failed", __func__);
114c5e268c6Sopenharmony_ci        return false;
115c5e268c6Sopenharmony_ci    }
116c5e268c6Sopenharmony_ci    if (validFlag && !WriteFileDescriptor(hdiFd_, parcel)) {
117c5e268c6Sopenharmony_ci        HDF_LOGE("%{public}s: parcel.WriteFileDescriptor fd failed", __func__);
118c5e268c6Sopenharmony_ci        return false;
119c5e268c6Sopenharmony_ci    }
120c5e268c6Sopenharmony_ci    return true;
121c5e268c6Sopenharmony_ci}
122c5e268c6Sopenharmony_ci
123c5e268c6Sopenharmony_cisptr<HdifdParcelable> HdifdParcelable::Unmarshalling(Parcel& parcel)
124c5e268c6Sopenharmony_ci{
125c5e268c6Sopenharmony_ci    bool validFlag = false;
126c5e268c6Sopenharmony_ci    if (!parcel.ReadBool(validFlag)) {
127c5e268c6Sopenharmony_ci        HDF_LOGE("%{public}s: ReadBool validFlag failed", __func__);
128c5e268c6Sopenharmony_ci        return sptr<HdifdParcelable>();
129c5e268c6Sopenharmony_ci    }
130c5e268c6Sopenharmony_ci    int32_t fd = -1;
131c5e268c6Sopenharmony_ci    if (validFlag) {
132c5e268c6Sopenharmony_ci        fd = ReadFileDescriptor(parcel);
133c5e268c6Sopenharmony_ci        if (fd < 0) {
134c5e268c6Sopenharmony_ci            HDF_LOGE("%{public}s: ReadFileDescriptor fd failed", __func__);
135c5e268c6Sopenharmony_ci            return sptr<HdifdParcelable>();
136c5e268c6Sopenharmony_ci        }
137c5e268c6Sopenharmony_ci    }
138c5e268c6Sopenharmony_ci    sptr<HdifdParcelable> newParcelable(new HdifdParcelable(fd));
139c5e268c6Sopenharmony_ci
140c5e268c6Sopenharmony_ci    if (newParcelable == nullptr) {
141c5e268c6Sopenharmony_ci        HDF_LOGE("%{public}s: new HdifdParcelable failed", __func__);
142c5e268c6Sopenharmony_ci        if (fd >= 0) {
143c5e268c6Sopenharmony_ci            close(fd);
144c5e268c6Sopenharmony_ci        }
145c5e268c6Sopenharmony_ci        return sptr<HdifdParcelable>();
146c5e268c6Sopenharmony_ci    }
147c5e268c6Sopenharmony_ci    return newParcelable;
148c5e268c6Sopenharmony_ci}
149c5e268c6Sopenharmony_ci
150c5e268c6Sopenharmony_ciint32_t HdifdParcelable::GetFd()
151c5e268c6Sopenharmony_ci{
152c5e268c6Sopenharmony_ci    return hdiFd_;
153c5e268c6Sopenharmony_ci}
154c5e268c6Sopenharmony_ci
155c5e268c6Sopenharmony_ciint32_t HdifdParcelable::Move()
156c5e268c6Sopenharmony_ci{
157c5e268c6Sopenharmony_ci    isOwner_ = false;
158c5e268c6Sopenharmony_ci    return hdiFd_;
159c5e268c6Sopenharmony_ci}
160c5e268c6Sopenharmony_ci
161c5e268c6Sopenharmony_cistd::string HdifdParcelable::Dump() const
162c5e268c6Sopenharmony_ci{
163c5e268c6Sopenharmony_ci    std::stringstream os;
164c5e268c6Sopenharmony_ci    os << "fd: {" << hdiFd_ << "}\n";
165c5e268c6Sopenharmony_ci    return os.str();
166c5e268c6Sopenharmony_ci}
167c5e268c6Sopenharmony_ci} // Display
168c5e268c6Sopenharmony_ci} // HDI
169c5e268c6Sopenharmony_ci} // OHOS
170