~aleteoryx/muditaos

c96dc7dc30a62ea6d66bfdcc1c536726358a8925 — rrandomsky 2 years ago 3c2728e
[MOS-686] Fixed MTP availability only after phone unlocked

Fixed file access via MTP even when phone is not unlocked.
Now access is granted when the phone is unlocked by the user entering
a passcode. If the phone is not passcode protected (passcode is nor set)
then access to the files is always possible via MTP.
M module-apps/apps-common/ApplicationCommon.cpp => module-apps/apps-common/ApplicationCommon.cpp +12 -3
@@ 835,11 835,20 @@ namespace app
            assert(0 && "invalid popup data received");
            return;
        }

        // two lines below is to **not** loose data on copy on dynamic_cast, but to move the data
        (void)params.release();
        auto data      = std::unique_ptr<gui::PopupRequestParams>(rdata);
        auto id        = data->getPopupId();
        auto blueprint = popupBlueprint.getBlueprint(id);
        auto data                    = std::unique_ptr<gui::PopupRequestParams>(rdata);
        auto id                      = data->getPopupId();
        auto blueprint               = popupBlueprint.getBlueprint(id);
        auto appNameWhichAskForPopup = data->nameOfSenderApplication;

        auto topOfWindowsStackId = windowsStack().getWindowData(app::topWindow)->disposition.id;
        if (data->ignoreIfTheSamePopupIsOnTopOfTheStack && id == topOfWindowsStackId) {
            LOG_WARN("ignoring popup because the same is already on the top of the stack");
            return;
        }

        if (!blueprint) {
            LOG_ERROR("no blueprint to handle %s popup - fallback", std::string(magic_enum::enum_name(id)).c_str());
            blueprint = popupBlueprintFallback(id);

M module-apps/apps-common/ApplicationCommonPopupBlueprints.cpp => module-apps/apps-common/ApplicationCommonPopupBlueprints.cpp +0 -3
@@ 95,9 95,6 @@ namespace app
                return false;
            }

            popupParams->setDisposition(gui::popup::Disposition{gui::popup::Disposition::Priority::Normal,
                                                                gui::popup::Disposition::WindowType::Popup,
                                                                params->getPopupId()});
            switchWindowPopup(
                gui::popup::resolveWindowName(id),
                popupParams->getDisposition(),

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

#include "WindowsPopupFilter.hpp"

M module-apps/apps-common/locks/data/LockData.hpp => module-apps/apps-common/locks/data/LockData.hpp +1 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

M module-apps/apps-common/locks/data/PhoneLockMessages.hpp => module-apps/apps-common/locks/data/PhoneLockMessages.hpp +4 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 12,6 12,9 @@ namespace locks
    class UnlockPhone : public sys::DataMessage
    {};

    class UnlockPhoneForMTP : public sys::DataMessage
    {};

    class CancelUnlockPhone : public sys::DataMessage
    {};


M module-apps/apps-common/locks/handlers/PhoneLockHandler.cpp => module-apps/apps-common/locks/handlers/PhoneLockHandler.cpp +16 -12
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "PhoneLockHandler.hpp"


@@ 115,9 115,12 @@ namespace locks
                std::make_unique<gui::PopupRequestParams>(gui::popup::ID::PhoneLockInfo));
        }

        app::manager::Controller::sendAction(owner,
                                             app::manager::actions::AbortPopup,
                                             std::make_unique<gui::PopupRequestParams>(gui::popup::ID::PhoneLockInput));
        if (lock.inputValue.empty()) {
            app::manager::Controller::sendAction(
                owner,
                app::manager::actions::AbortPopup,
                std::make_unique<gui::PopupRequestParams>(gui::popup::ID::PhoneLockInput));
        }
    }

    void PhoneLockHandler::phoneUnlockAction()


