// This will find the library and UUID tags of the sub effect pointed by the // node, gets the effect descriptor and lib_entry_t and adds the subeffect - // sub_entry_t to the gSubEffectList int addSubEffect(cnode *root) { ALOGV("addSubEffect"); cnode *node; effect_uuid_t uuid; effect_descriptor_t *d; lib_entry_t *l; list_elem_t *e; node = config_find(root, LIBRARY_TAG); if (node == NULL) { return -EINVAL; } l = getLibrary(node->value); if (l == NULL) { ALOGW("addSubEffect() could not get library %s", node->value); return -EINVAL; } node = config_find(root, UUID_TAG); if (node == NULL) { return -EINVAL; } if (stringToUuid(node->value, &uuid) != 0) { ALOGW("addSubEffect() invalid uuid %s", node->value); return -EINVAL; } d = malloc(sizeof(effect_descriptor_t)); if (l->desc->get_descriptor(&uuid, d) != 0) { char s[40]; uuidToString(&uuid, s, 40); ALOGW("Error querying effect %s on lib %s", s, l->name); free(d); return -EINVAL; } #if (LOG_NDEBUG==0) char s[256]; dumpEffectDescriptor(d, s, 256); ALOGV("addSubEffect() read descriptor %p:%s",d, s); #endif if (EFFECT_API_VERSION_MAJOR(d->apiVersion) != EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) { ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name); free(d); return -EINVAL; } sub_effect_entry_t *sub_effect = malloc(sizeof(sub_effect_entry_t)); sub_effect->object = d; // lib_entry_t is stored since the sub effects are not linked to the library sub_effect->lib = l; e = malloc(sizeof(list_elem_t)); e->object = sub_effect; e->next = gSubEffectList->sub_elem; gSubEffectList->sub_elem = e; ALOGV("addSubEffect end"); return 0; }
int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor) { int ret = init(); if (ret < 0) { return ret; } if (pDescriptor == NULL || index >= gNumEffects) { return -EINVAL; } if (gCanQueryEffect == 0) { return -ENOSYS; } pthread_mutex_lock(&gLibLock); ret = -ENOENT; if (index < gCurEffectIdx) { resetEffectEnumeration(); } while (gCurLib) { if (gCurEffect) { if (index == gCurEffectIdx) { memcpy(pDescriptor, gCurEffect->object, sizeof(effect_descriptor_t)); ret = 0; break; } else { gCurEffect = gCurEffect->next; gCurEffectIdx++; } } else { gCurLib = gCurLib->next; gCurEffect = ((lib_entry_t *)gCurLib->object)->effects; } } #if (LOG_NDEBUG == 0) char str[256]; dumpEffectDescriptor(pDescriptor, str, 256); LOGV("EffectQueryEffect() desc:%s", str); #endif pthread_mutex_unlock(&gLibLock); return ret; }
int loadLibrary(const char *libPath, int *handle) { void *hdl; effect_QueryNumberEffects_t queryNumFx; effect_QueryEffect_t queryFx; effect_CreateEffect_t createFx; effect_ReleaseEffect_t releaseFx; uint32_t numFx; uint32_t fx; int ret; list_elem_t *e, *descHead = NULL; lib_entry_t *l; if (handle == NULL) { return -EINVAL; } *handle = 0; hdl = dlopen(libPath, RTLD_NOW); if (hdl == 0) { LOGW("could open lib %s", libPath); return -ENODEV; } // Check functions availability queryNumFx = (effect_QueryNumberEffects_t)dlsym(hdl, "EffectQueryNumberEffects"); if (queryNumFx == NULL) { LOGW("could not get EffectQueryNumberEffects from lib %s", libPath); ret = -ENODEV; goto error; } queryFx = (effect_QueryEffect_t)dlsym(hdl, "EffectQueryEffect"); if (queryFx == NULL) { LOGW("could not get EffectQueryEffect from lib %s", libPath); ret = -ENODEV; goto error; } createFx = (effect_CreateEffect_t)dlsym(hdl, "EffectCreate"); if (createFx == NULL) { LOGW("could not get EffectCreate from lib %s", libPath); ret = -ENODEV; goto error; } releaseFx = (effect_ReleaseEffect_t)dlsym(hdl, "EffectRelease"); if (releaseFx == NULL) { LOGW("could not get EffectRelease from lib %s", libPath); ret = -ENODEV; goto error; } // load effect descriptors ret = queryNumFx(&numFx); if (ret) { goto error; } for (fx = 0; fx < numFx; fx++) { effect_descriptor_t *d = malloc(sizeof(effect_descriptor_t)); if (d == NULL) { ret = -ENOMEM; goto error; } ret = queryFx(fx, d); if (ret == 0) { #if (LOG_NDEBUG==0) char s[256]; dumpEffectDescriptor(d, s, 256); LOGV("loadLibrary() read descriptor %p:%s",d, s); #endif if (d->apiVersion != EFFECT_API_VERSION) { LOGW("Bad API version %04x on lib %s", d->apiVersion, libPath); free(d); continue; } e = malloc(sizeof(list_elem_t)); if (e == NULL) { free(d); ret = -ENOMEM; goto error; } e->object = d; e->next = descHead; descHead = e; } else { LOGW("Error querying effect # %d on lib %s", fx, libPath); } } pthread_mutex_lock(&gLibLock); // add entry for library in gLibraryList l = malloc(sizeof(lib_entry_t)); l->id = ++gNextLibId; l->handle = hdl; strncpy(l->path, libPath, PATH_MAX); l->createFx = createFx; l->releaseFx = releaseFx; l->effects = descHead; pthread_mutex_init(&l->lock, NULL); e = malloc(sizeof(list_elem_t)); e->next = gLibraryList; e->object = l; gLibraryList = e; pthread_mutex_unlock(&gLibLock); LOGV("loadLibrary() linked library %p", l); *handle = l->id; return 0; error: LOGW("loadLibrary() error: %d on lib: %s", ret, libPath); while (descHead) { free(descHead->object); e = descHead->next; free(descHead); descHead = e;; } dlclose(hdl); return ret; }
int loadEffect(cnode *root) { cnode *node; effect_uuid_t uuid; lib_entry_t *l; effect_descriptor_t *d; list_elem_t *e; node = config_find(root, LIBRARY_TAG); if (node == NULL) { return -EINVAL; } l = getLibrary(node->value); if (l == NULL) { ALOGW("loadEffect() could not get library %s", node->value); return -EINVAL; } node = config_find(root, UUID_TAG); if (node == NULL) { return -EINVAL; } if (stringToUuid(node->value, &uuid) != 0) { ALOGW("loadEffect() invalid uuid %s", node->value); return -EINVAL; } d = malloc(sizeof(effect_descriptor_t)); if (!d) { ALOGE("failed to allocate effect descriptor"); return -EINVAL; } if (l->desc->get_descriptor(&uuid, d) != 0) { char s[40]; uuidToString(&uuid, s, 40); ALOGW("Error querying effect %s on lib %s", s, l->name); free(d); return -EINVAL; } #if (LOG_NDEBUG==0) char s[256]; dumpEffectDescriptor(d, s, 256); ALOGV("loadEffect() read descriptor %p:%s",d, s); #endif if (EFFECT_API_VERSION_MAJOR(d->apiVersion) != EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) { ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name); free(d); return -EINVAL; } e = malloc(sizeof(list_elem_t)); if (!e) { return -ENOMEM; } e->object = d; e->next = l->effects; l->effects = e; // After the UUID node in the config_tree, if node->next is valid, // that would be sub effect node. // Find the sub effects and add them to the gSubEffectList node = node->next; int count = 2; bool hwSubefx = false, swSubefx = false; list_sub_elem_t *sube = NULL; if (node != NULL) { ALOGV("Adding the effect to gEffectSubList as there are sub effects"); sube = malloc(sizeof(list_sub_elem_t)); if (!sube) { ALOGE("failed to allocate sub element list"); return -ENOMEM; } sube->object = d; sube->sub_elem = NULL; sube->next = gSubEffectList; gSubEffectList = sube; } while (node != NULL && count) { if (addSubEffect(node)) { ALOGW("loadEffect() could not add subEffect %s", node->value); // Change the gSubEffectList to point to older list; gSubEffectList = sube->next; free(sube->sub_elem);// Free an already added sub effect sube->sub_elem = NULL; free(sube); return -ENOENT; } sub_effect_entry_t *subEntry = (sub_effect_entry_t*)gSubEffectList->sub_elem->object; effect_descriptor_t *subEffectDesc = (effect_descriptor_t*)(subEntry->object); // Since we return a dummy descriptor for the proxy during // get_descriptor call,we replace it with the correspoding // sw effect descriptor, but with Proxy UUID // check for Sw desc if (!((subEffectDesc->flags & EFFECT_FLAG_HW_ACC_MASK) == EFFECT_FLAG_HW_ACC_TUNNEL)) { swSubefx = true; *d = *subEffectDesc; d->uuid = uuid; ALOGV("loadEffect() Changed the Proxy desc"); } else hwSubefx = true; count--; node = node->next; } // 1 HW and 1 SW sub effect found. Set the offload flag in the Proxy desc if (hwSubefx && swSubefx) { d->flags |= EFFECT_FLAG_OFFLOAD_SUPPORTED; } return 0; }