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 => +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 => +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 => +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 => +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 => +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