~aleteoryx/muditaos

ad3aa54b661e8c5f8d1fbd62299092e29606a237 — Przemyslaw Brudny 3 years ago 014d24f
[MOS-123] Added bluetooth authentication popups

Added bluetooth authentication popups with different
pair methods and process info display.
38 files changed, 641 insertions(+), 240 deletions(-)

M image/assets/lang/English.json
M module-apps/application-alarm-clock/ApplicationAlarmClock.cpp
M module-apps/application-antenna/ApplicationAntenna.cpp
M module-apps/application-calculator/ApplicationCalculator.cpp
M module-apps/application-calendar/ApplicationCalendar.cpp
M module-apps/application-calllog/ApplicationCallLog.cpp
M module-apps/application-desktop/ApplicationDesktop.cpp
M module-apps/application-meditation/ApplicationMeditation.cpp
M module-apps/application-messages/ApplicationMessages.cpp
M module-apps/application-music-player/ApplicationMusicPlayer.cpp
M module-apps/application-notes/ApplicationNotes.cpp
M module-apps/application-phonebook/ApplicationPhonebook.cpp
M module-apps/application-settings/ApplicationSettings.cpp
M module-apps/application-settings/CMakeLists.txt
M module-apps/application-settings/models/bluetooth/BluetoothSettingsModel.cpp
M module-apps/application-settings/models/bluetooth/BluetoothSettingsModel.hpp
M module-apps/application-settings/widgets/SettingsStyle.hpp
M module-apps/application-settings/windows/WindowNames.hpp
D module-apps/application-settings/windows/bluetooth/BluetoothCheckPasskeyWindow.cpp
D module-apps/application-settings/windows/bluetooth/BluetoothCheckPasskeyWindow.hpp
M module-apps/apps-common/ApplicationCommonPopupBlueprints.cpp
A module-apps/apps-common/popups/BluetoothAuthenticatePopup.cpp
A module-apps/apps-common/popups/BluetoothAuthenticatePopup.hpp
A module-apps/apps-common/popups/BluetoothInfoPopup.cpp
A module-apps/apps-common/popups/BluetoothInfoPopup.hpp
M module-apps/apps-common/popups/CMakeLists.txt
M module-apps/apps-common/popups/Popups.cpp
M module-apps/apps-common/popups/Popups.hpp
M module-apps/apps-common/popups/data/PopupRequestParams.hpp
M module-bluetooth/Bluetooth/interface/profiles/GAP/GAP.cpp
M module-services/service-bluetooth/ServiceBluetooth.cpp
M module-services/service-bluetooth/service-bluetooth/BluetoothMessage.hpp
M module-services/service-bluetooth/service-bluetooth/ServiceBluetooth.hpp
A module-services/service-bluetooth/service-bluetooth/messages/Authenticate.hpp
M module-services/service-bluetooth/service-bluetooth/messages/Connect.hpp
D module-services/service-bluetooth/service-bluetooth/messages/Passkey.hpp
M products/PurePhone/apps/Application.cpp
M products/PurePhone/services/appmgr/ApplicationManager.cpp
M image/assets/lang/English.json => image/assets/lang/English.json +8 -1
@@ 322,7 322,6 @@
  "app_settings_bluetooth_main": "Bluetooth",
  "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": "<text font='gt_pressura' weight='regular' size='27'>Bluetooth initialization process has failed.</text>",
  "app_settings_bluetooth_pairing_error_message": "<text font='gt_pressura' weight='regular' size='27'>Pairing process has failed.<br></br>Check the device and </text> <text font='gt_pressura' weight='bold' size='27'>TRY AGAIN.</text>",
  "app_settings_bluetooth_unpairing_error_message": "<text font='gt_pressura' weight='regular' size='27'>Unpairing process has failed.<br></br>Check the device and </text> <text font='gt_pressura' weight='bold' size='27'>TRY AGAIN.</text>",


@@ 587,6 586,14 @@
  "tethering_enable_question": "<text>You're connected to the computer.<br />Turn tethering on?<br /><text color='5'>(some functions may be disabled)</text></text>",
  "tethering_phone_mode_change_prohibited": "<text>Tethering is on.<br /><br />Other modes (Connected, DND,<br />Offline) are overriden by this mode<br />and are not working.</text>",
  "tethering_menu_access_decline": "<text>Tethering is on.<br /><br />To access menu,<br />turn tethering off.</text>",
  "bluetooth_popup": "Bluetooth",
  "bluetooth_popup_pin": "Enter PIN:",
  "bluetooth_popup_passkey": "Enter passkey:",
  "bluetooth_popup_pair_cancel": "<text>Device </text><text weight='bold'><token>$DEVICE</token></text><text> would like to pair with your phone</text>",
  "bluetooth_popup_pair": "Pair",
  "bluetooth_popup_cancel": "Cancel",
  "bluetooth_info_popup_success": "<text>Your phone is connected to: <br></br></text><text weight='bold'><token>$DEVICE</token></text>",
  "bluetooth_info_popup_error": "<text>Pairing process with </text><text weight='bold'><token>$DEVICE</token></text><br></br><text> has failed. Error code: <token>$ERROR</token></text>",
  "app_bell_settings_time_units_time_fmt_top_message": "Time format",
  "app_bell_settings_time_units_time_message": "Time",
  "app_bellmain_alarm": "Alarm",

M module-apps/application-alarm-clock/ApplicationAlarmClock.cpp => module-apps/application-alarm-clock/ApplicationAlarmClock.cpp +2 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "ApplicationAlarmClock.hpp"


@@ 111,6 111,7 @@ namespace app

        attachPopups({gui::popup::ID::Volume,
                      gui::popup::ID::Tethering,
                      gui::popup::ID::BluetoothAuthenticate,
                      gui::popup::ID::PhoneModes,
                      gui::popup::ID::PhoneLock,
                      gui::popup::ID::Alarm});

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

