summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Hung <hunga@google.com>2016-03-07 14:57:15 -0800
committerAndy Hung <hunga@google.com>2016-03-17 11:32:46 -0700
commit96247d261abb53418a646873b527715a8ba9bb95 (patch)
tree61078d8e49c9aeb35d703557d14cc1f381cd08f0
parent8b867934df43494b07c6d51aa6feab17cd64b3d2 (diff)
downloadandroid_system_media-96247d261abb53418a646873b527715a8ba9bb95.tar.gz
android_system_media-96247d261abb53418a646873b527715a8ba9bb95.tar.bz2
android_system_media-96247d261abb53418a646873b527715a8ba9bb95.zip
Update audio_route to properly handle long values
Required for 64 bit audioserver. Bug: 27479136 Change-Id: Ic6f2d047648898fcbac43f325020d331f349c718
-rw-r--r--audio_route/audio_route.c152
1 files changed, 86 insertions, 66 deletions
diff --git a/audio_route/audio_route.c b/audio_route/audio_route.c
index af1abca9..99db0ee5 100644
--- a/audio_route/audio_route.c
+++ b/audio_route/audio_route.c
@@ -33,7 +33,8 @@
#define INITIAL_MIXER_PATH_SIZE 8
union ctl_values {
- int *integer;
+ int *enumerated;
+ long *integer;
void *ptr;
unsigned char *bytes;
};
@@ -56,7 +57,7 @@ struct mixer_setting {
struct mixer_value {
unsigned int ctl_index;
int index;
- int value;
+ long value;
};
struct mixer_path {
@@ -97,6 +98,25 @@ static bool is_supported_ctl_type(enum mixer_ctl_type type)
}
}
+/* as they match in alsa */
+static size_t sizeof_ctl_type(enum mixer_ctl_type type) {
+ switch (type) {
+ case MIXER_CTL_TYPE_BOOL:
+ case MIXER_CTL_TYPE_INT:
+ return sizeof(long);
+ case MIXER_CTL_TYPE_ENUM:
+ return sizeof(int);
+ case MIXER_CTL_TYPE_BYTE:
+ return sizeof(unsigned char);
+ case MIXER_CTL_TYPE_INT64:
+ case MIXER_CTL_TYPE_IEC958:
+ case MIXER_CTL_TYPE_UNKNOWN:
+ default:
+ LOG_ALWAYS_FATAL("Unsupported mixer ctl type: %d, check type before calling", (int)type);
+ return 0;
+ }
+}
+
static inline struct mixer_ctl *index_to_ctl(struct audio_route *ar,
unsigned int ctl_index)
{
@@ -116,9 +136,12 @@ static void path_print(struct audio_route *ar, struct mixer_path *path)
if (mixer_ctl_get_type(ctl) == MIXER_CTL_TYPE_BYTE) {
for (j = 0; j < path->setting[i].num_values; j++)
ALOGE(" id=%d value=0x%02x", j, path->setting[i].value.bytes[j]);
+ } else if (mixer_ctl_get_type(ctl) == MIXER_CTL_TYPE_ENUM) {
+ for (j = 0; j < path->setting[i].num_values; j++)
+ ALOGE(" id=%d value=%d", j, path->setting[i].value.enumerated[j]);
} else {
for (j = 0; j < path->setting[i].num_values; j++)
- ALOGE(" id=%d value=%d", j, path->setting[i].value.integer[j]);
+ ALOGE(" id=%d value=%ld", j, path->setting[i].value.integer[j]);
}
}
}
@@ -231,7 +254,6 @@ static int path_add_setting(struct audio_route *ar, struct mixer_path *path,
struct mixer_setting *setting)
{
int path_index;
- unsigned int value_sz = sizeof(int);
if (find_ctl_index_in_path(path, setting->ctl_index) != -1) {
struct mixer_ctl *ctl = index_to_ctl(ar, setting->ctl_index);
@@ -241,6 +263,11 @@ static int path_add_setting(struct audio_route *ar, struct mixer_path *path,
return -1;
}
+ if (!is_supported_ctl_type(setting->type)) {
+ ALOGE("unsupported type %d", (int)setting->type);
+ return -1;
+ }
+
path_index = alloc_path_setting(path);
if (path_index < 0)
return -1;
@@ -249,10 +276,9 @@ static int path_add_setting(struct audio_route *ar, struct mixer_path *path,
path->setting[path_index].type = setting->type;
path->setting[path_index].num_values = setting->num_values;
- if (setting->type == MIXER_CTL_TYPE_BYTE)
- value_sz = sizeof(unsigned char);
+ size_t value_sz = sizeof_ctl_type(setting->type);
- path->setting[path_index].value.ptr = malloc(setting->num_values * value_sz);
+ path->setting[path_index].value.ptr = calloc(setting->num_values, value_sz);
/* copy all values */
memcpy(path->setting[path_index].value.ptr, setting->value.ptr,
setting->num_values * value_sz);
@@ -266,7 +292,6 @@ static int path_add_value(struct audio_route *ar, struct mixer_path *path,
unsigned int i;
int path_index;
unsigned int num_values;
- unsigned int value_sz = sizeof(int);
struct mixer_ctl *ctl;
/* Check that mixer value index is within range */
@@ -282,6 +307,11 @@ static int path_add_value(struct audio_route *ar, struct mixer_path *path,
if (path_index < 0) {
/* New path */
+ enum mixer_ctl_type type = mixer_ctl_get_type(ctl);
+ if (!is_supported_ctl_type(type)) {
+ ALOGE("unsupported type %d", (int)type);
+ return -1;
+ }
path_index = alloc_path_setting(path);
if (path_index < 0)
return -1;
@@ -289,14 +319,14 @@ static int path_add_value(struct audio_route *ar, struct mixer_path *path,
/* initialise the new path setting */
path->setting[path_index].ctl_index = mixer_value->ctl_index;
path->setting[path_index].num_values = num_values;
- path->setting[path_index].type = mixer_ctl_get_type(ctl);
-
- if (path->setting[path_index].type == MIXER_CTL_TYPE_BYTE)
- value_sz = sizeof(unsigned char);
+ path->setting[path_index].type = type;
- path->setting[path_index].value.ptr = malloc(num_values * value_sz);
+ size_t value_sz = sizeof_ctl_type(type);
+ path->setting[path_index].value.ptr = calloc(num_values, value_sz);
if (path->setting[path_index].type == MIXER_CTL_TYPE_BYTE)
path->setting[path_index].value.bytes[0] = mixer_value->value;
+ else if (path->setting[path_index].type == MIXER_CTL_TYPE_ENUM)
+ path->setting[path_index].value.enumerated[0] = mixer_value->value;
else
path->setting[path_index].value.integer[0] = mixer_value->value;
}
@@ -306,6 +336,9 @@ static int path_add_value(struct audio_route *ar, struct mixer_path *path,
if (path->setting[path_index].type == MIXER_CTL_TYPE_BYTE) {
for (i = 0; i < num_values; i++)
path->setting[path_index].value.bytes[i] = mixer_value->value;
+ } else if (path->setting[path_index].type == MIXER_CTL_TYPE_ENUM) {
+ for (i = 0; i < num_values; i++)
+ path->setting[path_index].value.enumerated[i] = mixer_value->value;
} else {
for (i = 0; i < num_values; i++)
path->setting[path_index].value.integer[i] = mixer_value->value;
@@ -314,6 +347,8 @@ static int path_add_value(struct audio_route *ar, struct mixer_path *path,
/* set only one value */
if (path->setting[path_index].type == MIXER_CTL_TYPE_BYTE)
path->setting[path_index].value.bytes[mixer_value->index] = mixer_value->value;
+ else if (path->setting[path_index].type == MIXER_CTL_TYPE_ENUM)
+ path->setting[path_index].value.enumerated[mixer_value->index] = mixer_value->value;
else
path->setting[path_index].value.integer[mixer_value->index] = mixer_value->value;
}
@@ -336,7 +371,6 @@ static int path_add_path(struct audio_route *ar, struct mixer_path *path,
static int path_apply(struct audio_route *ar, struct mixer_path *path)
{
unsigned int i;
- unsigned int value_sz;
unsigned int ctl_index;
struct mixer_ctl *ctl;
enum mixer_ctl_type type;
@@ -347,12 +381,7 @@ static int path_apply(struct audio_route *ar, struct mixer_path *path)
type = mixer_ctl_get_type(ctl);
if (!is_supported_ctl_type(type))
continue;
-
- if (type == MIXER_CTL_TYPE_BYTE)
- value_sz = sizeof(unsigned char);
- else
- value_sz = sizeof(int);
-
+ size_t value_sz = sizeof_ctl_type(type);
memcpy(ar->mixer_state[ctl_index].new_value.ptr, path->setting[i].value.ptr,
path->setting[i].num_values * value_sz);
}
@@ -364,7 +393,6 @@ static int path_reset(struct audio_route *ar, struct mixer_path *path)
{
unsigned int i;
unsigned int j;
- unsigned int value_sz;
unsigned int ctl_index;
struct mixer_ctl *ctl;
enum mixer_ctl_type type;
@@ -375,12 +403,7 @@ static int path_reset(struct audio_route *ar, struct mixer_path *path)
type = mixer_ctl_get_type(ctl);
if (!is_supported_ctl_type(type))
continue;
-
- if (type == MIXER_CTL_TYPE_BYTE)
- value_sz = sizeof(unsigned char);
- else
- value_sz = sizeof(int);
-
+ size_t value_sz = sizeof_ctl_type(type);
/* reset the value(s) */
memcpy(ar->mixer_state[ctl_index].new_value.ptr,
ar->mixer_state[ctl_index].reset_value.ptr,
@@ -415,7 +438,7 @@ static void start_tag(void *data, const XML_Char *tag_name,
unsigned int i;
unsigned int ctl_index;
struct mixer_ctl *ctl;
- int value;
+ long value;
unsigned int id;
struct mixer_value mixer_value;
enum mixer_ctl_type type;
@@ -457,7 +480,7 @@ static void start_tag(void *data, const XML_Char *tag_name,
switch (mixer_ctl_get_type(ctl)) {
case MIXER_CTL_TYPE_BOOL:
case MIXER_CTL_TYPE_INT:
- value = (int) strtol((char *)attr_value, NULL, 0);
+ value = strtol((char *)attr_value, NULL, 0);
break;
case MIXER_CTL_TYPE_BYTE:
value = (unsigned char) strtol((char *)attr_value, NULL, 16);
@@ -488,6 +511,8 @@ static void start_tag(void *data, const XML_Char *tag_name,
if (id < ar->mixer_state[ctl_index].num_values)
if (type == MIXER_CTL_TYPE_BYTE)
ar->mixer_state[ctl_index].new_value.bytes[id] = value;
+ else if (type == MIXER_CTL_TYPE_ENUM)
+ ar->mixer_state[ctl_index].new_value.enumerated[id] = value;
else
ar->mixer_state[ctl_index].new_value.integer[id] = value;
else
@@ -498,6 +523,8 @@ static void start_tag(void *data, const XML_Char *tag_name,
for (i = 0; i < ar->mixer_state[ctl_index].num_values; i++)
if (type == MIXER_CTL_TYPE_BYTE)
ar->mixer_state[ctl_index].new_value.bytes[i] = value;
+ else if (type == MIXER_CTL_TYPE_ENUM)
+ ar->mixer_state[ctl_index].new_value.enumerated[i] = value;
else
ar->mixer_state[ctl_index].new_value.integer[i] = value;
}
@@ -531,12 +558,11 @@ static int alloc_mixer_state(struct audio_route *ar)
unsigned int i;
unsigned int j;
unsigned int num_values;
- unsigned int value_sz;
struct mixer_ctl *ctl;
enum mixer_ctl_type type;
ar->num_mixer_ctls = mixer_get_num_ctls(ar->mixer);
- ar->mixer_state = malloc(ar->num_mixer_ctls * sizeof(struct mixer_state));
+ ar->mixer_state = calloc(ar->num_mixer_ctls, sizeof(struct mixer_state));
if (!ar->mixer_state)
return -1;
@@ -553,17 +579,13 @@ static int alloc_mixer_state(struct audio_route *ar)
if (!is_supported_ctl_type(type))
continue;
- if (type == MIXER_CTL_TYPE_BYTE)
- value_sz = sizeof(unsigned char);
- else
- value_sz = sizeof(int);
-
- ar->mixer_state[i].old_value.ptr = malloc(num_values * value_sz);
- ar->mixer_state[i].new_value.ptr = malloc(num_values * value_sz);
- ar->mixer_state[i].reset_value.ptr = malloc(num_values * value_sz);
+ size_t value_sz = sizeof_ctl_type(type);
+ ar->mixer_state[i].old_value.ptr = calloc(num_values, value_sz);
+ ar->mixer_state[i].new_value.ptr = calloc(num_values, value_sz);
+ ar->mixer_state[i].reset_value.ptr = calloc(num_values, value_sz);
if (type == MIXER_CTL_TYPE_ENUM)
- ar->mixer_state[i].old_value.integer[0] = mixer_ctl_get_value(ctl, 0);
+ ar->mixer_state[i].old_value.enumerated[0] = mixer_ctl_get_value(ctl, 0);
else
mixer_ctl_get_array(ctl, ar->mixer_state[i].old_value.ptr, num_values);
@@ -620,6 +642,14 @@ int audio_route_update_mixer(struct audio_route *ar)
break;
}
}
+ } else if (type == MIXER_CTL_TYPE_ENUM) {
+ for (j = 0; j < num_values; j++) {
+ if (ar->mixer_state[i].old_value.enumerated[j]
+ != ar->mixer_state[i].new_value.enumerated[j]) {
+ changed = true;
+ break;
+ }
+ }
} else {
for (j = 0; j < num_values; j++) {
if (ar->mixer_state[i].old_value.integer[j] != ar->mixer_state[i].new_value.integer[j]) {
@@ -629,16 +659,12 @@ int audio_route_update_mixer(struct audio_route *ar)
}
}
if (changed) {
- unsigned int value_sz = sizeof(int);
-
- if (type == MIXER_CTL_TYPE_BYTE)
- value_sz = sizeof(unsigned char);
-
if (type == MIXER_CTL_TYPE_ENUM)
- mixer_ctl_set_value(ctl, 0, ar->mixer_state[i].new_value.integer[0]);
+ mixer_ctl_set_value(ctl, 0, ar->mixer_state[i].new_value.enumerated[0]);
else
mixer_ctl_set_array(ctl, ar->mixer_state[i].new_value.ptr, num_values);
+ size_t value_sz = sizeof_ctl_type(type);
memcpy(ar->mixer_state[i].old_value.ptr, ar->mixer_state[i].new_value.ptr,
num_values * value_sz);
}
@@ -651,7 +677,6 @@ int audio_route_update_mixer(struct audio_route *ar)
static void save_mixer_state(struct audio_route *ar)
{
unsigned int i;
- unsigned int value_sz;
enum mixer_ctl_type type;
for (i = 0; i < ar->num_mixer_ctls; i++) {
@@ -659,11 +684,7 @@ static void save_mixer_state(struct audio_route *ar)
if (!is_supported_ctl_type(type))
continue;
- if (type == MIXER_CTL_TYPE_BYTE)
- value_sz = sizeof(unsigned char);
- else
- value_sz = sizeof(int);
-
+ size_t value_sz = sizeof_ctl_type(type);
memcpy(ar->mixer_state[i].reset_value.ptr, ar->mixer_state[i].new_value.ptr,
ar->mixer_state[i].num_values * value_sz);
}
@@ -673,7 +694,6 @@ static void save_mixer_state(struct audio_route *ar)
void audio_route_reset(struct audio_route *ar)
{
unsigned int i;
- unsigned int value_sz;
enum mixer_ctl_type type;
/* load all of the saved values */
@@ -682,11 +702,7 @@ void audio_route_reset(struct audio_route *ar)
if (!is_supported_ctl_type(type))
continue;
- if (type == MIXER_CTL_TYPE_BYTE)
- value_sz = sizeof(unsigned char);
- else
- value_sz = sizeof(int);
-
+ size_t value_sz = sizeof_ctl_type(type);
memcpy(ar->mixer_state[i].new_value.ptr, ar->mixer_state[i].reset_value.ptr,
ar->mixer_state[i].num_values * value_sz);
}
@@ -771,21 +787,25 @@ static int audio_route_update_path(struct audio_route *ar, const char *name, boo
continue;
}
+ size_t value_sz = sizeof_ctl_type(type);
/* if any value has changed, update the mixer */
for (j = 0; j < ms->num_values; j++) {
if (type == MIXER_CTL_TYPE_BYTE) {
if (ms->old_value.bytes[j] != ms->new_value.bytes[j]) {
mixer_ctl_set_array(ms->ctl, ms->new_value.bytes, ms->num_values);
- memcpy(ms->old_value.bytes, ms->new_value.bytes, ms->num_values);
+ memcpy(ms->old_value.bytes, ms->new_value.bytes, ms->num_values * value_sz);
break;
}
- }
- else if (ms->old_value.integer[j] != ms->new_value.integer[j]) {
- if (type == MIXER_CTL_TYPE_ENUM)
- mixer_ctl_set_value(ms->ctl, 0, ms->new_value.integer[0]);
- else
- mixer_ctl_set_array(ms->ctl, ms->new_value.integer, ms->num_values);
- memcpy(ms->old_value.integer, ms->new_value.integer, ms->num_values * sizeof(int));
+ } else if (type == MIXER_CTL_TYPE_ENUM) {
+ if (ms->old_value.enumerated[j] != ms->new_value.enumerated[j]) {
+ mixer_ctl_set_value(ms->ctl, 0, ms->new_value.enumerated[0]);
+ memcpy(ms->old_value.enumerated, ms->new_value.enumerated,
+ ms->num_values * value_sz);
+ break;
+ }
+ } else if (ms->old_value.integer[j] != ms->new_value.integer[j]) {
+ mixer_ctl_set_array(ms->ctl, ms->new_value.integer, ms->num_values);
+ memcpy(ms->old_value.integer, ms->new_value.integer, ms->num_values * value_sz);
break;
}
}