~aleteoryx/muditaos

1f9c6b4a5174aab1e88ac5f3bba1e1bc791eb207 — Maciej-Mudita 3 years ago ca9579a
[MOS-26] Add tethering info on status bar

When tethering is on, info appears in the status bar
and network coverage indicates "no connection"
38 files changed, 260 insertions(+), 18 deletions(-)

M image/assets/lang/Deutsch.json
M image/assets/lang/English.json
M image/assets/lang/Espanol.json
M image/assets/lang/Francais.json
M image/assets/lang/Polski.json
M image/assets/lang/Svenska.json
M module-apps/application-desktop/include/application-desktop/ApplicationDesktop.hpp
M module-apps/application-desktop/windows/DesktopMainWindow.cpp
M module-apps/apps-common/ApplicationCommon.cpp
M module-apps/apps-common/ApplicationCommon.hpp
M module-apps/apps-common/locks/windows/LockInputWindow.cpp
M module-apps/apps-common/popups/TetheringNotificationPopup.cpp
A module-apps/apps-common/popups/data/TetheringParams.hpp
M module-apps/apps-common/popups/lock-popups/PhoneLockInputWindow.cpp
M module-apps/apps-common/popups/lock-popups/PhoneLockedInfoWindow.cpp
M module-apps/apps-common/popups/lock-popups/PhoneLockedWindow.cpp
M module-apps/apps-common/windows/AppWindow.cpp
M module-apps/apps-common/windows/AppWindow.hpp
M module-gui/gui/widgets/CMakeLists.txt
M module-gui/gui/widgets/StatusBar.cpp
M module-gui/gui/widgets/StatusBar.hpp
M module-gui/gui/widgets/status-bar/SignalStrengthBar.cpp
M module-gui/gui/widgets/status-bar/SignalStrengthBar.hpp
M module-gui/gui/widgets/status-bar/SignalStrengthBase.hpp
M module-gui/gui/widgets/status-bar/SignalStrengthText.cpp
M module-gui/gui/widgets/status-bar/SignalStrengthText.hpp
M module-gui/gui/widgets/status-bar/Style.hpp
A module-gui/gui/widgets/status-bar/Tethering.cpp
A module-gui/gui/widgets/status-bar/Tethering.hpp
M module-services/service-appmgr/include/service-appmgr/Actions.hpp
M module-services/service-cellular/ServiceCellular.cpp
M module-utils/EventStore/EventStore.cpp
M module-utils/EventStore/EventStore.hpp
M products/PurePhone/apps/Application.cpp
M products/PurePhone/services/appmgr/ApplicationManager.cpp
M products/PurePhone/services/appmgr/RunAppsInBackground.cpp
M products/PurePhone/services/appmgr/include/appmgr/ApplicationManager.hpp
M pure_changelog.md
M image/assets/lang/Deutsch.json => image/assets/lang/Deutsch.json +1 -0
@@ 622,6 622,7 @@
  "app_desktop_update_success": "MuditaOS wurde erfolgreich auf Version $VERSION aktualisiert.",
  "app_call_private_number": "Private Nummer",
  "app_call_ending_call": "Anruf wird beendet",
  "statusbar_tethering": "TETHERING",
  "tethering": "Tethering",
  "tethering_turn_off_question": "Tethering ausschalten?",
  "tethering_enable_question": "<text>Sie sind mit dem Computer verbunden.<br />Tethering einschalten?<br /><text color='5'>(einige Funktionen können deaktiviert sein)</text></text>",

M image/assets/lang/English.json => image/assets/lang/English.json +1 -0
@@ 595,6 595,7 @@
  "app_desktop_update_success": "MuditaOS has been updated to ver. $VERSION succesfully.",
  "app_call_private_number": "Private number",
  "app_call_ending_call": "Disconnecting call",
  "statusbar_tethering": "TETHERING",
  "tethering": "Tethering",
  "tethering_turn_off_question": "Turn tethering off?",
  "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>",

M image/assets/lang/Espanol.json => image/assets/lang/Espanol.json +1 -0
@@ 623,6 623,7 @@
  "app_desktop_update_success": "El SO de MuditaOS se ha actualizado a la ver. $VERSION correctamente.",
  "app_call_private_number": "Número privado",
  "app_call_ending_call": "Desconectando llamada",
  "statusbar_tethering": "ANCLAJE DE RED",
  "tethering": "Anclaje de red",
  "tethering_turn_off_question": "¿Desactivar el anclaje de red?",
  "tethering_enable_question": "<text>Estás conectado al ordenador.<br />¿Activar el anclaje de red?<br /><text color='5'>(algunas funciones podrían desactivarse)</text></text>",