/*


@@ 162,6 162,7 @@ namespace app

        attachPopups({gui::popup::ID::Volume,
                      gui::popup::ID::Tethering,
                      gui::popup::ID::BluetoothAuthenticate,
                      gui::popup::ID::PhoneModes,
                      gui::popup::ID::PhoneLock,
                      gui::popup::ID::Alarm});

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

#include <application-calculator/ApplicationCalculator.hpp>


@@ 39,6 39,7 @@ namespace app

        attachPopups({gui::popup::ID::Volume,
                      gui::popup::ID::Tethering,
                      gui::popup::ID::BluetoothAuthenticate,
                      gui::popup::ID::PhoneModes,
                      gui::popup::ID::PhoneLock,
                      gui::popup::ID::Alarm});

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

#include <application-calendar/ApplicationCalendar.hpp>


@@ 45,6 45,7 @@ namespace app

        attachPopups({gui::popup::ID::Volume,
                      gui::popup::ID::Tethering,
                      gui::popup::ID::BluetoothAuthenticate,
                      gui::popup::ID::PhoneModes,
                      gui::popup::ID::PhoneLock,
                      gui::popup::ID::Alarm});

M module-apps/application-calllog/ApplicationCallLog.cpp => module-apps/application-calllog/ApplicationCallLog.cpp +1 -0
@@ 99,6 99,7 @@ namespace app

        attachPopups({gui::popup::ID::Volume,
                      gui::popup::ID::Tethering,
                      gui::popup::ID::BluetoothAuthenticate,
                      gui::popup::ID::PhoneModes,
                      gui::popup::ID::PhoneLock,
                      gui::popup::ID::Alarm});

M module-apps/application-desktop/ApplicationDesktop.cpp => module-apps/application-desktop/ApplicationDesktop.cpp +1 -0
@@ 182,6 182,7 @@ namespace app

        attachPopups({gui::popup::ID::Volume,
                      gui::popup::ID::Tethering,
                      gui::popup::ID::BluetoothAuthenticate,
                      gui::popup::ID::PhoneModes,
                      gui::popup::ID::PhoneLock,
                      gui::popup::ID::SimLock,

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

#include "ApplicationMeditation.hpp"


@@ 64,6 64,7 @@ namespace app

        attachPopups({gui::popup::ID::Volume,
                      gui::popup::ID::Tethering,
                      gui::popup::ID::BluetoothAuthenticate,
                      gui::popup::ID::PhoneModes,
                      gui::popup::ID::PhoneLock,
                      gui::popup::ID::Alarm});

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

#include "ApplicationMessages.hpp"


@@ 154,6 154,7 @@ namespace app

        attachPopups({gui::popup::ID::Volume,
                      gui::popup::ID::Tethering,
                      gui::popup::ID::BluetoothAuthenticate,
                      gui::popup::ID::PhoneModes,
                      gui::popup::ID::PhoneLock,
                      gui::popup::ID::Alarm});

M module-apps/application-music-player/ApplicationMusicPlayer.cpp => module-apps/application-music-player/ApplicationMusicPlayer.cpp +2 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <application-music-player/ApplicationMusicPlayer.hpp>


@@ 143,6 143,7 @@ namespace app
                              });
        attachPopups({gui::popup::ID::Volume,
                      gui::popup::ID::Tethering,
                      gui::popup::ID::BluetoothAuthenticate,
                      gui::popup::ID::PhoneModes,
                      gui::popup::ID::PhoneLock,
                      gui::popup::ID::Alarm});

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

#include <application-notes/ApplicationNotes.hpp>


@@ 126,6 126,7 @@ namespace app

        attachPopups({gui::popup::ID::Volume,
                      gui::popup::ID::Tethering,
                      gui::popup::ID::BluetoothAuthenticate,
                      gui::popup::ID::PhoneModes,
                      gui::popup::ID::PhoneLock,
                      gui::popup::ID::Alarm});

M module-apps/application-phonebook/ApplicationPhonebook.cpp => module-apps/application-phonebook/ApplicationPhonebook.cpp +1 -0
@@ 143,6 143,7 @@ namespace app

        attachPopups({gui::popup::ID::Volume,
                      gui::popup::ID::Tethering,
                      gui::popup::ID::BluetoothAuthenticate,
                      gui::popup::ID::PhoneModes,
                      gui::popup::ID::PhoneLock,
                      gui::popup::ID::Alarm});

M module-apps/application-settings/ApplicationSettings.cpp => module-apps/application-settings/ApplicationSettings.cpp +1 -26
@@ 15,7 15,6 @@
#include <application-settings/windows/bluetooth/AddDeviceWindow.hpp>
#include <application-settings/windows/bluetooth/AllDevicesWindow.hpp>
#include <application-settings/windows/bluetooth/PhoneNameWindow.hpp>
#include <application-settings/windows/bluetooth/BluetoothCheckPasskeyWindow.hpp>
#include <application-settings/windows/network/NetworkWindow.hpp>
#include <application-settings/windows/network/SimPINSettingsWindow.hpp>
#include <application-settings/windows/network/SimCardsWindow.hpp>


@@ 70,7 69,6 @@
#include <service-bluetooth/messages/Connect.hpp>
#include <service-bluetooth/messages/DeviceName.hpp>
#include <service-bluetooth/messages/InitializationResult.hpp>
#include <service-bluetooth/messages/Passkey.hpp>
#include <service-bluetooth/messages/ResponseVisibleDevices.hpp>
#include <service-bluetooth/messages/Status.hpp>
#include <service-bluetooth/messages/Unpair.hpp>


@@ 211,26 209,6 @@ namespace app
            return sys::MessageNone{};
        });

        connect(typeid(BluetoothPairResultMessage), [&](sys::Message *msg) {
            auto bluetoothPairResultMsg = static_cast<BluetoothPairResultMessage *>(msg);
            auto device                 = bluetoothPairResultMsg->getDevice();
            if (bluetoothPairResultMsg->isSucceed()) {
                return sys::MessageNone{};
            }
            auto message = std::make_shared<BluetoothPairMessage>(device);

            switchToAllDevicesViaBtErrorPrompt(std::move(message), "app_settings_bluetooth_pairing_error_message");

            return sys::MessageNone{};
        });

        connect(typeid(::message::bluetooth::RequestPasskey), [&](sys::Message *msg) {
            auto m                               = dynamic_cast<::message::bluetooth::RequestPasskey *>(msg);
            bluetoothSettingsModel->pinRequestor = m->getDevice();
            switchWindow(gui::window::name::bluetooth_check_passkey);
            return sys::MessageNone{};
        });

        connect(typeid(::message::bluetooth::ProfileStatus), [&](sys::Message *msg) { return sys::MessageNone{}; });

        connect(typeid(::message::bluetooth::UnpairResult), [&](sys::Message *msg) {


@@ 397,10 375,6 @@ namespace app
        windowsFactory.attach(gui::window::name::phone_name, [this](ApplicationCommon *app, const std::string &name) {
            return std::make_unique<gui::PhoneNameWindow>(app, bluetoothSettingsModel);
        });
        windowsFactory.attach(
            gui::window::name::bluetooth_check_passkey, [this](ApplicationCommon *app, const std::string &name) {
                return std::make_unique<gui::BluetoothCheckPasskeyWindow>(app, bluetoothSettingsModel);
            });

        // Network
        windowsFactory.attach(gui::window::name::network, [](ApplicationCommon *app, const std::string &name) {


@@ 563,6 537,7 @@ namespace app

        attachPopups({gui::popup::ID::Volume,
                      gui::popup::ID::Tethering,
                      gui::popup::ID::BluetoothAuthenticate,
                      gui::popup::ID::PhoneModes,
                      gui::popup::ID::PhoneLock,
                      gui::popup::ID::SimLock,

M module-apps/application-settings/CMakeLists.txt => module-apps/application-settings/CMakeLists.txt +0 -1
@@ 60,7 60,6 @@ target_sources(application-settings
        windows/apps/SoundSelectWindow.cpp
        windows/bluetooth/AddDeviceWindow.cpp
        windows/bluetooth/AllDevicesWindow.cpp
        windows/bluetooth/BluetoothCheckPasskeyWindow.cpp
        windows/bluetooth/BluetoothWindow.cpp
        windows/bluetooth/PhoneNameWindow.cpp
        windows/display-keypad/DisplayAndKeypadWindow.cpp

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

#include "BluetoothSettingsModel.hpp"


@@ 10,7 10,7 @@
#include <service-bluetooth/messages/Disconnect.hpp>
#include <service-bluetooth/messages/SetStatus.hpp>
#include <service-bluetooth/messages/SetDeviceName.hpp>
#include <service-bluetooth/messages/Passkey.hpp>
#include <service-bluetooth/messages/Authenticate.hpp>
#include <service-bluetooth/messages/Unpair.hpp>
#include <service-bluetooth/messages/SyncDevices.hpp>



@@ 68,12 68,6 @@ void BluetoothSettingsModel::requestDeviceUnpair(const Devicei &device)
    service->bus.sendUnicast(std::make_shared<message::bluetooth::Unpair>(device), service::name::bluetooth);
}

void BluetoothSettingsModel::responsePasskey(const std::string &passkey)
{
    service->bus.sendUnicast(std::make_shared<message::bluetooth::ResponsePasskey>(passkey, pinRequestor),
                             service::name::bluetooth);
}

void BluetoothSettingsModel::requestConnection(const Devicei &device)
{
    service->bus.sendUnicast(std::make_shared<message::bluetooth::Connect>(device), service::name::bluetooth);

M module-apps/application-settings/models/bluetooth/BluetoothSettingsModel.hpp => module-apps/application-settings/models/bluetooth/BluetoothSettingsModel.hpp +1 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 26,7 26,6 @@ class BluetoothSettingsModel
    void stopScan();
    void requestDevicePair(const Devicei &device);
    void requestDeviceUnpair(const Devicei &device);
    void responsePasskey(const std::string &passkey);
    void requestConnection(const Devicei &device);
    void requestDisconnection();


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

#pragma once


@@ 50,32 50,6 @@ namespace style
                inline constexpr uint32_t h = style::window_height - y - style::nav_bar::height;
            } // namespace newApn

            namespace bluetooth
            {
                namespace passkey
                {
                    namespace image
                    {
                        inline constexpr auto x = 176;
                        inline constexpr auto y = 132;
                    } // namespace image

                    namespace label
                    {
                        inline constexpr auto x = 150U;
                        inline constexpr auto y = 300U;
                        inline constexpr auto w = 200U;
                    } // namespace label

                    namespace text
                    {
                        inline constexpr auto x = 40U;
                        inline constexpr auto y = 370U;
                        inline constexpr auto w = style::window_width - 2 * x;
                        inline constexpr auto h = 52;
                    } // namespace text
                }     // namespace passkey
            }         // namespace bluetooth

            namespace phone_modes
            {

M module-apps/application-settings/windows/WindowNames.hpp => module-apps/application-settings/windows/WindowNames.hpp +1 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 17,7 17,6 @@ namespace gui::window::name
    inline constexpr auto all_devices             = "AllDevices";
    inline constexpr auto phone_name              = "PhoneName";
    inline constexpr auto add_device              = "AddDevice";
    inline constexpr auto bluetooth_check_passkey = "BluetoothCheckPasskey";

    inline constexpr auto network          = "Network";
    inline constexpr auto sim_cards        = "SimCards";

D module-apps/application-settings/windows/bluetooth/BluetoothCheckPasskeyWindow.cpp => module-apps/application-settings/windows/bluetooth/BluetoothCheckPasskeyWindow.cpp +0 -73
@@ 1,73 0,0 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "BluetoothCheckPasskeyWindow.hpp"

#include <application-settings/widgets/SettingsStyle.hpp>
#include <application-settings/windows/WindowNames.hpp>

#include <utility>
#include <widgets/text/Text.hpp>

namespace gui
{
    namespace
    {
        constexpr auto maxPasskeyCharactersCount = 16U;
        constexpr auto minPasskeyCharactersCount = 4U;
    } // namespace
    namespace passkey_style = style::settings::window::bluetooth::passkey;

    BluetoothCheckPasskeyWindow::BluetoothCheckPasskeyWindow(
        app::ApplicationCommon *app, std::shared_ptr<BluetoothSettingsModel> bluetoothSettingsModel)
        : AppWindow(app, window::name::bluetooth_check_passkey),
          bluetoothSettingsModel(std::move(bluetoothSettingsModel))
    {
        buildInterface();
    }

    void BluetoothCheckPasskeyWindow::buildInterface()
    {
        AppWindow::buildInterface();

        setTitle(utils::translate("app_settings_bt"));

        navBar->setActive(nav_bar::Side::Center, true);
        navBar->setActive(nav_bar::Side::Right, true);
        navBar->setText(nav_bar::Side::Center, utils::translate(style::strings::common::confirm));
        navBar->setText(nav_bar::Side::Right, utils::translate(style::strings::common::back));

        image = new Image(this, passkey_style::image::x, passkey_style::image::y, 0, 0, "bluetooth_128px_W_G");

        label = new Label(this,
                          passkey_style::label::x,
                          passkey_style::label::y,
                          passkey_style::label::w,
                          style::window::label::default_h);
        label->setFont(style::window::font::big);
        label->setEdges(RectangleEdge::None);
        label->setText(utils::translate("app_settings_bluetooth_enter_passkey"));

        text = new Text(
            this, passkey_style::text::x, passkey_style::text::y, passkey_style::text::w, passkey_style::text::h);
        text->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));
        text->setTextLimitType(TextLimitType::MaxSignsCount, maxPasskeyCharactersCount);
        text->setEdges(RectangleEdge::Bottom);
        text->setInputMode(new InputMode({InputMode::digit}));
        text->setPenWidth(style::window::default_border_rect_no_focus);
        text->setFont(style::window::font::largelight);

        setFocusItem(text);
    }

    auto BluetoothCheckPasskeyWindow::onInput(const InputEvent &inputEvent) -> bool
    {
        auto passkey = text->getText();
        if (passkey.length() >= minPasskeyCharactersCount && inputEvent.isShortRelease(KeyCode::KEY_ENTER)) {
            bluetoothSettingsModel->responsePasskey(passkey);
            application->returnToPreviousWindow();
            return true;
        }
        return AppWindow::onInput(inputEvent);
    }
} // namespace gui

D module-apps/application-settings/windows/bluetooth/BluetoothCheckPasskeyWindow.hpp => module-apps/application-settings/windows/bluetooth/BluetoothCheckPasskeyWindow.hpp +0 -29
@@ 1,29 0,0 @@
// 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 <application-settings/models/bluetooth/BluetoothSettingsModel.hpp>
#include <AppWindow.hpp>

namespace gui
{
    class Image;
    class Label;
    class Text;
    class BluetoothCheckPasskeyWindow : public AppWindow
    {
      public:
        BluetoothCheckPasskeyWindow(app::ApplicationCommon *app,
                                    std::shared_ptr<BluetoothSettingsModel> bluetoothSettingsModel);

      private:
        void buildInterface() override;
        auto onInput(const InputEvent &inputEvent) -> bool override;

        Image *image = nullptr;
        Label *label = nullptr;
        Text *text   = nullptr;
        std::shared_ptr<BluetoothSettingsModel> bluetoothSettingsModel;
    };
} // namespace gui

M module-apps/apps-common/ApplicationCommonPopupBlueprints.cpp => module-apps/apps-common/ApplicationCommonPopupBlueprints.cpp +21 -0
@@ 13,6 13,7 @@ namespace app
    void ApplicationCommon::registerPopupBlueprints()
    {
        using namespace gui::popup;

        popupBlueprint.registerBlueprint(
            ID::PhoneModes, [&](gui::popup::ID /*id*/, std::unique_ptr<gui::PopupRequestParams> &params) {
                auto popupParams = dynamic_cast<gui::PhoneModePopupRequestParams *>(params.get());


@@ 35,6 36,7 @@ namespace app
                }
                return true;
            });

        popupBlueprint.registerBlueprint(
            ID::Volume, [&](gui::popup::ID /*id*/, std::unique_ptr<gui::PopupRequestParams> &params) {
                auto volumeParams = dynamic_cast<const gui::VolumePopupRequestParams *>(params.get());


@@ 57,6 59,24 @@ namespace app
                }
                return true;
            });

        popupBlueprint.registerBlueprint(
            ID::BluetoothAuthenticate, [&](gui::popup::ID id, std::unique_ptr<gui::PopupRequestParams> &params) {
                switchWindowPopup(resolveWindowName(id),
                                  gui::popup::popupDisposition(id, gui::popup::Disposition::Priority::High),
                                  std::move(params),
                                  SwitchReason::Popup);
                return true;
            });
        popupBlueprint.registerBlueprint(
            ID::BluetoothInfo, [&](gui::popup::ID id, std::unique_ptr<gui::PopupRequestParams> &params) {
                switchWindowPopup(resolveWindowName(id),
                                  gui::popup::popupDisposition(id, gui::popup::Disposition::Priority::High),
                                  std::move(params),
                                  SwitchReason::Popup);
                return true;
            });

        popupBlueprint.registerBlueprint(
            ID::PhoneLock, [&](gui::popup::ID id, std::unique_ptr<gui::PopupRequestParams> & /*params*/) {
                switchWindowPopup(resolveWindowName(id),


@@ 83,6 103,7 @@ namespace app
        };
        popupBlueprint.registerBlueprint(ID::PhoneLockInput, phoneLockBlueprint);
        popupBlueprint.registerBlueprint(ID::PhoneLockChangeInfo, phoneLockBlueprint);

        auto simLockBlueprint = [&](gui::popup::ID id, std::unique_ptr<gui::PopupRequestParams> &params) {
            auto popupParams = dynamic_cast<const gui::SimUnlockInputRequestParams *>(params.get());
            if (popupParams == nullptr) {

A module-apps/apps-common/popups/BluetoothAuthenticatePopup.cpp => module-apps/apps-common/popups/BluetoothAuthenticatePopup.cpp +198 -0
@@ 0,0 1,198 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "BluetoothAuthenticatePopup.hpp"

#include <ApplicationCommon.hpp>
#include <i18n/i18n.hpp>

namespace gui
{
    namespace bluetooth::authenticate
    {
        inline constexpr auto option_box_top_margin = 40U;

        inline constexpr auto max_passkey_signs_count = 16U;
        inline constexpr auto min_passkey_signs_count = 4U;
        inline constexpr auto passkey_input_w         = 300U;
        inline constexpr auto passkey_input_h         = 60U;

        inline constexpr auto buttons_input_w = 150U;
        inline constexpr auto buttons_input_h = 75U;
        inline constexpr auto buttons_margin  = 30U;

        enum ButtonsOptions
        {
            Pair,
            Cancel,
        };

    } // namespace bluetooth::authenticate

    BluetoothAuthenticatePopup::BluetoothAuthenticatePopup(app::ApplicationCommon *app, const std::string &name)
        : AppWindow(app, name)
    {
        buildInterface();
    }

    void BluetoothAuthenticatePopup::buildInterface()
    {
        AppWindow::buildInterface();

        setTitle(utils::translate("bluetooth_popup"));

        navBar->setText(nav_bar::Side::Right, utils::translate(style::strings::common::back));

        infoIcon = new gui::Icon(this,
                                 style::window::default_left_margin,
                                 style::window::default_vertical_pos,
                                 style::window::default_body_width,
                                 style::window::default_body_height,
                                 "bluetooth_128px_W_G",
                                 utils::translate(""));
        infoIcon->setAlignment(Alignment::Horizontal::Center);
    }

    void BluetoothAuthenticatePopup::onBeforeShow(ShowMode mode, SwitchData *data)
    {
        auto temp          = dynamic_cast<BluetoothAuthenticateRequestParams *>(data);
        authenticateParams = new BluetoothAuthenticateRequestParams(temp->getDevice(), temp->getAuthenticateType());

        if (authenticateParams == nullptr) {
            LOG_ERROR("No authenticate data received");
            return;
        }

        switch (authenticateParams->getAuthenticateType()) {
        case ::bluetooth::AuthenticateType::Pin:
        case ::bluetooth::AuthenticateType::Passkey:
            createTextAuthenticateInput();
            break;
        case ::bluetooth::AuthenticateType::PairCancel:
            createButtonsAuthenticateInput();
            break;
        }
    }

    void BluetoothAuthenticatePopup::createTextAuthenticateInput()
    {
        inputText = new TextFixedSize(infoIcon, 0, 0, 0, 0);
        inputText->drawUnderline(false);
        inputText->setTextType(TextType::SingleLine);
        inputText->setTextEllipsisType(TextEllipsis::Both);
        inputText->setFont(style::window::font::largelight);
        inputText->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));
        inputText->setEdges(RectangleEdge::Bottom);
        inputText->setInputMode(new InputMode({InputMode::digit}));
        inputText->setPenWidth(style::window::default_border_rect_no_focus);
        inputText->setMinimumSize(bluetooth::authenticate::passkey_input_w, bluetooth::authenticate::passkey_input_h);
        inputText->setMargins({0, bluetooth::authenticate::option_box_top_margin, 0, 0});

        if (authenticateParams->getAuthenticateType() == ::bluetooth::AuthenticateType::Passkey) {
            infoIcon->text->setText(utils::translate("bluetooth_popup_passkey"));
            inputText->setTextLimitType(TextLimitType::MaxSignsCount, bluetooth::authenticate::max_passkey_signs_count);

            inputText->activatedCallback = [&](Item &) -> bool {
                auto passkey = inputText->getText();
                if (passkey.length() >= bluetooth::authenticate::min_passkey_signs_count) {
                    application->bus.sendUnicast(std::make_shared<message::bluetooth::ResponseAuthenticatePasskey>(
                                                     passkey, authenticateParams->getDevice()),
                                                 service::name::bluetooth);
                    return true;
                }
                return false;
            };
        }
        else if (authenticateParams->getAuthenticateType() == ::bluetooth::AuthenticateType::Pin) {
            infoIcon->text->setText(utils::translate("bluetooth_popup_pin"));
            inputText->setTextLimitType(TextLimitType::MaxSignsCount, bluetooth::authenticate::min_passkey_signs_count);

            inputText->activatedCallback = [&](Item &) -> bool {
                auto pin = inputText->getText();
                if (pin.length() == bluetooth::authenticate::min_passkey_signs_count) {
                    application->bus.sendUnicast(std::make_shared<message::bluetooth::ResponseAuthenticatePin>(
                                                     pin, authenticateParams->getDevice()),
                                                 service::name::bluetooth);
                    return true;
                }
                return false;
            };
        }

        infoIcon->resizeItems();

        setFocusItem(inputText);
    }

    auto BluetoothAuthenticatePopup::onInput(const InputEvent &inputEvent) -> bool
    {
        auto ret = AppWindow::onInput(inputEvent);

        if (authenticateParams->getAuthenticateType() == ::bluetooth::AuthenticateType::Passkey ||
            authenticateParams->getAuthenticateType() == ::bluetooth::AuthenticateType::Pin) {

            if (inputText->getText().length() >= bluetooth::authenticate::min_passkey_signs_count) {
                navBar->setText(nav_bar::Side::Center, utils::translate(style::strings::common::confirm));
            }
            else {
                navBar->setActive(nav_bar::Side::Center, false);
            }
        }
        return ret;
    }

    void BluetoothAuthenticatePopup::createButtonsAuthenticateInput()
    {
        infoIcon->text->setRichText(utils::translate("bluetooth_popup_pair_cancel"),
                                    {{"$DEVICE", std::string(authenticateParams->getDevice().name.data())}});
        navBar->setText(nav_bar::Side::Center, utils::translate(style::strings::common::confirm));

        auto hBox = new HBox(infoIcon, 0, 0, 0, 0);
        hBox->setMinimumSize(style::window::default_body_width, bluetooth::authenticate::buttons_input_h);
        hBox->setAlignment(Alignment(gui::Alignment::Horizontal::Center));
        hBox->setEdges(RectangleEdge::None);
        hBox->setMargins({0, bluetooth::authenticate::option_box_top_margin, 0, 0});

        auto createButton = [&](gui::bluetooth::authenticate::ButtonsOptions optionName) {
            Label *option = new Label(hBox, 0, 0, 0, 0, "");

            if (optionName == gui::bluetooth::authenticate::ButtonsOptions::Pair) {
                option->setText(utils::translate(style::strings::common::yes));
                option->activatedCallback = [&](Item &) -> bool {
                    application->bus.sendUnicast(std::make_shared<message::bluetooth::ResponseAuthenticatePairCancel>(
                                                     true, authenticateParams->getDevice()),
                                                 service::name::bluetooth);
                    return true;
                };
            }
            else if (optionName == gui::bluetooth::authenticate::ButtonsOptions::Cancel) {
                option->setText(utils::translate(style::strings::common::no));
                option->setMargins({0, 0, gui::bluetooth::authenticate::buttons_margin, 0});
                option->activatedCallback = [=](Item &) -> bool {
                    application->bus.sendUnicast(std::make_shared<message::bluetooth::ResponseAuthenticatePairCancel>(
                                                     false, authenticateParams->getDevice()),
                                                 service::name::bluetooth);
                    application->returnToPreviousWindow();
                    return true;
                };
            }

            option->setMinimumSize(bluetooth::authenticate::buttons_input_w, bluetooth::authenticate::buttons_input_h);
            option->setPenWidth(0);
            option->setPenFocusWidth(3);
            option->setEdges(RectangleEdge::Bottom | RectangleEdge::Top);
            option->setFont(style::window::font::big);
            option->setAlignment(Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));

            return option;
        };

        createButton(bluetooth::authenticate::Cancel);
        createButton(bluetooth::authenticate::Pair);

        infoIcon->resizeItems();

        setFocusItem(hBox);
    }

} // namespace gui

A module-apps/apps-common/popups/BluetoothAuthenticatePopup.hpp => module-apps/apps-common/popups/BluetoothAuthenticatePopup.hpp +32 -0
@@ 0,0 1,32 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "Popups.hpp"
#include "data/PopupRequestParams.hpp"

#include <TextFixedSize.hpp>
#include <Icon.hpp>
#include <AppWindow.hpp>

namespace gui
{
    class BluetoothAuthenticatePopup : public AppWindow
    {
      public:
        BluetoothAuthenticatePopup(app::ApplicationCommon *app, const std::string &name);

      private:
        void buildInterface() override;
        bool onInput(const InputEvent &inputEvent) override;
        void onBeforeShow(ShowMode mode, SwitchData *data) override;

        void createTextAuthenticateInput();
        void createButtonsAuthenticateInput();

        BluetoothAuthenticateRequestParams *authenticateParams = nullptr;
        Icon *infoIcon                                         = nullptr;
        TextFixedSize *inputText                               = nullptr;
    };
} // namespace gui

A module-apps/apps-common/popups/BluetoothInfoPopup.cpp => module-apps/apps-common/popups/BluetoothInfoPopup.cpp +83 -0
@@ 0,0 1,83 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "BluetoothInfoPopup.hpp"
#include "data/PopupRequestParams.hpp"

#include <service-appmgr/Controller.hpp>
#include <ApplicationCommon.hpp>
#include <i18n/i18n.hpp>

using namespace gui;

BluetoothInfoPopup::BluetoothInfoPopup(app::ApplicationCommon *app, const std::string &name)
    : WindowWithTimer(app, name)
{
    buildInterface();
}

void BluetoothInfoPopup::buildInterface()
{
    AppWindow::buildInterface();

    setTitle(utils::translate("bluetooth_popup"));

    navBar->setText(nav_bar::Side::Center, utils::translate(style::strings::common::ok));

    infoIcon = new gui::Icon(this,
                             style::window::default_left_margin,
                             style::window::default_vertical_pos,
                             style::window::default_body_width,
                             style::window::default_body_height,
                             "",
                             utils::translate(""));
    infoIcon->setAlignment(Alignment::Horizontal::Center);
}

void BluetoothInfoPopup::onBeforeShow(ShowMode mode, SwitchData *data)
{
    auto infoData = dynamic_cast<BluetoothInfoParams *>(data);

    if (infoData == nullptr) {
        LOG_ERROR("No info data received");
        return;
    }

    if (infoData->isSucceed()) {
        infoIcon->image->set("success_128px_W_G");
        infoIcon->text->setRichText(utils::translate("bluetooth_info_popup_success"),
                                    {{"$DEVICE", std::string(infoData->getDevice().name.data())}});

        timerCallback = [this](Item &, sys::Timer &timer) {
            closePopups();
            return true;
        };
        resetTimer();
    }
    else {
        infoIcon->image->set("fail_128px_W_G");
        infoIcon->text->setRichText(utils::translate("bluetooth_info_popup_error"),
                                    {{"$DEVICE", std::string(infoData->getDevice().name.data())},
                                     {"$ERROR", std::string(infoData->getErrorCode())}});
    }
}

bool BluetoothInfoPopup::onInput(const InputEvent &inputEvent)
{
    if (inputEvent.isShortRelease(KeyCode::KEY_ENTER)) {
        closePopups();
        return true;
    }
    return false;
}

void BluetoothInfoPopup::closePopups()
{
    app::manager::Controller::sendAction(
        application,
        app::manager::actions::AbortPopup,
        std::make_unique<gui::PopupRequestParams>(gui::popup::ID::BluetoothAuthenticate));
    app::manager::Controller::sendAction(application,
                                         app::manager::actions::AbortPopup,
                                         std::make_unique<gui::PopupRequestParams>(gui::popup::ID::BluetoothInfo));
}

A module-apps/apps-common/popups/BluetoothInfoPopup.hpp => module-apps/apps-common/popups/BluetoothInfoPopup.hpp +24 -0
@@ 0,0 1,24 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <popups/WindowWithTimer.hpp>
#include <gui/widgets/Icon.hpp>

namespace gui
{
    class BluetoothInfoPopup : public WindowWithTimer
    {
      private:
        Icon *infoIcon = nullptr;
        void closePopups();

      public:
        BluetoothInfoPopup(app::ApplicationCommon *app, const std::string &name);

        void buildInterface() override;
        bool onInput(const InputEvent &inputEvent) override;
        void onBeforeShow(ShowMode mode, SwitchData *data) override;
    };
} /* namespace gui */

M module-apps/apps-common/popups/CMakeLists.txt => module-apps/apps-common/popups/CMakeLists.txt +4 -0
@@ 15,6 15,8 @@ target_sources(apps-common
		TetheringNotificationPopup.cpp
		TetheringPhoneModePopup.cpp
		TetheringOffPopup.cpp
		BluetoothAuthenticatePopup.cpp
		BluetoothInfoPopup.cpp
		VolumeWindow.cpp
		WindowWithTimer.cpp
		lock-popups/PhoneLockedInfoWindow.cpp


@@ 41,6 43,8 @@ target_sources(apps-common
		TetheringConfirmationPopup.hpp
		TetheringNotificationPopup.hpp
		TetheringPhoneModePopup.hpp
		BluetoothAuthenticatePopup.hpp
		BluetoothInfoPopup.hpp
		VolumeWindow.hpp
		WindowWithTimer.hpp
		data/PopupData.hpp

M module-apps/apps-common/popups/Popups.cpp => module-apps/apps-common/popups/Popups.cpp +5 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "Popups.hpp"


@@ 20,6 20,10 @@ namespace gui::popup
            return gui::popup::window::tethering_confirmation_window;
        case ID::TetheringPhoneModeChangeProhibited:
            return gui::popup::window::tethering_phonemode_change_window;
        case ID::BluetoothAuthenticate:
            return gui::popup::window::bluetooth_authenticate;
        case ID::BluetoothInfo:
            return gui::popup::window::bluetooth_info;
        case ID::PhoneLock:
            return gui::popup::window::phone_lock_window;
        case ID::PhoneLockInput:

M module-apps/apps-common/popups/Popups.hpp => module-apps/apps-common/popups/Popups.hpp +4 -0
@@ 16,6 16,8 @@ namespace gui
            Brightness,
            Tethering,
            TetheringPhoneModeChangeProhibited,
            BluetoothAuthenticate,
            BluetoothInfo,
            PhoneLock,
            PhoneLockInput,
            PhoneLockInfo,


@@ 40,6 42,8 @@ namespace gui
            inline constexpr auto tethering_confirmation_window     = "TetheringConfirmationPopup";
            inline constexpr auto tethering_phonemode_change_window = "TetheringPhoneModeChangeProhibitedPopup";
            inline constexpr auto tethering_off_window              = "TetheringOffPopup";
            inline constexpr auto bluetooth_authenticate            = "BluetoothAuthenticatePopup";
            inline constexpr auto bluetooth_info                    = "BluetoothInfoPopup";
            inline constexpr auto phone_lock_window                 = "PhoneLockPopup";
            inline constexpr auto phone_lock_info_window            = "PhoneLockInfoPopup";
            inline constexpr auto phone_lock_input_window           = "PhoneLockInputPopup";

M module-apps/apps-common/popups/data/PopupRequestParams.hpp => module-apps/apps-common/popups/data/PopupRequestParams.hpp +50 -0
@@ 8,6 8,7 @@

#include <PhoneModes/Common.hpp>
#include <module-audio/Audio/AudioCommon.hpp>
#include <service-bluetooth/messages/Authenticate.hpp>
#include <locks/widgets/Lock.hpp>
#include <locks/data/LockData.hpp>



@@ 85,6 86,55 @@ namespace gui
        sys::phone_modes::PhoneMode phoneMode;
    };

    class BluetoothAuthenticateRequestParams : public PopupRequestParams
    {
      private:
        Devicei device;
        bluetooth::AuthenticateType type;

      public:
        explicit BluetoothAuthenticateRequestParams(const Devicei &dev, bluetooth::AuthenticateType type)
            : PopupRequestParams{gui::popup::ID::BluetoothAuthenticate}, device{dev}, type{type}
        {}

        [[nodiscard]] auto getDevice() const noexcept
        {
            return device;
        }

        [[nodiscard]] auto getAuthenticateType() const noexcept
        {
            return type;
        }
    };

    class BluetoothInfoParams : public PopupRequestParams
    {
      private:
        Devicei device;
        bool succeed;
        std::string errorCode;

      public:
        explicit BluetoothInfoParams(const Devicei &dev, bool succeed, std::string errorCode = "")
            : PopupRequestParams{gui::popup::ID::BluetoothInfo}, device{dev}, succeed{succeed}, errorCode{errorCode}
        {}

        [[nodiscard]] auto getDevice() const noexcept
        {
            return device;
        }

        [[nodiscard]] auto isSucceed() const noexcept -> bool
        {
            return succeed;
        }
        [[nodiscard]] auto getErrorCode() const noexcept -> std::string
        {
            return errorCode;
        }
    };

    class VolumePopupRequestParams : public PopupRequestParams
    {
      public:

M module-bluetooth/Bluetooth/interface/profiles/GAP/GAP.cpp => module-bluetooth/Bluetooth/interface/profiles/GAP/GAP.cpp +10 -6
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "GAP.hpp"


@@ 9,7 9,7 @@
#include <service-bluetooth/BluetoothMessage.hpp>
#include <service-bluetooth/messages/ResponseVisibleDevices.hpp>
#include <service-bluetooth/messages/Unpair.hpp>
#include <service-bluetooth/messages/Passkey.hpp>
#include <service-bluetooth/messages/Authenticate.hpp>
#include <service-bluetooth/Constants.hpp>
#include <log/log.hpp>
#include <memory>


@@ 97,7 97,6 @@ namespace bluetooth
        return false;
    }


    void GAP::sendDevices()
    {
        auto msg = std::make_shared<message::bluetooth::ResponseVisibleDevices>(devices().getList());


@@ 258,7 257,9 @@ namespace bluetooth
            }
            it->isPairingSSP = false;

            auto msg = std::make_shared<::message::bluetooth::RequestPasskey>(*it);
            /// TODO additional authenticate types to be added in next PRs.
            auto msg =
                std::make_shared<::message::bluetooth::RequestAuthenticate>(*it, bluetooth::AuthenticateType::Passkey);
            ownerService->bus.sendMulticast(std::move(msg), sys::BusChannel::BluetoothNotifications);
        } break;



@@ 289,8 290,11 @@ namespace bluetooth
                it = devices().put(addr);
            }
            it->isPairingSSP = true;
            ownerService->bus.sendMulticast(std::make_shared<::message::bluetooth::RequestPasskey>(*it),
                                            sys::BusChannel::BluetoothNotifications);

            /// TODO additional authenticate types to be added in next PRs.
            ownerService->bus.sendMulticast(
                std::make_shared<::message::bluetooth::RequestAuthenticate>(*it, bluetooth::AuthenticateType::Passkey),
                sys::BusChannel::BluetoothNotifications);
        } break;
        case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: {
            bd_addr_t addr;

M module-services/service-bluetooth/ServiceBluetooth.cpp => module-services/service-bluetooth/ServiceBluetooth.cpp +21 -4
@@ 37,7 37,7 @@
#include <BtKeysStorage.hpp>
#include <Timers/TimerFactory.hpp>
#include <typeinfo>
#include <service-bluetooth/messages/Passkey.hpp>
#include <service-bluetooth/messages/Authenticate.hpp>
#include <GAP/GAP.hpp>
#include <service-cellular/CellularMessage.hpp>



@@ 106,7 106,9 @@ sys::ReturnCodes ServiceBluetooth::InitHandler()
    connectHandler<message::bluetooth::SetStatus>();
    connectHandler<message::bluetooth::Unpair>();
    connectHandler<sdesktop::developerMode::DeveloperModeRequest>();
    connectHandler<message::bluetooth::ResponsePasskey>();
    connectHandler<message::bluetooth::ResponseAuthenticatePin>();
    connectHandler<message::bluetooth::ResponseAuthenticatePasskey>();
    connectHandler<message::bluetooth::ResponseAuthenticatePairCancel>();
    connectHandler<CellularCallerIdMessage>();
    connectHandler<CellularCallActiveNotification>();



@@ 241,6 243,7 @@ auto ServiceBluetooth::handle(BluetoothPairResultMessage *msg) -> std::shared_pt

    bluetoothDevicesModel->syncDevicesWithApp();

    /// TODO error code handing added in next PRs
    bus.sendMulticast(std::make_shared<BluetoothPairResultMessage>(msg->getDevice(), msg->isSucceed()),
                      sys::BusChannel::BluetoothNotifications);



@@ 295,7 298,7 @@ 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();
        auto device = msg->getDevice();
        bluetoothDevicesModel->mergeInternalDeviceState(device);

        settingsHolder->setValue(bluetooth::Settings::ConnectedDevice, bd_addr_to_str(device.address));


@@ 348,13 351,27 @@ auto ServiceBluetooth::handle(message::bluetooth::DisconnectResult *msg) -> std:
    return sys::MessageNone{};
}

