From c51411c8768f02327ef61abfc3ab85ca8b8f428d Mon Sep 17 00:00:00 2001 From: Pawel Olejniczak Date: Thu, 25 Feb 2021 21:55:38 +0100 Subject: [PATCH] [EGD-5861] Complete bluetooth connecting process on settings side Enable connecting BT devices in settings. Connect popup and add adjust messages for connection error handling. --- image/assets/lang/English.json | 5 +++ .../ApplicationSettings.cpp | 30 ++++++++++++- .../data/BondedDevicesData.hpp | 10 ++++- .../models/BluetoothSettingsModel.cpp | 13 +++++- .../models/BluetoothSettingsModel.hpp | 3 +- .../windows/AddDeviceWindow.cpp | 1 + .../windows/AllDevicesWindow.cpp | 21 +++++++--- .../windows/AllDevicesWindow.hpp | 1 + .../service-bluetooth/ServiceBluetooth.cpp | 28 ++++++++++--- .../messages/BondedDevices.hpp | 8 +++- .../service-bluetooth/messages/Connect.hpp | 42 +++++++++++++++++++ .../service-bluetooth/messages/Disconnect.hpp | 12 ++++++ .../service-bluetooth/messages/Passkey.hpp | 2 +- 13 files changed, 157 insertions(+), 19 deletions(-) create mode 100644 module-services/service-bluetooth/service-bluetooth/messages/Connect.hpp create mode 100644 module-services/service-bluetooth/service-bluetooth/messages/Disconnect.hpp diff --git a/image/assets/lang/English.json b/image/assets/lang/English.json index f8a94fb96ea86d7bc9f905773549f5b47e040dad..28db5d9c5200d0867edf75247922556186564c94 100644 --- a/image/assets/lang/English.json +++ b/image/assets/lang/English.json @@ -25,6 +25,8 @@ "common_pause": "PAUSE", "common_retry": "TRY AGAIN", "common_abort": "ABORT", + "common_connect": "CONNECT", + "common_disconnect": "DISCONNECT", "common_mo": "MO", "common_tu": "TU", "common_we": "WE", @@ -321,7 +323,9 @@ "app_settings_bluetooth_phone_name": "Phone name", "app_settings_bluetooth_phone_visibility": "Phone visibility", "app_settings_bluetooth_enter_passkey": "Enter passkey:", + "app_settings_bluetooth_init_error_message": "Bluetooth initialization process \nhas failed. TRY AGAIN.", "app_settings_bluetooth_pairing_error_message": "Pairing process with %NAME\nhas failed. Check the device\nand TRY AGAIN.", + "app_settings_bluetooth_connecting_error_message": "Connection process has failed.\nCheck the device and TRY AGAIN.", "app_settings_net": "Network", "app_settings_disp_key": "Display and keypad", "app_settings_display_display_light": "Display light", @@ -422,6 +426,7 @@ "app_settings_apn_apnprotocol": "APN Protocol", "app_settings_title_color_test": "Display available colors", "app_settings_toolbar_reset": "RESET", + "app_settings_option_connected": "CONNECTED", "app_phonebook_title_main": "Contacts", "app_phonebook_search_win_contacts": "Contacts", "common_search_uc": "Search", diff --git a/module-apps/application-settings-new/ApplicationSettings.cpp b/module-apps/application-settings-new/ApplicationSettings.cpp index 134d0077a190aafc533a9c57c9275e18b9a3ede9..1ae309c68a117b8a6c84041f7cb23f274cf768b8 100644 --- a/module-apps/application-settings-new/ApplicationSettings.cpp +++ b/module-apps/application-settings-new/ApplicationSettings.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -149,8 +150,8 @@ namespace app connect(typeid(::message::bluetooth::ResponseBondedDevices), [&](sys::Message *msg) { auto responseBondedDevicesMsg = static_cast<::message::bluetooth::ResponseBondedDevices *>(msg); if (gui::window::name::all_devices == getCurrentWindow()->getName()) { - auto bondedDevicesData = - std::make_unique(responseBondedDevicesMsg->getDevices()); + auto bondedDevicesData = std::make_unique( + responseBondedDevicesMsg->getDevices(), responseBondedDevicesMsg->getAddressOfConnectedDevice()); switchWindow(gui::window::name::all_devices, std::move(bondedDevicesData)); } return sys::MessageNone{}; @@ -197,6 +198,31 @@ namespace app return sys::MessageNone{}; }); + connect(typeid(::message::bluetooth::ConnectResult), [&](sys::Message *msg) { + auto connectResultMsg = static_cast<::message::bluetooth::ConnectResult *>(msg); + if (connectResultMsg->isSucceed()) { + bus.sendUnicast(std::make_shared<::message::bluetooth::RequestBondedDevices>(), + service::name::bluetooth); + return sys::MessageNone{}; + } + + switchWindow(gui::window::name::dialog_retry, + gui::ShowMode::GUI_SHOW_INIT, + std::make_unique( + gui::DialogMetadata{utils::localize.get("app_settings_bt"), + "search_big", + utils::localize.get("app_settings_bluetooth_connecting_error_message"), + "", + [=]() -> bool { + bus.sendUnicast(std::make_shared( + connectResultMsg->getAddr()), + service::name::bluetooth); + return true; + }})); + + return sys::MessageNone{}; + }); + connect(typeid(CellularGetAPNResponse), [&](sys::Message *msg) { if (gui::window::name::apn_settings == getCurrentWindow()->getName()) { auto apns = dynamic_cast(msg); diff --git a/module-apps/application-settings-new/data/BondedDevicesData.hpp b/module-apps/application-settings-new/data/BondedDevicesData.hpp index 2a5b2eebad87460f012e9c3fadd2db75229c137c..8177ad6057e8bfdc5d975246ee0f84ce5649f54c 100644 --- a/module-apps/application-settings-new/data/BondedDevicesData.hpp +++ b/module-apps/application-settings-new/data/BondedDevicesData.hpp @@ -11,14 +11,20 @@ namespace gui class BondedDevicesData : public SwitchData { public: - explicit BondedDevicesData(std::vector devices) : devices(std::move(devices)) + explicit BondedDevicesData(std::vector devices, std::string addressOfConnectedDevice) + : devices(std::move(devices)), addressOfConnectedDevice(std::move(addressOfConnectedDevice)) {} [[nodiscard]] auto getDevices() const noexcept -> const std::vector & { return devices; } + [[nodiscard]] auto getAddressOfConnectedDevice() const noexcept -> const std::string & + { + return addressOfConnectedDevice; + } private: - const std::vector devices; + const std::vector devices{}; + const std::string addressOfConnectedDevice; }; } // namespace gui diff --git a/module-apps/application-settings-new/models/BluetoothSettingsModel.cpp b/module-apps/application-settings-new/models/BluetoothSettingsModel.cpp index 10b8b1ca0e008c5316a1dabcaf92622ab21b5f45..8f56b1f98ba6f35919fa2520ba7a0d52a1b73d84 100644 --- a/module-apps/application-settings-new/models/BluetoothSettingsModel.cpp +++ b/module-apps/application-settings-new/models/BluetoothSettingsModel.cpp @@ -5,7 +5,9 @@ #include #include +#include #include +#include #include #include #include @@ -67,7 +69,14 @@ void BluetoothSettingsModel::responsePasskey(std::string passkey) application->bus.sendUnicast(std::make_shared(std::move(passkey)), service::name::bluetooth); } -void BluetoothSettingsModel::requestAudioConnection(std::string addr) + +void BluetoothSettingsModel::requestConnection(std::string addr) +{ + application->bus.sendUnicast(std::make_shared(std::move(addr)), + service::name::bluetooth); +} + +void BluetoothSettingsModel::requestDisconnection() { - application->bus.sendUnicast(std::make_shared(std::move(addr)), service::name::bluetooth); + application->bus.sendUnicast(std::make_shared(), service::name::bluetooth); } diff --git a/module-apps/application-settings-new/models/BluetoothSettingsModel.hpp b/module-apps/application-settings-new/models/BluetoothSettingsModel.hpp index 9b3d17545583ca3f25b11f139192597d00d97e58..dedcdc55b96486dd7e0cfe0d2145f917c774378e 100644 --- a/module-apps/application-settings-new/models/BluetoothSettingsModel.hpp +++ b/module-apps/application-settings-new/models/BluetoothSettingsModel.hpp @@ -21,10 +21,11 @@ class BluetoothSettingsModel void setDeviceName(const UTF8 &deviceName); void requestBondedDevices(); void requestScan(); - void requestAudioConnection(std::string addr); void stopScan(); void requestDevicePairing(std::string addr); void responsePasskey(std::string passkey); + void requestConnection(std::string addr); + void requestDisconnection(); private: app::Application *application = nullptr; diff --git a/module-apps/application-settings-new/windows/AddDeviceWindow.cpp b/module-apps/application-settings-new/windows/AddDeviceWindow.cpp index 4d3c9b007c8c0f588e5b207f496c789c8eedfbfa..81fce1482c0eea98b4579b7c7765b7b5a6c47cc0 100644 --- a/module-apps/application-settings-new/windows/AddDeviceWindow.cpp +++ b/module-apps/application-settings-new/windows/AddDeviceWindow.cpp @@ -44,6 +44,7 @@ namespace gui [=](gui::Item & /*unused*/) { LOG_DEBUG("Device: %s", device.name.c_str()); bluetoothSettingsModel->requestDevicePairing(bd_addr_to_str(device.address)); + application->switchWindow(gui::window::name::all_devices); return true; }, nullptr, diff --git a/module-apps/application-settings-new/windows/AllDevicesWindow.cpp b/module-apps/application-settings-new/windows/AllDevicesWindow.cpp index 246fc9cd602c9757d2494715278882707a197aa0..12b4aaab922e73d523fb4c880f701d4fee283623 100644 --- a/module-apps/application-settings-new/windows/AllDevicesWindow.cpp +++ b/module-apps/application-settings-new/windows/AllDevicesWindow.cpp @@ -42,7 +42,8 @@ namespace gui { const auto newData = dynamic_cast(data); if (newData != nullptr) { - devices = newData->getDevices(); + devices = newData->getDevices(); + addressOfConnectedDevice = newData->getAddressOfConnectedDevice(); } refreshOptionsList(); } @@ -66,17 +67,27 @@ namespace gui { std::list optionsList; for (const auto &device : devices) { + std::string addr{bd_addr_to_str(device.address)}; + auto isConnected = addr == addressOfConnectedDevice; optionsList.emplace_back(std::make_unique( device.name, [=](gui::Item & /*item*/) { LOG_DEBUG("Device: %s", device.name.c_str()); - std::string addr{bd_addr_to_str(device.address)}; - bluetoothSettingsModel->requestAudioConnection(std::move(addr)); + bluetoothSettingsModel->requestConnection(addr); + return true; + }, + [=](gui::Item &item) { + if (item.focus) { + this->setBottomBarText(isConnected ? utils::translateI18("common_disconnect") + : utils::translateI18("common_connect"), + BottomBar::Side::CENTER); + } return true; }, nullptr, - nullptr, - gui::option::SettingRightItem::Bt)); + isConnected ? gui::option::SettingRightItem::Text : gui::option::SettingRightItem::Bt, + false, + utils::localize.get("app_settings_option_connected"))); } return optionsList; } diff --git a/module-apps/application-settings-new/windows/AllDevicesWindow.hpp b/module-apps/application-settings-new/windows/AllDevicesWindow.hpp index 4a1f47dc7575027c38d8148d594252cc2ca012ec..7ee5196fb4733f6f9e2d9b33bc0d5893125f5a63 100644 --- a/module-apps/application-settings-new/windows/AllDevicesWindow.hpp +++ b/module-apps/application-settings-new/windows/AllDevicesWindow.hpp @@ -23,6 +23,7 @@ namespace gui Image *leftArrowImage = nullptr; Image *crossImage = nullptr; std::vector devices; + std::string addressOfConnectedDevice; std::unique_ptr bluetoothSettingsModel; }; diff --git a/module-services/service-bluetooth/ServiceBluetooth.cpp b/module-services/service-bluetooth/ServiceBluetooth.cpp index a31916cab32c20f1ec3a1b4a2862d10eb64d4029..f3dd5f139622507316826361fee017a392853822 100644 --- a/module-services/service-bluetooth/ServiceBluetooth.cpp +++ b/module-services/service-bluetooth/ServiceBluetooth.cpp @@ -4,13 +4,14 @@ #include "service-bluetooth/ServiceBluetooth.hpp" #include "service-bluetooth/BluetoothMessage.hpp" - #include #include #include #include #include #include +#include "service-bluetooth/messages/Connect.hpp" +#include "service-bluetooth/messages/Disconnect.hpp" #include "service-bluetooth/messages/Status.hpp" #include "service-bluetooth/messages/SetStatus.hpp" #include @@ -28,8 +29,8 @@ ServiceBluetooth::ServiceBluetooth() : sys::Service(service::name::bluetooth, "", 4096) { - auto settings = std::make_unique(this); - settingsHolder = std::make_shared(std::move(settings)); + auto settings = std::make_unique(this); + settingsHolder = std::make_shared(std::move(settings)); bluetooth::KeyStorage::settings = settingsHolder; LOG_INFO("[ServiceBluetooth] Initializing"); } @@ -60,7 +61,7 @@ sys::ReturnCodes ServiceBluetooth::InitHandler() std::visit(bluetooth::StringVisitor(), this->settingsHolder->getValue(bluetooth::Settings::BondedDevices)); return std::make_shared( - SettingsSerializer::fromString(bondedDevicesStr)); + SettingsSerializer::fromString(bondedDevicesStr), std::string()); }); connect(message::bluetooth::RequestStatus(), [&](sys::Message *msg) { @@ -101,7 +102,7 @@ sys::ReturnCodes ServiceBluetooth::InitHandler() }); connect(typeid(BluetoothPairMessage), [&](sys::Message *msg) { - auto pairMsg = static_cast(msg); + auto pairMsg = static_cast(msg); const auto addrString = pairMsg->addr; bd_addr_t addr; sscanf_bd_addr(addrString.c_str(), addr); @@ -130,6 +131,23 @@ sys::ReturnCodes ServiceBluetooth::InitHandler() return sys::MessageNone{}; }); + connect(typeid(message::bluetooth::Connect), [&](sys::Message *msg) { + auto connectMsg = static_cast(msg); + const auto addrString = connectMsg->getAddr(); + LOG_DEBUG("Connecting with %s", addrString.c_str()); + bd_addr_t addr; + sscanf_bd_addr(addrString.c_str(), addr); + sendWorkerCommand(bluetooth::Command(bluetooth::Command::Type::ConnectAudio, addr)); + bus.sendUnicast(std::make_shared(addrString, true), + service::name::bluetooth); + return sys::MessageNone{}; + }); + + connect(typeid(message::bluetooth::Disconnect), [&](sys::Message *msg) { + sendWorkerCommand(bluetooth::Command(bluetooth::Command::Type::DisconnectAudio)); + return sys::MessageNone{}; + }); + settingsHolder->onStateChange = [this]() { auto initialState = std::visit(bluetooth::IntVisitor(), settingsHolder->getValue(bluetooth::Settings::State)); if (static_cast(initialState) == BluetoothStatus::State::On) { diff --git a/module-services/service-bluetooth/service-bluetooth/messages/BondedDevices.hpp b/module-services/service-bluetooth/service-bluetooth/messages/BondedDevices.hpp index 1ea0798e8a96ca035df171401b0a37df243c009e..e138c93005c575ec9dd52569c5cd72edc08d5960 100644 --- a/module-services/service-bluetooth/service-bluetooth/messages/BondedDevices.hpp +++ b/module-services/service-bluetooth/service-bluetooth/messages/BondedDevices.hpp @@ -13,14 +13,20 @@ namespace message::bluetooth class ResponseBondedDevices : public BluetoothMessage { public: - explicit ResponseBondedDevices(std::vector devices) : devices(std::move(devices)) + explicit ResponseBondedDevices(std::vector devices, std::string addressOfConnectedDevice) + : devices(std::move(devices)), addressOfConnectedDevice(std::move(addressOfConnectedDevice)) {} [[nodiscard]] auto getDevices() const -> std::vector { return devices; } + [[nodiscard]] auto getAddressOfConnectedDevice() const noexcept -> const std::string & + { + return addressOfConnectedDevice; + } private: std::vector devices; + std::string addressOfConnectedDevice; }; } // namespace message::bluetooth diff --git a/module-services/service-bluetooth/service-bluetooth/messages/Connect.hpp b/module-services/service-bluetooth/service-bluetooth/messages/Connect.hpp new file mode 100644 index 0000000000000000000000000000000000000000..46fdeaceaa8fa94f5eab124396602ca78cdaf8e7 --- /dev/null +++ b/module-services/service-bluetooth/service-bluetooth/messages/Connect.hpp @@ -0,0 +1,42 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#include "service-bluetooth/BluetoothMessage.hpp" + +namespace message::bluetooth +{ + class Connect : public BluetoothMessage + { + public: + explicit Connect(std::string addr) : addr(std::move(addr)) + {} + [[nodiscard]] auto getAddr() const -> std::string + { + return addr; + } + + private: + std::string addr; + }; + + class ConnectResult : public BluetoothMessage + { + public: + explicit ConnectResult(std::string addr, bool succeed) : addr(std::move(addr)), succeed(succeed) + {} + [[nodiscard]] auto getAddr() const -> std::string + { + return addr; + } + [[nodiscard]] auto isSucceed() const -> bool + { + return succeed; + } + + private: + std::string addr; + bool succeed; + }; +} // namespace message::bluetooth diff --git a/module-services/service-bluetooth/service-bluetooth/messages/Disconnect.hpp b/module-services/service-bluetooth/service-bluetooth/messages/Disconnect.hpp new file mode 100644 index 0000000000000000000000000000000000000000..90f3f049b67100ef2c697f9279415bfd1f96ec82 --- /dev/null +++ b/module-services/service-bluetooth/service-bluetooth/messages/Disconnect.hpp @@ -0,0 +1,12 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#include "service-bluetooth/BluetoothMessage.hpp" + +namespace message::bluetooth +{ + class Disconnect : public BluetoothMessage + {}; +} // namespace message::bluetooth diff --git a/module-services/service-bluetooth/service-bluetooth/messages/Passkey.hpp b/module-services/service-bluetooth/service-bluetooth/messages/Passkey.hpp index 7a87ea0cadb9b798632b01763441a05dfe5979a2..0e59569a2795e1d9ac2bd9ff1e54d9f55b4967a1 100644 --- a/module-services/service-bluetooth/service-bluetooth/messages/Passkey.hpp +++ b/module-services/service-bluetooth/service-bluetooth/messages/Passkey.hpp @@ -15,7 +15,7 @@ namespace message::bluetooth public: explicit ResponsePasskey(std::string passkey) : passkey(std::move(passkey)) {} - [[nodiscard]] auto getName() const -> std::string + [[nodiscard]] auto getPasskey() const -> std::string { return passkey; }