M image/assets/lang/Francais.json => image/assets/lang/Francais.json +1 -0
@@ 590,6 590,7 @@
  "app_desktop_update_success": "La mise à jour de MuditaOS à la version $VERSION a été effectuée avec succès.",
  "app_call_private_number": "Numéro privé",
  "app_call_ending_call": "Déconnexion de l'appel",
  "statusbar_tethering": "MODE MODEM",
  "tethering": "Partage de connexion",
  "tethering_turn_off_question": "Voulez-vous désactiver le partage de connexion?",
  "tethering_enable_question": "<text>Vous êtes connecté à l'ordinateur.<br />Voulez-vous activer le partage de connexion?<br /><text color='5'>(certaines fonctions peuvent être désactivées)</text></text>",

M image/assets/lang/Polski.json => image/assets/lang/Polski.json +1 -0
@@ 639,6 639,7 @@
  "app_desktop_update_success": "System MuditaOS został pomyślnie zaktualizowany do wer. $VERSION.",
  "app_call_private_number": "Numer prywatny",
  "app_call_ending_call": "Kończenie połączenia",
  "statusbar_tethering": "TETHERING",
  "tethering": "Tethering",
  "tethering_turn_off_question": "Wyłączyć tethering?",
  "tethering_enable_question": "<text>Połączono z komputerem.<br />Włączyć tethering?<br /><text color='5'>(Niektóre funkcje mogą być niedostępne)</text></text>",

M image/assets/lang/Svenska.json => image/assets/lang/Svenska.json +1 -0
@@ 524,6 524,7 @@
  "app_desktop_update_unpacking": "Packar upp",
  "app_call_private_number": "Dolt nummer",
  "app_call_ending_call": "Avslutar samtalet",
  "statusbar_tethering": "INTERNETDELNING",
  "tethering": "Internetdelning",
  "tethering_turn_off_question": "Stänga av Internetdelning?",
  "tethering_enable_question": "<text>Du är ansluten till datorn.<br />Slå på Internetdelning?<br /><text color='9'>(vissa funktioner kan vara inaktiverade)</text></text>",

M module-apps/application-desktop/include/application-desktop/ApplicationDesktop.hpp => module-apps/application-desktop/include/application-desktop/ApplicationDesktop.hpp +2 -1
@@ 65,7 65,8 @@ namespace app
                     manager::actions::PhoneModeChanged,
                     manager::actions::BluetoothModeChanged,
                     manager::actions::NotificationsChanged,
                     manager::actions::AlarmClockStatusChanged}};
                     manager::actions::AlarmClockStatusChanged,
                     manager::actions::TetheringStateChanged}};
        }
    };


M module-apps/application-desktop/windows/DesktopMainWindow.cpp => module-apps/application-desktop/windows/DesktopMainWindow.cpp +1 -0
@@ 74,6 74,7 @@ namespace gui
        appConfiguration.enable(status_bar::Indicator::SimCard);
        appConfiguration.enable(status_bar::Indicator::Bluetooth);
        appConfiguration.enable(status_bar::Indicator::AlarmClock);
        appConfiguration.enable(status_bar::Indicator::Tethering);
        return appConfiguration;
    }


M module-apps/apps-common/ApplicationCommon.cpp => module-apps/apps-common/ApplicationCommon.cpp +8 -0
@@ 27,6 27,7 @@

#include <popups/data/PhoneModeParams.hpp>
#include <popups/data/BluetoothModeParams.hpp>
#include <popups/data/TetheringParams.hpp>

#if DEBUG_INPUT_EVENTS == 1
#define debug_input_events(...) LOG_DEBUG(__VA_ARGS__)