@@ 127,12 130,13 @@ namespace locks
        owner->bus.sendMulticast(std::make_shared<locks::UnlockedPhone>(), sys::BusChannel::PhoneLockChanges);
    }

    void PhoneLockHandler::phoneInputRequiredAction()
    void PhoneLockHandler::phoneInputRequiredAction(ReasonForRequest reqReason)
    {
        app::manager::Controller::sendAction(owner,
                                             app::manager::actions::ShowPopup,
                                             std::make_unique<gui::PhoneUnlockInputRequestParams>(
                                                 gui::popup::ID::PhoneLockInput, lock, phoneLockInputTypeAction));
        auto data = std::make_unique<gui::PhoneUnlockInputRequestParams>(
            gui::popup::ID::PhoneLockInput, lock, phoneLockInputTypeAction);
        // If it's for MTP, don't show the input passcode popup if it's already on the screen
        data->ignoreIfTheSamePopupIsOnTopOfTheStack = (reqReason == ReasonForRequest::MTPUnlock);
        app::manager::Controller::sendAction(owner, app::manager::actions::ShowPopup, std::move(data));
    }

    void PhoneLockHandler::phoneLockEnableAction()


@@ 249,7 253,7 @@ namespace locks
        saveNoLockTimeAttemptsLeft();
    }

    sys::MessagePointer PhoneLockHandler::handleUnlockRequest()
    sys::MessagePointer PhoneLockHandler::handleUnlockRequest(ReasonForRequest reqReason)
    {
        setPhoneLockInputTypeAction(PhoneLockInputTypeAction::Unlock);



@@ 262,11 266,11 @@ namespace locks
            if (lockedFor == 0) {
                lock.lockState = Lock::LockState::InputRequired;
            }
            phoneInputRequiredAction();
            phoneInputRequiredAction(reqReason);
        }
        else if (!lock.isState(Lock::LockState::Unlocked)) {
            lock.lockState = Lock::LockState::InputRequired;
            phoneInputRequiredAction();
            phoneInputRequiredAction(reqReason);
        }

        return sys::msgHandled();