auto ServiceBluetooth::handle(message::bluetooth::ResponsePasskey *msg) -> std::shared_ptr<sys::Message>
auto ServiceBluetooth::handle(message::bluetooth::ResponseAuthenticatePin *msg) -> std::shared_ptr<sys::Message>
{
    /// TODO to be added in next PRs
    auto pin = msg->getPin();
    bluetooth::GAP::respondPinCode(pin, msg->getDevice());
    return sys::MessageNone{};
}

auto ServiceBluetooth::handle(message::bluetooth::ResponseAuthenticatePasskey *msg) -> std::shared_ptr<sys::Message>
{
    auto passKey = msg->getPasskey();
    bluetooth::GAP::respondPinCode(passKey, msg->getDevice());
    return sys::MessageNone{};
}

auto ServiceBluetooth::handle(message::bluetooth::ResponseAuthenticatePairCancel *msg) -> std::shared_ptr<sys::Message>
{
    /// TODO to be added in next PRs
    return sys::MessageNone{};
}

auto ServiceBluetooth::handle(BluetoothMessage *msg) -> std::shared_ptr<sys::Message>
{
    LOG_INFO("Bluetooth request!");

M module-services/service-bluetooth/service-bluetooth/BluetoothMessage.hpp => module-services/service-bluetooth/service-bluetooth/BluetoothMessage.hpp +9 -3
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 50,8 50,9 @@ class BluetoothMessage : public sys::DataMessage
class BluetoothPairResultMessage : public sys::DataMessage
{
  public:
    explicit BluetoothPairResultMessage(const Devicei device, bool succeed)
        : sys::DataMessage(MessageType::BluetoothPairResult), device(device), succeed(succeed)
    explicit BluetoothPairResultMessage(const Devicei &device, bool succeed, std::string errorCode = "")
        : sys::DataMessage(MessageType::BluetoothPairResult), device(device), succeed(succeed),
          errorCode(std::move(errorCode))
    {}
    [[nodiscard]] auto getDevice() const -> Devicei
    {


@@ 61,10 62,15 @@ class BluetoothPairResultMessage : public sys::DataMessage
    {
        return succeed;
    }
    [[nodiscard]] auto getErrorCode() const noexcept -> std::string
    {
        return errorCode;
    }

  private:
    Devicei device;
    bool succeed;
    std::string errorCode;
};

class BluetoothAddrMessage : public sys::DataMessage

M module-services/service-bluetooth/service-bluetooth/ServiceBluetooth.hpp => module-services/service-bluetooth/service-bluetooth/ServiceBluetooth.hpp +5 -3
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 19,7 19,7 @@
#include <memory> // for unique_ptr
namespace message::bluetooth
{
    class ResponsePasskey;
    class ResponseAuthenticate;
}
class BluetoothWorker;
namespace settings


@@ 112,7 112,9 @@ class ServiceBluetooth : public sys::Service
    [[nodiscard]] auto handle(message::bluetooth::HFPVolume *msg) -> std::shared_ptr<sys::Message>;
    [[nodiscard]] auto handle(message::bluetooth::Ring *msg) -> std::shared_ptr<sys::Message>;
    [[nodiscard]] auto handle(message::bluetooth::StartAudioRouting *msg) -> std::shared_ptr<sys::Message>;
    [[nodiscard]] auto handle(message::bluetooth::ResponsePasskey *msg) -> std::shared_ptr<sys::Message>;
    [[nodiscard]] auto handle(message::bluetooth::ResponseAuthenticatePin *msg) -> std::shared_ptr<sys::Message>;
    [[nodiscard]] auto handle(message::bluetooth::ResponseAuthenticatePasskey *msg) -> std::shared_ptr<sys::Message>;
    [[nodiscard]] auto handle(message::bluetooth::ResponseAuthenticatePairCancel *msg) -> std::shared_ptr<sys::Message>;
    [[nodiscard]] auto handle(CellularCallerIdMessage *msg) -> std::shared_ptr<sys::Message>;
    [[nodiscard]] auto handle(CellularCallActiveNotification *msg) -> std::shared_ptr<sys::Message>;
};

A module-services/service-bluetooth/service-bluetooth/messages/Authenticate.hpp => module-services/service-bluetooth/service-bluetooth/messages/Authenticate.hpp +105 -0
@@ 0,0 1,105 @@
// Copyright (c) 2017-2022, 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 bluetooth
{
    enum class AuthenticateType
    {
        Pin,
        Passkey,
        PairCancel
    };
}

namespace message::bluetooth
{

    class RequestAuthenticate : public BluetoothMessage
    {
      private:
        Devicei device;
        ::bluetooth::AuthenticateType type;

      public:
        RequestAuthenticate(const Devicei &dev, ::bluetooth::AuthenticateType type) : device(dev), type(type)
        {}

        [[nodiscard]] auto getDevice()
        {
            return device;
        }

        [[nodiscard]] auto getAuthenticateType()
        {
            return type;
        }
    };

    class ResponseAuthenticate : public BluetoothMessage
    {
      private:
        Devicei device;

      protected:
        explicit ResponseAuthenticate(const Devicei &dev) : device(dev)
        {}

      public:
        [[nodiscard]] auto getDevice()
        {
            return device;
        }
    };

    class ResponseAuthenticatePin : public ResponseAuthenticate
    {
      private:
        std::string pin;

      public:
        ResponseAuthenticatePin(std::string pin, const Devicei &dev) : ResponseAuthenticate(dev), pin(std::move(pin))
        {}

        [[nodiscard]] auto getPin() const -> std::string
        {
            return pin;
        }
    };

    class ResponseAuthenticatePasskey : public ResponseAuthenticate
    {
      private:
        std::string passkey;

      public:
        ResponseAuthenticatePasskey(std::string passkey, const Devicei &dev)
            : ResponseAuthenticate(dev), passkey(std::move(passkey))
        {}

        [[nodiscard]] auto getPasskey() const -> std::string
        {
            return passkey;
        }
    };

    class ResponseAuthenticatePairCancel : public ResponseAuthenticate
    {
      private:
        bool pairApproved = false;

      public:
        ResponseAuthenticatePairCancel(bool pairApproved, const Devicei &dev)
            : ResponseAuthenticate(dev), pairApproved(pairApproved)
        {}

        [[nodiscard]] auto getPairApproved() const -> bool
        {
            return pairApproved;
        }
    };

} // namespace message::bluetooth

M module-services/service-bluetooth/service-bluetooth/messages/Connect.hpp => module-services/service-bluetooth/service-bluetooth/messages/Connect.hpp +1 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

D module-services/service-bluetooth/service-bluetooth/messages/Passkey.hpp => module-services/service-bluetooth/service-bluetooth/messages/Passkey.hpp +0 -45
@@ 1,45 0,0 @@
// 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 RequestPasskey : public BluetoothMessage
    {
        Devicei device;

      public:
        explicit RequestPasskey(const Devicei &dev) : device(dev)
        {}

        [[nodiscard]] auto getDevice()
        {
            return device;
        }
    };

    class ResponsePasskey : public BluetoothMessage
    {
        Devicei device;

      public:
        ResponsePasskey(std::string passkey, const Devicei &dev) : device(dev), passkey(std::move(passkey))
        {}

        [[nodiscard]] auto getPasskey() const -> std::string
        {
            return passkey;
        }

        [[nodiscard]] auto getDevice()
        {
            return device;
        }

      private:
        std::string passkey;
    };
} // namespace message::bluetooth

