• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 
16 #include "codec_callback_type_stub.h"
17 #include <dlfcn.h>
18 #include <hdf_base.h>
19 #include <hdf_dlist.h>
20 #include <hdf_log.h>
21 #include <hdf_remote_service.h>
22 #include <osal_mem.h>
23 #include <securec.h>
24 #include "codec_callback_type_service.h"
25 #include "codec_internal.h"
26 #include "codec_types.h"
27 
28 #define HDF_LOG_TAG codec_hdi_cb_server
29 
30 #ifdef __ARM64__
31 #define DRIVER_PATH "/vendor/lib64"
32 #else
33 #define DRIVER_PATH "/vendor/lib"
34 #endif
35 #define OMX_CALLBACK_IMPLEMENT  "libcodec_hdi_omx_callback_type_service_impl"
36 
37 typedef void (*SERVICE_CONSTRUCT_FUNC)(struct CodecCallbackType *);
38 
39 struct CodecCallbackTypeStub {
40     struct CodecCallbackType service;
41     struct HdfRemoteDispatcher dispatcher;
42     void *dlHandler;
43 };
44 
FreeMem(int8_t * mem,uint32_t memLen)45 static void FreeMem(int8_t *mem, uint32_t memLen)
46 {
47     if (memLen > 0 && mem != NULL) {
48         OsalMemFree(mem);
49     }
50 }
51 
ReadArray(struct HdfSBuf * data,int8_t ** array,uint32_t * arrayLen)52 static int32_t ReadArray(struct HdfSBuf *data, int8_t **array, uint32_t *arrayLen)
53 {
54     int8_t *buffer = NULL;
55     uint32_t bufferLen = 0;
56     if (!HdfSbufReadUint32(data, &bufferLen)) {
57         HDF_LOGE("%{public}s: read buffer size failed!", __func__);
58         return HDF_ERR_INVALID_PARAM;
59     }
60 
61     if (bufferLen == 0) {
62         *arrayLen = bufferLen;
63         return HDF_SUCCESS;
64     }
65 
66     buffer = (int8_t*)OsalMemCalloc(sizeof(int8_t) * bufferLen);
67     if (buffer == NULL) {
68         return HDF_ERR_MALLOC_FAIL;
69     }
70 
71     for (uint32_t i = 0; i < bufferLen; i++) {
72         if (!HdfSbufReadInt8(data, &buffer[i])) {
73             HDF_LOGE("%{public}s: read &buffer[i] failed!", __func__);
74             OsalMemFree(buffer);
75             return HDF_ERR_INVALID_PARAM;
76         }
77     }
78 
79     *array = buffer;
80     *arrayLen = bufferLen;
81     return HDF_SUCCESS;
82 }
83 
ReadEventInfo(struct HdfSBuf * data,struct EventInfo * info)84 static int32_t ReadEventInfo(struct HdfSBuf *data, struct EventInfo *info)
85 {
86     int32_t ret;
87     if (!HdfSbufReadInt64(data, &info->appData)) {
88         HDF_LOGE("%{public}s: read appData failed!", __func__);
89         return HDF_ERR_INVALID_PARAM;
90     }
91 
92     if (!HdfSbufReadUint32(data, &info->data1)) {
93         HDF_LOGE("%{public}s: read &data1 failed!", __func__);
94         return HDF_ERR_INVALID_PARAM;
95     }
96 
97     if (!HdfSbufReadUint32(data, &info->data2)) {
98         HDF_LOGE("%{public}s: read &data2 failed!", __func__);
99         return HDF_ERR_INVALID_PARAM;
100     }
101 
102     ret = ReadArray(data, &info->eventData, &info->eventDataLen);
103     if (ret != HDF_SUCCESS) {
104         HDF_LOGE("%{public}s: read eventData failed!", __func__);
105     }
106     return ret;
107 }
108 
ReleaseEventInfo(struct EventInfo * info)109 static void ReleaseEventInfo(struct EventInfo *info)
110 {
111     FreeMem(info->eventData, info->eventDataLen);
112 }
113 
SerStubEventHandler(struct CodecCallbackType * serviceImpl,struct HdfSBuf * data,struct HdfSBuf * reply)114 static int32_t SerStubEventHandler(struct CodecCallbackType *serviceImpl,
115     struct HdfSBuf *data, struct HdfSBuf *reply)
116 {
117     int32_t ret;
118     enum OMX_EVENTTYPE event;
119     struct EventInfo info = {0};
120 
121     if (!HdfSbufReadUint32(data, (uint32_t*)&event)) {
122         HDF_LOGE("%{public}s: read &event failed!", __func__);
123         return HDF_ERR_INVALID_PARAM;
124     }
125 
126     ret = ReadEventInfo(data, &info);
127     if (ret != HDF_SUCCESS) {
128         HDF_LOGE("%{public}s: read &info failed!", __func__);
129         return HDF_ERR_INVALID_PARAM;
130     }
131 
132     ret = serviceImpl->EventHandler(serviceImpl, event, &info);
133     if (ret != HDF_SUCCESS) {
134         HDF_LOGE("%{public}s: call EventHandler function failed!", __func__);
135     }
136     ReleaseEventInfo(&info);
137     return ret;
138 }
139 
SerStubEmptyBufferDone(struct CodecCallbackType * serviceImpl,struct HdfSBuf * data,struct HdfSBuf * reply)140 static int32_t SerStubEmptyBufferDone(struct CodecCallbackType *serviceImpl,
141     struct HdfSBuf *data, struct HdfSBuf *reply)
142 {
143     int32_t ret;
144     int64_t appData = 0;
145     struct OmxCodecBuffer buffer;
146     InitOmxCodecBuffer(&buffer);
147 
148     if (!HdfSbufReadInt64(data, &appData)) {
149         HDF_LOGE("%{public}s: read appData size failed!", __func__);
150         return HDF_ERR_INVALID_PARAM;
151     }
152 
153     if (!OmxCodecBufferBlockUnmarshalling(data, &buffer)) {
154         HDF_LOGE("%{public}s: read buffer failed!", __func__);
155         ReleaseOmxCodecBuffer(&buffer);
156         return HDF_ERR_INVALID_PARAM;
157     }
158 
159     ret = serviceImpl->EmptyBufferDone(serviceImpl, appData, &buffer);
160     if (ret != HDF_SUCCESS) {
161         HDF_LOGE("%{public}s: call EmptyBufferDone function failed!", __func__);
162         ReleaseOmxCodecBuffer(&buffer);
163         return ret;
164     }
165 
166     ReleaseOmxCodecBuffer(&buffer);
167     return ret;
168 }
169 
SerStubFillBufferDone(struct CodecCallbackType * serviceImpl,struct HdfSBuf * data,struct HdfSBuf * reply)170 static int32_t SerStubFillBufferDone(struct CodecCallbackType *serviceImpl,
171     struct HdfSBuf *data, struct HdfSBuf *reply)
172 {
173     int32_t ret;
174     int64_t appData = 0;
175     struct OmxCodecBuffer buffer;
176     InitOmxCodecBuffer(&buffer);
177     if (!HdfSbufReadInt64(data, &appData)) {
178         HDF_LOGE("%{public}s: read appData size failed!", __func__);
179         return HDF_ERR_INVALID_PARAM;
180     }
181 
182     if (!OmxCodecBufferBlockUnmarshalling(data, &buffer)) {
183         HDF_LOGE("%{public}s: read buffer failed!", __func__);
184         return HDF_ERR_INVALID_PARAM;
185     }
186 
187     ret = serviceImpl->FillBufferDone(serviceImpl, appData, &buffer);
188     if (ret != HDF_SUCCESS) {
189         HDF_LOGE("%{public}s: call FillBufferDone function failed!", __func__);
190         ReleaseOmxCodecBuffer(&buffer);
191         return ret;
192     }
193 
194     ReleaseOmxCodecBuffer(&buffer);
195     return ret;
196 }
197 
CodecCallbackTypeServiceOnRemoteRequest(struct HdfRemoteService * service,int32_t code,struct HdfSBuf * data,struct HdfSBuf * reply)198 static int32_t CodecCallbackTypeServiceOnRemoteRequest(struct HdfRemoteService *service, int32_t code,
199     struct HdfSBuf *data, struct HdfSBuf *reply)
200 {
201     struct CodecCallbackType *serviceImpl = (struct CodecCallbackType*)service;
202     if (!HdfRemoteServiceCheckInterfaceToken(serviceImpl->remote, data)) {
203         HDF_LOGE("%{public}s: check interface token failed", __func__);
204         return HDF_ERR_INVALID_PARAM;
205     }
206 
207     switch (code) {
208         case CMD_EVENT_HANDLER:
209             return SerStubEventHandler(serviceImpl, data, reply);
210         case CMD_EMPTY_BUFFER_DONE:
211             return SerStubEmptyBufferDone(serviceImpl, data, reply);
212         case CMD_FILL_BUFFER_DONE:
213             return SerStubFillBufferDone(serviceImpl, data, reply);
214         default: {
215             HDF_LOGE("%{public}s: not support cmd %{public}d", __func__, code);
216             return HDF_ERR_INVALID_PARAM;
217         }
218     }
219 }
220 
LoadServiceHandler(void)221 static void *LoadServiceHandler(void)
222 {
223     char *libPath = NULL;
224     void *handler = NULL;
225 
226     char pathBuf[PATH_MAX] = {'\0'};
227     libPath = HDF_LIBRARY_FULL_PATH(OMX_CALLBACK_IMPLEMENT);
228     if (realpath(libPath, pathBuf) == NULL) {
229         HDF_LOGE("%{public}s: realpath failed!", __func__);
230         return NULL;
231     }
232 
233     handler = dlopen(pathBuf, RTLD_LAZY);
234     if (handler == NULL) {
235         HDF_LOGE("%{public}s: dlopen failed %{public}s", __func__, dlerror());
236         return NULL;
237     }
238 
239     return handler;
240 }
241 
CodecCallbackTypeStubGetInstance(void)242 struct CodecCallbackType *CodecCallbackTypeStubGetInstance(void)
243 {
244     SERVICE_CONSTRUCT_FUNC serviceConstructFunc = NULL;
245     struct CodecCallbackTypeStub *stub
246         = (struct CodecCallbackTypeStub *)OsalMemAlloc(sizeof(struct CodecCallbackTypeStub));
247     if (stub == NULL) {
248         HDF_LOGE("%{public}s: OsalMemAlloc obj failed!", __func__);
249         return NULL;
250     }
251 
252     stub->dispatcher.Dispatch = CodecCallbackTypeServiceOnRemoteRequest;
253     stub->service.remote = HdfRemoteServiceObtain((struct HdfObject*)stub, &(stub->dispatcher));
254     if (stub->service.remote == NULL) {
255         HDF_LOGE("%{public}s: stub->service.remote is null", __func__);
256         OsalMemFree(stub);
257         return NULL;
258     }
259 
260     if (!HdfRemoteServiceSetInterfaceDesc(stub->service.remote, "ohos.hdi.codec_service")) {
261         HDF_LOGE("%{public}s: failed to init interface desc", __func__);
262         return NULL;
263     }
264 
265     stub->dlHandler = LoadServiceHandler();
266     if (stub->dlHandler == NULL) {
267         HDF_LOGE("%{public}s: stub->dlHanlder is null", __func__);
268         OsalMemFree(stub);
269         return NULL;
270     }
271 
272     serviceConstructFunc = (SERVICE_CONSTRUCT_FUNC)dlsym(stub->dlHandler, "CodecCallbackTypeServiceConstruct");
273     if (serviceConstructFunc == NULL) {
274         HDF_LOGE("%{public}s: dlsym failed %{public}s", __func__, dlerror());
275         dlclose(stub->dlHandler);
276         OsalMemFree(stub);
277         return NULL;
278     }
279 
280     serviceConstructFunc(&stub->service);
281     return &stub->service;
282 }
283 
CodecCallbackTypeStubRelease(struct CodecCallbackType * instance)284 void CodecCallbackTypeStubRelease(struct CodecCallbackType *instance)
285 {
286     if (instance == NULL) {
287         HDF_LOGE("%{public}s: instance is null", __func__);
288         return;
289     }
290     struct CodecCallbackTypeStub *stub = CONTAINER_OF(instance, struct CodecCallbackTypeStub, service);
291     dlclose(stub->dlHandler);
292     if (stub->service.remote != NULL) {
293         HdfRemoteServiceRecycle(stub->service.remote);
294         stub->service.remote = NULL;
295     }
296     OsalMemFree(stub);
297 }