M module-apps/apps-common/locks/handlers/PhoneLockHandler.hpp => module-apps/apps-common/locks/handlers/PhoneLockHandler.hpp +10 -3
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 20,6 20,13 @@ namespace locks

    class PhoneLockHandler
    {
      public:
        enum class ReasonForRequest
        {
            Default = 0, // For default behaviors
            MTPUnlock
        };

      private:
        enum class PhoneState
        {


@@ 65,7 72,7 @@ namespace locks
        void phoneLockDisableAction();
        void phoneLockChangeAction();
        void phoneLockSetAction();
        void phoneInputRequiredAction();
        void phoneInputRequiredAction(ReasonForRequest reqReason = ReasonForRequest::Default);
        void phoneUnlockPopupsCloseAction();
        void phoneLockChangeInfoAction();
        void phoneExternalUnlockInfoAction();


@@ 82,7 89,7 @@ namespace locks
        explicit PhoneLockHandler(sys::Service *owner, std::shared_ptr<settings::Settings> settings);

        sys::MessagePointer handleLockRequest();
        sys::MessagePointer handleUnlockRequest();
        sys::MessagePointer handleUnlockRequest(ReasonForRequest reqReason = ReasonForRequest::Default);
        sys::MessagePointer handleUnlockCancelRequest();
        sys::MessagePointer handleEnablePhoneLock();
        sys::MessagePointer handleDisablePhoneLock();

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

#pragma once


@@ 17,10 17,13 @@ namespace gui
    class PhoneUnlockInputRequestParams : public PopupRequestParams
    {
      public:
        PhoneUnlockInputRequestParams(gui::popup::ID popupId,
        PhoneUnlockInputRequestParams(popup::ID popupId,
                                      locks::Lock lock,
                                      locks::PhoneLockInputTypeAction phoneLockInputTypeAction)
            : PopupRequestParams{popupId}, lock{std::move(lock)}, phoneLockInputTypeAction(phoneLockInputTypeAction)
                                      locks::PhoneLockInputTypeAction phoneLockInputTypeAction,
                                      popup::Disposition::Priority priority = popup::Disposition::Priority::Normal)
            : PopupRequestParams{popupId,
                                 gui::popup::Disposition{priority, popup::Disposition::WindowType::Popup, popupId}},
              lock{std::move(lock)}, phoneLockInputTypeAction(phoneLockInputTypeAction)
        {}

        [[nodiscard]] auto getLock() const noexcept

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

#pragma once


@@ 19,6 19,8 @@ namespace gui
        [[nodiscard]] const popup::Disposition &getDisposition() const noexcept;
        void setDisposition(const popup::Disposition &d);

        bool ignoreIfTheSamePopupIsOnTopOfTheStack = false;

      private:
        gui::popup::ID popupId;
        popup::Disposition disposition;

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

#include "PhoneLockInputWindow.hpp"

M module-bsp/board/linux/usb_cdc/usb_cdc.cpp => module-bsp/board/linux/usb_cdc/usb_cdc.cpp +6 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "bsp/usb/usb.hpp"


@@ 156,6 156,11 @@ namespace bsp
            vTaskDelete(taskHandleReceive);
    }

    void usbUnlockMTP()
    {
        LOG_INFO("mtpUnlock");
    }

    int usbInit(const bsp::usbInitParams &initParams)
    {


M module-bsp/bsp/usb/usb.hpp => module-bsp/bsp/usb/usb.hpp +1 -1
@@ 45,7 45,7 @@ namespace bsp
    int usbCDCSend(std::string *sendMsg);
    int usbCDCSendRaw(const char *dataPtr, size_t dataLen);
    void usbDeinit();
    void usbSuspend();
    void usbHandleDataReceived();
    void usbUnlockMTP();

} // namespace bsp

M module-services/service-desktop/ServiceDesktop.cpp => module-services/service-desktop/ServiceDesktop.cpp +8 -5
@@ 184,10 184,11 @@ auto ServiceDesktop::usbWorkerInit() -> sys::ReturnCodes
                                                    caseColour,
                                                    mtpRootPath);

    initialized =
        desktopWorker->init({{sdesktop::RECEIVE_QUEUE_BUFFER_NAME, sizeof(std::string *), sdesktop::cdc_queue_len},
                             {sdesktop::SEND_QUEUE_BUFFER_NAME, sizeof(std::string *), sdesktop::cdc_queue_object_size},
                             {sdesktop::IRQ_QUEUE_BUFFER_NAME, 1, sdesktop::irq_queue_object_size}});
    initialized = desktopWorker->init(
        {{sdesktop::RECEIVE_QUEUE_BUFFER_NAME, sizeof(std::string *), sdesktop::cdcReceiveQueueLength},
         {sdesktop::SEND_QUEUE_BUFFER_NAME, sizeof(std::string *), sdesktop::cdcSendQueueLength},
         {sdesktop::IRQ_QUEUE_BUFFER_NAME, sdesktop::irqQueueSize, sdesktop::irqQueueLength},
         {sdesktop::SIGNALLING_QUEUE_BUFFER_NAME, sizeof(WorkerDesktop::Signal), sdesktop::signallingQueueLength}});

    if (!initialized) {
        LOG_ERROR("!!! service-desktop usbWorkerInit failed to initialize worker, service-desktop won't work");


@@ 247,6 248,7 @@ auto ServiceDesktop::handle(locks::UnlockedPhone * /*msg*/) -> std::shared_ptr<s
        bus.sendUnicast(std::make_shared<sys::TetheringStateRequest>(sys::phone_modes::Tethering::On),
                        service::name::system_manager);
        isPlugEventUnhandled = false;
        desktopWorker->notify(WorkerDesktop::Signal::unlockMTP);
    }

    return sys::MessageNone{};


@@ 324,13 326,14 @@ auto ServiceDesktop::handle(sdesktop::usb::USBConfigured *msg) -> std::shared_pt
    isUsbConfigured = true;
    if (usbSecurityModel->isSecurityEnabled()) {
        LOG_INFO("Endpoint security enabled, requesting passcode");
        bus.sendUnicast(std::make_shared<locks::UnlockPhone>(), service::name::appmgr);
        bus.sendUnicast(std::make_shared<locks::UnlockPhoneForMTP>(), service::name::appmgr);
    }
    else {
        if (isPlugEventUnhandled) {
            bus.sendUnicast(std::make_shared<sys::TetheringStateRequest>(sys::phone_modes::Tethering::On),
                            service::name::system_manager);
            isPlugEventUnhandled = false;
            desktopWorker->notify(WorkerDesktop::Signal::unlockMTP);
        }
    }


M module-services/service-desktop/WorkerDesktop.cpp => module-services/service-desktop/WorkerDesktop.cpp +32 -0
@@ 106,6 106,13 @@ void WorkerDesktop::reset()
    }
}