M products/PurePhone/apps/Application.cpp => products/PurePhone/apps/Application.cpp +12 -0
@@ 7,6 7,8 @@
#include <popups/HomeModesWindow.hpp>
#include <popups/TetheringPhoneModePopup.hpp>
#include <popups/TetheringConfirmationPopup.hpp>
#include <popups/BluetoothAuthenticatePopup.hpp>
#include <popups/BluetoothInfoPopup.hpp>
#include <popups/PowerOffWindow.hpp>
#include <popups/presenter/PowerOffPresenter.hpp>
#include <popups/presenter/WallpaperPresenter.hpp>


@@ 60,6 62,16 @@ namespace app
                    return std::make_unique<gui::HomeModesWindow>(app, window::phone_modes_window);
                });
                break;
            case ID::BluetoothAuthenticate:
            case ID::BluetoothInfo:
                windowsFactory.attach(
                    window::bluetooth_authenticate, [](ApplicationCommon *app, const std::string &name) {
                        return std::make_unique<gui::BluetoothAuthenticatePopup>(app, window::bluetooth_authenticate);
                    });
                windowsFactory.attach(window::bluetooth_info, [](ApplicationCommon *app, const std::string &name) {
                    return std::make_unique<gui::BluetoothInfoPopup>(app, window::bluetooth_info);
                });
                break;
            case ID::Brightness:
                break;
            case ID::PhoneLock:

