Loading system/bta/le_audio/client.cc +6 −0 Original line number Original line Diff line number Diff line Loading @@ -1413,14 +1413,20 @@ class LeAudioClientImpl : public LeAudioClient { } } if (!DeserializeSinkPacs(leAudioDevice, sink_pacs)) { if (!DeserializeSinkPacs(leAudioDevice, sink_pacs)) { /* If PACs are invalid, just say whole cache is invalid */ leAudioDevice->known_service_handles_ = false; LOG_WARN("Could not load sink pacs"); LOG_WARN("Could not load sink pacs"); } } if (!DeserializeSourcePacs(leAudioDevice, source_pacs)) { if (!DeserializeSourcePacs(leAudioDevice, source_pacs)) { /* If PACs are invalid, just say whole cache is invalid */ leAudioDevice->known_service_handles_ = false; LOG_WARN("Could not load source pacs"); LOG_WARN("Could not load source pacs"); } } if (!DeserializeAses(leAudioDevice, ases)) { if (!DeserializeAses(leAudioDevice, ases)) { /* If ASEs are invalid, just say whole cache is invalid */ leAudioDevice->known_service_handles_ = false; LOG_WARN("Could not load ases"); LOG_WARN("Could not load ases"); } } Loading system/bta/le_audio/le_audio_client_test.cc +148 −0 Original line number Original line Diff line number Diff line Loading @@ -3430,6 +3430,154 @@ TEST_F(UnicastTestNoInit, ConnectFailedDueToInvalidParameters) { Mock::VerifyAndClearExpectations(&mock_gatt_interface_); Mock::VerifyAndClearExpectations(&mock_gatt_interface_); } } TEST_F(UnicastTestNoInit, LoadStoredEarbudsBroakenStorage) { // Prepare two devices uint8_t group_size = 2; uint8_t group_id = 2; /* If the storage has been broken, make sure device will be rediscovered after * reconnection */ /* Prepare mock to not inject connect event so the device can stay in * CONNECTING state*/ ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, false)) .WillByDefault(DoAll(Return())); const RawAddress test_address0 = GetTestAddress(0); SetSampleDatabaseEarbudsValid( 1, test_address0, codec_spec_conf::kLeAudioLocationFrontLeft, codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt, default_channel_cnt, 0x0004, /* source sample freq 16khz */ true, /*add_csis*/ true, /*add_cas*/ true, /*add_pacs*/ default_ase_cnt, /*add_ascs_cnt*/ group_size, 1); const RawAddress test_address1 = GetTestAddress(1); SetSampleDatabaseEarbudsValid( 2, test_address1, codec_spec_conf::kLeAudioLocationFrontRight, codec_spec_conf::kLeAudioLocationFrontRight, default_channel_cnt, default_channel_cnt, 0x0004, /* source sample freq 16khz */ true, /*add_csis*/ true, /*add_cas*/ true, /*add_pacs*/ default_ase_cnt, /*add_ascs_cnt*/ group_size, 2); // Load devices from the storage when storage API is called bool autoconnect = true; std::vector<uint8_t> empty_buf; EXPECT_CALL(mock_storage_load, Call()).WillOnce([&]() { do_in_main_thread( FROM_HERE, base::BindOnce(&LeAudioClient::AddFromStorage, test_address0, autoconnect, codec_spec_conf::kLeAudioLocationFrontLeft, codec_spec_conf::kLeAudioLocationFrontLeft, 0xff, 0xff, std::move(empty_buf), std::move(empty_buf), std::move(empty_buf), std::move(empty_buf))); do_in_main_thread( FROM_HERE, base::BindOnce(&LeAudioClient::AddFromStorage, test_address1, autoconnect, codec_spec_conf::kLeAudioLocationFrontRight, codec_spec_conf::kLeAudioLocationFrontRight, 0xff, 0xff, std::move(empty_buf), std::move(empty_buf), std::move(empty_buf), std::move(empty_buf))); SyncOnMainLoop(); }); // Expect stored device0 to connect automatically (first directed connection ) EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _)) .Times(1); // Expect stored device1 to connect automatically (first direct connection) EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address1, BTM_BLE_DIRECT_CONNECTION, _)) .Times(1); ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address1, _)) .WillByDefault(DoAll(Return(true))); ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _)) .WillByDefault(DoAll(Return(true))); ON_CALL(mock_groups_module_, GetGroupId(_, _)) .WillByDefault(DoAll(Return(group_id))); ON_CALL(mock_btm_interface_, GetSecurityFlagsByTransport(test_address0, NotNull(), _)) .WillByDefault( DoAll(SetArgPointee<1>(BTM_SEC_FLAG_ENCRYPTED), Return(true))); std::vector<::bluetooth::le_audio::btle_audio_codec_config_t> framework_encode_preference; // Initialize BtaAppRegisterCallback app_register_callback; ON_CALL(mock_gatt_interface_, AppRegister(_, _, _)) .WillByDefault(DoAll(SaveArg<0>(&gatt_callback), SaveArg<1>(&app_register_callback))); LeAudioClient::Initialize( &mock_audio_hal_client_callbacks_, base::Bind([](MockFunction<void()>* foo) { foo->Call(); }, &mock_storage_load), base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); }, &mock_hal_2_1_verifier), framework_encode_preference); if (app_register_callback) app_register_callback.Run(gatt_if, GATT_SUCCESS); // We need to wait for the storage callback before verifying stuff SyncOnMainLoop(); ASSERT_TRUE(LeAudioClient::IsLeAudioClientRunning()); Mock::VerifyAndClearExpectations(&mock_gatt_interface_); // Simulate devices are not there and phone fallbacks to targeted // announcements EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _)) .Times(1); EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address1, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _)) .Times(1); // Devices not found InjectConnectedEvent(test_address0, 0, GATT_ERROR); InjectConnectedEvent(test_address1, 0, GATT_ERROR); SyncOnMainLoop(); Mock::VerifyAndClearExpectations(&mock_gatt_interface_); /* Stack should rediscover services as storage is broken */ EXPECT_CALL(mock_gatt_interface_, ServiceSearchRequest(2, _)).Times(1); EXPECT_CALL(mock_gatt_interface_, ServiceSearchRequest(1, _)).Times(1); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::CONNECTED, test_address0)) .Times(1); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::CONNECTED, test_address1)) .Times(1); /* For background connect, test needs to Inject Connected Event */ InjectConnectedEvent(test_address0, 1); InjectConnectedEvent(test_address1, 2); SyncOnMainLoop(); // Verify if all went well and we got the proper group std::vector<RawAddress> devs = LeAudioClient::Get()->GetGroupDevices(group_id); ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end()); ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end()); DisconnectLeAudioWithAclClose(test_address0, 1); DisconnectLeAudioWithAclClose(test_address1, 2); } TEST_F(UnicastTestNoInit, LoadStoredEarbudsCsisGrouped) { TEST_F(UnicastTestNoInit, LoadStoredEarbudsCsisGrouped) { // Prepare two devices // Prepare two devices uint8_t group_size = 2; uint8_t group_size = 2; Loading Loading
system/bta/le_audio/client.cc +6 −0 Original line number Original line Diff line number Diff line Loading @@ -1413,14 +1413,20 @@ class LeAudioClientImpl : public LeAudioClient { } } if (!DeserializeSinkPacs(leAudioDevice, sink_pacs)) { if (!DeserializeSinkPacs(leAudioDevice, sink_pacs)) { /* If PACs are invalid, just say whole cache is invalid */ leAudioDevice->known_service_handles_ = false; LOG_WARN("Could not load sink pacs"); LOG_WARN("Could not load sink pacs"); } } if (!DeserializeSourcePacs(leAudioDevice, source_pacs)) { if (!DeserializeSourcePacs(leAudioDevice, source_pacs)) { /* If PACs are invalid, just say whole cache is invalid */ leAudioDevice->known_service_handles_ = false; LOG_WARN("Could not load source pacs"); LOG_WARN("Could not load source pacs"); } } if (!DeserializeAses(leAudioDevice, ases)) { if (!DeserializeAses(leAudioDevice, ases)) { /* If ASEs are invalid, just say whole cache is invalid */ leAudioDevice->known_service_handles_ = false; LOG_WARN("Could not load ases"); LOG_WARN("Could not load ases"); } } Loading
system/bta/le_audio/le_audio_client_test.cc +148 −0 Original line number Original line Diff line number Diff line Loading @@ -3430,6 +3430,154 @@ TEST_F(UnicastTestNoInit, ConnectFailedDueToInvalidParameters) { Mock::VerifyAndClearExpectations(&mock_gatt_interface_); Mock::VerifyAndClearExpectations(&mock_gatt_interface_); } } TEST_F(UnicastTestNoInit, LoadStoredEarbudsBroakenStorage) { // Prepare two devices uint8_t group_size = 2; uint8_t group_id = 2; /* If the storage has been broken, make sure device will be rediscovered after * reconnection */ /* Prepare mock to not inject connect event so the device can stay in * CONNECTING state*/ ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, false)) .WillByDefault(DoAll(Return())); const RawAddress test_address0 = GetTestAddress(0); SetSampleDatabaseEarbudsValid( 1, test_address0, codec_spec_conf::kLeAudioLocationFrontLeft, codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt, default_channel_cnt, 0x0004, /* source sample freq 16khz */ true, /*add_csis*/ true, /*add_cas*/ true, /*add_pacs*/ default_ase_cnt, /*add_ascs_cnt*/ group_size, 1); const RawAddress test_address1 = GetTestAddress(1); SetSampleDatabaseEarbudsValid( 2, test_address1, codec_spec_conf::kLeAudioLocationFrontRight, codec_spec_conf::kLeAudioLocationFrontRight, default_channel_cnt, default_channel_cnt, 0x0004, /* source sample freq 16khz */ true, /*add_csis*/ true, /*add_cas*/ true, /*add_pacs*/ default_ase_cnt, /*add_ascs_cnt*/ group_size, 2); // Load devices from the storage when storage API is called bool autoconnect = true; std::vector<uint8_t> empty_buf; EXPECT_CALL(mock_storage_load, Call()).WillOnce([&]() { do_in_main_thread( FROM_HERE, base::BindOnce(&LeAudioClient::AddFromStorage, test_address0, autoconnect, codec_spec_conf::kLeAudioLocationFrontLeft, codec_spec_conf::kLeAudioLocationFrontLeft, 0xff, 0xff, std::move(empty_buf), std::move(empty_buf), std::move(empty_buf), std::move(empty_buf))); do_in_main_thread( FROM_HERE, base::BindOnce(&LeAudioClient::AddFromStorage, test_address1, autoconnect, codec_spec_conf::kLeAudioLocationFrontRight, codec_spec_conf::kLeAudioLocationFrontRight, 0xff, 0xff, std::move(empty_buf), std::move(empty_buf), std::move(empty_buf), std::move(empty_buf))); SyncOnMainLoop(); }); // Expect stored device0 to connect automatically (first directed connection ) EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _)) .Times(1); // Expect stored device1 to connect automatically (first direct connection) EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address1, BTM_BLE_DIRECT_CONNECTION, _)) .Times(1); ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address1, _)) .WillByDefault(DoAll(Return(true))); ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _)) .WillByDefault(DoAll(Return(true))); ON_CALL(mock_groups_module_, GetGroupId(_, _)) .WillByDefault(DoAll(Return(group_id))); ON_CALL(mock_btm_interface_, GetSecurityFlagsByTransport(test_address0, NotNull(), _)) .WillByDefault( DoAll(SetArgPointee<1>(BTM_SEC_FLAG_ENCRYPTED), Return(true))); std::vector<::bluetooth::le_audio::btle_audio_codec_config_t> framework_encode_preference; // Initialize BtaAppRegisterCallback app_register_callback; ON_CALL(mock_gatt_interface_, AppRegister(_, _, _)) .WillByDefault(DoAll(SaveArg<0>(&gatt_callback), SaveArg<1>(&app_register_callback))); LeAudioClient::Initialize( &mock_audio_hal_client_callbacks_, base::Bind([](MockFunction<void()>* foo) { foo->Call(); }, &mock_storage_load), base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); }, &mock_hal_2_1_verifier), framework_encode_preference); if (app_register_callback) app_register_callback.Run(gatt_if, GATT_SUCCESS); // We need to wait for the storage callback before verifying stuff SyncOnMainLoop(); ASSERT_TRUE(LeAudioClient::IsLeAudioClientRunning()); Mock::VerifyAndClearExpectations(&mock_gatt_interface_); // Simulate devices are not there and phone fallbacks to targeted // announcements EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _)) .Times(1); EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address1, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _)) .Times(1); // Devices not found InjectConnectedEvent(test_address0, 0, GATT_ERROR); InjectConnectedEvent(test_address1, 0, GATT_ERROR); SyncOnMainLoop(); Mock::VerifyAndClearExpectations(&mock_gatt_interface_); /* Stack should rediscover services as storage is broken */ EXPECT_CALL(mock_gatt_interface_, ServiceSearchRequest(2, _)).Times(1); EXPECT_CALL(mock_gatt_interface_, ServiceSearchRequest(1, _)).Times(1); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::CONNECTED, test_address0)) .Times(1); EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::CONNECTED, test_address1)) .Times(1); /* For background connect, test needs to Inject Connected Event */ InjectConnectedEvent(test_address0, 1); InjectConnectedEvent(test_address1, 2); SyncOnMainLoop(); // Verify if all went well and we got the proper group std::vector<RawAddress> devs = LeAudioClient::Get()->GetGroupDevices(group_id); ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end()); ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end()); DisconnectLeAudioWithAclClose(test_address0, 1); DisconnectLeAudioWithAclClose(test_address1, 2); } TEST_F(UnicastTestNoInit, LoadStoredEarbudsCsisGrouped) { TEST_F(UnicastTestNoInit, LoadStoredEarbudsCsisGrouped) { // Prepare two devices // Prepare two devices uint8_t group_size = 2; uint8_t group_size = 2; Loading