Loading system/bta/Android.bp +0 −2 Original line number Original line Diff line number Diff line Loading @@ -657,7 +657,6 @@ cc_test { srcs: [ srcs: [ ":TestCommonMockFunctions", ":TestCommonMockFunctions", ":TestMockStackBtmInterface", ":TestMockStackBtmInterface", ":TestStubOsi", "gatt/database.cc", "gatt/database.cc", "gatt/database_builder.cc", "gatt/database_builder.cc", "test/common/bta_gatt_api_mock.cc", "test/common/bta_gatt_api_mock.cc", Loading Loading @@ -685,7 +684,6 @@ cc_test { "libbt_shim_ffi", "libbt_shim_ffi", "libchrome", "libchrome", "libgmock", "libgmock", "libosi", ], ], sanitize: { sanitize: { cfi: false, cfi: false, Loading system/bta/vc/types.h +5 −0 Original line number Original line Diff line number Diff line Loading @@ -87,6 +87,11 @@ struct VolumeOperation { started_ = false; started_ = false; } } // Disallow copying due to owning operation_timeout_t which is freed in the // destructor - prevents double free. VolumeOperation(const VolumeOperation&) = delete; VolumeOperation& operator=(const VolumeOperation&) = delete; ~VolumeOperation() { ~VolumeOperation() { if (operation_timeout_ == nullptr) { if (operation_timeout_ == nullptr) { log::warn("operation_timeout_ should not be null, id {}, device cnt {}", operation_id_, log::warn("operation_timeout_ should not be null, id {}, device cnt {}", operation_id_, Loading system/bta/vc/vc.cc +8 −3 Original line number Original line Diff line number Diff line Loading @@ -663,9 +663,14 @@ public: } } // Remove operations with no devices // Remove operations with no devices ongoing_operations_.erase(std::remove_if(ongoing_operations_.begin(), ongoing_operations_.end(), auto it = ongoing_operations_.begin(); [](auto& op) { return op.devices_.empty(); }), while (it != ongoing_operations_.end()) { ongoing_operations_.end()); if (it->devices_.empty()) { it = ongoing_operations_.erase(it); } else { ++it; } } } } void RemoveDeviceFromOperationList(const RawAddress& addr, int operation_id) { void RemoveDeviceFromOperationList(const RawAddress& addr, int operation_id) { Loading system/bta/vc/vc_test.cc +76 −10 Original line number Original line Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include "gatt/database_builder.h" #include "gatt/database_builder.h" #include "hardware/bt_gatt_types.h" #include "hardware/bt_gatt_types.h" #include "mock_csis_client.h" #include "mock_csis_client.h" #include "osi/test/alarm_mock.h" #include "stack/include/bt_uuid16.h" #include "stack/include/bt_uuid16.h" #include "test/common/mock_functions.h" #include "test/common/mock_functions.h" #include "types.h" #include "types.h" Loading @@ -34,6 +35,12 @@ #include "types/raw_address.h" #include "types/raw_address.h" void btif_storage_add_volume_control(const RawAddress& addr, bool auto_conn) {} void btif_storage_add_volume_control(const RawAddress& addr, bool auto_conn) {} struct alarm_t { alarm_callback_t cb = nullptr; void* data = nullptr; bool on_main_loop = false; }; namespace bluetooth { namespace bluetooth { namespace vc { namespace vc { namespace internal { namespace internal { Loading Loading @@ -276,6 +283,45 @@ protected: cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(), cb_data); cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(), cb_data); } } })); })); auto mock_alarm = AlarmMock::Get(); ON_CALL(*mock_alarm, AlarmNew(_)).WillByDefault(Invoke([](const char* name) { return new alarm_t(); })); ON_CALL(*mock_alarm, AlarmFree(_)).WillByDefault(Invoke([](alarm_t* alarm) { if (alarm) { free(alarm); } })); ON_CALL(*mock_alarm, AlarmCancel(_)).WillByDefault(Invoke([](alarm_t* alarm) { if (alarm) { alarm->cb = nullptr; alarm->data = nullptr; alarm->on_main_loop = false; } })); ON_CALL(*mock_alarm, AlarmIsScheduled(_)).WillByDefault(Invoke([](const alarm_t* alarm) { if (alarm) { return alarm->cb != nullptr; } return false; })); ON_CALL(*mock_alarm, AlarmSet(_, _, _, _)) .WillByDefault(Invoke( [](alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb, void* data) { if (alarm) { alarm->data = data; alarm->cb = cb; } })); ON_CALL(*mock_alarm, AlarmSetOnMloop(_, _, _, _)) .WillByDefault(Invoke( [](alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb, void* data) { if (alarm) { alarm->on_main_loop = true; alarm->data = data; alarm->cb = cb; } })); } } void TearDown(void) override { void TearDown(void) override { Loading @@ -284,6 +330,7 @@ protected: gatt::SetMockBtaGattQueue(nullptr); gatt::SetMockBtaGattQueue(nullptr); gatt::SetMockBtaGattInterface(nullptr); gatt::SetMockBtaGattInterface(nullptr); bluetooth::manager::SetMockBtmInterface(nullptr); bluetooth::manager::SetMockBtmInterface(nullptr); AlarmMock::Reset(); } } void TestAppRegister(void) { void TestAppRegister(void) { Loading Loading @@ -1167,14 +1214,13 @@ TEST_F(VolumeControlValueSetTest, test_volume_operation_failed) { cb(conn_id, status, handle, value.size(), value.data(), cb_data); cb(conn_id, status, handle, value.size(), value.data(), cb_data); } } })); })); ASSERT_EQ(0, get_func_call_count("alarm_set_on_mloop")); ASSERT_EQ(0, get_func_call_count("alarm_cancel")); EXPECT_CALL(*AlarmMock::Get(), AlarmSetOnMloop(_, _, _, _)).Times(1); EXPECT_CALL(*AlarmMock::Get(), AlarmCancel(_)).Times(1); VolumeControl::Get()->SetVolume(test_address, 0x10); VolumeControl::Get()->SetVolume(test_address, 0x10); Mock::VerifyAndClearExpectations(&gatt_queue); ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop")); Mock::VerifyAndClearExpectations(&gatt_queue); ASSERT_EQ(1, get_func_call_count("alarm_cancel")); Mock::VerifyAndClearExpectations(AlarmMock::Get()); } } TEST_F(VolumeControlValueSetTest, test_volume_operation_failed_due_to_device_disconnection) { TEST_F(VolumeControlValueSetTest, test_volume_operation_failed_due_to_device_disconnection) { Loading @@ -1187,18 +1233,38 @@ TEST_F(VolumeControlValueSetTest, test_volume_operation_failed_due_to_device_dis /* Do nothing */ /* Do nothing */ })); })); ASSERT_EQ(0, get_func_call_count("alarm_set_on_mloop")); EXPECT_CALL(*AlarmMock::Get(), AlarmSetOnMloop(_, _, _, _)).Times(0); ASSERT_EQ(0, get_func_call_count("alarm_cancel")); alarm_callback_t active_alarm_cb = nullptr; EXPECT_CALL(*AlarmMock::Get(), AlarmSetOnMloop(_, _, _, _)) .WillOnce(Invoke( [&](alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb, void* data) { if (alarm) { alarm->on_main_loop = true; alarm->cb = cb; active_alarm_cb = cb; } })); ON_CALL(*AlarmMock::Get(), AlarmCancel(_)).WillByDefault(Invoke([&](alarm_t* alarm) { if (alarm) { alarm->cb = nullptr; alarm->on_main_loop = false; active_alarm_cb = nullptr; } })); VolumeControl::Get()->SetVolume(test_address, 0x10); VolumeControl::Get()->SetVolume(test_address, 0x10); Mock::VerifyAndClearExpectations(&gatt_queue); Mock::VerifyAndClearExpectations(&gatt_queue); Mock::VerifyAndClearExpectations(AlarmMock::Get()); ASSERT_NE(active_alarm_cb, nullptr); EXPECT_CALL(*AlarmMock::Get(), AlarmCancel(_)).Times(1); EXPECT_CALL(*callbacks, OnConnectionState(ConnectionState::DISCONNECTED, test_address)); EXPECT_CALL(*callbacks, OnConnectionState(ConnectionState::DISCONNECTED, test_address)); GetDisconnectedEvent(test_address, conn_id); GetDisconnectedEvent(test_address, conn_id); Mock::VerifyAndClearExpectations(callbacks.get()); ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop")); ASSERT_EQ(active_alarm_cb, nullptr); ASSERT_EQ(1, get_func_call_count("alarm_cancel")); Mock::VerifyAndClearExpectations(callbacks.get()); } } TEST_F(VolumeControlValueSetTest, test_set_volume) { TEST_F(VolumeControlValueSetTest, test_set_volume) { Loading system/osi/test/alarm_mock.h +2 −16 Original line number Original line Diff line number Diff line Loading @@ -14,20 +14,6 @@ public: void(alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb, void* data)); void(alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb, void* data)); MOCK_METHOD1(AlarmIsScheduled, bool(const alarm_t*)); MOCK_METHOD1(AlarmIsScheduled, bool(const alarm_t*)); alarm_t* AlarmNewImpl(const char* name) { AlarmNew(name); // We must return something from alarm_new in tests, if we just return null, // unique_ptr will misbehave. Just reserve few bits they will be freed in // AlarmFreeImpl return (alarm_t*)new uint8_t[30]; } void AlarmFreeImpl(alarm_t* alarm) { uint8_t* ptr = (uint8_t*)alarm; delete[] ptr; return AlarmFree(alarm); } static inline AlarmMock* Get() { static inline AlarmMock* Get() { if (!localAlarmMock) { if (!localAlarmMock) { localAlarmMock = std::make_unique<AlarmMock>(); localAlarmMock = std::make_unique<AlarmMock>(); Loading @@ -43,9 +29,9 @@ private: std::unique_ptr<AlarmMock> AlarmMock::localAlarmMock; std::unique_ptr<AlarmMock> AlarmMock::localAlarmMock; alarm_t* alarm_new(const char* name) { return AlarmMock::Get()->AlarmNewImpl(name); } alarm_t* alarm_new(const char* name) { return AlarmMock::Get()->AlarmNew(name); } void alarm_free(alarm_t* alarm) { AlarmMock::Get()->AlarmFreeImpl(alarm); } void alarm_free(alarm_t* alarm) { AlarmMock::Get()->AlarmFree(alarm); } void alarm_set_on_mloop(alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb, void* data) { void alarm_set_on_mloop(alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb, void* data) { AlarmMock::Get()->AlarmSetOnMloop(alarm, interval_ms, cb, data); AlarmMock::Get()->AlarmSetOnMloop(alarm, interval_ms, cb, data); Loading Loading
system/bta/Android.bp +0 −2 Original line number Original line Diff line number Diff line Loading @@ -657,7 +657,6 @@ cc_test { srcs: [ srcs: [ ":TestCommonMockFunctions", ":TestCommonMockFunctions", ":TestMockStackBtmInterface", ":TestMockStackBtmInterface", ":TestStubOsi", "gatt/database.cc", "gatt/database.cc", "gatt/database_builder.cc", "gatt/database_builder.cc", "test/common/bta_gatt_api_mock.cc", "test/common/bta_gatt_api_mock.cc", Loading Loading @@ -685,7 +684,6 @@ cc_test { "libbt_shim_ffi", "libbt_shim_ffi", "libchrome", "libchrome", "libgmock", "libgmock", "libosi", ], ], sanitize: { sanitize: { cfi: false, cfi: false, Loading
system/bta/vc/types.h +5 −0 Original line number Original line Diff line number Diff line Loading @@ -87,6 +87,11 @@ struct VolumeOperation { started_ = false; started_ = false; } } // Disallow copying due to owning operation_timeout_t which is freed in the // destructor - prevents double free. VolumeOperation(const VolumeOperation&) = delete; VolumeOperation& operator=(const VolumeOperation&) = delete; ~VolumeOperation() { ~VolumeOperation() { if (operation_timeout_ == nullptr) { if (operation_timeout_ == nullptr) { log::warn("operation_timeout_ should not be null, id {}, device cnt {}", operation_id_, log::warn("operation_timeout_ should not be null, id {}, device cnt {}", operation_id_, Loading
system/bta/vc/vc.cc +8 −3 Original line number Original line Diff line number Diff line Loading @@ -663,9 +663,14 @@ public: } } // Remove operations with no devices // Remove operations with no devices ongoing_operations_.erase(std::remove_if(ongoing_operations_.begin(), ongoing_operations_.end(), auto it = ongoing_operations_.begin(); [](auto& op) { return op.devices_.empty(); }), while (it != ongoing_operations_.end()) { ongoing_operations_.end()); if (it->devices_.empty()) { it = ongoing_operations_.erase(it); } else { ++it; } } } } void RemoveDeviceFromOperationList(const RawAddress& addr, int operation_id) { void RemoveDeviceFromOperationList(const RawAddress& addr, int operation_id) { Loading
system/bta/vc/vc_test.cc +76 −10 Original line number Original line Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include "gatt/database_builder.h" #include "gatt/database_builder.h" #include "hardware/bt_gatt_types.h" #include "hardware/bt_gatt_types.h" #include "mock_csis_client.h" #include "mock_csis_client.h" #include "osi/test/alarm_mock.h" #include "stack/include/bt_uuid16.h" #include "stack/include/bt_uuid16.h" #include "test/common/mock_functions.h" #include "test/common/mock_functions.h" #include "types.h" #include "types.h" Loading @@ -34,6 +35,12 @@ #include "types/raw_address.h" #include "types/raw_address.h" void btif_storage_add_volume_control(const RawAddress& addr, bool auto_conn) {} void btif_storage_add_volume_control(const RawAddress& addr, bool auto_conn) {} struct alarm_t { alarm_callback_t cb = nullptr; void* data = nullptr; bool on_main_loop = false; }; namespace bluetooth { namespace bluetooth { namespace vc { namespace vc { namespace internal { namespace internal { Loading Loading @@ -276,6 +283,45 @@ protected: cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(), cb_data); cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(), cb_data); } } })); })); auto mock_alarm = AlarmMock::Get(); ON_CALL(*mock_alarm, AlarmNew(_)).WillByDefault(Invoke([](const char* name) { return new alarm_t(); })); ON_CALL(*mock_alarm, AlarmFree(_)).WillByDefault(Invoke([](alarm_t* alarm) { if (alarm) { free(alarm); } })); ON_CALL(*mock_alarm, AlarmCancel(_)).WillByDefault(Invoke([](alarm_t* alarm) { if (alarm) { alarm->cb = nullptr; alarm->data = nullptr; alarm->on_main_loop = false; } })); ON_CALL(*mock_alarm, AlarmIsScheduled(_)).WillByDefault(Invoke([](const alarm_t* alarm) { if (alarm) { return alarm->cb != nullptr; } return false; })); ON_CALL(*mock_alarm, AlarmSet(_, _, _, _)) .WillByDefault(Invoke( [](alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb, void* data) { if (alarm) { alarm->data = data; alarm->cb = cb; } })); ON_CALL(*mock_alarm, AlarmSetOnMloop(_, _, _, _)) .WillByDefault(Invoke( [](alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb, void* data) { if (alarm) { alarm->on_main_loop = true; alarm->data = data; alarm->cb = cb; } })); } } void TearDown(void) override { void TearDown(void) override { Loading @@ -284,6 +330,7 @@ protected: gatt::SetMockBtaGattQueue(nullptr); gatt::SetMockBtaGattQueue(nullptr); gatt::SetMockBtaGattInterface(nullptr); gatt::SetMockBtaGattInterface(nullptr); bluetooth::manager::SetMockBtmInterface(nullptr); bluetooth::manager::SetMockBtmInterface(nullptr); AlarmMock::Reset(); } } void TestAppRegister(void) { void TestAppRegister(void) { Loading Loading @@ -1167,14 +1214,13 @@ TEST_F(VolumeControlValueSetTest, test_volume_operation_failed) { cb(conn_id, status, handle, value.size(), value.data(), cb_data); cb(conn_id, status, handle, value.size(), value.data(), cb_data); } } })); })); ASSERT_EQ(0, get_func_call_count("alarm_set_on_mloop")); ASSERT_EQ(0, get_func_call_count("alarm_cancel")); EXPECT_CALL(*AlarmMock::Get(), AlarmSetOnMloop(_, _, _, _)).Times(1); EXPECT_CALL(*AlarmMock::Get(), AlarmCancel(_)).Times(1); VolumeControl::Get()->SetVolume(test_address, 0x10); VolumeControl::Get()->SetVolume(test_address, 0x10); Mock::VerifyAndClearExpectations(&gatt_queue); ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop")); Mock::VerifyAndClearExpectations(&gatt_queue); ASSERT_EQ(1, get_func_call_count("alarm_cancel")); Mock::VerifyAndClearExpectations(AlarmMock::Get()); } } TEST_F(VolumeControlValueSetTest, test_volume_operation_failed_due_to_device_disconnection) { TEST_F(VolumeControlValueSetTest, test_volume_operation_failed_due_to_device_disconnection) { Loading @@ -1187,18 +1233,38 @@ TEST_F(VolumeControlValueSetTest, test_volume_operation_failed_due_to_device_dis /* Do nothing */ /* Do nothing */ })); })); ASSERT_EQ(0, get_func_call_count("alarm_set_on_mloop")); EXPECT_CALL(*AlarmMock::Get(), AlarmSetOnMloop(_, _, _, _)).Times(0); ASSERT_EQ(0, get_func_call_count("alarm_cancel")); alarm_callback_t active_alarm_cb = nullptr; EXPECT_CALL(*AlarmMock::Get(), AlarmSetOnMloop(_, _, _, _)) .WillOnce(Invoke( [&](alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb, void* data) { if (alarm) { alarm->on_main_loop = true; alarm->cb = cb; active_alarm_cb = cb; } })); ON_CALL(*AlarmMock::Get(), AlarmCancel(_)).WillByDefault(Invoke([&](alarm_t* alarm) { if (alarm) { alarm->cb = nullptr; alarm->on_main_loop = false; active_alarm_cb = nullptr; } })); VolumeControl::Get()->SetVolume(test_address, 0x10); VolumeControl::Get()->SetVolume(test_address, 0x10); Mock::VerifyAndClearExpectations(&gatt_queue); Mock::VerifyAndClearExpectations(&gatt_queue); Mock::VerifyAndClearExpectations(AlarmMock::Get()); ASSERT_NE(active_alarm_cb, nullptr); EXPECT_CALL(*AlarmMock::Get(), AlarmCancel(_)).Times(1); EXPECT_CALL(*callbacks, OnConnectionState(ConnectionState::DISCONNECTED, test_address)); EXPECT_CALL(*callbacks, OnConnectionState(ConnectionState::DISCONNECTED, test_address)); GetDisconnectedEvent(test_address, conn_id); GetDisconnectedEvent(test_address, conn_id); Mock::VerifyAndClearExpectations(callbacks.get()); ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop")); ASSERT_EQ(active_alarm_cb, nullptr); ASSERT_EQ(1, get_func_call_count("alarm_cancel")); Mock::VerifyAndClearExpectations(callbacks.get()); } } TEST_F(VolumeControlValueSetTest, test_set_volume) { TEST_F(VolumeControlValueSetTest, test_set_volume) { Loading
system/osi/test/alarm_mock.h +2 −16 Original line number Original line Diff line number Diff line Loading @@ -14,20 +14,6 @@ public: void(alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb, void* data)); void(alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb, void* data)); MOCK_METHOD1(AlarmIsScheduled, bool(const alarm_t*)); MOCK_METHOD1(AlarmIsScheduled, bool(const alarm_t*)); alarm_t* AlarmNewImpl(const char* name) { AlarmNew(name); // We must return something from alarm_new in tests, if we just return null, // unique_ptr will misbehave. Just reserve few bits they will be freed in // AlarmFreeImpl return (alarm_t*)new uint8_t[30]; } void AlarmFreeImpl(alarm_t* alarm) { uint8_t* ptr = (uint8_t*)alarm; delete[] ptr; return AlarmFree(alarm); } static inline AlarmMock* Get() { static inline AlarmMock* Get() { if (!localAlarmMock) { if (!localAlarmMock) { localAlarmMock = std::make_unique<AlarmMock>(); localAlarmMock = std::make_unique<AlarmMock>(); Loading @@ -43,9 +29,9 @@ private: std::unique_ptr<AlarmMock> AlarmMock::localAlarmMock; std::unique_ptr<AlarmMock> AlarmMock::localAlarmMock; alarm_t* alarm_new(const char* name) { return AlarmMock::Get()->AlarmNewImpl(name); } alarm_t* alarm_new(const char* name) { return AlarmMock::Get()->AlarmNew(name); } void alarm_free(alarm_t* alarm) { AlarmMock::Get()->AlarmFreeImpl(alarm); } void alarm_free(alarm_t* alarm) { AlarmMock::Get()->AlarmFree(alarm); } void alarm_set_on_mloop(alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb, void* data) { void alarm_set_on_mloop(alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb, void* data) { AlarmMock::Get()->AlarmSetOnMloop(alarm, interval_ms, cb, data); AlarmMock::Get()->AlarmSetOnMloop(alarm, interval_ms, cb, data); Loading