~aleteoryx/muditaos

67e728ee57a6f217a63539c3ebefe54750824821 — alek 5 years ago d0200de
[EGD-5291] Fixes in Call App

Fix for Call ended window displayed to shortly
Separted the logic of two gui timers in call window.
Removed redundant main window in call app
Refactored CallWindow interface
M module-apps/application-call/ApplicationCall.cpp => module-apps/application-call/ApplicationCall.cpp +37 -13
@@ 6,7 6,6 @@
#include "DialogMetadata.hpp"
#include "DialogMetadataMessage.hpp"
#include "data/CallSwitchData.hpp"
#include "windows/CallMainWindow.hpp"
#include "windows/CallWindow.hpp"
#include "windows/EmergencyCallWindow.hpp"
#include "windows/EnterNumberWindow.hpp"


@@ 198,9 197,6 @@ namespace app

    void ApplicationCall::createUserInterface()
    {
        windowsFactory.attach(gui::name::window::main_window, [](Application *app, const std::string name) {
            return std::make_unique<gui::CallMainWindow>(app);
        });
        windowsFactory.attach(app::window::name_enterNumber, [](Application *app, const std::string newname) {
            return std::make_unique<gui::EnterNumberWindow>(app, static_cast<ApplicationCall *>(app));
        });


@@ 267,25 263,53 @@ namespace app
        }
    }

    void ApplicationCall::transmitDtmfTone(uint32_t digit)
    {
        if (!CellularServiceAPI::TransmitDtmfTones(this, digit)) {
            LOG_ERROR("transmitDtmfTone failed");
        }
    }

    void ApplicationCall::stopAudio()
    {
        AudioServiceAPI::StopAll(this);
    }

    void ApplicationCall::startRinging()
    void ApplicationCall::startAudioRinging()
    {
        AudioServiceAPI::PlaybackStart(this, audio::PlaybackType::CallRingtone, ringtone_path);
    }

    void ApplicationCall::startRouting()
    void ApplicationCall::startAudioRouting()
    {
        AudioServiceAPI::RoutingStart(this);
    }

    void ApplicationCall::sendAudioEvent(AudioEvent audioEvent)
    {
        switch (audioEvent) {
        case AudioEvent::Mute:
            AudioServiceAPI::SendEvent(this, audio::EventType::CallMute);
            break;
        case AudioEvent::Unmute:
            AudioServiceAPI::SendEvent(this, audio::EventType::CallUnmute);
            break;
        case AudioEvent::LoudspeakerOn:
            AudioServiceAPI::SendEvent(this, audio::EventType::CallLoudspeakerOn);
            break;
        case AudioEvent::LoudspeakerOff:
            AudioServiceAPI::SendEvent(this, audio::EventType::CallLoudspeakerOff);
            break;
        }
    }

    void ApplicationCall::hangupCall()
    {
        CellularServiceAPI::HangupCall(this);
    }

    void ApplicationCall::answerIncomingCall()
    {
        CellularServiceAPI::AnswerIncomingCall(this);
    }

    void ApplicationCall::transmitDtmfTone(uint32_t digit)
    {
        if (!CellularServiceAPI::TransmitDtmfTones(this, digit)) {
            LOG_ERROR("transmitDtmfTone failed");
        }
    }
} // namespace app

M module-apps/application-call/ApplicationCall.hpp => module-apps/application-call/ApplicationCall.hpp +24 -7
@@ 19,7 19,7 @@ namespace app

    namespace window
    {
        inline constexpr auto name_call              = "CallWindow";
        inline constexpr auto name_call              = gui::name::window::main_window;
        inline constexpr auto name_enterNumber       = "EnterNumberWindow";
        inline constexpr auto name_emergencyCall     = "EmergencyCallWindow";
        inline constexpr auto name_duplicatedContact = "DuplicatedContactWindow";


@@ 37,10 37,22 @@ namespace app
        virtual void setState(app::call::State state) noexcept              = 0;
        [[nodiscard]] virtual auto getState() const noexcept -> call::State = 0;

        enum class AudioEvent
        {
            Mute,
            Unmute,
            LoudspeakerOn,
            LoudspeakerOff
        };

        virtual void stopAudio()                           = 0;
        virtual void startAudioRinging()                   = 0;
        virtual void startAudioRouting()                   = 0;
        virtual void sendAudioEvent(AudioEvent audioEvent) = 0;

        virtual void transmitDtmfTone(uint32_t digit) = 0;
        virtual void stopAudio()                      = 0;
        virtual void startRinging()                   = 0;
        virtual void startRouting()                   = 0;
        virtual void hangupCall()                     = 0;
        virtual void answerIncomingCall()             = 0;
    };

    class EnterNumberWindowInterface


