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_service.h"
16 #include <hdf_base.h>
17 #include <osal_mem.h>
18 #include <securec.h>
19 #include <unistd.h>
20 #include "codec_adapter_interface.h"
21 #include "codec_component_capability_config.h"
22 #include "codec_component_manager_stub.h"
23 #include "codec_component_type_service.h"
24 #include "codec_death_recipient.h"
25 #include "codec_log_wrapper.h"
26
27 #define MAX_COMPONENT_SIZE 32
28 struct CodecComponentManagerSerivce *g_service = NULL;
29 uint32_t g_componentId = 0;
30
OnRemoteServiceDied(struct HdfDeathRecipient *deathRecipient, struct HdfRemoteService *remote)31 static void OnRemoteServiceDied(struct HdfDeathRecipient *deathRecipient, struct HdfRemoteService *remote)
32 {
33 CleanRemoteServiceResource(deathRecipient, remote);
34 }
35
36 static struct RemoteServiceDeathRecipient g_deathRecipient = {
37 .recipient = {
38 .OnRemoteDied = OnRemoteServiceDied,
39 }
40 };
41
AddDeathRecipientForService(struct CodecCallbackType *callbacks, uint32_t componentId, struct CodecComponentNode *codecNode)42 static void AddDeathRecipientForService(struct CodecCallbackType *callbacks, uint32_t componentId,
43 struct CodecComponentNode *codecNode)
44 {
45 if (callbacks == NULL) {
46 CODEC_LOGE("invalid parameter");
47 return;
48 }
49 bool needAdd = RegisterService(callbacks, componentId, codecNode);
50 if (needAdd) {
51 CODEC_LOGI("add deathRecipient for remoteService!");
52 HdfRemoteServiceAddDeathRecipient(callbacks->remote, &g_deathRecipient.recipient);
53 }
54 }
55
GetNextComponentIdnull56 static uint32_t GetNextComponentId()
57 {
58 uint32_t tempId = 0;
59 if (g_service == NULL) {
60 return tempId;
61 }
62 struct ComponentTypeNode *pos = NULL;
63 struct ComponentTypeNode *next = NULL;
64 bool find = false;
65
66 do {
67 tempId = ++g_componentId;
68 find = false;
69 DLIST_FOR_EACH_ENTRY_SAFE(pos, next, &g_service->head, struct ComponentTypeNode, node)
70 {
71 if (pos != NULL && tempId == pos->componentId) {
72 find = true;
73 break;
74 }
75 }
76 } while (find);
77 return tempId;
78 }
79
OmxManagerGetComponentNumnull80 static int32_t OmxManagerGetComponentNum()
81 {
82 int32_t num = 0;
83 if (GetComponentNum(&num) != HDF_SUCCESS) {
84 CODEC_LOGE("GetComponentNum error!");
85 }
86 return num;
87 }
88
OmxManagerGetComponentCapabilityList(CodecCompCapability *capList, int32_t count)89 static int32_t OmxManagerGetComponentCapabilityList(CodecCompCapability *capList, int32_t count)
90 {
91 int32_t err = GetComponentCapabilityList(capList, count);
92 if (err != HDF_SUCCESS) {
93 CODEC_LOGE("GetComponentNum error!");
94 }
95 return err;
96 }
97
OmxManagerDestroyComponent(uint32_t componentId)98 static int32_t OmxManagerDestroyComponent(uint32_t componentId)
99 {
100 CODEC_LOGI("service impl, %{public}d!", componentId);
101 if (g_service == NULL) {
102 CODEC_LOGE("g_service is not init!");
103 return HDF_ERR_INVALID_PARAM;
104 }
105
106 struct ComponentTypeNode *pos = NULL;
107 struct ComponentTypeNode *next = NULL;
108 int32_t err = HDF_SUCCESS;
109 pthread_mutex_lock(&g_service->listMute);
110
111 DLIST_FOR_EACH_ENTRY_SAFE(pos, next, &g_service->head, struct ComponentTypeNode, node)
112 {
113 if (pos == NULL || componentId != pos->componentId) {
114 continue;
115 }
116
117 struct CodecComponentNode *codecNode = CodecComponentTypeServiceGetCodecNode(pos->service);
118 if (codecNode != NULL) {
119 err = OmxAdapterDestroyComponent(codecNode);
120 if (err != HDF_SUCCESS) {
121 CODEC_LOGE("OmxAdapterDestroyComponent ret err[%{public}d]!", err);
122 break;
123 }
124 RemoveDestoryedComponent(componentId);
125 }
126
127 DListRemove(&pos->node);
128 CodecComponentTypeServiceRelease(pos->service);
129 OsalMemFree(pos);
130 pos = NULL;
131 break;
132 }
133
134 pthread_mutex_unlock(&g_service->listMute);
135 return err;
136 }
137
OmxManagerCreateComponent(struct CodecComponentType **component, uint32_t *componentId, char *compName, int64_t appData, struct CodecCallbackType *callbacks)138 static int32_t OmxManagerCreateComponent(struct CodecComponentType **component, uint32_t *componentId, char *compName,
139 int64_t appData, struct CodecCallbackType *callbacks)
140 {
141 CODEC_LOGI("service impl!");
142 if (g_service == NULL) {
143 CODEC_LOGE("g_service is not init!");
144 return HDF_ERR_INVALID_PARAM;
145 }
146
147 struct CodecComponentType *comp = CodecComponentTypeServiceGet();
148 if (comp == NULL) {
149 CODEC_LOGE("CodecComponentTypeServiceGet ret null!");
150 return HDF_ERR_INVALID_PARAM;
151 }
152
153 struct ComponentTypeNode *node = (struct ComponentTypeNode *)OsalMemCalloc(sizeof(struct ComponentTypeNode));
154 if (node == NULL) {
155 CODEC_LOGE("CodecComponentTypeServiceGet ret null!");
156 CodecComponentTypeServiceRelease(comp);
157 return HDF_ERR_INVALID_PARAM;
158 }
159
160 struct CodecComponentNode *codecNode = NULL;
161 int32_t err = OMXAdapterCreateComponent(&codecNode, compName, appData, callbacks);
162 if (err != HDF_SUCCESS) {
163 CODEC_LOGE("OMXAdapterCreateComponent err [%{public}x]", err);
164 CodecComponentTypeServiceRelease(comp);
165 OsalMemFree(node);
166 return HDF_ERR_INVALID_PARAM;
167 }
168 *component = comp;
169 pthread_mutex_lock(&g_service->listMute);
170 *componentId = GetNextComponentId();
171 CodecComponentTypeServiceSetCodecNode(comp, codecNode);
172 DListInsertTail(&node->node, &g_service->head);
173 pthread_mutex_unlock(&g_service->listMute);
174 node->componentId = *componentId;
175 node->service = comp;
176 #ifdef SUPPORT_ROLE
177 err = OmxAdapterSetComponentRole(codecNode, compName);
178 if (err != HDF_SUCCESS) {
179 CODEC_LOGE("OMXAdapterSetComponentRole err [%{public}x]", err);
180 OmxManagerDestroyComponent(*componentId);
181 CodecComponentTypeServiceRelease(comp);
182 OsalMemFree(node);
183 return HDF_ERR_INVALID_PARAM;
184 }
185 #endif
186 CODEC_LOGI("componentId:%{public}d", node->componentId);
187 AddDeathRecipientForService(callbacks, *componentId, codecNode);
188 return err;
189 }
190
CodecComponentManagerServiceConstruct(struct CodecComponentManager *manager)191 static void CodecComponentManagerServiceConstruct(struct CodecComponentManager *manager)
192 {
193 if (manager != NULL) {
194 manager->GetComponentNum = OmxManagerGetComponentNum;
195 manager->GetComponentCapabilityList = OmxManagerGetComponentCapabilityList;
196 manager->CreateComponent = OmxManagerCreateComponent;
197 manager->DestroyComponent = OmxManagerDestroyComponent;
198 }
199 }
200
CodecComponentManagerSerivceGet(void)201 struct CodecComponentManagerSerivce *CodecComponentManagerSerivceGet(void)
202 {
203 if (g_service == NULL) {
204 g_service = (struct CodecComponentManagerSerivce *)OsalMemCalloc(sizeof(struct CodecComponentManagerSerivce));
205 if (g_service == NULL) {
206 CODEC_LOGE("malloc OmxComponentManagerService obj failed!");
207 return NULL;
208 }
209 DListHeadInit(&g_service->head);
210 if (!CodecComponentManagerStubConstruct(&g_service->stub)) {
211 CODEC_LOGE("construct SampleStub obj failed!");
212 OmxComponentManagerSeriveRelease(g_service);
213 g_service = NULL;
214 }
215 CodecComponentManagerServiceConstruct(&g_service->stub.interface);
216 }
217 return g_service;
218 }
219
OmxComponentManagerSeriveRelease(struct CodecComponentManagerSerivce *instance)220 void OmxComponentManagerSeriveRelease(struct CodecComponentManagerSerivce *instance)
221 {
222 if (instance == NULL) {
223 return;
224 }
225 if (g_service == instance) {
226 g_service = NULL;
227 }
228 OsalMemFree(instance);
229 }
230
CleanRemoteServiceResource(struct HdfDeathRecipient *deathRecipient, struct HdfRemoteService *remote)231 void CleanRemoteServiceResource(struct HdfDeathRecipient *deathRecipient, struct HdfRemoteService *remote)
232 {
233 uint32_t compIds[MAX_COMPONENT_SIZE];
234 uint32_t size = 0;
235 int32_t ret = CleanMapperOfDiedService(remote, compIds, &size);
236 if (ret != HDF_SUCCESS) {
237 CODEC_LOGE("clearn remote resource error!");
238 return;
239 }
240
241 if (size == 0) {
242 CODEC_LOGE("remoteService no componment resource need to be release!");
243 return;
244 }
245 for (uint32_t i = 0; i < size; i++) {
246 OmxManagerDestroyComponent(compIds[i]);
247 CODEC_LOGI("destroyComponent done, compId=[%{public}d]", compIds[i]);
248 }
249
250 CODEC_LOGI("remote service died , clean resource success!");
251 }