~aleteoryx/muditaos

fe1c652ed6c12229ec6874e8cc147355b4eb3573 — Pawel Olejniczak 4 years ago 7c687fc
[EGD-6064] Add connecting and pairing bluetooth states

Pairing and connecting states are now visualized
in All devices window to inform phone user what is happening.
M image/assets/lang/English.json => image/assets/lang/English.json +2 -0
@@ 457,6 457,8 @@
  "app_settings_title_color_test": "Display available colors",
  "app_settings_toolbar_reset": "RESET",
  "app_settings_option_connected": "<text font='gt_pressura' weight='regular' size='27'>CONNECTED</text>",
  "app_settings_option_connecting": "<text font='gt_pressura' weight='regular' size='27'>CONNECTING</text>",
  "app_settings_option_pairing": "<text font='gt_pressura' weight='regular' size='27'>PAIRING</text>",
  "app_settings_title_do_not_disturb": "Do not disturb",
  "app_settings_title_offline": "Offline",
  "app_settings_title_connection_frequency": "Connection frequency",

M module-apps/application-settings-new/ApplicationSettings.cpp => module-apps/application-settings-new/ApplicationSettings.cpp +27 -45
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "ApplicationSettings.hpp"


@@ 204,21 204,9 @@ namespace app
                                service::name::bluetooth);
                return sys::MessageNone{};
            }
            auto addr = bluetoothPairResultMsg->getAddr();
            switchWindow(gui::window::name::dialog_retry,
                         gui::ShowMode::GUI_SHOW_INIT,
                         std::make_unique<gui::DialogMetadataMessage>(
                             gui::DialogMetadata{utils::translate("app_settings_bt"),
                                                 "info_big_circle_W_G",
                                                 utils::translate("app_settings_bluetooth_pairing_error_message"),
                                                 "",
                                                 [=]() -> bool {
                                                     bus.sendUnicast(std::make_shared<BluetoothPairMessage>(addr),
                                                                     service::name::bluetooth);

                                                     returnToPreviousWindow();
                                                     return true;
                                                 }}));
            auto addr    = bluetoothPairResultMsg->getAddr();
            auto message = std::make_shared<BluetoothPairMessage>(std::move(addr));
            switchToAllDevicesViaBtErrorPrompt(std::move(message), "app_settings_bluetooth_pairing_error_message");

            return sys::MessageNone{};
        });


@@ 235,19 223,8 @@ namespace app
            }
            auto addr = unpairResultMsg->getAddr();
            bus.sendUnicast(std::make_shared<::message::bluetooth::RequestBondedDevices>(), service::name::bluetooth);
            switchWindow(gui::window::name::dialog_retry,
                         gui::ShowMode::GUI_SHOW_INIT,
                         std::make_unique<gui::DialogMetadataMessage>(
                             gui::DialogMetadata{utils::translate("app_settings_bt"),
                                                 "info_big_circle_W_G",
                                                 utils::translate("app_settings_bluetooth_unpairing_error_message"),
                                                 "",
                                                 [=]() -> bool {
                                                     bus.sendUnicast(std::make_shared<message::bluetooth::Unpair>(addr),
                                                                     service::name::bluetooth);
                                                     returnToPreviousWindow();
                                                     return true;
                                                 }}));
            auto message = std::make_shared<message::bluetooth::Unpair>(std::move(addr));
            switchToAllDevicesViaBtErrorPrompt(std::move(message), "app_settings_bluetooth_unpairing_error_message");
            return sys::MessageNone{};
        });