@@ 119,6 120,13 @@ namespace app
            }
            return actionHandled();
        });
        addActionReceiver(app::manager::actions::TetheringStateChanged, [this](auto &&params) {
            if (params != nullptr) {
                auto modeParams                       = static_cast<gui::TetheringParams *>(params.get());
                this->statusIndicators.tetheringState = modeParams->getTetheringState();
            }
            return actionHandled();
        });
        addActionReceiver(app::manager::actions::BluetoothModeChanged, [this](auto &&params) {
            if (params != nullptr) {
                auto modeParams                      = static_cast<gui::BluetoothModeParams *>(params.get());

M module-apps/apps-common/ApplicationCommon.hpp => module-apps/apps-common/ApplicationCommon.hpp +1 -0
@@ 125,6 125,7 @@ namespace app
    {
      public:
        sys::phone_modes::PhoneMode phoneMode       = sys::phone_modes::PhoneMode::Uninitialized;
        sys::phone_modes::Tethering tetheringState  = sys::phone_modes::Tethering::Off;
        sys::bluetooth::BluetoothMode bluetoothMode = sys::bluetooth::BluetoothMode::Disabled;
        bool alarmClockStatus                       = false;
    };

M module-apps/apps-common/locks/windows/LockInputWindow.cpp => module-apps/apps-common/locks/windows/LockInputWindow.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 "LockInputWindow.hpp"


@@ 113,6 113,7 @@ namespace gui
        appConfiguration.enable(status_bar::Indicator::SimCard);
        appConfiguration.enable(status_bar::Indicator::Bluetooth);
        appConfiguration.enable(status_bar::Indicator::AlarmClock);
        appConfiguration.enable(status_bar::Indicator::Tethering);
        return appConfiguration;
    }


M module-apps/apps-common/popups/TetheringNotificationPopup.cpp => module-apps/apps-common/popups/TetheringNotificationPopup.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 "TetheringNotificationPopup.hpp"


@@ 20,6 20,7 @@ namespace gui
        appConfiguration.setIndicator(gui::status_bar::Indicator::Battery, true);
        appConfiguration.setIndicator(gui::status_bar::Indicator::SimCard, false);
        appConfiguration.setIndicator(gui::status_bar::Indicator::Signal, true);
        appConfiguration.setIndicator(gui::status_bar::Indicator::Tethering, true);
        return appConfiguration;
    }
} // namespace gui

A module-apps/apps-common/popups/data/TetheringParams.hpp => module-apps/apps-common/popups/data/TetheringParams.hpp +27 -0
@@ 0,0 1,27 @@
// 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/Popups.hpp"

#include <service-appmgr/Actions.hpp>
#include <PhoneModes/Common.hpp>

namespace gui
{
    class TetheringParams : public app::manager::actions::ActionParams
    {
      public:
        explicit TetheringParams(sys::phone_modes::Tethering state) : tetheringState{state}
        {}

        [[nodiscard]] auto getTetheringState() const noexcept
        {
            return tetheringState;
        }

      private:
        sys::phone_modes::Tethering tetheringState;
    };
} // namespace gui

M module-apps/apps-common/popups/lock-popups/PhoneLockInputWindow.cpp => module-apps/apps-common/popups/lock-popups/PhoneLockInputWindow.cpp +1 -0
@@ 44,6 44,7 @@ namespace gui
            appConfiguration.enable(status_bar::Indicator::SimCard);
            appConfiguration.enable(status_bar::Indicator::Bluetooth);
            appConfiguration.enable(status_bar::Indicator::AlarmClock);
            appConfiguration.enable(status_bar::Indicator::Tethering);
        }
        else {
            appConfiguration.enable(status_bar::Indicator::Time);

M module-apps/apps-common/popups/lock-popups/PhoneLockedInfoWindow.cpp => module-apps/apps-common/popups/lock-popups/PhoneLockedInfoWindow.cpp +1 -0
@@ 101,6 101,7 @@ status_bar::Configuration PhoneLockedInfoWindow::configureStatusBar(status_bar::
    appConfiguration.enable(status_bar::Indicator::Signal);
    appConfiguration.enable(status_bar::Indicator::Bluetooth);
    appConfiguration.enable(status_bar::Indicator::AlarmClock);
    appConfiguration.enable(status_bar::Indicator::Tethering);
    return appConfiguration;
}


M module-apps/apps-common/popups/lock-popups/PhoneLockedWindow.cpp => module-apps/apps-common/popups/lock-popups/PhoneLockedWindow.cpp +1 -0
@@ 150,6 150,7 @@ namespace gui
        appConfiguration.disable(status_bar::Indicator::SimCard);
        appConfiguration.enable(status_bar::Indicator::Bluetooth);
        appConfiguration.enable(status_bar::Indicator::AlarmClock);
        appConfiguration.enable(status_bar::Indicator::Tethering);

        return appConfiguration;
    }

