static int path_add_path(struct mixer_path *path, struct mixer_path *sub_path) { unsigned int i; for (i = 0; i < sub_path->length; i++) if (path_add_setting(path, &sub_path->setting[i]) < 0) return -1; return 0; }
static int path_add_path(struct audio_route *ar, struct mixer_path *path, struct mixer_path *sub_path) { unsigned int i; for (i = 0; i < sub_path->length; i++) { if (path_add_setting(ar, path, &sub_path->setting[i]) < 0) return -1; } return 0; }
static void start_tag(void *data, const XML_Char *tag_name, const XML_Char **attr) { const XML_Char *attr_name = NULL; const XML_Char *attr_value = NULL; const XML_Char *attr_ignore = NULL; char *sub_attr_value; struct config_parse_state *state = data; struct audio_route *ar = state->ar; unsigned int i; unsigned int j; unsigned int k; struct mixer_ctl *ctl; int values[MAX_CTL_VALS]; unsigned int num_values; unsigned int num_ctl_vals; struct mixer_setting mixer_setting; unsigned ignored = 0; /* Get name, type and value attributes (these may be empty) */ for (i = 0; attr[i]; i += 2) { if (strcmp(attr[i], "name") == 0) attr_name = attr[i + 1]; else if (strcmp(attr[i], "value") == 0) attr_value = attr[i + 1]; else if (strcmp(attr[i], "ignore") == 0) attr_ignore = attr[i + 1]; } if (attr_ignore && strcmp(attr_ignore, "1") == 0) { ignored = 1; } /* Look at tags */ if (strcmp(tag_name, "path") == 0) { if (attr_name == NULL) { ALOGE("Unnamed path!"); } else { if (state->level == 1) { /* top level path: create and stash the path */ state->path = path_create(ar, (char *)attr_name); } else { /* nested path */ struct mixer_path *sub_path = path_get_by_name(ar, attr_name); path_add_path(state->path, sub_path); } } } else if (strcmp(tag_name, "ctl") == 0 && state->level == 1 && ignored) { /* Obtain the mixer ctl and value */ ctl = mixer_get_ctl_by_name(ar->mixer, attr_name); /* locate the mixer ctl in the list */ for (i = 0; i < ar->num_mixer_ctls; i++) { if (ar->mixer_state[i].ctl == ctl) break; } ar->mixer_state[i].ignored = 1; } else if (strcmp(tag_name, "ctl") == 0) { /* Obtain the mixer ctl and value */ ctl = mixer_get_ctl_by_name(ar->mixer, attr_name); switch (mixer_ctl_get_type(ctl)) { case MIXER_CTL_TYPE_BOOL: case MIXER_CTL_TYPE_INT: /* TODO */ num_values = 1; char *sub_attr_value; for (j = 0; j < strlen((char*)attr_value); j++) { if (attr_value[j] == ',') num_values++; } sub_attr_value = (char*)attr_value; k = strlen((char*)attr_value); for (j = 0; j < k; j++) { if (sub_attr_value[j] == ',') sub_attr_value[j] = '\0'; } sub_attr_value = (char*)attr_value; for (j = 0; j < num_values; j++) { values[j] = atoi(sub_attr_value); #if 1 ALOGV("attr='%s' idx=%u str='%s' val=%d", attr_name, j, sub_attr_value, values[j]); #endif sub_attr_value += (strlen(sub_attr_value) + 1); } break; case MIXER_CTL_TYPE_ENUM: num_values = 1; values[0] = mixer_enum_string_to_value(ctl, (char *)attr_value); ALOGV("attr='%s' attr_val='%s' val=%d", attr_name, attr_value, values[0]); break; default: num_values = 1; values[0] = 0; ALOGV("attr='%s' UNKNOWN CTL TYPE", attr_name); break; } if (state->level == 1) { /* top level ctl (initial setting) */ /* locate the mixer ctl in the list */ for (i = 0; i < ar->num_mixer_ctls; i++) { if (ar->mixer_state[i].ctl == ctl) break; } /* apply the new value */ ar->mixer_state[i].ignored = 0; ar->mixer_state[i].ctl_vals = num_values; for (j = 0; j < num_values; j++) { ar->mixer_state[i].new_value[j] = values[j]; } } else { /* nested ctl (within a path) */ mixer_setting.ctl = ctl; mixer_setting.ctl_vals = num_values; for (j = 0; j < num_values; j++) { mixer_setting.value[j] = values[j]; } path_add_setting(state->path, &mixer_setting); } } state->level++; }
static void start_tag(void *data, const XML_Char *tag_name, const XML_Char **attr) { const XML_Char *attr_name = NULL; const XML_Char *attr_value = NULL; struct config_parse_state *state = data; struct audio_route *ar = state->ar; unsigned int i; struct mixer_ctl *ctl; int value = 0; struct mixer_setting mixer_setting; struct mixer_path *new_mixer_path = NULL; /* Get name, type and value attributes (these may be empty) */ for (i = 0; attr[i]; i += 2) { if (strcmp(attr[i], "name") == 0) attr_name = attr[i + 1]; else if (strcmp(attr[i], "value") == 0) attr_value = attr[i + 1]; } /* Look at tags */ if (strcmp(tag_name, "path") == 0) { if (attr_name == NULL) { ALOGE("Unnamed path!"); } else { if (state->level == 1) { /* top level path: create and stash the path */ new_mixer_path = path_create(ar, (char *)attr_name); if (new_mixer_path != NULL) state->path = new_mixer_path; } else { /* nested path */ struct mixer_path *sub_path = path_get_by_name(ar, attr_name); if (sub_path != NULL) path_add_path(state->path, sub_path); } } } else if (strcmp(tag_name, "ctl") == 0) { if (attr_name == NULL) { ALOGE("Unnamed ctl!"); } else { /* Obtain the mixer ctl and value */ ctl = mixer_get_ctl_by_name(ar->mixer, attr_name); switch (mixer_ctl_get_type(ctl)) { case MIXER_CTL_TYPE_BOOL: case MIXER_CTL_TYPE_INT: if (attr_value != NULL) value = atoi((char *)attr_value); break; case MIXER_CTL_TYPE_ENUM: if (attr_value != NULL) value = mixer_enum_string_to_value(ctl, (char *)attr_value); break; default: value = 0; break; } if (state->level == 1) { /* top level ctl (initial setting) */ /* locate the mixer ctl in the list */ for (i = 0; i < ar->num_mixer_ctls; i++) { if (ar->mixer_state[i].ctl == ctl) break; } if (i < ar->num_mixer_ctls) { /* apply the new value */ ar->mixer_state[i].new_value = value; } } else { /* nested ctl (within a path) */ mixer_setting.ctl = ctl; mixer_setting.value = value; path_add_setting(state->path, &mixer_setting); } } } state->level++; }