@@ 258,21 235,9 @@ namespace app
                                service::name::bluetooth);
                return sys::MessageNone{};
            }
            auto addr = connectResultMsg->getAddr();
            switchWindow(gui::window::name::dialog_retry,
                         gui::ShowMode::GUI_SHOW_INIT,
                         std::make_unique<gui::DialogMetadataMessage>(gui::DialogMetadata{
                             utils::translate("app_settings_bt"),
                             "info_big_circle_W_G",
                             utils::translate("app_settings_bluetooth_connecting_error_message"),
                             "",
                             [=]() -> bool {
                                 bus.sendUnicast(std::make_shared<message::bluetooth::Connect>(addr),
                                                 service::name::bluetooth);
                                 returnToPreviousWindow();
                                 return true;
                             }}));

            auto addr    = connectResultMsg->getAddr();
            auto message = std::make_shared<message::bluetooth::Connect>(std::move(addr));
            switchToAllDevicesViaBtErrorPrompt(std::move(message), "app_settings_bluetooth_connecting_error_message");
            return sys::MessageNone{};
        });



@@ 285,7 250,7 @@ namespace app
                         gui::ShowMode::GUI_SHOW_INIT,
                         std::make_unique<gui::DialogMetadataMessage>(
                             gui::DialogMetadata{utils::translate("app_settings_bt"),
                                                 "info_big_circle_W_G",
                                                 "emergency_W_G",
                                                 utils::translate("app_settings_bluetooth_init_error_message"),
                                                 "",
                                                 [=]() -> bool {


@@ 733,4 698,21 @@ namespace app
        connectionFrequency = val;
        CellularServiceAPI::SetConnectionFrequency(this, val);
    }

    void ApplicationSettingsNew::switchToAllDevicesViaBtErrorPrompt(std::shared_ptr<sys::DataMessage> msg,
                                                                    const std::string &errorMsg)
    {
        switchWindow(gui::window::name::dialog_retry,
                     gui::ShowMode::GUI_SHOW_INIT,
                     std::make_unique<gui::DialogMetadataMessage>(
                         gui::DialogMetadata{utils::translate("app_settings_bt"),
                                             "emergency_W_G",
                                             utils::translate(errorMsg),
                                             "",
                                             [this, message{std::move(msg)}]() -> bool {
                                                 bus.sendUnicast(message, service::name::bluetooth);
                                                 switchWindow(gui::window::name::all_devices);
                                                 return true;
                                             }}));
    }
} /* namespace app */

M module-apps/application-settings-new/ApplicationSettings.hpp => module-apps/application-settings-new/ApplicationSettings.hpp +9 -8
@@ 31,14 31,14 @@ namespace gui::window::name
    inline constexpr auto input_language = "InputLanguage";
    inline constexpr auto locked_screen  = "LockedScreen";

    inline constexpr auto phone              = "Phone";
    inline constexpr auto messages           = "Messages";
    inline constexpr auto message_templates  = "MessageTemplates";
    inline constexpr auto calendar           = "Calendar";
    inline constexpr auto alarm_clock        = "AlarmClock";
    inline constexpr auto sound_select       = "SoundSelect";
    inline constexpr auto torch              = "Torch";
    inline constexpr auto nightshift         = "Nightshift";
    inline constexpr auto phone             = "Phone";
    inline constexpr auto messages          = "Messages";
    inline constexpr auto message_templates = "MessageTemplates";
    inline constexpr auto calendar          = "Calendar";
    inline constexpr auto alarm_clock       = "AlarmClock";
    inline constexpr auto sound_select      = "SoundSelect";
    inline constexpr auto torch             = "Torch";
    inline constexpr auto nightshift        = "Nightshift";

    inline constexpr auto autolock             = "Autolock";
    inline constexpr auto wallpaper            = "Wallpaper";


@@ 237,6 237,7 @@ namespace app

      private:
        void attachQuotesWindows();
        void switchToAllDevicesViaBtErrorPrompt(std::shared_ptr<sys::DataMessage> msg, const std::string &errorMsg);

        Store::GSM::SIM selectedSim   = Store::GSM::get()->selected;
        std::string selectedSimNumber = {};

A module-apps/application-settings-new/data/PairingDeviceData.hpp => module-apps/application-settings-new/data/PairingDeviceData.hpp +24 -0
@@ 0,0 1,24 @@
// 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 <Device.hpp>

namespace gui
{

    class PairingDeviceData : public SwitchData
    {
      public:
        explicit PairingDeviceData(const Devicei &pairingDevice) : pairingDevice(pairingDevice)
        {}
        [[nodiscard]] auto getPairingDevice() const noexcept -> const Devicei &
        {
            return pairingDevice;
        }

      private:
        const Devicei pairingDevice;
    };
} // namespace gui

M module-apps/application-settings-new/windows/AddDeviceWindow.cpp => module-apps/application-settings-new/windows/AddDeviceWindow.cpp +5 -2
@@ 2,8 2,9 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "AddDeviceWindow.hpp"
#include "application-settings-new/ApplicationSettings.hpp"
#include "application-settings-new/data/DeviceData.hpp"
#include <application-settings-new/ApplicationSettings.hpp>
#include <application-settings-new/data/DeviceData.hpp>
#include <application-settings-new/data/PairingDeviceData.hpp>

#include "OptionSetting.hpp"



@@ 43,6 44,8 @@ namespace gui
                device.name,
                [=](gui::Item & /*unused*/) {
                    LOG_DEBUG("Device: %s", device.name.c_str());
                    auto pairingDeviceData = std::make_unique<PairingDeviceData>(device);
                    application->switchWindow(gui::window::name::all_devices, std::move(pairingDeviceData));
                    bluetoothSettingsModel->requestDevicePair(bd_addr_to_str(device.address));
                    application->switchWindow(gui::window::name::all_devices);
                    return true;

M module-apps/application-settings-new/windows/AllDevicesWindow.cpp => module-apps/application-settings-new/windows/AllDevicesWindow.cpp +114 -31
@@ 2,12 2,13 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "AllDevicesWindow.hpp"
#include "application-settings-new/ApplicationSettings.hpp"
#include "application-settings-new/data/BondedDevicesData.hpp"
#include "application-settings-new/widgets/SettingsStyle.hpp"
#include <application-settings-new/ApplicationSettings.hpp>
#include <application-settings-new/data/BondedDevicesData.hpp>
#include <application-settings-new/data/PairingDeviceData.hpp>
#include <application-settings-new/widgets/SettingsStyle.hpp>

#include "DialogMetadataMessage.hpp"
#include "OptionSetting.hpp"
#include <DialogMetadataMessage.hpp>
#include <OptionSetting.hpp>

#include <InputEvent.hpp>
#include <Image.hpp>


@@ 43,11 44,31 @@ namespace gui
    {
        if (mode == ShowMode::GUI_SHOW_RETURN) {
            bluetoothSettingsModel->stopScan();
            if (activeDevice.state == ActiveDevice::DeviceState::Connecting) {
                activeDevice.address.clear();
                activeDevice.state = ActiveDevice::DeviceState::Unknown;
            }
            else if (activeDevice.state == ActiveDevice::DeviceState::Pairing) {
                devices.erase(std::remove_if(devices.begin(),
                                             devices.end(),
                                             [&](const auto &device) {
                                                 return (bd_addr_to_str(device.address) == activeDevice.address);
                                             }),
                              devices.end());

                activeDevice.address.clear();
                activeDevice.state = ActiveDevice::DeviceState::Unknown;
            }
        }
        if (const auto bondedDevicesData = dynamic_cast<BondedDevicesData *>(data); bondedDevicesData != nullptr) {
            devices              = bondedDevicesData->getDevices();
            activeDevice.address = bondedDevicesData->getAddressOfConnectedDevice();
            activeDevice.state   = ActiveDevice::DeviceState::Connected;
        }
        const auto newData = dynamic_cast<BondedDevicesData *>(data);
        if (newData != nullptr) {
            devices                  = newData->getDevices();
            addressOfConnectedDevice = newData->getAddressOfConnectedDevice();
        else if (const auto pairingDeviceData = dynamic_cast<PairingDeviceData *>(data); pairingDeviceData != nullptr) {
            activeDevice.address = bd_addr_to_str(pairingDeviceData->getPairingDevice().address);
            activeDevice.state   = ActiveDevice::DeviceState::Pairing;
            devices.emplace_back(pairingDeviceData->getPairingDevice());
        }
        refreshOptionsList();
    }


@@ 71,13 92,13 @@ namespace gui
            devices.erase(std::remove_if(devices.begin(),
                                         devices.end(),
                                         [&](const auto &device) {
                                             return (bd_addr_to_str(device.address) == addressOfSelectedDevice);
                                             return (bd_addr_to_str(device.address) == addressOfDeviceSelected);
                                         }),
                          devices.end());
            bottomBar->setActive(BottomBar::Side::LEFT, false);
            bottomBar->setActive(BottomBar::Side::CENTER, false);
            refreshOptionsList();
            bluetoothSettingsModel->requestDeviceUnpair(addressOfSelectedDevice);
            bluetoothSettingsModel->requestDeviceUnpair(addressOfDeviceSelected);
            return true;
        }
        return AppWindow::onInput(inputEvent);


@@ 85,41 106,103 @@ namespace gui

    auto AllDevicesWindow::buildOptionsList() -> std::list<Option>
    {
        bottomBar->setActive(BottomBar::Side::CENTER, !devices.empty());

        std::list<gui::Option> optionsList;
        for (const auto &device : devices) {
            std::string addr{bd_addr_to_str(device.address)};
            auto isConnected = addr == addressOfConnectedDevice;
            ActiveDevice newDevice(bd_addr_to_str(device.address));
            newDevice.address == activeDevice.address ? newDevice.state = activeDevice.state
                                                      : newDevice.state = ActiveDevice::DeviceState::Paired;
            UTF8 textOnCenter                                           = getTextOnCenter(newDevice.state);
            option::SettingRightItem rightItem                          = getRightItem(newDevice.state);
            UTF8 textOnRight                                            = getTextOnRight(newDevice.state);

            optionsList.emplace_back(std::make_unique<gui::option::OptionSettings>(
                device.name,
                [=](gui::Item & /*item*/) {
                    LOG_DEBUG("Device: %s", device.name.c_str());
                    if (isConnected) {
                        bluetoothSettingsModel->requestDisconnection();
                        addressOfConnectedDevice.clear();
                        refreshOptionsList();
                    }
                    else {
                        bluetoothSettingsModel->requestConnection(addr);
                    }

                    return true;
                    return handleDeviceAction(newDevice);
                },
                [=](gui::Item &item) {
                    if (item.focus) {
                        this->setBottomBarText(isConnected ? utils::translate("common_disconnect")
                                                           : utils::translate("common_connect"),
                                               BottomBar::Side::CENTER);
                        this->setBottomBarText(utils::translate("common_forget"), BottomBar::Side::LEFT);
                        this->bottomBar->setActive(BottomBar::Side::LEFT, true);
                        addressOfSelectedDevice = addr;
                        this->setBottomBarText(textOnCenter, BottomBar::Side::CENTER);
                        if (newDevice.state != ActiveDevice::DeviceState::Pairing) {
                            this->setBottomBarText(utils::translate("common_forget"), BottomBar::Side::LEFT);
                            this->bottomBar->setActive(BottomBar::Side::LEFT, true);
                        }
                        addressOfDeviceSelected = newDevice.address;
                    }
                    return true;
                },
                nullptr,
                isConnected ? gui::option::SettingRightItem::Text : gui::option::SettingRightItem::Bt,
                rightItem,
                false,
                utils::translate("app_settings_option_connected")));
                std::move(textOnRight)));
        }
        return optionsList;
    }

    UTF8 AllDevicesWindow::getTextOnCenter(const ActiveDevice::DeviceState &state) const
    {
        switch (state) {
        case ActiveDevice::DeviceState::Connected:
            return utils::translate("common_disconnect");
        case ActiveDevice::DeviceState::Paired:
            return utils::translate("common_connect");
        case ActiveDevice::DeviceState::Pairing:
        case ActiveDevice::DeviceState::Connecting:
        case ActiveDevice::DeviceState::Unknown:
            break;
        }
        return UTF8();
    }

    UTF8 AllDevicesWindow::getTextOnRight(const ActiveDevice::DeviceState &state) const
    {
        switch (state) {
        case ActiveDevice::DeviceState::Connected:
            return utils::translate("app_settings_option_connected");
        case ActiveDevice::DeviceState::Connecting:
            return utils::translate("app_settings_option_connecting");
        case ActiveDevice::DeviceState::Pairing:
            return utils::translate("app_settings_option_pairing");
        case ActiveDevice::DeviceState::Paired:
        case ActiveDevice::DeviceState::Unknown:
            break;
        }
        return UTF8();
    }

    option::SettingRightItem AllDevicesWindow::getRightItem(const ActiveDevice::DeviceState &state) const
    {
        switch (state) {
        case ActiveDevice::DeviceState::Connected:
        case ActiveDevice::DeviceState::Connecting:
        case ActiveDevice::DeviceState::Pairing:
            return option::SettingRightItem::Text;
        case ActiveDevice::DeviceState::Paired:
            return option::SettingRightItem::Bt;
        case ActiveDevice::DeviceState::Unknown:
            break;
        }
        return option::SettingRightItem::Disabled;
    }

    auto AllDevicesWindow::handleDeviceAction(const ActiveDevice &newDevice) -> bool
    {
        if (newDevice.state == ActiveDevice::DeviceState::Connected) {
            activeDevice.address.clear();
            activeDevice.state = ActiveDevice::DeviceState::Unknown;
            bluetoothSettingsModel->requestDisconnection();
            refreshOptionsList();
        }
        else if (newDevice.state == ActiveDevice::DeviceState::Paired) {
            activeDevice.address = newDevice.address;
            activeDevice.state   = ActiveDevice::DeviceState::Connecting;
            bluetoothSettingsModel->requestConnection(newDevice.address);
            refreshOptionsList();
        }
        return true;
    }

} // namespace gui