M module-apps/apps-common/windows/AppWindow.cpp => module-apps/apps-common/windows/AppWindow.cpp +9 -0
@@ 134,6 134,15 @@ namespace gui
        applyToStatusBar(std::move(fn));
    }

    bool AppWindow::updateTethering(const sys::phone_modes::Tethering state)
    {
        if (statusBar == nullptr) {
            return false;
        }

        return statusBar->updateTetheringState(state);
    }

    bool AppWindow::preventsAutoLocking() const noexcept
    {
        return preventsAutoLock;

M module-apps/apps-common/windows/AppWindow.hpp => module-apps/apps-common/windows/AppWindow.hpp +1 -0
@@ 72,6 72,7 @@ namespace gui
        bool updateSignalStrength();
        bool updateNetworkAccessTechnology();
        void updatePhoneMode(sys::phone_modes::PhoneMode mode);
        bool updateTethering(const sys::phone_modes::Tethering state);
        [[nodiscard]] bool preventsAutoLocking() const noexcept;
        virtual RefreshModes updateTime();


M module-gui/gui/widgets/CMakeLists.txt => module-gui/gui/widgets/CMakeLists.txt +1 -0
@@ 41,6 41,7 @@ target_sources( ${PROJECT_NAME}
        "${CMAKE_CURRENT_LIST_DIR}/status-bar/SignalStrengthText.cpp"
        "${CMAKE_CURRENT_LIST_DIR}/status-bar/NetworkAccessTechnology.cpp"
        "${CMAKE_CURRENT_LIST_DIR}/status-bar/PhoneMode.cpp"
        "${CMAKE_CURRENT_LIST_DIR}/status-bar/Tethering.cpp"
        "${CMAKE_CURRENT_LIST_DIR}/status-bar/Time.cpp"
        "${CMAKE_CURRENT_LIST_DIR}/status-bar/Lock.cpp"
        "${CMAKE_CURRENT_LIST_DIR}/Style.cpp"

M module-gui/gui/widgets/StatusBar.cpp => module-gui/gui/widgets/StatusBar.cpp +50 -2
@@ 13,6 13,7 @@
#include "status-bar/SignalStrengthText.hpp"
#include "status-bar/NetworkAccessTechnology.hpp"
#include "status-bar/PhoneMode.hpp"
#include "status-bar/Tethering.hpp"
#include "status-bar/AlarmClock.hpp"
#include "status-bar/BT.hpp"
#include "status-bar/SIM.hpp"


@@ 87,6 88,16 @@ namespace gui::status_bar
        return mAlarmClockStatus;
    }

    void Configuration::setTetheringState(sys::phone_modes::Tethering tetheringState)
    {
        mTetheringState = tetheringState;
    }

    auto Configuration::getTetheringState() const noexcept -> sys::phone_modes::Tethering
    {
        return mTetheringState;
    }

    auto Configuration::isEnabled(Indicator indicator) const -> bool
    {
        return indicatorStatuses.at(indicator);


@@ 135,6 146,10 @@ namespace gui::status_bar
        phoneMode->setMaximumSize(phonemode::maxX, this->drawArea.h);
        phoneMode->setMargins(gui::Margins(margins::between, 0, 0, margins::textBottom));
        phoneMode->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Bottom));
        tethering = new Tethering(leftBox, 0, 0, 0, 0);
        tethering->setMaximumSize(tethering::maxX, this->drawArea.h);
        tethering->setMargins(gui::Margins(margins::between, 0, 0, margins::textBottom));
        tethering->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Bottom));

        // center
        centralBox = new HBox(this, 0, 0, 0, 0);


@@ 241,6 256,9 @@ namespace gui::status_bar
        case Indicator::PhoneMode:
            showPhoneMode(enabled);
            break;
        case Indicator::Tethering:
            showTethering(enabled);
            break;
        }
    }



@@ 338,7 356,8 @@ namespace gui::status_bar
    {
        const auto signalStrength = Store::GSM::get()->getSignalStrength();
        const auto networkStatus  = Store::GSM::get()->getNetwork().status;
        signal->update(signalStrength, networkStatus);
        const auto tethering      = Store::GSM::get()->getTethering();
        signal->update(signalStrength, networkStatus, tethering);
        enabled ? signal->show() : signal->hide();
    }