M products/PurePhone/services/appmgr/ApplicationManager.cpp => products/PurePhone/services/appmgr/ApplicationManager.cpp +24 -0
@@ 18,6 18,7 @@
#include <service-appmgr/messages/GetAllNotificationsRequest.hpp>
#include <service-appmgr/messages/GetWallpaperOptionRequest.hpp>
#include <service-bluetooth/messages/BluetoothModeChanged.hpp>
#include <service-bluetooth/messages/Authenticate.hpp>
#include <service-cellular/CellularMessage.hpp>
#include <service-db/DBNotificationMessage.hpp>
#include <service-db/agents/settings/SystemSettings.hpp>


@@ 352,6 353,29 @@ namespace app::manager
            handleBluetoothModeChanged(data->getBluetoothMode());
            return sys::msgHandled();
        });
        connect(typeid(message::bluetooth::RequestAuthenticate), [&](sys::Message *msg) {
            auto m = dynamic_cast<::message::bluetooth::RequestAuthenticate *>(msg);

            auto data =
                std::make_unique<gui::BluetoothAuthenticateRequestParams>(m->getDevice(), m->getAuthenticateType());
            data->setDisposition(gui::popup::Disposition{gui::popup::Disposition::Priority::High,
                                                         gui::popup::Disposition::WindowType::Popup,
                                                         gui::popup::ID::BluetoothAuthenticate});
            actionsRegistry.enqueue(ActionEntry{actions::ShowPopup, std::move(data)});

            return sys::MessageNone{};
        });
        connect(typeid(BluetoothPairResultMessage), [&](sys::Message *msg) {
            auto m = dynamic_cast<BluetoothPairResultMessage *>(msg);

            auto data = std::make_unique<gui::BluetoothInfoParams>(m->getDevice(), m->isSucceed(), m->getErrorCode());
            data->setDisposition(gui::popup::Disposition{gui::popup::Disposition::Priority::High,
                                                         gui::popup::Disposition::WindowType::Popup,
                                                         gui::popup::ID::BluetoothInfo});
            actionsRegistry.enqueue(ActionEntry{actions::ShowPopup, std::move(data)});

            return sys::MessageNone{};
        });

        alarms::AlarmServiceAPI::requestRegisterSnoozedAlarmsCountChangeCallback(this);
        connect(typeid(alarms::SnoozedAlarmsCountChangeMessage), [&](sys::Message *request) -> sys::MessagePointer {