M module-apps/application-settings-new/windows/AllDevicesWindow.hpp => module-apps/application-settings-new/windows/AllDevicesWindow.hpp +24 -2
@@ 11,6 11,24 @@ namespace gui
{
    class Image;

    class ActiveDevice
    {
      public:
        explicit ActiveDevice(std::string address) : address(std::move(address))
        {}
        ActiveDevice() = default;
        enum class DeviceState
        {
            Connected,
            Connecting,
            Pairing,
            Paired,
            Unknown
        };
        DeviceState state = DeviceState::Unknown;
        std::string address;
    };

    class AllDevicesWindow : public BaseSettingsWindow
    {
      public:


@@ 21,12 39,16 @@ namespace gui
        auto buildOptionsList() -> std::list<Option> override;
        void onBeforeShow(ShowMode mode, SwitchData *data) override;
        auto onInput(const InputEvent &inputEvent) -> bool override;
        UTF8 getTextOnCenter(const ActiveDevice::DeviceState &) const;
        UTF8 getTextOnRight(const ActiveDevice::DeviceState &) const;
        option::SettingRightItem getRightItem(const ActiveDevice::DeviceState &) const;
        auto handleDeviceAction(const ActiveDevice &) -> bool;

        ActiveDevice activeDevice;
        Image *leftArrowImage = nullptr;
        Image *crossImage     = nullptr;
        std::vector<Devicei> devices{};
        std::string addressOfConnectedDevice;
        std::string addressOfSelectedDevice;
        std::string addressOfDeviceSelected;
        std::unique_ptr<BluetoothSettingsModel> bluetoothSettingsModel{};
    };