@@ 362,7 381,19 @@ namespace gui::status_bar

    void StatusBar::showPhoneMode(bool enabled)
    {
        enabled ? phoneMode->show() : phoneMode->hide();
        showPhoneModeOrTethering(enabled, configuration.isEnabled(Indicator::Tethering));
    }

    void StatusBar::showPhoneModeOrTethering(bool phoneModeEnabled, bool tetheringEnabled)
    {
        if (tetheringEnabled && configuration.getTetheringState() != sys::phone_modes::Tethering::Off) {
            phoneMode->hide();
            tethering->show();
        }
        else {
            tethering->hide();
            phoneModeEnabled ? phoneMode->show() : phoneMode->hide();
        }
    }

    bool StatusBar::updateNetworkAccessTechnology()


@@ 416,6 447,23 @@ namespace gui::status_bar
        return showTime(configuration.isEnabled(Indicator::Time));
    }

    bool StatusBar::updateTetheringState(const sys::phone_modes::Tethering state)
    {
        if (tethering == nullptr) {
            return false;
        }
        configuration.setTetheringState(state);
        showTethering(configuration.isEnabled(Indicator::Tethering));
        leftBox->resizeItems();

        return true;
    }

    void StatusBar::showTethering(bool enabled)
    {
        showPhoneModeOrTethering(configuration.isEnabled(Indicator::PhoneMode), enabled);
    }

    void StatusBar::accept(GuiVisitor &visitor)
    {
        visitor.visit(*this);

M module-gui/gui/widgets/StatusBar.hpp => module-gui/gui/widgets/StatusBar.hpp +27 -0
@@ 27,6 27,7 @@ namespace gui
        class SIM;
        class Time;
        class Lock;
        class Tethering;
    } // namespace status_bar
} // namespace gui



@@ 48,6 49,7 @@ namespace gui::status_bar
        NetworkAccessTechnology, /// NAT (eg 3G, 4G, LTE)
        PhoneMode,               /// phone mode
        AlarmClock,              /// alarm clock active
        Tethering,               /// tethering status
    };

    using Indicators          = std::vector<Indicator>;


@@ 87,6 89,10 @@ namespace gui::status_bar
        /// @param alarmClockStatus desired alarm clock status
        void setAlarmClockStatus(bool alarmClockStatus);

        /// Set tethering state
        /// @param tetheringState desired tethering state
        void setTetheringState(sys::phone_modes::Tethering tetheringState);

        /// Set a configuration modifier to the specified indicator
        /// @param indicator indicator type
        /// @param config desired indicator's configuration


@@ 104,6 110,10 @@ namespace gui::status_bar
        /// @return alarm clock status
        [[nodiscard]] auto getAlarmClockStatus() const noexcept -> bool;

        /// Get the tethering state configuration
        /// @return tethering state
        [[nodiscard]] auto getTetheringState() const noexcept -> sys::phone_modes::Tethering;

        /// Check if the specified indicator is enabled
        /// @param indicator indicator to be checked
        /// @return indicator status


@@ 129,6 139,7 @@ namespace gui::status_bar
            {Indicator::SimCard, false},
            {Indicator::NetworkAccessTechnology, false},
            {Indicator::AlarmClock, false},
            {Indicator::Tethering, false},
        };

        /// Phone mode


@@ 140,6 151,9 @@ namespace gui::status_bar
        /// Alarm Clock status
        bool mAlarmClockStatus = false;

        /// Tethering state
        sys::phone_modes::Tethering mTetheringState = sys::phone_modes::Tethering::Off;

        /// Indicator modifiers:
        IndicatorsModifiers indicatorsModifiers;
    };


@@ 192,6 206,9 @@ namespace gui::status_bar
        /// Update NAT widget state depending on the current configuration
        bool updateNetworkAccessTechnology();

        /// Update tethering widget state depending on the current configuration
        bool updateTetheringState(const sys::phone_modes::Tethering state);

        /// Accepts GuiVisitor to update the status bar
        void accept(GuiVisitor &visitor) override;



@@ 236,6 253,13 @@ namespace gui::status_bar
        /// @param enabled true to show false to hide the widget
        void showNetworkAccessTechnology(bool enabled);

        /// Show/hide tethering state widget
        /// @param enabled true to show false to hide the widget
        void showTethering(bool enabled);

        /// Show/hide phone mode or tethering widget
        void showPhoneModeOrTethering(bool phoneModeEnabled, bool tetheringEnabled);

        /// Sets the status of the specified indicator on the Status bar
        /// @param indicator indicator id
        /// @param enabled enable or disable the specified indicator