@@ 94,10 106,15 @@ namespace app
        {
            this->state = state;
        }
        void transmitDtmfTone(uint32_t digit) override;

        void stopAudio() override;
        void startRinging() override;
        void startRouting() override;
        void startAudioRinging() override;
        void startAudioRouting() override;
        void sendAudioEvent(AudioEvent audioEvent) override;

        void transmitDtmfTone(uint32_t digit) override;
        void hangupCall() override;
        void answerIncomingCall() override;
    };

    template <> struct ManifestTraits<ApplicationCall>

M module-apps/application-call/CMakeLists.txt => module-apps/application-call/CMakeLists.txt +0 -2
@@ 17,7 17,6 @@ target_sources( ${PROJECT_NAME}

	PRIVATE
		"${CMAKE_CURRENT_LIST_DIR}/ApplicationCall.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/windows/CallMainWindow.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/windows/EnterNumberWindow.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/windows/EmergencyCallWindow.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/windows/CallWindow.cpp"


@@ 37,4 36,3 @@ target_link_libraries(${PROJECT_NAME}
        service-audio
        service-cellular
)


M module-apps/application-call/widgets/StateIcon.hpp => module-apps/application-call/widgets/StateIcon.hpp +2 -2
@@ 38,7 38,7 @@ namespace gui
    /// icon::h where w = icon::w + 2 * w_margin. It is necessary as it is possible that text will exceed Icon visible
    /// area

    template <class T> class [[deprecated("Class to be merged with Icon.hpp")]] StateIcon : public Rect
    template <class T> class StateIcon : public Rect
    {
      public:
        using IconMap = std::map<T, std::pair<const std::string, const std::string>>;


@@ 98,7 98,7 @@ namespace gui
        }

        // sets/clears focus of internal boundingrect
        virtual bool onFocus(bool state) override
        bool onFocus(bool state) override
        {
            Item::onFocus(state);
            setFocusItem(state ? boundingRect : nullptr);

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

#include <Label.hpp>
#include "CallMainWindow.hpp"
#include <Style.hpp>

namespace gui
{

    CallMainWindow::CallMainWindow(app::Application *app) : AppWindow(app, gui::name::window::main_window)
    {
        buildInterface();
    }

    void CallMainWindow::rebuild()
    {}
    void CallMainWindow::buildInterface()
    {
        AppWindow::buildInterface();
        setTitle(getName());
    }
    void CallMainWindow::destroyInterface()
    {
        AppWindow::destroyInterface();
    }

    CallMainWindow::~CallMainWindow()
    {}

} /* namespace gui */

D module-apps/application-call/windows/CallMainWindow.hpp => module-apps/application-call/windows/CallMainWindow.hpp +0 -31
@@ 1,31 0,0 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#ifndef MODULE_APPS_APPLICATION_CALL_WINDOWS_CALLMAINWINDOW_HPP_
#define MODULE_APPS_APPLICATION_CALL_WINDOWS_CALLMAINWINDOW_HPP_

#include "AppWindow.hpp"
#include "Label.hpp"

namespace gui
{

    /*
     * This window is defined only to keep common approach to creating application.
     * This window should not be displayed.
     */
    class CallMainWindow : public AppWindow
    {
      protected:
      public:
        CallMainWindow(app::Application *app);
        virtual ~CallMainWindow();

        void rebuild() override;
        void buildInterface() override;
        void destroyInterface() override;
    };

} /* namespace gui */

#endif /* MODULE_APPS_APPLICATION_CALL_WINDOWS_CALLMAINWINDOW_HPP_ */

M module-apps/application-call/windows/CallWindow.cpp => module-apps/application-call/windows/CallWindow.cpp +22 -21
@@ 15,8 15,6 @@

#include <i18n/i18n.hpp>

#include <service-audio/AudioServiceAPI.hpp>
#include <service-cellular/CellularServiceAPI.hpp>
#include "service-db/DBServiceAPI.hpp"

#include "Label.hpp"


@@ 40,6 38,7 @@ namespace gui
    using namespace callAppStyle;
    using namespace callAppStyle::callWindow;
    using namespace app::call;
    using AudioEvent = app::CallWindowInterface::AudioEvent;

    CallWindow::CallWindow(app::Application *app, app::CallWindowInterface *interface, std::string windowName)
        : AppWindow(app, windowName), interface(interface)


@@ 96,10 95,10 @@ namespace gui

            switch (speakerIcon->get()) {
            case SpeakerIconState::SPEAKER: {
                AudioServiceAPI::SendEvent(this->application, audio::EventType::CallLoudspeakerOff);
                interface->sendAudioEvent(AudioEvent::LoudspeakerOff);
            } break;
            case SpeakerIconState::SPEAKERON: {
                AudioServiceAPI::SendEvent(this->application, audio::EventType::CallLoudspeakerOn);
                interface->sendAudioEvent(AudioEvent::LoudspeakerOn);
            } break;
            // case SpeakerIconState::BLUETOOTH: {
            //     // TODO: need implementation


@@ 122,9 121,8 @@ namespace gui
            application->refreshWindow(RefreshModes::GUI_REFRESH_FAST);
            LOG_INFO("Mic activated %d", static_cast<int>(microphoneIcon->get()));

            microphoneIcon->get() == MicrophoneIconState::MUTED
                ? AudioServiceAPI::SendEvent(this->application, audio::EventType::CallMute)
                : AudioServiceAPI::SendEvent(this->application, audio::EventType::CallUnmute);
            microphoneIcon->get() == MicrophoneIconState::MUTED ? interface->sendAudioEvent(AudioEvent::Mute)
                                                                : interface->sendAudioEvent(AudioEvent::Unmute);

            return true;
        };


@@ 163,7 161,7 @@ namespace gui

        switch (state) {
        case State::INCOMING_CALL: {
            interface->startRinging();
            interface->startAudioRinging();
            bottomBar->setActive(gui::BottomBar::Side::CENTER, true);
            bottomBar->setText(gui::BottomBar::Side::LEFT, utils::localize.get(strings::answer), true);
            bottomBar->setText(gui::BottomBar::Side::RIGHT, utils::localize.get(strings::reject), true);


@@ 193,7 191,7 @@ namespace gui
        } break;
        case State::CALL_IN_PROGRESS: {
            if (prevState == State::INCOMING_CALL) { // otherwise it is already started
                interface->startRouting();
                interface->startAudioRouting();
            }
            runCallTimer();
            bottomBar->setActive(gui::BottomBar::Side::LEFT, false);


@@ 209,7 207,7 @@ namespace gui
            }
        } break;
        case State::OUTGOING_CALL: {
            interface->startRouting();
            interface->startAudioRouting();
            bottomBar->setActive(gui::BottomBar::Side::LEFT, false);
            bottomBar->setActive(gui::BottomBar::Side::CENTER, false);
            bottomBar->setText(gui::BottomBar::Side::RIGHT, utils::localize.get(strings::endcall), true);


@@ 269,7 267,7 @@ namespace gui

            if (dynamic_cast<app::IncomingCallData *>(data) != nullptr) {
                if (getState() == State::INCOMING_CALL) {
                    LOG_DEBUG("ignoring call incoming");
                    LOG_DEBUG("ignoring IncomingCallData message");
                    return;
                }
                setState(State::INCOMING_CALL);


@@ 287,12 285,16 @@ namespace gui
        }

        if (dynamic_cast<app::CallActiveData *>(data) != nullptr) {
            setState(State::CALL_IN_PROGRESS);
            if (getState() != State::CALL_ENDED) {
                setState(State::CALL_IN_PROGRESS);
                return;
            }
            LOG_DEBUG("Ignoring CallActiveData message");
            return;
        }

        if (dynamic_cast<SMSTemplateSent *>(data) != nullptr) {
            CellularServiceAPI::HangupCall(application);
            interface->hangupCall();
            return;
        }
    }


@@ 300,9 302,7 @@ namespace gui
    bool CallWindow::handleLeftButton()
    {
        if (getState() == State::INCOMING_CALL) {
            auto ret = CellularServiceAPI::AnswerIncomingCall(application);

            LOG_INFO("AnswerIncomingCall: %s", (ret ? "OK" : "FAIL"));
            interface->answerIncomingCall();
            return true;
        }



@@ 315,7 315,7 @@ namespace gui
        case State::INCOMING_CALL:
        case State::OUTGOING_CALL:
        case State::CALL_IN_PROGRESS:
            CellularServiceAPI::HangupCall(application);
            interface->hangupCall();
            return true;
            break;
        default:


@@ 388,11 388,12 @@ namespace gui
    {
        static const sys::ms one_second = 1000;
        stop_timer                      = false;
        auto timer    = std::make_unique<app::GuiTimer>("CallTime", application, one_second, Timer::Continous);
        timerCallback = [&](Item &, Timer &timer) {
        auto timer = std::make_unique<app::GuiTimer>("CallTime", application, one_second, Timer::Continous);
        durationLabel->timerCallback = [&](Item &item, Timer &timer) {
            if (stop_timer) {
                timer.stop();
                detachTimer(timer);
                item.detachTimer(timer);
                return true;
            }
            std::chrono::time_point<std::chrono::system_clock> systemUnitDuration(callDuration);
            updateDuration(std::chrono::system_clock::to_time_t(systemUnitDuration));


@@ 402,7 403,7 @@ namespace gui
            return true;
        };
        timer->start();
        application->connect(std::move(timer), this);
        application->connect(std::move(timer), durationLabel);
    }

    void CallWindow::stopCallTimer()

M module-services/service-cellular/CellularServiceAPI.cpp => module-services/service-cellular/CellularServiceAPI.cpp +8 -19
@@ 36,33 36,22 @@ bool CellularServiceAPI::DialEmergencyNumber(sys::Service *serv, const utils::Ph

bool CellularServiceAPI::AnswerIncomingCall(sys::Service *serv)
{
    std::shared_ptr<CellularRequestMessage> msg =
        std::make_shared<CellularRequestMessage>(MessageType::CellularAnswerIncomingCall);
    auto msg = std::make_shared<CellularRequestMessage>(MessageType::CellularAnswerIncomingCall);

    auto ret                          = serv->bus.sendUnicast(msg, ServiceCellular::serviceName, 5000);
    CellularResponseMessage *response = reinterpret_cast<CellularResponseMessage *>(ret.second.get());
    if ((ret.first == sys::ReturnCodes::Success) && (response->retCode == true)) {
        return true;
    }
    else {
        LOG_ERROR("Failed");
        return false;
    }
    return serv->bus.sendUnicast(msg, ServiceCellular::serviceName);
}

void CellularServiceAPI::HangupCall(sys::Service *serv)
bool CellularServiceAPI::HangupCall(sys::Service *serv)
{
    std::shared_ptr<CellularRequestMessage> msg =
        std::make_shared<CellularRequestMessage>(MessageType::CellularHangupCall);
    auto msg = std::make_shared<CellularRequestMessage>(MessageType::CellularHangupCall);

    serv->bus.sendUnicast(msg, ServiceCellular::serviceName);
    return serv->bus.sendUnicast(msg, ServiceCellular::serviceName);
}

std::string CellularServiceAPI::GetIMSI(sys::Service *serv, bool getFullIMSINumber)
{

    std::shared_ptr<CellularRequestMessage> msg =
        std::make_shared<CellularRequestMessage>(MessageType::CellularGetIMSI);
    auto msg = std::make_shared<CellularRequestMessage>(MessageType::CellularGetIMSI);

    auto ret                          = serv->bus.sendUnicast(msg, ServiceCellular::serviceName, 5000);
    CellularResponseMessage *response = dynamic_cast<CellularResponseMessage *>(ret.second.get());


@@ 278,8 267,8 @@ bool CellularServiceAPI::TransmitDtmfTones(sys::Service *serv, uint32_t digit)
bool CellularServiceAPI::USSDRequest(sys::Service *serv, CellularUSSDMessage::RequestType type, std::string data)
{
    auto msg = std::make_shared<CellularUSSDMessage>(type, data);
    serv->bus.sendUnicast(msg, ServiceCellular::serviceName);
    return true;
    return serv->bus.sendUnicast(msg, ServiceCellular::serviceName);
    ;
}

bool CellularServiceAPI::ChangeSimPin(sys::Service *serv,

M module-services/service-cellular/service-cellular/CellularServiceAPI.hpp => module-services/service-cellular/service-cellular/CellularServiceAPI.hpp +1 -1
@@ 26,7 26,7 @@ namespace CellularServiceAPI
    bool DialEmergencyNumber(sys::Service *serv, const utils::PhoneNumber &number);

    bool AnswerIncomingCall(sys::Service *serv);
    void HangupCall(sys::Service *serv);
    bool HangupCall(sys::Service *serv);
    /*
     * @brief Its calls sercive-cellular for selected SIM IMSI number.
     * @param serv pointer to caller service.