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_id = NULL; const XML_Char *attr_value = NULL; struct config_parse_state *state = data; struct audio_route *ar = state->ar; unsigned int i; unsigned int ctl_index; struct mixer_ctl *ctl; int value; unsigned int id; struct mixer_value mixer_value; /* Get name, id 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]; if (strcmp(attr[i], "id") == 0) attr_id = 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 */ 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(ar, state->path, sub_path); } } } else if (strcmp(tag_name, "ctl") == 0) { /* Obtain the mixer ctl and value */ ctl = mixer_get_ctl_by_name(ar->mixer, attr_name); if (ctl == NULL) { ALOGE("Control '%s' doesn't exist - skipping", attr_name); goto done; } switch (mixer_ctl_get_type(ctl)) { case MIXER_CTL_TYPE_BOOL: case MIXER_CTL_TYPE_INT: value = atoi((char *)attr_value); break; case MIXER_CTL_TYPE_ENUM: value = mixer_enum_string_to_value(ctl, (char *)attr_value); break; default: value = 0; break; } /* locate the mixer ctl in the list */ for (ctl_index = 0; ctl_index < ar->num_mixer_ctls; ctl_index++) { if (ar->mixer_state[ctl_index].ctl == ctl) break; } if (state->level == 1) { /* top level ctl (initial setting) */ /* apply the new value */ if (attr_id) { /* set only one value */ id = atoi((char *)attr_id); if (id < ar->mixer_state[ctl_index].num_values) ar->mixer_state[ctl_index].new_value[id] = value; else ALOGE("value id out of range for mixer ctl '%s'", mixer_ctl_get_name(ctl)); } else { /* set all values the same */ for (i = 0; i < ar->mixer_state[ctl_index].num_values; i++) ar->mixer_state[ctl_index].new_value[i] = value; } } else { /* nested ctl (within a path) */ mixer_value.ctl_index = ctl_index; mixer_value.value = value; if (attr_id) mixer_value.index = atoi((char *)attr_id); else mixer_value.index = -1; path_add_value(ar, state->path, &mixer_value); } } done: 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; 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++; }