@@ 273,6 297,9 @@ namespace gui::status_bar
        /// Pointer to widget with battery status
        BatteryBase *battery = nullptr;

        /// Pointer to widget with tethering state
        Tethering *tethering = nullptr;

        /// Pointer to the left horizontal box
        HBox *leftBox = nullptr;


M module-gui/gui/widgets/status-bar/SignalStrengthBar.cpp => module-gui/gui/widgets/status-bar/SignalStrengthBar.cpp +8 -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

#include "SignalStrengthBar.hpp"


@@ 47,7 47,9 @@ namespace gui::status_bar
        setMinimumSize(img->getWidth(), style::status_bar::height);
    }

    void SignalStrengthBar::update(const Store::SignalStrength &signal, const Store::Network::Status &status)
    void SignalStrengthBar::update(const Store::SignalStrength &signal,
                                   const Store::Network::Status &status,
                                   const Store::Tethering &tethering)
    {
        try {
            if (img == nullptr) {


@@ 55,7 57,10 @@ namespace gui::status_bar
                return;
            }

            if (status == Store::Network::Status::RegisteredRoaming) {
            if (tethering == Store::Tethering::On) {
                img->set(signal_none, style::status_bar::imageTypeSpecifier);
            }
            else if (status == Store::Network::Status::RegisteredRoaming) {
                img->set(signalMapRoaming.at(signal.rssiBar), style::status_bar::imageTypeSpecifier);
            }
            else if (status == Store::Network::Status::RegisteredHomeNetwork) {

M module-gui/gui/widgets/status-bar/SignalStrengthBar.hpp => module-gui/gui/widgets/status-bar/SignalStrengthBar.hpp +4 -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


@@ 15,7 15,9 @@ namespace gui::status_bar
    {
      public:
        SignalStrengthBar(Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h);
        void update(const Store::SignalStrength &signal, const Store::Network::Status &status) override;
        void update(const Store::SignalStrength &signal,
                    const Store::Network::Status &status,
                    const Store::Tethering &tethering) override;

      private:
        Image *img = nullptr;

M module-gui/gui/widgets/status-bar/SignalStrengthBase.hpp => module-gui/gui/widgets/status-bar/SignalStrengthBase.hpp +4 -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


@@ 13,6 13,8 @@ namespace gui::status_bar
    {
      public:
        SignalStrengthBase(Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h);
        virtual void update(const Store::SignalStrength &signal, const Store::Network::Status &status) = 0;
        virtual void update(const Store::SignalStrength &signal,
                            const Store::Network::Status &status,
                            const Store::Tethering &tethering) = 0;
    };
} // namespace gui::status_bar

M module-gui/gui/widgets/status-bar/SignalStrengthText.cpp => module-gui/gui/widgets/status-bar/SignalStrengthText.cpp +3 -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

#include "SignalStrengthText.hpp"


@@ 23,7 23,8 @@ namespace gui::status_bar
    }

    void SignalStrengthText::update(const Store::SignalStrength &signal,
                                    [[maybe_unused]] const Store::Network::Status &status)
                                    [[maybe_unused]] const Store::Network::Status &status,
                                    [[maybe_unused]] const Store::Tethering &tethering)
    {
        label->setText(utils::to_string(signal.rssidBm) + " dBm");
    }

M module-gui/gui/widgets/status-bar/SignalStrengthText.hpp => module-gui/gui/widgets/status-bar/SignalStrengthText.hpp +3 -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,8 @@ namespace gui::status_bar
      public:
        SignalStrengthText(Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h);
        void update(const Store::SignalStrength &signal,
                    [[maybe_unused]] const Store::Network::Status &status) override;
                    [[maybe_unused]] const Store::Network::Status &status,
                    [[maybe_unused]] const Store::Tethering &tethering) override;

      private:
        Label *label = nullptr;

M module-gui/gui/widgets/status-bar/Style.hpp => module-gui/gui/widgets/status-bar/Style.hpp +6 -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


@@ 35,6 35,11 @@ namespace style::status_bar
        inline constexpr auto maxX = 157u;
        inline constexpr auto font = style::window::font::verysmall;
    }; // namespace phonemode
    namespace tethering
    {
        inline constexpr auto maxX = 180u;
        inline constexpr auto font = style::window::font::verysmall;
    }; // namespace tethering
    namespace signal
    {
        inline constexpr auto font = style::window::font::verysmall;

A module-gui/gui/widgets/status-bar/Tethering.cpp => module-gui/gui/widgets/status-bar/Tethering.cpp +23 -0
@@ 0,0 1,23 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "Tethering.hpp"

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

#include "Item.hpp"
#include "Style.hpp"

namespace gui::status_bar
{
    Tethering::Tethering(Item *parent, std::uint32_t x, std::uint32_t y, std::uint32_t w, std::uint32_t h)
        : StatusBarWidgetBase(parent, x, y, w, h)
    {
        setEdges(RectangleEdge::None);
        setFont(style::status_bar::tethering::font);
        setTextEllipsisType(TextEllipsis::Right);
        setText(utils::translate("statusbar_tethering"));
        setAlignment(gui::Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Center));
    }
} // namespace gui::status_bar

