1/*
2 * Copyright (c) 2022-2023 Shenzhen Kaihong DID 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#include "codec_component_manager_stub.h"
16#include <dlfcn.h>
17#include <hdf_device_desc.h>
18#include <hdf_device_object.h>
19#include <osal_mem.h>
20#include <securec.h>
21#include "codec_component_capability_config.h"
22#include "codec_component_manager_service.h"
23#include "codec_util.h"
24#include "codec_log_wrapper.h"
25
26#define CODEC_SERVICE_IMPL "libcodec_hdi_omx_service_impl"
27typedef void (*SERVICE_CONSTRUCT_FUNC)(struct OmxComponentManager *);
28static int32_t SerStubGetComponentNum(struct CodecComponentManager *serviceImpl, struct HdfSBuf *data,
29                                      struct HdfSBuf *reply)
30{
31    if (serviceImpl == NULL) {
32        CODEC_LOGE("invalid paramter");
33        return HDF_ERR_INVALID_PARAM;
34    }
35    int32_t num = serviceImpl->GetComponentNum();
36    if (!HdfSbufWriteInt32(reply, num)) {
37        CODEC_LOGE("write num failed!");
38        return HDF_ERR_INVALID_PARAM;
39    }
40    return HDF_SUCCESS;
41}
42
43static int32_t SerStubGetComponentCapablityList(struct CodecComponentManager *serviceImpl, struct HdfSBuf *data,
44                                                struct HdfSBuf *reply)
45{
46    if (serviceImpl == NULL) {
47        CODEC_LOGE("invalid paramter");
48        return HDF_ERR_INVALID_PARAM;
49    }
50    int32_t count = 0;
51    int32_t err = HDF_SUCCESS;
52    CodecCompCapability *caps = NULL;
53    if (!HdfSbufReadInt32(data, &count) || (count <= 0)) {
54        CODEC_LOGE("read count failed!");
55        return HDF_ERR_INVALID_PARAM;
56    }
57    if (count > serviceImpl->GetComponentNum()) {
58        CODEC_LOGE("count exceed compomentNum");
59        return HDF_ERR_INVALID_PARAM;
60    }
61    caps = (CodecCompCapability *)OsalMemCalloc(sizeof(CodecCompCapability) * (count));
62    if (caps == NULL) {
63        CODEC_LOGE("alloc caps failed!");
64        return HDF_ERR_INVALID_PARAM;
65    }
66    err = serviceImpl->GetComponentCapabilityList(caps, count);
67    if (err != HDF_SUCCESS) {
68        OsalMemFree(caps);
69        CODEC_LOGE("call GetComponentCapabilityList function failed!");
70        return err;
71    }
72
73    for (int32_t i = 0; i < count; i++) {
74        if (!CodecCompCapabilityBlockMarshalling(reply, &caps[i])) {
75            CODEC_LOGE("call CodecCompCapabilityBlockMarshalling function failed!");
76            err = HDF_ERR_INVALID_PARAM;
77            break;
78        }
79    }
80    OsalMemFree(caps);
81    return err;
82}
83
84static int32_t ReadParamsForCreateComponent(struct HdfSBuf *data, char **compName, int64_t *appData,
85                                            struct CodecCallbackType **callback)
86{
87    const char *compNameCp = HdfSbufReadString(data);
88    if (compNameCp == NULL) {
89        CODEC_LOGE("read compNameCp failed!");
90        return HDF_ERR_INVALID_PARAM;
91    }
92
93    if (!HdfSbufReadInt64(data, appData)) {
94        CODEC_LOGE("read appData failed!");
95        return HDF_ERR_INVALID_PARAM;
96    }
97    *compName = strdup(compNameCp);
98
99    struct HdfRemoteService *callbackRemote = HdfSbufReadRemoteService(data);
100    if (callbackRemote == NULL) {
101        CODEC_LOGE("read callbackRemote failed!");
102        return HDF_ERR_INVALID_PARAM;
103    }
104    *callback = CodecCallbackTypeGet(callbackRemote);
105
106    return HDF_SUCCESS;
107}
108
109static int32_t SerStubCreateComponent(struct CodecComponentManager *serviceImpl, struct HdfSBuf *data,
110                                      struct HdfSBuf *reply)
111{
112    if (serviceImpl == NULL) {
113        CODEC_LOGE("invalid paramter");
114        return HDF_ERR_INVALID_PARAM;
115    }
116    int32_t ret = HDF_SUCCESS;
117    struct CodecComponentType *component = NULL;
118    uint32_t componentId = 0;
119    int64_t appData = 0;
120    struct CodecCallbackType *callback = NULL;
121    char *compName = NULL;
122
123    ret = ReadParamsForCreateComponent(data, &compName, &appData, &callback);
124    if (ret != HDF_SUCCESS) {
125        if (compName != NULL) {
126            OsalMemFree(compName);
127            compName = NULL;
128        }
129        return ret;
130    }
131    ret = serviceImpl->CreateComponent(&component, &componentId, compName, appData, callback);
132    if (component == NULL) {
133        CODEC_LOGE("fail to create component");
134        if (compName != NULL) {
135            OsalMemFree(compName);
136            compName = NULL;
137        }
138        return ret;
139    }
140    if (compName != NULL) {
141        OsalMemFree(compName);
142        compName = NULL;
143    }
144    if (ret != HDF_SUCCESS) {
145        CODEC_LOGE("call CreateComponent function failed!");
146        return ret;
147    }
148
149    if (HdfSbufWriteRemoteService(reply, component->AsObject(component)) != 0) {
150        CODEC_LOGE("write component failed!");
151        return HDF_ERR_INVALID_PARAM;
152    }
153    if (!HdfSbufWriteUint32(reply, componentId)) {
154        CODEC_LOGE("write componentId failed!");
155        return HDF_ERR_INVALID_PARAM;
156    }
157#ifdef CONFIG_USE_JEMALLOC_DFX_INTF
158    ReleaseCodecCache();
159#endif
160    return ret;
161}
162
163static int32_t SerStubDestroyComponent(struct CodecComponentManager *serviceImpl, struct HdfSBuf *data,
164                                       struct HdfSBuf *reply)
165{
166    if (serviceImpl == NULL) {
167        CODEC_LOGE("invalid paramter");
168        return HDF_ERR_INVALID_PARAM;
169    }
170    uint32_t componentId = 0;
171    if (!HdfSbufReadUint32(data, &componentId)) {
172        CODEC_LOGE("read componentId failed!");
173        return HDF_ERR_INVALID_PARAM;
174    }
175    int32_t ret = serviceImpl->DestroyComponent(componentId);
176    if (ret != HDF_SUCCESS) {
177        CODEC_LOGE("call DestroyComponent function failed!");
178    }
179#ifdef CONFIG_USE_JEMALLOC_DFX_INTF
180    ReleaseCodecCache();
181#endif
182    return ret;
183}
184
185static int32_t CodecComponentManagerServiceOnRemoteRequest(struct CodecComponentManager *serviceImpl, int32_t cmdId,
186                                                           struct HdfSBuf *data, struct HdfSBuf *reply)
187{
188    switch (cmdId) {
189        case CMD_CODEC_GET_COMPONENT_NUM:
190            return SerStubGetComponentNum(serviceImpl, data, reply);
191        case CMD_CODEC_GET_COMPONENT_CAPABILITY_LIST:
192            return SerStubGetComponentCapablityList(serviceImpl, data, reply);
193        case CMD_CREATE_COMPONENT:
194            return SerStubCreateComponent(serviceImpl, data, reply);
195        case CMD_DESTROY_COMPONENT:
196            return SerStubDestroyComponent(serviceImpl, data, reply);
197        default:
198            CODEC_LOGE("not support cmd %{public}d", cmdId);
199            return HDF_ERR_INVALID_PARAM;
200    }
201}
202
203static struct HdfRemoteService *CodecComponentManagerStubAsObject(struct CodecComponentManager *self)
204{
205    return NULL;
206}
207
208bool CodecComponentManagerStubConstruct(struct CodecComponentManagerStub *stub)
209{
210    if (stub == NULL) {
211        CODEC_LOGE("stub is null!");
212        return false;
213    }
214
215    stub->OnRemoteRequest = CodecComponentManagerServiceOnRemoteRequest;
216    stub->interface.AsObject = CodecComponentManagerStubAsObject;
217    return true;
218}