bluez5: use save flag in profile

Add SPA_PARAM_PROFILE_save to current profile information, and handle it
properly in set_param and when setting profile.
This commit is contained in:
Pauli Virtanen 2022-01-06 16:26:11 +02:00
parent 41392eda7f
commit 38c8a19d9e

View file

@ -137,6 +137,7 @@ struct impl {
uint32_t profile;
unsigned int switching_codec:1;
unsigned int save_profile:1;
uint32_t prev_bt_connected_profiles;
const struct a2dp_codec **supported_codecs;
@ -757,7 +758,7 @@ static void emit_remove_nodes(struct impl *this)
static bool validate_profile(struct impl *this, uint32_t profile,
enum spa_bluetooth_audio_codec codec);
static int set_profile(struct impl *this, uint32_t profile, enum spa_bluetooth_audio_codec codec)
static int set_profile(struct impl *this, uint32_t profile, enum spa_bluetooth_audio_codec codec, bool save)
{
if (!validate_profile(this, profile, codec)) {
spa_log_warn(this->log, "trying to set invalid profile %d, codec %d, %08x %08x",
@ -766,6 +767,8 @@ static int set_profile(struct impl *this, uint32_t profile, enum spa_bluetooth_a
return -EINVAL;
}
this->save_profile = save;
if (this->profile == profile &&
(this->profile != DEVICE_PROFILE_A2DP || codec == this->props.codec) &&
(this->profile != DEVICE_PROFILE_HSP_HFP || codec == this->props.codec))
@ -1133,7 +1136,8 @@ static void set_initial_profile(struct impl *this)
}
static struct spa_pod *build_profile(struct impl *this, struct spa_pod_builder *b,
uint32_t id, uint32_t index, uint32_t profile_index, enum spa_bluetooth_audio_codec codec)
uint32_t id, uint32_t index, uint32_t profile_index, enum spa_bluetooth_audio_codec codec,
bool current)
{
struct spa_bt_device *device = this->bt_dev;
struct spa_pod_frame f[2];
@ -1266,6 +1270,10 @@ static struct spa_pod *build_profile(struct impl *this, struct spa_pod_builder *
}
spa_pod_builder_pop(b, &f[1]);
}
if (current) {
spa_pod_builder_prop(b, SPA_PARAM_PROFILE_save, 0);
spa_pod_builder_bool(b, this->save_profile);
}
if (name_and_codec)
free(name_and_codec);
@ -1282,7 +1290,7 @@ static bool validate_profile(struct impl *this, uint32_t profile,
uint8_t buffer[1024];
spa_pod_builder_init(&b, buffer, sizeof(buffer));
return (build_profile(this, &b, 0, 0, profile, codec) != NULL);
return (build_profile(this, &b, 0, 0, profile, codec, false) != NULL);
}
static struct spa_pod *build_route(struct impl *this, struct spa_pod_builder *b,
@ -1597,7 +1605,7 @@ static int impl_enum_params(void *object, int seq,
case DEVICE_PROFILE_AG:
case DEVICE_PROFILE_A2DP:
case DEVICE_PROFILE_HSP_HFP:
param = build_profile(this, &b, id, result.index, profile, codec);
param = build_profile(this, &b, id, result.index, profile, codec, false);
if (param == NULL)
goto next;
break;
@ -1613,7 +1621,7 @@ static int impl_enum_params(void *object, int seq,
switch (result.index) {
case 0:
index = get_index_from_profile(this, this->profile, this->props.codec);
param = build_profile(this, &b, id, index, this->profile, this->props.codec);
param = build_profile(this, &b, id, index, this->profile, this->props.codec, true);
if (param == NULL)
return 0;
break;
@ -1858,13 +1866,15 @@ static int impl_set_param(void *object,
uint32_t idx, next;
uint32_t profile;
enum spa_bluetooth_audio_codec codec;
bool save = false;
if (param == NULL)
return -EINVAL;
if ((res = spa_pod_parse_object(param,
SPA_TYPE_OBJECT_ParamProfile, NULL,
SPA_PARAM_PROFILE_index, SPA_POD_Int(&idx))) < 0) {
SPA_PARAM_PROFILE_index, SPA_POD_Int(&idx),
SPA_PARAM_PROFILE_save, SPA_POD_OPT_Bool(&save))) < 0) {
spa_log_warn(this->log, "can't parse profile");
spa_debug_pod(0, NULL, param);
return res;
@ -1874,8 +1884,8 @@ static int impl_set_param(void *object,
if (profile == SPA_ID_INVALID)
return -EINVAL;
spa_log_debug(this->log, "setting profile %d codec:%d", profile, codec);
return set_profile(this, profile, codec);
spa_log_debug(this->log, "setting profile %d codec:%d save:%d", profile, codec, (int)save);
return set_profile(this, profile, codec, save);
}
case SPA_PARAM_Route:
{
@ -1927,6 +1937,8 @@ static int impl_set_param(void *object,
return res;
}
spa_log_debug(this->log, "setting props codec:%d", codec_id);
if (codec_id == SPA_ID_INVALID)
return 0;
@ -1934,16 +1946,16 @@ static int impl_set_param(void *object,
size_t j;
for (j = 0; j < this->supported_codec_count; ++j) {
if (this->supported_codecs[j]->id == codec_id) {
return set_profile(this, this->profile, codec_id);
return set_profile(this, this->profile, codec_id, true);
}
}
} else if (this->profile == DEVICE_PROFILE_HSP_HFP) {
if (codec_id == SPA_BLUETOOTH_AUDIO_CODEC_CVSD &&
spa_bt_device_supports_hfp_codec(this->bt_dev, HFP_AUDIO_CODEC_CVSD) == 1) {
return set_profile(this, this->profile, codec_id);
return set_profile(this, this->profile, codec_id, true);
} else if (codec_id == SPA_BLUETOOTH_AUDIO_CODEC_MSBC &&
spa_bt_device_supports_hfp_codec(this->bt_dev, HFP_AUDIO_CODEC_MSBC) == 1) {
return set_profile(this, this->profile, codec_id);
return set_profile(this, this->profile, codec_id, true);
}
}
return -EINVAL;