A module-gui/gui/widgets/status-bar/Tethering.hpp => module-gui/gui/widgets/status-bar/Tethering.hpp +26 -0
@@ 0,0 1,26 @@
// 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 "StatusBarWidgetBase.hpp"
#include <Label.hpp>
#include <gui/widgets/StatusBar.hpp>

namespace gui::status_bar
{
    /// widget drawn on the status bar showing current tethering state:
    class Tethering : public StatusBarWidgetBase<Label>
    {

      public:
        /// Phone mode widget class constructor
        /// @param parent parent item pointer
        /// @param x widget x position
        /// @param y widget y position
        /// @param w widget width
        /// @param h widget height
        Tethering(Item *parent, std::uint32_t x, std::uint32_t y, std::uint32_t w, std::uint32_t h);
    };

} // namespace gui::status_bar

M module-services/service-appmgr/include/service-appmgr/Actions.hpp => module-services/service-appmgr/include/service-appmgr/Actions.hpp +1 -0
@@ 55,6 55,7 @@ namespace app::manager
            SMSRejectedByOfflineNotification,
            CallRejectedByOfflineNotification,
            PhoneModeChanged,
            TetheringStateChanged,
            BluetoothModeChanged,
            AlarmClockStatusChanged,
            NotificationsChanged,

M module-services/service-cellular/ServiceCellular.cpp => module-services/service-cellular/ServiceCellular.cpp +2 -0
@@ 319,9 319,11 @@ void ServiceCellular::registerMessageHandlers()
    });
    phoneModeObserver->subscribe([&](sys::phone_modes::Tethering tethering) {
        if (tethering == sys::phone_modes::Tethering::On) {
            Store::GSM::get()->setTethering(Store::Tethering::On);
            priv->tetheringHandler->enable();
        }
        else {
            Store::GSM::get()->setTethering(Store::Tethering::Off);
            priv->tetheringHandler->disable();
        }
        if (ongoingCall != nullptr) {

M module-utils/EventStore/EventStore.cpp => module-utils/EventStore/EventStore.cpp +10 -0
@@ 90,4 90,14 @@ namespace Store
        cpp_freertos::LockGuard lock(mutex);
        return networkOperatorName;
    }
    void GSM::setTethering(const Tethering &tethering)
    {
        cpp_freertos::LockGuard lock(mutex);
        this->tethering = tethering;
    }
    Tethering GSM::getTethering() const
    {
        cpp_freertos::LockGuard lock(mutex);
        return tethering;
    }
}; // namespace Store

M module-utils/EventStore/EventStore.hpp => module-utils/EventStore/EventStore.hpp +11 -1
@@ 74,6 74,12 @@ namespace Store
        RssiBar rssiBar = RssiBar::zero;
    };

    enum class Tethering
    {
        Off,
        On
    };

    struct Network
    {
        enum class Status


@@ 116,6 122,7 @@ namespace Store
        SignalStrength signalStrength;
        Network network;
        std::string networkOperatorName;
        Tethering tethering;

        static cpp_freertos::MutexStandard mutex;



@@ 154,12 161,15 @@ namespace Store
        void setSignalStrength(const SignalStrength &signalStrength);
        SignalStrength getSignalStrength() const;

        void setNetwork(const Network &signalStrength);
        void setNetwork(const Network &network);
        Network getNetwork() const;

        void setNetworkOperatorName(const std::string &newNetworkOperatorName);
        std::string getNetworkOperatorName() const;

        void setTethering(const Tethering &tethering);
        Tethering getTethering() const;

        static GSM *get();
    };
}; // namespace Store

