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