M image/assets/lang/English.json => image/assets/lang/English.json +3 -0
@@ 464,6 464,9 @@
"app_settings_title_color_test": "Display available colors",
"app_settings_toolbar_reset": "RESET",
"app_settings_option_connected": "CONNECTED",
+ "app_settings_option_connected_audio": "CONNECTED AUDIO",
+ "app_settings_option_connected_voice": "CONNECTED VOICE",
+ "app_settings_option_connected_both": "CONNECTED VOICE,AUDIO",
"app_settings_option_connecting": "CONNECTING",
"app_settings_option_pairing": "PAIRING",
"app_settings_title_do_not_disturb": "Do not disturb",
M module-apps/application-settings/windows/bluetooth/AllDevicesWindow.cpp => module-apps/application-settings/windows/bluetooth/AllDevicesWindow.cpp +18 -17
@@ 115,7 115,11 @@ namespace gui
UTF8 AllDevicesWindow::getTextOnCenter(const DeviceState &state) const
{
switch (state) {
- case DeviceState::Connected:
+ case DeviceState::ConnectedAudio:
+ [[fallthrough]];
+ case DeviceState::ConnectedVoice:
+ [[fallthrough]];
+ case DeviceState::ConnectedBoth:
return utils::translate("common_disconnect");
case DeviceState::Paired:
if (bluetoothSettingsModel->isDeviceConnecting()) {
@@ 127,10 131,6 @@ namespace gui
case DeviceState::Connecting:
[[fallthrough]];
case DeviceState::Unknown:
- [[fallthrough]];
- case DeviceState::ConnectedAudio:
- [[fallthrough]];
- case DeviceState::ConnectedVoice:
break;
}
return UTF8();
@@ 139,19 139,19 @@ namespace gui
UTF8 AllDevicesWindow::getTextOnRight(const DeviceState &state) const
{
switch (state) {
- case DeviceState::Connected:
- return utils::translate("app_settings_option_connected");
+ case DeviceState::ConnectedBoth:
+ return utils::translate("app_settings_option_connected_both");
case DeviceState::Connecting:
return utils::translate("app_settings_option_connecting");
case DeviceState::Pairing:
return utils::translate("app_settings_option_pairing");
+ case DeviceState::ConnectedAudio:
+ return utils::translate("app_settings_option_connected_audio");
+ case DeviceState::ConnectedVoice:
+ return utils::translate("app_settings_option_connected_voice");
case DeviceState::Paired:
[[fallthrough]];
case DeviceState::Unknown:
- [[fallthrough]];
- case DeviceState::ConnectedAudio:
- [[fallthrough]];
- case DeviceState::ConnectedVoice:
break;
}
return UTF8();
@@ 160,7 160,11 @@ namespace gui
option::SettingRightItem AllDevicesWindow::getRightItem(const DeviceState &state) const
{
switch (state) {
- case DeviceState::Connected:
+ case DeviceState::ConnectedBoth:
+ [[fallthrough]];
+ case DeviceState::ConnectedAudio:
+ [[fallthrough]];
+ case DeviceState::ConnectedVoice:
[[fallthrough]];
case DeviceState::Connecting:
[[fallthrough]];
@@ 169,10 173,6 @@ namespace gui
case DeviceState::Paired:
return option::SettingRightItem::Bt;
case DeviceState::Unknown:
- [[fallthrough]];
- case DeviceState::ConnectedAudio:
- [[fallthrough]];
- case DeviceState::ConnectedVoice:
break;
}
return option::SettingRightItem::Disabled;
@@ 180,7 180,8 @@ namespace gui
auto AllDevicesWindow::handleDeviceAction(const Devicei &device) -> bool
{
- if (device.deviceState == DeviceState::Connected) {
+ if (device.deviceState == DeviceState::ConnectedBoth || device.deviceState == DeviceState::ConnectedAudio ||
+ device.deviceState == DeviceState::ConnectedVoice) {
bluetoothSettingsModel->requestDisconnection();
refreshOptionsList();
}
M module-apps/tests/tests-BluetoothSettingsModel.cpp => module-apps/tests/tests-BluetoothSettingsModel.cpp +3 -3
@@ 121,8 121,8 @@ TEST_CASE("Device handling")
settingsModel.replaceDevicesList(devicesList);
settingsModel.setActiveDevice(device2);
- settingsModel.setActiveDeviceState(DeviceState::Connected);
- REQUIRE(settingsModel.getActiveDevice().value().get().deviceState == DeviceState::Connected);
+ settingsModel.setActiveDeviceState(DeviceState::ConnectedBoth);
+ REQUIRE(settingsModel.getActiveDevice().value().get().deviceState == DeviceState::ConnectedBoth);
}
SECTION("Is device connecting? - true")
@@ 139,7 139,7 @@ TEST_CASE("Device handling")
settingsModel.replaceDevicesList(devicesList);
settingsModel.setActiveDevice(device2);
- settingsModel.setActiveDeviceState(DeviceState::Connected);
+ settingsModel.setActiveDeviceState(DeviceState::ConnectedBoth);
REQUIRE_FALSE(settingsModel.isDeviceConnecting());
}
}
M module-bluetooth/Bluetooth/Device.hpp => module-bluetooth/Bluetooth/Device.hpp +1 -1
@@ 76,7 76,7 @@ static inline std::string getListOfSupportedServicesInString(uint32_t cod)
enum class DeviceState
{
- Connected,
+ ConnectedBoth,
ConnectedAudio,
ConnectedVoice,
Connecting,
M module-bluetooth/Bluetooth/interface/profiles/A2DP/A2DP.cpp => module-bluetooth/Bluetooth/interface/profiles/A2DP/A2DP.cpp +1 -0
@@ 350,6 350,7 @@ namespace bluetooth
AVRCP::mediaTracker.local_seid);
isConnected = true;
auto &busProxy = const_cast<sys::Service *>(ownerService)->bus;
+ device.deviceState = DeviceState::ConnectedAudio;
busProxy.sendUnicast(std::make_shared<message::bluetooth::ConnectResult>(device, true),
service::name::bluetooth);
break;
M module-bluetooth/Bluetooth/interface/profiles/HFP/HFP.cpp => module-bluetooth/Bluetooth/interface/profiles/HFP/HFP.cpp +15 -1
@@ 9,6 9,8 @@
#include <service-evtmgr/Constants.hpp>
#include <service-audio/AudioMessage.hpp>
#include <service-bluetooth/messages/AudioVolume.hpp>
+#include <service-bluetooth/messages/Connect.hpp>
+#include <service-bluetooth/messages/Disconnect.hpp>
#include <BluetoothWorker.hpp>
#include "SCO/ScoUtils.hpp"
@@ 234,6 236,12 @@ namespace bluetooth
LOG_DEBUG("Service level connection established to %s.\n", bd_addr_to_str(device.address));
isConnected = true;
sendAudioEvent(audio::EventType::BlutoothHFPDeviceState, audio::Event::DeviceState::Connected);
+ {
+ auto &busProxy = const_cast<sys::Service *>(ownerService)->bus;
+ device.deviceState = DeviceState::ConnectedVoice;
+ busProxy.sendUnicast(std::make_shared<message::bluetooth::ConnectResult>(device, true),
+ service::name::bluetooth);
+ }
dump_supported_codecs();
break;
case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED:
@@ 241,7 249,11 @@ namespace bluetooth
aclHandle = HCI_CON_HANDLE_INVALID;
isConnected = false;
sendAudioEvent(audio::EventType::BlutoothHFPDeviceState, audio::Event::DeviceState::Disconnected);
-
+ {
+ auto &busProxy = const_cast<sys::Service *>(ownerService)->bus;
+ busProxy.sendUnicast(std::make_shared<message::bluetooth::DisconnectResult>(device),
+ service::name::bluetooth);
+ }
break;
case HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED:
if (hfp_subevent_audio_connection_established_get_status(event)) {
@@ 384,6 396,8 @@ namespace bluetooth
void HFP::HFPImpl::disconnect()
{
hfp_ag_release_service_level_connection(aclHandle);
+ auto &busProxy = const_cast<sys::Service *>(ownerService)->bus;
+ busProxy.sendUnicast(std::make_shared<message::bluetooth::DisconnectResult>(device), service::name::bluetooth);
}
void HFP::HFPImpl::setDevice(Devicei dev)
M module-bluetooth/Bluetooth/interface/profiles/HSP/HSP.cpp => module-bluetooth/Bluetooth/interface/profiles/HSP/HSP.cpp +12 -0
@@ 12,6 12,7 @@
#include <service-audio/AudioMessage.hpp>
#include <service-bluetooth/Constants.hpp>
#include <service-bluetooth/messages/AudioVolume.hpp>
+#include <service-bluetooth/messages/Connect.hpp>
#include <service-bluetooth/messages/Disconnect.hpp>
#include <service-cellular/service-cellular/CellularServiceAPI.hpp>
#include <service-evtmgr/Constants.hpp>
@@ 173,6 174,12 @@ namespace bluetooth
}
LOG_DEBUG("RFCOMM connection established.\n");
sendAudioEvent(audio::EventType::BlutoothHSPDeviceState, audio::Event::DeviceState::Connected);
+ {
+ auto &busProxy = const_cast<sys::Service *>(ownerService)->bus;
+ device.deviceState = DeviceState::ConnectedVoice;
+ busProxy.sendUnicast(std::make_shared<message::bluetooth::ConnectResult>(device, true),
+ service::name::bluetooth);
+ }
isConnected = true;
break;
case HSP_SUBEVENT_RFCOMM_DISCONNECTION_COMPLETE:
@@ 183,6 190,9 @@ namespace bluetooth
else {
LOG_DEBUG("RFCOMM disconnected.\n");
sendAudioEvent(audio::EventType::BlutoothHSPDeviceState, audio::Event::DeviceState::Disconnected);
+ auto &busProxy = const_cast<sys::Service *>(ownerService)->bus;
+ busProxy.sendUnicast(std::make_shared<message::bluetooth::DisconnectResult>(device),
+ service::name::bluetooth);
}
isConnected = false;
break;
@@ 311,6 321,8 @@ namespace bluetooth
{
hsp_ag_release_audio_connection();
hsp_ag_disconnect();
+ auto &busProxy = const_cast<sys::Service *>(ownerService)->bus;
+ busProxy.sendUnicast(std::make_shared<message::bluetooth::DisconnectResult>(device), service::name::bluetooth);
}
void HSP::HSPImpl::setDevice(const Devicei &dev)
M module-bluetooth/tests/tests-BluetoothDevicesModel.cpp => module-bluetooth/tests/tests-BluetoothDevicesModel.cpp +34 -0
@@ 127,4 127,38 @@ TEST_CASE("Device handling")
devicesModel.removeDevice(device2);
REQUIRE(devicesModel.getDevices().size() == 2);
}
+
+ SECTION("Merge devices states - Voice -> Audio")
+ {
+ device1.deviceState = DeviceState::Paired;
+
+ Devicei updatedDevice = device1;
+
+ updatedDevice.deviceState = DeviceState::ConnectedVoice;
+ devicesModel.mergeInternalDeviceState(updatedDevice);
+ REQUIRE(devicesModel.getDeviceByAddress(device1.address).value().get().deviceState ==
+ DeviceState::ConnectedVoice);
+
+ updatedDevice.deviceState = DeviceState::ConnectedAudio;
+ devicesModel.mergeInternalDeviceState(updatedDevice);
+ REQUIRE(devicesModel.getDeviceByAddress(device1.address).value().get().deviceState ==
+ DeviceState::ConnectedBoth);
+ }
+
+ SECTION("Merge devices states - Audio -> Voice")
+ {
+ device1.deviceState = DeviceState::Paired;
+
+ Devicei updatedDevice = device1;
+
+ updatedDevice.deviceState = DeviceState::ConnectedAudio;
+ devicesModel.mergeInternalDeviceState(updatedDevice);
+ REQUIRE(devicesModel.getDeviceByAddress(device1.address).value().get().deviceState ==
+ DeviceState::ConnectedAudio);
+
+ updatedDevice.deviceState = DeviceState::ConnectedVoice;
+ devicesModel.mergeInternalDeviceState(updatedDevice);
+ REQUIRE(devicesModel.getDeviceByAddress(device1.address).value().get().deviceState ==
+ DeviceState::ConnectedBoth);
+ }
}
M module-services/service-bluetooth/ServiceBluetooth.cpp => module-services/service-bluetooth/ServiceBluetooth.cpp +4 -2
@@ 293,8 293,10 @@ auto ServiceBluetooth::handle(message::bluetooth::Connect *msg) -> std::shared_p
auto ServiceBluetooth::handle(message::bluetooth::ConnectResult *msg) -> std::shared_ptr<sys::Message>
{
if (msg->isSucceed()) {
- auto device = msg->getDevice();
- bluetoothDevicesModel->setInternalDeviceState(device, DeviceState::Connected);
+ auto device = msg->getDevice();
+ auto deviceInModel = bluetoothDevicesModel->getDeviceByAddress(device.address)->get();
+
+ bluetoothDevicesModel->mergeInternalDeviceState(device);
settingsHolder->setValue(bluetooth::Settings::ConnectedDevice, bd_addr_to_str(device.address));
startTimeoutTimer();
M module-services/service-bluetooth/service-bluetooth/BluetoothDevicesModel.cpp => module-services/service-bluetooth/service-bluetooth/BluetoothDevicesModel.cpp +14 -0
@@ 75,3 75,17 @@ void BluetoothDevicesModel::setInternalDeviceState(const Devicei &device, const
auto dev = getDeviceByAddress(device.address);
dev.value().get().deviceState = state;
}
+void BluetoothDevicesModel::mergeInternalDeviceState(const Devicei &device)
+{
+ auto deviceInModel = getDeviceByAddress(device.address).value().get();
+
+ if ((deviceInModel.deviceState == DeviceState::ConnectedVoice &&
+ device.deviceState == DeviceState::ConnectedAudio) ||
+ (device.deviceState == DeviceState::ConnectedVoice &&
+ deviceInModel.deviceState == DeviceState::ConnectedAudio)) {
+ setInternalDeviceState(device, DeviceState::ConnectedBoth);
+ }
+ else {
+ setInternalDeviceState(device, device.deviceState);
+ }
+}
M module-services/service-bluetooth/service-bluetooth/BluetoothDevicesModel.hpp => module-services/service-bluetooth/service-bluetooth/BluetoothDevicesModel.hpp +1 -0
@@ 23,6 23,7 @@ class BluetoothDevicesModel
auto getDevices() -> std::vector<Devicei> &;
void syncDevicesWithApp();
void setInternalDeviceState(const Devicei &device, const DeviceState &state);
+ void mergeInternalDeviceState(const Devicei &device);
private:
std::vector<Devicei> devices{};