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#include <hdf_base.h>
17#include <hdf_device_desc.h>
18#include <hdf_log.h>
19#include <hdf_sbuf_ipc.h>
20#include "codec_image_config.h"
21#include "codec_log_wrapper.h"
22#include "v2_0/codec_image_stub.h"
23
24using namespace OHOS::HDI::Codec::Image::V2_0;
25
26struct HdfCodecImageHost {
27    struct IDeviceIoService ioService;
28    OHOS::sptr<OHOS::IRemoteObject> stub;
29};
30
31static int32_t CodecImageDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data,
32    struct HdfSBuf *reply)
33{
34    auto *hdfCodecImageHost = CONTAINER_OF(client->device->service, struct HdfCodecImageHost, ioService);
35
36    OHOS::MessageParcel *dataParcel = nullptr;
37    OHOS::MessageParcel *replyParcel = nullptr;
38    OHOS::MessageOption option;
39
40    if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) {
41        CODEC_LOGE("invalid data sbuf object to dispatch");
42        return HDF_ERR_INVALID_PARAM;
43    }
44    if (SbufToParcel(reply, &replyParcel) != HDF_SUCCESS) {
45        CODEC_LOGE("invalid reply sbuf object to dispatch");
46        return HDF_ERR_INVALID_PARAM;
47    }
48
49    return hdfCodecImageHost->stub->SendRequest(cmdId, *dataParcel, *replyParcel, option);
50}
51
52static int HdfCodecImageDriverInit(struct HdfDeviceObject *deviceObject)
53{
54    HDF_LOGI("driver init start");
55    if (deviceObject->property == nullptr) {
56        CODEC_LOGE("fail to get deviceObject property");
57        return HDF_FAILURE;
58    }
59    CodecImageConfig::GetInstance()->Init(*(deviceObject->property));
60    return HDF_SUCCESS;
61}
62
63static int HdfCodecImageDriverBind(struct HdfDeviceObject *deviceObject)
64{
65    HDF_LOGI("driver bind start");
66    auto *hdfCodecImageHost = new (std::nothrow) HdfCodecImageHost;
67    if (hdfCodecImageHost == nullptr) {
68        CODEC_LOGE("failed to create create HdfCodecImageHost object");
69        return HDF_FAILURE;
70    }
71
72    hdfCodecImageHost->ioService.Dispatch = CodecImageDriverDispatch;
73    hdfCodecImageHost->ioService.Open = NULL;
74    hdfCodecImageHost->ioService.Release = NULL;
75
76    auto serviceImpl = OHOS::HDI::Codec::Image::V2_0::ICodecImage::Get(true);
77    if (serviceImpl == nullptr) {
78        CODEC_LOGE("failed to get of implement service");
79        delete hdfCodecImageHost;
80        return HDF_FAILURE;
81    }
82
83    hdfCodecImageHost->stub = OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl,
84        OHOS::HDI::Codec::Image::V2_0::ICodecImage::GetDescriptor());
85    if (hdfCodecImageHost->stub == nullptr) {
86        CODEC_LOGE("failed to get stub object");
87        delete hdfCodecImageHost;
88        return HDF_FAILURE;
89    }
90
91    deviceObject->service = &hdfCodecImageHost->ioService;
92    return HDF_SUCCESS;
93}
94
95static void HdfCodecImageDriverRelease(struct HdfDeviceObject *deviceObject)
96{
97    HDF_LOGI("driver release start");
98    if (deviceObject->service == nullptr) {
99        return;
100    }
101
102    auto *hdfCodecImageHost = CONTAINER_OF(deviceObject->service, struct HdfCodecImageHost, ioService);
103    if (hdfCodecImageHost != nullptr) {
104        delete hdfCodecImageHost;
105    }
106}
107
108static struct HdfDriverEntry g_CodecImageDriverEntry = {
109    .moduleVersion = 1,
110    .moduleName = "libcodec_image_service",
111    .Bind = HdfCodecImageDriverBind,
112    .Init = HdfCodecImageDriverInit,
113    .Release = HdfCodecImageDriverRelease,
114};
115
116#ifdef __cplusplus
117extern "C" {
118#endif /* __cplusplus */
119HDF_INIT(g_CodecImageDriverEntry);
120#ifdef __cplusplus
121}
122#endif /* __cplusplus */
123