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 28struct CodecComponentManagerSerivce *g_service = NULL; 29uint32_t g_componentId = 0; 30 31static void OnRemoteServiceDied(struct HdfDeathRecipient *deathRecipient, struct HdfRemoteService *remote) 32{ 33 CleanRemoteServiceResource(deathRecipient, remote); 34} 35 36static struct RemoteServiceDeathRecipient g_deathRecipient = { 37 .recipient = { 38 .OnRemoteDied = OnRemoteServiceDied, 39 } 40}; 41 42static 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 56static 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 80static 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 89static 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 98static 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 138static 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 191static 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 201struct 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 220void 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 231void 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}