diff --git a/cras/src/server/cras_a2dp_manager.c b/cras/src/server/cras_a2dp_manager.c index 3f6985d7a..c152a22c3 100644 --- a/cras/src/server/cras_a2dp_manager.c +++ b/cras/src/server/cras_a2dp_manager.c @@ -246,10 +246,17 @@ static bool cras_floss_a2dp_nonstandard_codecs_allowed() { return cras_feature_enabled(CrOSLateBootAudioA2DPAdvancedCodecs); } -static struct cras_fl_a2dp_codec_config* cras_floss_a2dp_get_best_codec( +static struct cras_fl_a2dp_codec_config cras_floss_a2dp_get_best_codec( struct cras_fl_a2dp_codec_config* codecs) { struct cras_fl_a2dp_codec_config* codec; - struct cras_fl_a2dp_codec_config* best_codec = NULL; + struct cras_fl_a2dp_codec_config best_codec = { + .bits_per_sample = FL_SAMPLE_16, + .channel_mode = FL_MODE_STEREO, + .codec_priority = -1, + .codec_type = FL_A2DP_CODEC_SRC_SBC, + .sample_rate = FL_RATE_44100, + .next = NULL, + }; DL_FOREACH (codecs, codec) { // TODO(b/279991957): Add UMA to record availability of codecs @@ -262,11 +269,15 @@ static struct cras_fl_a2dp_codec_config* cras_floss_a2dp_get_best_codec( continue; } - if (!best_codec || codec->codec_priority > best_codec->codec_priority) { - best_codec = codec; + if (codec->codec_priority >= best_codec.codec_priority) { + best_codec = *codec; } } + if (best_codec.codec_priority == -1) { + syslog(LOG_WARNING, "No valid A2DP codec available, fallback to SBC."); + } + return best_codec; } @@ -275,12 +286,8 @@ struct cras_a2dp* cras_floss_a2dp_create( const char* addr, const char* name, struct cras_fl_a2dp_codec_config* codecs) { - struct cras_fl_a2dp_codec_config* codec = + struct cras_fl_a2dp_codec_config codec = cras_floss_a2dp_get_best_codec(codecs); - if (!codec) { - syslog(LOG_WARNING, "No supported A2dp codec"); - return NULL; - } struct cras_a2dp* a2dp = (struct cras_a2dp*)calloc(1, sizeof(*a2dp)); if (!a2dp) { @@ -290,9 +297,9 @@ struct cras_a2dp* cras_floss_a2dp_create( a2dp->fm = fm; a2dp->addr = strdup(addr); a2dp->name = strdup(name); - a2dp->active_codec_type = codec->codec_type; + a2dp->active_codec_type = codec.codec_type; a2dp->iodev = a2dp_pcm_iodev_create( - a2dp, codec->sample_rate, codec->bits_per_sample, codec->channel_mode); + a2dp, codec.sample_rate, codec.bits_per_sample, codec.channel_mode); if (!a2dp->iodev) { syslog(LOG_WARNING, "Failed to create a2dp pcm_iodev for %s", name); diff --git a/cras/src/tests/a2dp_manager_unittest.cc b/cras/src/tests/a2dp_manager_unittest.cc index 6226abd6f..012ebf7df 100644 --- a/cras/src/tests/a2dp_manager_unittest.cc +++ b/cras/src/tests/a2dp_manager_unittest.cc @@ -92,15 +92,17 @@ TEST_F(A2dpManagerTestSuite, CreateFailed) { a2dp_pcm_iodev_create_ret = (struct cras_iodev*)calloc(1, sizeof(struct cras_iodev)); - // NULL a2dp_codec_configs should fail the a2dp_create without a crash - ASSERT_EQ(cras_floss_a2dp_create(NULL, "addr", "name", - (struct cras_fl_a2dp_codec_config*)NULL), - (struct cras_a2dp*)NULL); + // NULL a2dp_codec_configs should succeed with fallback to default params + struct cras_a2dp* a2dp = cras_floss_a2dp_create( + NULL, "addr", "name", (struct cras_fl_a2dp_codec_config*)NULL); + ASSERT_NE(a2dp, (struct cras_a2dp*)NULL); + cras_floss_a2dp_destroy(a2dp); - // Unsupported codecs should fail the a2dp_create without a crash + // Unsupported codecs should succeed with fallback to default params a2dp_codecs.codec_type = FL_A2DP_CODEC_SINK_AAC; - ASSERT_EQ(cras_floss_a2dp_create(NULL, "addr", "name", &a2dp_codecs), - (struct cras_a2dp*)NULL); + a2dp = cras_floss_a2dp_create(NULL, "addr", "name", &a2dp_codecs); + ASSERT_NE(a2dp, (struct cras_a2dp*)NULL); + cras_floss_a2dp_destroy(a2dp); } TEST_F(A2dpManagerTestSuite, CreateDestroy) {