void WorkerDesktop::notify(Signal command)
{
    if (auto queue = getQueueByName(sdesktop::SIGNALLING_QUEUE_BUFFER_NAME); !queue->Overwrite(&command)) {
        LOG_ERROR("Unable to overwrite the command in the commands queue.");
    }
}

bool WorkerDesktop::handleMessage(std::uint32_t queueID)
{
    bool result       = false;


@@ 124,6 131,9 @@ bool WorkerDesktop::handleMessage(std::uint32_t queueID)
    else if (qname == sdesktop::IRQ_QUEUE_BUFFER_NAME) {
        result = handleIrqQueueMessage(queue);
    }
    else if (qname == sdesktop::SIGNALLING_QUEUE_BUFFER_NAME) {
        result = handleSignallingQueueMessage(queue);
    }
    else {
        LOG_INFO("handeMessage got message on an unhandled queue");
    }


@@ 220,3 230,25 @@ bool WorkerDesktop::handleIrqQueueMessage(std::shared_ptr<sys::WorkerQueue> &que
    }
    return true;
}

bool WorkerDesktop::handleSignallingQueueMessage(std::shared_ptr<sys::WorkerQueue> &queue)
{
    if (!initialized) {
        return false;
    }
    sys::WorkerCommand command;
    if (!queue->Dequeue(&command, 0)) {
        LOG_ERROR("handleMessage failed to receive from \"%s\"", sdesktop::SIGNALLING_QUEUE_BUFFER_NAME);
        return false;
    }

    switch (static_cast<Signal>(command.command)) {
    case Signal::unlockMTP:
        bsp::usbUnlockMTP();
        break;
    default:
        LOG_ERROR("Command not valid.");
        return false;
    }
    return true;
}

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

#pragma once


@@ 19,6 19,11 @@
class WorkerDesktop : public sys::Worker
{
  public:
    enum class Signal
    {
        unlockMTP
    };