M products/PurePhone/apps/Application.cpp => products/PurePhone/apps/Application.cpp +1 -0
@@ 32,6 32,7 @@ namespace app
        window->updateSignalStrength();
        window->updateNetworkAccessTechnology();
        window->updatePhoneMode(statusIndicators.phoneMode);
        window->updateTethering(statusIndicators.tetheringState);
    }

    void Application::attachPopups(const std::vector<gui::popup::ID> &popupsList)

M products/PurePhone/services/appmgr/ApplicationManager.cpp => products/PurePhone/services/appmgr/ApplicationManager.cpp +14 -0
@@ 4,6 4,7 @@
#include <appmgr/ApplicationManager.hpp>

#include <apps-common/popups/data/BluetoothModeParams.hpp>
#include <apps-common/popups/data/TetheringParams.hpp>
#include <application-desktop/ApplicationDesktop.hpp>
#include <application-onboarding/ApplicationOnBoarding.hpp>
#include <apps-common/popups/data/PhoneModeParams.hpp>


@@ 455,6 456,16 @@ namespace app::manager
    void ApplicationManager::handleTetheringChanged(sys::phone_modes::Tethering tethering)
    {
        notificationProvider.handle(tethering);
        for (const auto app : getStackedApplications()) {
            changeTetheringState(tethering, app);
        }
    }

    void ApplicationManager::changeTetheringState(const sys::phone_modes::Tethering state, const ApplicationHandle *app)
    {
        ActionEntry action{actions::TetheringStateChanged, std::make_unique<gui::TetheringParams>(state)};
        action.setTargetApplication(app->name());
        actionsRegistry.enqueue(std::move(action));
    }

    void ApplicationManager::handleSnoozeCountChange(unsigned snoozeCount)


@@ 532,6 543,8 @@ namespace app::manager
            LOG_INFO("Starting application %s", app.name().c_str());
            StatusIndicators statusIndicators;
            statusIndicators.phoneMode        = phoneModeObserver->getCurrentPhoneMode();
            statusIndicators.tetheringState =
                phoneModeObserver->isTetheringOn() ? sys::phone_modes::Tethering::On : sys::phone_modes::Tethering::Off;
            statusIndicators.bluetoothMode    = bluetoothMode;
            statusIndicators.alarmClockStatus = alarmClockStatus;
            app.run(statusIndicators, this);


@@ 585,6 598,7 @@ namespace app::manager
        switch (action.actionId) {
        case actions::BluetoothModeChanged:
        case actions::PhoneModeChanged:
        case actions::TetheringStateChanged:
        case actions::AlarmClockStatusChanged:
            return handleActionOnActiveApps(action);
        default:

M products/PurePhone/services/appmgr/RunAppsInBackground.cpp => products/PurePhone/services/appmgr/RunAppsInBackground.cpp +2 -0
@@ 13,6 13,8 @@ namespace app::manager
            if (auto app = getApplication(name); app != nullptr) {
                StatusIndicators statusIndicators;
                statusIndicators.phoneMode        = phoneModeObserver->getCurrentPhoneMode();
                statusIndicators.tetheringState   = phoneModeObserver->isTetheringOn() ? sys::phone_modes::Tethering::On
                                                                                       : sys::phone_modes::Tethering::Off;
                statusIndicators.bluetoothMode    = bluetoothMode;
                statusIndicators.alarmClockStatus = alarmClockStatus;
                app->runInBackground(statusIndicators, this);

M products/PurePhone/services/appmgr/include/appmgr/ApplicationManager.hpp => products/PurePhone/services/appmgr/include/appmgr/ApplicationManager.hpp +1 -0
@@ 30,6 30,7 @@ namespace app::manager
        void changeBluetoothMode(const ApplicationHandle *app);
        void changeAlarmClockStatus(const ApplicationHandle *app);
        void handleTetheringChanged(sys::phone_modes::Tethering tethering);
        void changeTetheringState(const sys::phone_modes::Tethering state, const ApplicationHandle *app);
        void handleSnoozeCountChange(unsigned snoozeCount);
        void processKeypadBacklightState(bsp::keypad_backlight::State keypadLightState);
        void registerMessageHandlers() override;

M pure_changelog.md => pure_changelog.md +1 -0
@@ 35,6 35,7 @@
* Fixed windows flow regarding PUK requests after too many PIN mistakes

### Added
* Added tethering information on the status bar
* Added basic MMS handling

## [1.3.0 2022-08-04]