    WorkerDesktop(sys::Service *ownerServicePtr,
                  std::function<void()> messageProcessedCallback,
                  const sdesktop::USBSecurityModel &securityModel,


@@ 30,6 35,7 @@ class WorkerDesktop : public sys::Worker
    void closeWorker();

    bool handleMessage(std::uint32_t queueID) override final;
    void notify(Signal command);

    xQueueHandle getReceiveQueue()
    {


@@ 44,6 50,7 @@ class WorkerDesktop : public sys::Worker
    bool handleSendQueueMessage(std::shared_ptr<sys::WorkerQueue> &queue);
    bool handleServiceQueueMessage(std::shared_ptr<sys::WorkerQueue> &queue);
    bool handleIrqQueueMessage(std::shared_ptr<sys::WorkerQueue> &queue);
    bool handleSignallingQueueMessage(std::shared_ptr<sys::WorkerQueue> &queue);

    std::atomic<bool> initialized = false;


M module-services/service-desktop/include/service-desktop/ServiceDesktop.hpp => module-services/service-desktop/include/service-desktop/ServiceDesktop.hpp +17 -14
@@ 26,20 26,23 @@ class WorkerDesktop;

namespace sdesktop
{
    inline constexpr auto service_stack             = 8192;
    inline constexpr auto worker_stack              = 8704;
    inline constexpr auto cdc_queue_len             = 1024;
    inline constexpr auto cdc_queue_object_size     = 1024;
    inline constexpr auto irq_queue_object_size     = sizeof(bsp::USBDeviceStatus);
    constexpr auto connectionActiveTimerName        = "connectionActiveTimer";
    constexpr auto connectionActiveTimerDelayMs     = std::chrono::milliseconds{1000 * 20};
    inline constexpr auto RECEIVE_QUEUE_BUFFER_NAME = "receiveQueueBuffer";
    inline constexpr auto SEND_QUEUE_BUFFER_NAME    = "sendQueueBuffer";
    inline constexpr auto IRQ_QUEUE_BUFFER_NAME     = "irqQueueBuffer";
    inline constexpr auto DeviceUniqueIdLength      = 32;
    inline constexpr auto DeviceUniqueIdName        = "sd_device_unique_id";
    constexpr auto pathFactoryDataSerial            = "factory_data/serial";
    constexpr auto pathFactoryDataCaseColour        = "factory_data/case_colour";
    inline constexpr auto service_stack                = 8192;
    inline constexpr auto worker_stack                 = 8704;
    inline constexpr auto cdcReceiveQueueLength        = 1024;
    inline constexpr auto cdcSendQueueLength           = 1024;
    inline constexpr auto signallingQueueLength        = 4;
    inline constexpr auto irqQueueLength               = 4;
    inline constexpr auto irqQueueSize                 = sizeof(bsp::USBDeviceStatus);
    constexpr auto connectionActiveTimerName           = "connectionActiveTimer";
    constexpr auto connectionActiveTimerDelayMs        = std::chrono::milliseconds{1000 * 20};
    inline constexpr auto RECEIVE_QUEUE_BUFFER_NAME    = "receiveQueueBuffer";
    inline constexpr auto SEND_QUEUE_BUFFER_NAME       = "sendQueueBuffer";
    inline constexpr auto IRQ_QUEUE_BUFFER_NAME        = "irqQueueBuffer";
    inline constexpr auto SIGNALLING_QUEUE_BUFFER_NAME = "signallingQueueBuffer";
    inline constexpr auto DeviceUniqueIdLength         = 32;
    inline constexpr auto DeviceUniqueIdName           = "sd_device_unique_id";
    constexpr auto pathFactoryDataSerial               = "factory_data/serial";
    constexpr auto pathFactoryDataCaseColour           = "factory_data/case_colour";

}; // namespace sdesktop


M products/PurePhone/services/appmgr/ApplicationManager.cpp => products/PurePhone/services/appmgr/ApplicationManager.cpp +6 -2
@@ 185,6 185,9 @@ namespace app::manager
                [&](sys::Message *request) -> sys::MessagePointer { return phoneLockHandler.handleLockRequest(); });
        connect(typeid(locks::UnlockPhone),
                [&](sys::Message *request) -> sys::MessagePointer { return phoneLockHandler.handleUnlockRequest(); });
        connect(typeid(locks::UnlockPhoneForMTP), [&](sys::Message *request) -> sys::MessagePointer {
            return phoneLockHandler.handleUnlockRequest(locks::PhoneLockHandler::ReasonForRequest::MTPUnlock);
        });
        connect(typeid(locks::CancelUnlockPhone), [&](sys::Message *request) -> sys::MessagePointer {
            return phoneLockHandler.handleUnlockCancelRequest();
        });


@@ 527,7 530,8 @@ namespace app::manager
            autoLockTimer.stop();
            return;
        }
        if (const auto focusedApp = getFocusedApplication(); (focusedApp == nullptr) || focusedApp->preventsAutoLocking()) {
        if (const auto focusedApp = getFocusedApplication();
            (focusedApp == nullptr) || focusedApp->preventsAutoLocking()) {
            autoLockTimer.start();
            return;
        }


@@ 552,7 556,7 @@ namespace app::manager

            LOG_INFO("Starting application %s", app.name().c_str());
            StatusIndicators statusIndicators;
            statusIndicators.phoneMode        = phoneModeObserver->getCurrentPhoneMode();
            statusIndicators.phoneMode = phoneModeObserver->getCurrentPhoneMode();
            statusIndicators.tetheringState =
                phoneModeObserver->isTetheringOn() ? sys::phone_modes::Tethering::On : sys::phone_modes::Tethering::Off;
            statusIndicators.bluetoothMode    = bluetoothMode;

M pure_changelog.md => pure_changelog.md +1 -0
@@ 42,6 42,7 @@
* Fixed Template window clearing after all templates are removed.
* Fixed wrong notification about multiple unread messages in case there's only one unread left
* Fixed missing notification about new SMS when phone was locked on application Messages
* Fixed MTP availability only after phone unlocked

## [1.7.0 2023-03-23]
### Changed / Improved

M third-party/usb_stack => third-party/usb_stack +1 -1
@@ 1,1 1,1 @@
Subproject commit 73de0692b672d7bf2ff8fb2423cd461c3e5fa024
Subproject commit 7bd702e5037c4eca1be29aaf098f7567133fd384