M changelog.md => changelog.md +1 -0
@@ 4,6 4,7 @@
### Added
+* `[gui][desktop]` Added SIM PIN basic flow implementation
* `[cellular]` Added CLIR, CLIP, COLP, call waiting MMI support
## [0.47.1 2020-11-20]
M image/assets/lang/lang_en.json => image/assets/lang/lang_en.json +3 -0
@@ 163,6 163,8 @@
"app_desktop_sim_card": "card",
"app_desktop_sim_type_pin": "please type a PIN code:",
"app_desktop_sim_blocked": "The SIM card is blocked.",
+ "app_desktop_sim_enter_pin": "Enter new PIN code",
+ "app_desktop_sim_confirm_pin": "Enter new PIN code",
"app_desktop_sim_type_puk": "To unblock it, type the PUK code:",
"app_desktop_no_pin_lock": "<text>Press <b>Unlock</b> and then <b>#</b></text>",
"app_desktop_sim_wrong_pin": "Wrong PIN code",
@@ 175,6 177,7 @@
"app_desktop_sim_warning3": "have to contact the operator",
"app_desktop_sim_blocked_info1": "Sorry, SIM card permanently blocked.",
"app_desktop_sim_blocked_info2": "Please contact your service provider",
+ "app_desktop_sim_cme_error": "<text>SIM card\nCME error:</text>",
"app_desktop_unread_messages": "<text>Unread <b>messages</b></text>",
"app_desktop_missed_calls": "<text>Missed <b>calls</b></text>",
M module-apps/application-desktop/ApplicationDesktop.cpp => module-apps/application-desktop/ApplicationDesktop.cpp +30 -6
@@ 19,6 19,7 @@
#include <application-settings/ApplicationSettings.hpp>
#include <service-appmgr/Controller.hpp>
#include <service-cellular/ServiceCellular.hpp>
+#include <service-cellular/CellularMessage.hpp>
#include <application-calllog/ApplicationCallLog.hpp>
#include <service-db/QueryMessage.hpp>
#include <module-db/queries/notifications/QueryNotificationsClear.hpp>
@@ 30,6 31,31 @@ namespace app
: Application(name, parent, startInBackground), lockHandler(this, settings)
{
busChannels.push_back(sys::BusChannels::ServiceDBNotifications);
+
+ addActionReceiver(app::manager::actions::RequestPin, [this](auto &&data) {
+ lockHandler.handlePinRequest(std::move(data));
+ return msgHandled();
+ });
+
+ addActionReceiver(app::manager::actions::RequestPuk, [this](auto &&data) {
+ lockHandler.handlePukRequest(std::move(data));
+ return msgHandled();
+ });
+
+ addActionReceiver(app::manager::actions::RequestPinChange, [this](auto &&data) {
+ lockHandler.handlePinChangeRequest(std::move(data));
+ return msgHandled();
+ });
+
+ addActionReceiver(app::manager::actions::BlockSim, [this](auto &&data) {
+ lockHandler.handleSimBlocked(std::move(data));
+ return msgHandled();
+ });
+
+ addActionReceiver(app::manager::actions::DisplayCMEError, [this](auto &&data) {
+ lockHandler.handleCMEError(std::move(data));
+ return msgHandled();
+ });
}
ApplicationDesktop::~ApplicationDesktop()
@@ 63,9 89,6 @@ namespace app
else if (auto msg = dynamic_cast<sdesktop::UpdateOsMessage *>(msgl)) {
handled = handle(msg);
}
- else if (auto msg = dynamic_cast<CellularSimResponseMessage *>(msgl)) {
- handled = lockHandler.handle(msg);
- }
// handle database response
if (resp != nullptr) {
@@ 100,7 123,8 @@ namespace app
auto ApplicationDesktop::handle(sdesktop::developerMode::ScreenlockCheckEvent *event) -> bool
{
if (event != nullptr) {
- auto event = std::make_unique<sdesktop::developerMode::ScreenlockCheckEvent>(lockHandler.lock.isLocked());
+ auto event =
+ std::make_unique<sdesktop::developerMode::ScreenlockCheckEvent>(true); // lockHandler.lock.isLocked());
auto msg = std::make_shared<sdesktop::developerMode::DeveloperModeRequest>(std::move(event));
sys::Bus::SendUnicast(std::move(msg), service::name::service_desktop, this);
}
@@ 167,7 191,7 @@ namespace app
{
assert(msg);
if (msg->request == cellular::State::ST::URCReady) {
- if (need_sim_select && !lockHandler.lock.isLocked()) {
+ if (need_sim_select && !lockHandler.isScreenLocked()) {
app::manager::Controller::switchApplication(this, app::name_settings, app::sim_select, nullptr);
return true;
}
@@ 280,7 304,7 @@ namespace app
return std::make_unique<gui::DesktopMainWindow>(app);
});
windowsFactory.attach(desktop_pin_lock, [&](Application *app, const std::string newname) {
- return std::make_unique<gui::PinLockWindow>(app, desktop_pin_lock, lockHandler.lock);
+ return std::make_unique<gui::PinLockWindow>(app, desktop_pin_lock);
});
windowsFactory.attach(desktop_menu, [](Application *app, const std::string newname) {
return std::make_unique<gui::MenuWindow>(app);
M module-apps/application-desktop/ApplicationDesktop.hpp => module-apps/application-desktop/ApplicationDesktop.hpp +12 -1
@@ 15,6 15,11 @@
#include <service-desktop/ServiceDesktop.hpp>
#include <service-desktop/DesktopMessages.hpp>
+namespace cellular
+{
+ class StateChange;
+}
+
namespace app
{
inline constexpr auto name_desktop = "ApplicationDesktop";
@@ 83,7 88,13 @@ namespace app
{
static auto GetManifest() -> manager::ApplicationManifest
{
- return {{manager::actions::Launch}};
+ return {{manager::actions::Launch,
+ manager::actions::RequestPin,
+ manager::actions::RequestPuk,
+ manager::actions::RequestPinChange,
+ manager::actions::UnlockSim,
+ manager::actions::BlockSim,
+ manager::actions::DisplayCMEError}};
}
};
M module-apps/application-desktop/data/AppDesktopStyle.hpp => module-apps/application-desktop/data/AppDesktopStyle.hpp +13 -13
@@ 7,17 7,17 @@
namespace style::window::pin_lock
{
- const inline uint32_t image_x = 177;
- const inline uint32_t image_y = 132;
- const inline uint32_t title_label_y = 60;
- const inline uint32_t title_label_h = 40;
- const inline uint32_t label_size = 30;
- const inline uint32_t label_size_screen = 60;
- const inline uint32_t pin_label_x = 85;
- const inline uint32_t pin_label_x_screen = 100;
- const inline uint32_t pin_label_y = 450;
- const inline uint32_t info_text_y = 294;
- const inline uint32_t info_text_h_screen = 60;
- const inline uint32_t info_text_h_sim = 150;
- const inline uint32_t info_text_h_puk = 180;
+ constexpr inline auto image_x = 177;
+ constexpr inline auto image_y = 132;
+ constexpr inline auto title_label_y = 60;
+ constexpr inline auto title_label_h = 40;
+ constexpr inline auto label_size = 60;
+ constexpr inline auto label_margins = 10;
+ constexpr inline auto pin_label_x = 85;
+ constexpr inline auto pin_label_y = 450;
+ constexpr inline auto pin_label_y_screen = 400;
+ constexpr inline auto info_text_y = 294;
+ constexpr inline auto info_text_h_screen = 60;
+ constexpr inline auto info_text_h_sim = 150;
+ constexpr inline auto info_text_h_puk = 180;
} // namespace style::window::pin_lock
M module-apps/application-desktop/data/LockPhoneData.hpp => module-apps/application-desktop/data/LockPhoneData.hpp +10 -10
@@ 9,6 9,8 @@
#include <service-desktop/ServiceDesktop.hpp>
#include <filesystem>
+#include "application-desktop/widgets/PinLock.hpp"
+
namespace gui
{
@@ 16,17 18,10 @@ namespace gui
class LockPhoneData : public gui::SwitchData
{
std::string previousApplication;
- LockPhoneData() = default;
+ std::unique_ptr<PinLock> lock;
public:
- enum class Request
- {
- NoPin,
- Pin,
- ShowPrompt,
- } request;
-
- LockPhoneData(Request request) : SwitchData(), request(request)
+ LockPhoneData(std::unique_ptr<PinLock> &&lock) : SwitchData(), lock(std::move(lock))
{
description = "LockPhoneData";
}
@@ 37,10 32,15 @@ namespace gui
{
previousApplication = prevApp;
};
- const std::string &getPreviousApplication()
+ [[nodiscard]] const std::string &getPreviousApplication()
{
return previousApplication;
};
+
+ [[nodiscard]] std::unique_ptr<PinLock> getLock()
+ {
+ return std::make_unique<PinLock>(*lock.get());
+ }
};
class UpdateSwitchData : public gui::SwitchData
M module-apps/application-desktop/widgets/PinLock.cpp => module-apps/application-desktop/widgets/PinLock.cpp +25 -55
@@ 6,83 6,53 @@
namespace gui
{
- PinLock::PinLock(gui::PinLockHandler *handler) : handler(handler)
- {}
-
- void PinLock::consumeInvalidPinState() noexcept
+ void PinLock::consumeState() noexcept
{
- if (state == State::InvalidPin) {
- state = State::EnterPin;
+ if (lockState == LockState::PasscodeInvalidRetryRequired) {
+ lockState = LockState::PasscodeRequired;
}
- }
-
- void PinLock::putNextChar(unsigned int c) noexcept
- {
- if (state == State::EnterPin && charCount < pinValue.size()) {
- pinValue[charCount++] = c;
+ else if (lockState == LockState::NewPasscodeInvalid) {
+ lockState = LockState::NewPasscodeRequired;
}
}
- void PinLock::verifyPin() noexcept
+ void PinLock::setNewPasscodeInvalidState() noexcept
{
- if (charCount == pinValue.size()) {
- handler->handle(pinValue);
- clearAttempt();
+ if (lockState == LockState::NewPasscodeRequired) {
+ lockState = LockState::NewPasscodeInvalid;
}
}
- void PinLock::popChar() noexcept
+ void PinLock::putNextChar(unsigned int c)
{
- if (state == State::EnterPin && charCount > 0) {
- charCount--;
- pinValue[charCount] = 0;
+ if (maxPinSize > pinValue.size()) {
+ pinValue.push_back(c);
}
- }
-
- void PinLock::clearAttempt() noexcept
- {
- for (auto &c : pinValue) {
- c = 0;
+ if (canVerify() && autoActivate && onActivatedCallback != nullptr) {
+ onActivatedCallback(pinValue);
}
- charCount = 0;
}
- bool PinLock::unlock() noexcept
+ void PinLock::popChar()
{
- if (state == State::VerifiedPin || pinValue.size() == 0) {
- state = State::Unlocked;
- return true;
+ if (pinValue.size() > 0) {
+ pinValue.pop_back();
}
- return false;
}
- void PinLock::lock() noexcept
- {
- if (state == State::Unlocked) {
- state = State::EnterPin;
- }
- }
-
- bool PinLock::isLocked() const noexcept
+ void PinLock::clearAttempt() noexcept
{
- return state != State::Unlocked;
+ pinValue.clear();
}
- std::string PinLock::getLockInfo(const InfoName name) const
+ void PinLock::verify()
{
- try {
- return additionalLockInfo.at(name);
+ auto pinCopy = std::move(pinValue);
+ clearAttempt();
+ if (!onActivatedCallback) {
+ LOG_ERROR("Passcode verification callback null");
+ return;
}
- catch (std::out_of_range &) {
- return std::string{};
- }
- }
-
- void PinLock::reset(LockType newType, State newState, unsigned int attempts, unsigned int size) noexcept
- {
- type = newType;
- state = newState;
- remainingAttempts = attempts;
- pinValue = std::vector<unsigned int>(size, 0);
+ onActivatedCallback(pinCopy);
}
} // namespace gui
M module-apps/application-desktop/widgets/PinLock.hpp => module-apps/application-desktop/widgets/PinLock.hpp +71 -49
@@ 2,8 2,9 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
-
-#include "PhoneNumber.hpp"
+#include <vector>
+#include <string>
+#include <functional>
namespace gui
{
@@ 14,82 15,103 @@ namespace gui
public:
enum class LockType
{
- Screen,
- SIM,
- PUK,
- Unknown
+ SimPin,
+ SimPuk,
+ Screen
};
- enum class InfoName
+ enum class LockState
{
- LockName,
- PhoneNum
+ Unlocked,
+ PasscodeRequired,
+ PasscodeInvalidRetryRequired,
+ Blocked,
+ NewPasscodeRequired,
+ NewPasscodeInvalid,
+ ErrorOccurred
};
- enum class State
+ enum class SimCard
{
- EnterPin,
- InvalidPin,
- VerifiedPin,
- Blocked,
- Unlocked
+ SIM1,
+ SIM2,
+ NoCard
};
- [[nodiscard]] State getState() const noexcept
+ [[nodiscard]] LockState getState() const noexcept
{
- return state;
+ return lockState;
}
- [[nodiscard]] unsigned int getPinSize() const noexcept
+ [[nodiscard]] LockType getLockType() const noexcept
{
- return pinValue.size();
+ return lockType;
+ }
+ [[nodiscard]] unsigned int getMaxPinSize() const noexcept
+ {
+ return maxPinSize;
}
/// returns current position of a PIN character to be inserted
[[nodiscard]] unsigned int getCharCount() const noexcept
{
- return charCount;
+ return pinValue.size();
+ }
+ [[nodiscard]] bool canPut() const noexcept
+ {
+ return getCharCount() < getMaxPinSize();
}
- [[nodiscard]] unsigned int getRemainingAttempts() const noexcept
+ [[nodiscard]] bool canVerify() const noexcept
{
- return remainingAttempts;
+ return getCharCount() >= minPinSize;
}
- [[nodiscard]] bool canPut() const noexcept
+ [[nodiscard]] std::vector<unsigned int> getPin() const
{
- return getCharCount() != getPinSize();
+ return pinValue;
}
- void putNextChar(unsigned int c) noexcept;
- void verifyPin() noexcept;
+ [[nodiscard]] unsigned int getValue() const noexcept
+ {
+ return value;
+ }
+
+ void putNextChar(unsigned int c);
/// removes a last character passed to Lock via putNextChar. The last character can not be popped
- void popChar() noexcept;
+ void popChar();
/// clear all characters passed to the Lock
void clearAttempt() noexcept;
- /// if Lock is in the State::InvalidPin state, changes it's state to the State::EnterPin
- void consumeInvalidPinState() noexcept;
+ /// consumes LockState::PasscodeInvalidRetryRequired state and LockState::NewPasscodeInvalid)
+ void consumeState() noexcept;
+ void setNewPasscodeInvalidState() noexcept;
- [[nodiscard]] bool isLocked() const noexcept;
- bool unlock() noexcept;
- void lock() noexcept;
+ void verify();
- [[nodiscard]] std::string getLockInfo(const InfoName name) const;
- [[nodiscard]] LockType getLockType() const noexcept
- {
- return type;
- }
- PinLock(gui::PinLockHandler *);
+ PinLock(SimCard sim, LockState state, LockType type, unsigned int value)
+ : sim{sim}, lockState{state}, lockType{type}, value{value}
+ {}
+ PinLock(const PinLock &other) = default;
+
+ std::function<void(const std::vector<unsigned int> &)> onActivatedCallback = nullptr;
private:
- /// for PIN verification purposes as PIN storage and management is out of scope of PinLock class
- gui::PinLockHandler *handler;
+ SimCard sim = SimCard::NoCard;
+ LockState lockState = LockState::Unlocked;
+ LockType lockType = LockType::Screen;
+ unsigned int value = 0;
- LockType type = LockType::Unknown;
- State state = State::EnterPin;
- unsigned int remainingAttempts = 0;
- /// code of the entered character on specified position
std::vector<unsigned int> pinValue;
- /// flag defines number of entered pin characters
- unsigned int charCount = 0;
- std::map<InfoName, std::string> additionalLockInfo;
+ unsigned int maxPinSize = defaultPasscodeSize;
+ unsigned int minPinSize = defaultPasscodeSize;
+ bool autoActivate = false;
+
+ static constexpr unsigned int defaultPasscodeSize = 4;
- void reset(LockType, State, unsigned int remainingAttempts, unsigned int pinSize) noexcept;
+ void setAutoActivate(bool _autoActivate)
+ {
+ autoActivate = _autoActivate;
+ }
+ void setPinSizeBounds(unsigned int _minPinSize, unsigned int _maxPinSize)
+ {
+ minPinSize = _minPinSize;
+ maxPinSize = _maxPinSize;
+ }
- friend class gui::PinLockHandler;
+ friend class PinLockHandler;
};
} // namespace gui
M module-apps/application-desktop/widgets/PinLockHandler.cpp => module-apps/application-desktop/widgets/PinLockHandler.cpp +174 -95
@@ 1,139 1,218 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+//// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+//// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "PinLockHandler.hpp"
#include "PinHash.hpp"
#include "application-desktop/ApplicationDesktop.hpp"
-#include <service-cellular/ServiceCellular.hpp>
+#include "application-desktop/data/LockPhoneData.hpp"
+#include "application-desktop/windows/Names.hpp"
+
+#include <module-utils/common_data/EventStore.hpp>
+
+#include <service-appmgr/service-appmgr/data/SimActionsParams.hpp>
+#include <service-cellular/CellularMessage.hpp>
namespace gui
{
- constexpr unsigned int default_screen_pin_size = 4;
- constexpr unsigned int default_screen_attempts = 4;
+ namespace
+ {
+ constexpr unsigned int default_screen_pin_size = 4;
+ constexpr unsigned int screen_nopin_size = 0;
+ constexpr unsigned int default_attempts = 4;
+ constexpr unsigned int blocked_sim_attempts = 0;
+ constexpr unsigned int sim_max_passcode_size = 8;
+ constexpr unsigned int sim_min_passcode_size = 4;
+ } // namespace
PinLockHandler::PinLockHandler(app::ApplicationDesktop *app, SettingsRecord &settings)
- : app(app), appSettings(settings), lock(this)
+ : app(app), appSettings(settings), screenLock(PinLock::SimCard::NoCard,
+ PinLock::LockState::PasscodeRequired,
+ PinLock::LockType::Screen,
+ default_attempts),
+ simLock(PinLock::SimCard::NoCard, PinLock::LockState::Unlocked, PinLock::LockType::SimPin, default_attempts)
{
reloadScreenLock();
+ screenLock.setAutoActivate(true);
+
+ simLock.setPinSizeBounds(sim_min_passcode_size, sim_max_passcode_size);
}
- auto PinLockHandler::handle(CellularSimResponseMessage *msg) -> bool
+ void PinLockHandler::handleScreenPin(const std::vector<unsigned int> &pin)
{
- assert(msg);
+ if (screenLock.getMaxPinSize() == screen_nopin_size) {
+ screenLock.lockState = gui::PinLock::LockState::Unlocked;
+ }
+ else if (screenLock.value > 0) {
+ std::hash<std::vector<unsigned int>> hashEngine;
+ uint32_t hash = hashEngine(pin);
+ screenLock.value--;
+ if (hash == appSettings.lockPassHash) {
+ screenLock.lockState = gui::PinLock::LockState::Unlocked;
+ screenLock.value = default_attempts;
+ }
+ else if (screenLock.value > 0) {
+ screenLock.lockState = gui::PinLock::LockState::PasscodeInvalidRetryRequired;
+ }
+ else {
+ screenLock.lockState = gui::PinLock::LockState::Blocked;
+ }
+ }
+ }
- parseSimCard(msg);
- parseSimState(msg);
- parseAttemptsAndPinSize(msg);
+ void PinLockHandler::handleScreenConfirm()
+ {
+ simLock.consumeState();
+ }
- app->getWindow(app::window::name::desktop_pin_lock)->rebuild();
- app->switchWindow(gui::name::window::main_window);
- return true;
+ void PinLockHandler::reloadScreenLock()
+ {
+ screenLock.lockState = gui::PinLock::LockState::PasscodeRequired;
+ unsigned int pinSize = appSettings.lockPassHash == 0 ? screen_nopin_size : default_screen_pin_size;
+ screenLock.setPinSizeBounds(pinSize, pinSize);
+ screenLock.value = default_attempts;
}
- void PinLockHandler::handle(const std::vector<unsigned int> &pin)
+ auto PinLockHandler::handlePasscodeParams(app::manager::actions::ActionParamsPtr &&data) const -> gui::PinLock
{
- if (lock.getLockType() == gui::PinLock::LockType::Screen) {
- handleScreenPin(pin);
- }
- else {
- handleSimPinOrPuk(pin);
+ auto passcodeData = static_cast<app::manager::actions::PasscodeParams *>(data.get());
+
+ gui::PinLock lock(parseSimCard(passcodeData->getSim()),
+ gui::PinLock::LockState::PasscodeRequired,
+ simLock.getLockType(),
+ passcodeData->getAttempts());
+
+ if (simLock.getLockType() == lock.getLockType() && simLock.getState() == lock.getState() &&
+ simLock.getValue() > lock.getValue()) {
+ lock.lockState = PinLock::LockState::PasscodeInvalidRetryRequired;
}
+ lock.setPinSizeBounds(sim_min_passcode_size, sim_max_passcode_size);
+
+ return lock;
}
- void PinLockHandler::parseSimState(CellularSimResponseMessage *msg)
- {
- assert(msg);
- switch (msg->getSimState()) {
- case CellularSimResponseMessage::SimState::SIMUnlocked:
- lock.type = gui::PinLock::LockType::Screen;
- lock.state = gui::PinLock::State::EnterPin;
- break;
- case CellularSimResponseMessage::SimState::PINRequired:
- lock.type = gui::PinLock::LockType::SIM;
- lock.state = gui::PinLock::State::EnterPin;
- break;
- case CellularSimResponseMessage::SimState::PINInvalidRetryPossible:
- lock.type = gui::PinLock::LockType::SIM;
- lock.state = gui::PinLock::State::InvalidPin;
- break;
- case CellularSimResponseMessage::SimState::PUKRequired:
- lock.type = gui::PinLock::LockType::PUK;
- lock.state = gui::PinLock::State::EnterPin;
- break;
- case CellularSimResponseMessage::SimState::PUKInvalidRetryPossible:
- lock.type = gui::PinLock::LockType::PUK;
- lock.state = gui::PinLock::State::InvalidPin;
- break;
- case CellularSimResponseMessage::SimState::SIMBlocked:
- lock.type = gui::PinLock::LockType::PUK;
- lock.state = gui::PinLock::State::Blocked;
- break;
- }
+ void PinLockHandler::handlePinRequest(app::manager::actions::ActionParamsPtr &&data)
+ {
+ simLock = handlePasscodeParams(std::move(data));
+ simLock.lockType = gui::PinLock::LockType::SimPin;
+
+ auto onActivatedCallback = [this](const std::vector<unsigned int> &data) { handlePasscode(data); };
+ switchToPinlockWindow(onActivatedCallback);
}
- void PinLockHandler::parseSimCard(CellularSimResponseMessage *msg)
- {
- assert(msg);
- switch (msg->getSimCard()) {
- case Store::GSM::SIM::SIM1:
- lock.additionalLockInfo[gui::PinLock::InfoName::LockName] = "SIM1";
- break;
- case Store::GSM::SIM::SIM2:
- lock.additionalLockInfo[gui::PinLock::InfoName::LockName] = "SIM2";
- break;
- default:
- LOG_ERROR("Unknown SIM");
- break;
- }
+ void PinLockHandler::handlePukRequest(app::manager::actions::ActionParamsPtr &&data)
+ {
+ simLock = handlePasscodeParams(std::move(data));
+ simLock.lockType = gui::PinLock::LockType::SimPuk;
+
+ auto onActivatedCallback = [this](const std::vector<unsigned int> &data) { handlePasscodeChange(data); };
+ switchToPinlockWindow(onActivatedCallback);
}
- void PinLockHandler::parseAttemptsAndPinSize(CellularSimResponseMessage *msg)
+ void PinLockHandler::switchToPinlockWindow(
+ std::function<void(const std::vector<unsigned int> &)> onLockActivatedCallback)
{
- if (msg->getSimState() == CellularSimResponseMessage::SimState::SIMUnlocked) {
- reloadScreenLock();
+ auto lock = std::make_unique<gui::PinLock>(simLock);
+
+ if (lock->getState() == PinLock::LockState::PasscodeInvalidRetryRequired) {
+ lock->onActivatedCallback = [this, onLockActivatedCallback](const std::vector<unsigned int> &) {
+ simLock.consumeState();
+ switchToPinlockWindow(onLockActivatedCallback);
+ };
}
else {
- lock.pinValue = std::vector<unsigned int>(msg->getPinSize(), 0);
- lock.remainingAttempts = msg->getAttemptsLeft();
+ lock->onActivatedCallback = onLockActivatedCallback;
}
+
+ app->switchWindow(app::window::name::desktop_pin_lock,
+ gui::ShowMode::GUI_SHOW_INIT,
+ std::make_unique<gui::LockPhoneData>(std::move(lock)));
}
- void PinLockHandler::handleScreenPin(const std::vector<unsigned int> &pin)
+ void PinLockHandler::handlePinChangeRequest(app::manager::actions::ActionParamsPtr &&data)
{
- if (lock.remainingAttempts > 0) {
- std::hash<std::vector<unsigned int>> hashEngine;
- uint32_t hash = hashEngine(pin);
- lock.remainingAttempts--;
- if (hash == appSettings.lockPassHash) {
- lock.remainingAttempts = default_screen_attempts;
- lock.state = gui::PinLock::State::VerifiedPin;
- }
- else if (lock.remainingAttempts > 0) {
- lock.state = gui::PinLock::State::InvalidPin;
- }
- else {
- lock.state = gui::PinLock::State::Blocked;
- }
+ simLock = handlePasscodeParams(std::move(data));
+ simLock.lockType = gui::PinLock::LockType::SimPin;
- app->switchWindow(app::window::name::desktop_pin_lock);
- }
+ auto onActivatedCallback = [this](const std::vector<unsigned int> &data) { handlePasscodeChange(data); };
+ switchToPinlockWindow(onActivatedCallback);
}
- void PinLockHandler::handleSimPinOrPuk(const std::vector<unsigned int> &pin)
+ void PinLockHandler::handleSimBlocked(app::manager::actions::ActionParamsPtr &&data)
{
- auto sim = Store::GSM::SIM::SIM1;
- sys::Bus::SendUnicast(
- std::make_shared<CellularSimVerifyPinRequestMessage>(sim, pin), ServiceCellular::serviceName, app);
+ auto params = static_cast<app::manager::actions::SimStateParams *>(data.get());
+ simLock = PinLock(parseSimCard(params->getSim()),
+ gui::PinLock::LockState::Blocked,
+ gui::PinLock::LockType::SimPin,
+ blocked_sim_attempts);
+
+ auto lock = std::make_unique<gui::PinLock>(simLock);
+ app->switchWindow(app::window::name::desktop_pin_lock,
+ gui::ShowMode::GUI_SHOW_INIT,
+ std::make_unique<gui::LockPhoneData>(std::move(lock)));
}
- void PinLockHandler::reloadScreenLock()
+ void PinLockHandler::handleCMEError(app::manager::actions::ActionParamsPtr &&data) const
{
- lock.type = gui::PinLock::LockType::Screen;
- lock.state = gui::PinLock::State::EnterPin;
+ auto params = static_cast<app::manager::actions::UnhandledCMEParams *>(data.get());
+
+ auto lock = std::make_unique<gui::PinLock>(parseSimCard(params->getSim()),
+ PinLock::LockState::ErrorOccurred,
+ PinLock::LockType::SimPin,
+ params->getCMECode());
- unsigned int pinSize = appSettings.lockPassHash == 0 ? 0 : default_screen_pin_size;
- lock.pinValue = std::vector<unsigned int>(pinSize, 0);
- lock.remainingAttempts = default_screen_attempts;
+ app->switchWindow(app::window::name::desktop_pin_lock,
+ gui::ShowMode::GUI_SHOW_INIT,
+ std::make_unique<gui::LockPhoneData>(std::move(lock)));
+ }
+
+ void PinLockHandler::handlePasscode(const std::vector<unsigned int> passcode) const
+ {
+ if (simLock.getLockType() == PinLock::LockType::SimPin) {
+ sys::Bus::SendUnicast(
+ std::make_shared<CellularSimPinDataMessage>(Store::GSM::SIM::SIM1, passcode), "ServiceCellular", app);
+ }
+ else if (simLock.getLockType() == PinLock::LockType::SimPuk) {
+ handlePasscodeChange(passcode);
+ }
+ }
+ void PinLockHandler::handlePasscodeChange(const std::vector<unsigned int> passcode) const
+ {
+ auto lock = std::make_unique<gui::PinLock>(simLock);
+ lock->lockState = PinLock::LockState::NewPasscodeRequired;
+
+ lock->onActivatedCallback = [this, passcode](const std::vector<unsigned int> &pin) {
+ handleNewPasscodeConfirmed(passcode, pin);
+ };
+
+ app->switchWindow(app::window::name::desktop_pin_lock,
+ gui::ShowMode::GUI_SHOW_INIT,
+ std::make_unique<gui::LockPhoneData>(std::move(lock)));
+ }
+
+ void PinLockHandler::handleNewPasscodeConfirmed(const std::vector<unsigned int> &passcode,
+ const std::vector<unsigned int> &pin) const
+ {
+ if (simLock.getLockType() == PinLock::LockType::SimPin) {
+ sys::Bus::SendUnicast(std::make_shared<CellularSimNewPinDataMessage>(Store::GSM::SIM::SIM1, passcode, pin),
+ "ServiceCellular",
+ app);
+ }
+ else if (simLock.getLockType() == PinLock::LockType::SimPuk) {
+ sys::Bus::SendUnicast(std::make_shared<CellularSimPukDataMessage>(Store::GSM::SIM::SIM1, passcode, pin),
+ "ServiceCellular",
+ app);
+ }
+ }
+
+ auto PinLockHandler::parseSimCard(Store::GSM::SIM sim) const noexcept -> PinLock::SimCard
+ {
+ if (sim == Store::GSM::SIM::SIM1) {
+ return gui::PinLock::SimCard::SIM1;
+ }
+ else if (sim == Store::GSM::SIM::SIM2) {
+ return gui::PinLock::SimCard::SIM2;
+ }
+ return gui::PinLock::SimCard::NoCard;
}
} // namespace gui
M module-apps/application-desktop/widgets/PinLockHandler.hpp => module-apps/application-desktop/widgets/PinLockHandler.hpp +32 -9
@@ 4,9 4,12 @@
#pragma once
#include "PinLock.hpp"
-#include <service-cellular/CellularMessage.hpp>
#include "Interface/SettingsRecord.hpp"
+
+#include <module-services/service-appmgr/service-appmgr/messages/ActionRequest.hpp>
+#include <module-services/service-appmgr/service-appmgr/Actions.hpp>
+
namespace app
{
class ApplicationDesktop;
@@ 19,19 22,39 @@ namespace gui
app::ApplicationDesktop *app = nullptr;
const SettingsRecord &appSettings;
- void parseSimCard(CellularSimResponseMessage *msg);
- void parseSimState(CellularSimResponseMessage *msg);
- void parseAttemptsAndPinSize(CellularSimResponseMessage *msg);
+ auto parseSimCard(Store::GSM::SIM sim) const noexcept -> PinLock::SimCard;
- void handleScreenPin(const std::vector<unsigned int> &pin);
- void handleSimPinOrPuk(const std::vector<unsigned int> &pin);
+ void handlePasscode(const std::vector<unsigned int> passcode) const;
+ void handlePasscodeChange(const std::vector<unsigned int> passcode) const;
+ void handleNewPasscodeConfirmed(const std::vector<unsigned int> &passcode,
+ const std::vector<unsigned int> &pin) const;
+ auto handlePasscodeParams(app::manager::actions::ActionParamsPtr &&data) const -> gui::PinLock;
+
+ void switchToPinlockWindow(std::function<void(const std::vector<unsigned int> &)> onLockActivatedCallback);
public:
PinLockHandler(app::ApplicationDesktop *app, SettingsRecord &settings);
void reloadScreenLock();
- auto handle(CellularSimResponseMessage *msg) -> bool;
- void handle(const std::vector<unsigned int> &pin);
- gui::PinLock lock;
+ void handleScreenPin(const std::vector<unsigned int> &pin);
+ void handleScreenConfirm();
+ void handlePinRequest(app::manager::actions::ActionParamsPtr &&data);
+ void handlePukRequest(app::manager::actions::ActionParamsPtr &&data);
+ void handlePinChangeRequest(app::manager::actions::ActionParamsPtr &&data);
+
+ void handleSimBlocked(app::manager::actions::ActionParamsPtr &&data);
+ void handleCMEError(app::manager::actions::ActionParamsPtr &&data) const;
+
+ [[nodiscard]] bool isScreenLocked() const noexcept
+ {
+ return screenLock.getState() != PinLock::LockState::Unlocked;
+ }
+ void lockScreen() noexcept
+ {
+ screenLock.lockState = PinLock::LockState::PasscodeRequired;
+ }
+
+ gui::PinLock screenLock;
+ gui::PinLock simLock;
};
} // namespace gui
M module-apps/application-desktop/windows/DesktopMainWindow.cpp => module-apps/application-desktop/windows/DesktopMainWindow.cpp +70 -34
@@ 89,9 89,7 @@ namespace gui
void DesktopMainWindow::setVisibleState()
{
auto app = getAppDesktop();
-
- if (app->lockHandler.lock.isLocked() && app->lockHandler.lock.getLockType() == PinLock::LockType::Screen) {
-
+ if (app->lockHandler.isScreenLocked()) {
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get("app_desktop_unlock"));
bottomBar->setActive(BottomBar::Side::LEFT, false);
bottomBar->setActive(BottomBar::Side::RIGHT, false);
@@ 103,12 101,6 @@ namespace gui
sys::Bus::SendUnicast(
std::make_shared<TimersProcessingStopMessage>(), service::name::service_time, application);
}
- else if (app->lockHandler.lock.isLocked()) {
- application->switchWindow(app::window::name::desktop_pin_lock);
-
- sys::Bus::SendUnicast(
- std::make_shared<TimersProcessingStopMessage>(), service::name::service_time, application);
- }
else {
topBar->setActive(TopBar::Elements::LOCK, false);
@@ 135,36 127,47 @@ namespace gui
// check if there was a signal to lock the pone due to inactivity.
if ((data != nullptr) && (data->getDescription() == "LockPhoneData")) {
auto app = getAppDesktop();
- if (app->lockHandler.lock.isLocked()) {
+ if (app->lockHandler.isScreenLocked()) {
return;
}
-
auto *lockData = dynamic_cast<LockPhoneData *>(data);
lockTimeoutApplilcation = lockData->getPreviousApplication();
-
application->setSuspendFlag(true);
}
+
+ if (mode == ShowMode::GUI_SHOW_RETURN) {
+ auto lock = getScreenLock();
+ if (lock->getState() == PinLock::LockState::Unlocked) {
+ setVisibleState();
+ return;
+ }
+ switchToPinLockWindow(std::move(lock));
+ }
+
setVisibleState();
}
bool DesktopMainWindow::processLongPressEvent(const InputEvent &inputEvent)
{
- auto *app = getAppDesktop();
+ auto app = getAppDesktop();
- if (inputEvent.is(KeyCode::KEY_PND) && (!app->lockHandler.lock.isLocked())) {
- app->lockHandler.lock.lock();
- setVisibleState();
- application->setSuspendFlag(true);
- return true;
+ if (!app->lockHandler.isScreenLocked()) {
+ if (inputEvent.is(KeyCode::KEY_PND)) {
+ app->lockHandler.lockScreen();
+ setVisibleState();
+ application->setSuspendFlag(true);
+ return true;
+ }
+ // long press of '0' key is translated to '+'
+ else if (inputEvent.is(KeyCode::KEY_0)) {
+ return app::prepareCall(application, "+");
+ }
}
- else if (inputEvent.is(KeyCode::KEY_RF)) {
+
+ if (inputEvent.is(KeyCode::KEY_RF)) {
application->switchWindow("PowerOffWindow");
return true;
}
- // long press of '0' key is translated to '+'
- else if (inputEvent.is(KeyCode::KEY_0)) {
- return app::prepareCall(application, "+");
- }
// check if any of the lower inheritance onInput methods catch the event
return AppWindow::onInput(inputEvent);
}
@@ 195,18 198,16 @@ namespace gui
if (enter_cache.cached() && inputEvent.is(KeyCode::KEY_PND)) {
// if interval between enter and pnd keys is less than time defined for unlocking
// display pin lock screen or simply refresh current window to update labels
- std::unique_ptr<LockPhoneData> data = std::make_unique<LockPhoneData>(LockPhoneData::Request::Pin);
- // if there was no application on to before closing proceed normally to pin protection
- if (lockTimeoutApplilcation.empty()) {
- application->switchWindow(app::window::name::desktop_pin_lock, std::move(data));
- return true;
- }
- else {
- data->setPrevApplication(lockTimeoutApplilcation);
- lockTimeoutApplilcation = "";
- application->switchWindow(app::window::name::desktop_pin_lock, std::move(data));
+
+ auto lock = getScreenLock();
+ // if there is no pin,
+ if (lock->getMaxPinSize() == 0) {
+ lock->verify();
return true;
}
+
+ switchToPinLockWindow(std::move(lock));
+ return true;
}
else if (enter_cache.storeEnter(inputEvent)) {
return true;
@@ 227,7 228,7 @@ namespace gui
return processLongPressEvent(inputEvent);
}
else if (inputEvent.isShortPress()) {
- if (app->lockHandler.lock.isLocked()) {
+ if (app->lockHandler.isScreenLocked()) {
return processShortPressEventOnLocked(inputEvent);
}
else {
@@ 343,4 344,39 @@ namespace gui
assert(app);
return app;
}
+
+ auto DesktopMainWindow::getScreenLock() -> std::unique_ptr<PinLock>
+ {
+ auto lock = std::make_unique<PinLock>(getAppDesktop()->lockHandler.screenLock);
+ auto app = getAppDesktop();
+ if (lock->getState() == PinLock::LockState::PasscodeRequired) {
+ lock->onActivatedCallback = [app](const std::vector<unsigned int> &data) {
+ app->lockHandler.handleScreenPin(data);
+ app->switchWindow(app::window::name::desktop_main_window, ShowMode::GUI_SHOW_RETURN);
+ };
+ }
+ else if (lock->getState() == PinLock::LockState::PasscodeInvalidRetryRequired) {
+ lock->onActivatedCallback = [app](const std::vector<unsigned int> &) {
+ app->lockHandler.screenLock.consumeState();
+ app->switchWindow(app::window::name::desktop_main_window, ShowMode::GUI_SHOW_RETURN);
+ };
+ }
+ else if (lock->getState() == PinLock::LockState::Blocked) {
+ lock->onActivatedCallback = [app](const std::vector<unsigned int> &) {
+ app->switchWindow(app::window::name::desktop_main_window, ShowMode::GUI_SHOW_INIT);
+ };
+ }
+ return lock;
+ }
+
+ void DesktopMainWindow::switchToPinLockWindow(std::unique_ptr<PinLock> &&lock)
+ {
+ auto data = std::make_unique<LockPhoneData>(std::move(lock));
+ if (!lockTimeoutApplilcation.empty()) {
+ // if there was no application on to before closing proceed normally to pin protection
+ data->setPrevApplication(lockTimeoutApplilcation);
+ lockTimeoutApplilcation.clear();
+ }
+ application->switchWindow(app::window::name::desktop_pin_lock, std::move(data));
+ }
} /* namespace gui */
M module-apps/application-desktop/windows/DesktopMainWindow.hpp => module-apps/application-desktop/windows/DesktopMainWindow.hpp +4 -0
@@ 17,6 17,7 @@ namespace app
namespace gui
{
class NotificationsBox;
+ class PinLock;
class DesktopMainWindow : public AppWindow
{
@@ 69,6 70,9 @@ namespace gui
bool processLongPressEvent(const InputEvent &inputEvent);
bool processShortPressEventOnUnlocked(const InputEvent &inputEvent);
bool processShortPressEventOnLocked(const InputEvent &inputEvent);
+
+ auto getScreenLock() -> std::unique_ptr<PinLock>;
+ void switchToPinLockWindow(std::unique_ptr<PinLock> &&data);
app::ApplicationDesktop *getAppDesktop() const;
public:
M module-apps/application-desktop/windows/PinLockBaseWindow.cpp => module-apps/application-desktop/windows/PinLockBaseWindow.cpp +14 -16
@@ 47,24 47,28 @@ namespace gui
infoText->setVisible(true);
infoText->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Top));
}
- void PinLockBaseWindow::buildPinLabels(gui::Label *labelsBox, unsigned int pinSize, unsigned int singleLabelWidth)
+ void PinLockBaseWindow::buildPinLabels(std::function<Rect *()> itemBuilder,
+ unsigned int pinSize,
+ unsigned int offsetX,
+ unsigned int offsetY,
+ unsigned int boxWidth)
{
- if (pinSize * singleLabelWidth > labelsBox->getWidth()) {
- singleLabelWidth = labelsBox->getWidth() / pinSize;
+ pinLabelsBox = new gui::HBox(this, offsetX, offsetY, boxWidth, lock_style::label_size);
+ pinLabelsBox->setAlignment(Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
+
+ if (pinSize == 0) {
+ return;
}
- const uint32_t pinLabelSpacing = (labelsBox->getWidth() - pinSize * singleLabelWidth) / (pinSize - 1);
- uint32_t pinLabelX = 0;
for (uint32_t i = 0; i < pinSize; i++) {
- gui::Label *label = new gui::Label(labelsBox, pinLabelX, 0, singleLabelWidth, lock_style::label_size);
+ auto label = itemBuilder();
label->setFilled(false);
label->setBorderColor(gui::ColorFullBlack);
label->setPenWidth(2);
- label->setFont(style::window::font::largelight);
- label->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Bottom));
+ label->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
label->setVisible(true);
- this->pinLabels.push_back(label);
- pinLabelX += singleLabelWidth + pinLabelSpacing;
+ label->activeItem = false;
+ pinLabelsBox->addWidget(label);
}
}
void PinLockBaseWindow::buildImages(const std::string &lockImg, const std::string &infoImg)
@@ 88,10 92,4 @@ namespace gui
{
bottomBar->setText(side, txt, false);
}
- void PinLockBaseWindow::clearPinLabels()
- {
- for (auto label : pinLabels) {
- label->clear();
- }
- }
} // namespace gui
M module-apps/application-desktop/windows/PinLockBaseWindow.hpp => module-apps/application-desktop/windows/PinLockBaseWindow.hpp +8 -6
@@ 16,25 16,27 @@ namespace gui
class PinLockBaseWindow : public AppWindow
{
public:
- PinLockBaseWindow(app::Application *app, std::string name, PinLock &lock) : AppWindow(app, name), lock(lock)
+ PinLockBaseWindow(app::Application *app, std::string name) : AppWindow(app, name)
{}
void build();
void buildInfoText(unsigned int textHight);
- void buildPinLabels(gui::Label *labelBox, unsigned int pinSize, unsigned int singleLabelWidth);
+ void buildPinLabels(std::function<Rect *()> itemBuilder,
+ unsigned int pinSize,
+ unsigned int offsetX,
+ unsigned int offsetY,
+ unsigned int boxWidth);
void buildImages(const std::string &lockImg, const std::string &infoImg);
void setBottomBarWidgetsActive(bool left, bool center, bool right);
void setImagesVisible(bool lockImg, bool infoImg);
void setBottomBarWidgetText(BottomBar::Side side, const UTF8 &txt);
- void clearPinLabels();
gui::Label *titleLabel = nullptr;
gui::Text *infoText = nullptr;
- gui::Label *pinLabel = nullptr;
- std::vector<gui::Label *> pinLabels;
gui::Image *lockImage = nullptr;
gui::Image *infoImage = nullptr;
+ gui::HBox *pinLabelsBox = nullptr;
- PinLock &lock;
+ std::unique_ptr<PinLock> lock = nullptr;
private:
void buildBottomBar();
M module-apps/application-desktop/windows/PinLockBox.hpp => module-apps/application-desktop/windows/PinLockBox.hpp +19 -4
@@ 10,12 10,27 @@ namespace gui
class PinLockBox
{
public:
- virtual void popChar(uint32_t charNum) = 0;
- virtual void putChar(uint32_t charNum) = 0;
+ enum class EnterPasscodeType
+ {
+ ProvidePasscode,
+ ProvideNewPasscode,
+ ConfirmNewPasscode
+ };
- virtual void setVisibleStateEnterPin() = 0;
+ enum class PasscodeErrorType
+ {
+ InvalidPasscode,
+ NewPasscodeConfirmFailed,
+ UnhandledError
+ };
+
+ virtual void popChar(unsigned int charNum) = 0;
+ virtual void putChar(unsigned int charNum) = 0;
+ virtual void clear() = 0;
+
+ virtual void setVisibleStateEnterPin(EnterPasscodeType type) = 0;
virtual void setVisibleStateVerifiedPin() = 0;
- virtual void setVisibleStateInvalidPin() = 0;
+ virtual void setVisibleStateInvalidPin(PasscodeErrorType type, unsigned int value) = 0;
virtual void setVisibleStateBlocked() = 0;
virtual void buildLockBox(unsigned int pinSize) = 0;
M module-apps/application-desktop/windows/PinLockWindow.cpp => module-apps/application-desktop/windows/PinLockWindow.cpp +85 -55
@@ 19,8 19,8 @@
namespace gui
{
- PinLockWindow::PinLockWindow(app::Application *app, const std::string &window_name, PinLock &lock)
- : PinLockBaseWindow(app, window_name, lock), this_window_name(window_name)
+ PinLockWindow::PinLockWindow(app::Application *app, const std::string &window_name)
+ : PinLockBaseWindow(app, window_name), this_window_name(window_name)
{
buildInterface();
}
@@ 32,14 32,11 @@ namespace gui
buildInterface();
// set state
focusItem = nullptr;
- setVisibleState(lock.getState());
}
void PinLockWindow::buildInterface()
{
AppWindow::buildInterface();
PinLockBaseWindow::build();
- buildPinLockBox();
- LockBox->buildLockBox(lock.getPinSize());
}
void PinLockWindow::destroyInterface()
@@ 54,94 51,127 @@ namespace gui
lockImage = nullptr;
infoImage = nullptr;
infoText = nullptr;
- pinLabel = nullptr;
- pinLabels.clear();
+ pinLabelsBox = nullptr;
}
- void PinLockWindow::setVisibleState(const PinLock::State state)
+ void PinLockWindow::setVisibleState(const PinLock::LockState state)
{
- if (state == PinLock::State::EnterPin) {
- LockBox->setVisibleStateEnterPin();
+ if (state == PinLock::LockState::PasscodeRequired) {
+ currentPasscodeType = PinLockBox::EnterPasscodeType::ProvidePasscode;
+ LockBox->setVisibleStateEnterPin(currentPasscodeType);
}
- else if (state == PinLock::State::VerifiedPin) {
- LockBox->setVisibleStateVerifiedPin();
+ else if (state == PinLock::LockState::PasscodeInvalidRetryRequired) {
+ LockBox->setVisibleStateInvalidPin(PinLockBox::PasscodeErrorType::InvalidPasscode, lock->getValue());
}
- else if (state == PinLock::State::InvalidPin) {
- LockBox->setVisibleStateInvalidPin();
- }
- else if (state == PinLock::State::Blocked) {
+ else if (state == PinLock::LockState::Blocked) {
LockBox->setVisibleStateBlocked();
}
+ else if (state == PinLock::LockState::NewPasscodeRequired) {
+ LockBox->setVisibleStateEnterPin(currentPasscodeType);
+ }
+ else if (state == PinLock::LockState::NewPasscodeInvalid) {
+ LockBox->setVisibleStateInvalidPin(PinLockBox::PasscodeErrorType::NewPasscodeConfirmFailed,
+ lock->getValue());
+ }
+ else if (state == PinLock::LockState::ErrorOccurred) {
+ LockBox->setVisibleStateInvalidPin(PinLockBox::PasscodeErrorType::UnhandledError, lock->getValue());
+ }
application->refreshWindow(RefreshModes::GUI_REFRESH_FAST);
}
void PinLockWindow::onBeforeShow(ShowMode mode, SwitchData *data)
{
+ if (mode == ShowMode::GUI_SHOW_INIT) {
+ rebuild();
+ }
if (auto lockData = dynamic_cast<LockPhoneData *>(data)) {
+ assert(lockData);
lockTimeoutApplication = lockData->getPreviousApplication();
+ lock = lockData->getLock();
+ assert(lock);
+
+ buildPinLockBox();
+ LockBox->buildLockBox(lock->getMaxPinSize());
+
+ auto state = lock->getState();
+ if (state == PinLock::LockState::PasscodeRequired) {
+ currentPasscodeType = PinLockBox::EnterPasscodeType::ProvidePasscode;
+ }
+ else if (state == PinLock::LockState::NewPasscodeRequired) {
+ currentPasscodeType = PinLockBox::EnterPasscodeType::ProvideNewPasscode;
+ }
+ setVisibleState(lock->getState());
}
- if (lock.unlock()) {
- setVisibleState(PinLock::State::VerifiedPin);
- application->switchWindow(gui::name::window::main_window);
- }
- setVisibleState(lock.getState());
}
bool PinLockWindow::onInput(const InputEvent &inputEvent)
{
- auto state = lock.getState();
- if (!inputEvent.isShortPress() || state == PinLock::State::VerifiedPin) {
+ auto state = lock->getState();
+ if (!inputEvent.isShortPress()) {
return AppWindow::onInput(inputEvent);
}
// accept only LF, enter, RF, #, and numeric values;
- if (inputEvent.keyCode == KeyCode::KEY_LF && bottomBar->isActive(BottomBar::Side::LEFT)) {
+ if (inputEvent.is(KeyCode::KEY_LF) && bottomBar->isActive(BottomBar::Side::LEFT)) {
app::manager::Controller::switchApplication(
application, app::name_phonebook, gui::window::name::ice_contacts, nullptr);
return true;
}
- else if (inputEvent.keyCode == KeyCode::KEY_RF && bottomBar->isActive(BottomBar::Side::RIGHT)) {
- if (state == PinLock::State::EnterPin) {
- lock.clearAttempt();
- clearPinLabels();
+ else if (inputEvent.is(KeyCode::KEY_RF) && bottomBar->isActive(BottomBar::Side::RIGHT)) {
+ if (state == PinLock::LockState::PasscodeRequired || state == PinLock::LockState::NewPasscodeRequired) {
+ lock->clearAttempt();
}
- else if (state == PinLock::State::InvalidPin) {
- LockBox->setVisibleStateInvalidPin();
- lock.consumeInvalidPinState();
+ else if (state == PinLock::LockState::PasscodeInvalidRetryRequired) {
+ lock->consumeState();
}
application->switchWindow(gui::name::window::main_window);
return true;
}
- else if (inputEvent.keyCode == KeyCode::KEY_PND) {
- if (state == PinLock::State::EnterPin) {
- lock.popChar();
- LockBox->popChar(lock.getCharCount());
+ else if (inputEvent.is(KeyCode::KEY_PND)) {
+ if (state == PinLock::LockState::PasscodeRequired || state == PinLock::LockState::NewPasscodeRequired) {
+ lock->popChar();
+ LockBox->popChar(lock->getCharCount());
+ bottomBar->setActive(BottomBar::Side::CENTER, lock->canVerify());
return true;
}
}
else if (0 <= gui::toNumeric(inputEvent.keyCode) && gui::toNumeric(inputEvent.keyCode) <= 9) {
- if (state == PinLock::State::EnterPin && lock.canPut()) {
- LockBox->putChar(lock.getCharCount());
- lock.putNextChar(gui::toNumeric(inputEvent.keyCode));
- if (lock.getLockType() == PinLock::LockType::Screen) {
- lock.verifyPin();
- }
- else if (!lock.canPut()) {
- bottomBar->setActive(BottomBar::Side::CENTER, true);
- }
+ if ((state == PinLock::LockState::PasscodeRequired || state == PinLock::LockState::NewPasscodeRequired) &&
+ lock->canPut()) {
+ LockBox->putChar(lock->getCharCount());
+ lock->putNextChar(gui::toNumeric(inputEvent.keyCode));
+ bottomBar->setActive(BottomBar::Side::CENTER, lock->canVerify());
return true;
}
}
- else if (inputEvent.keyCode == KeyCode::KEY_ENTER && bottomBar->isActive(BottomBar::Side::CENTER)) {
- if (state == PinLock::State::InvalidPin) {
- lock.consumeInvalidPinState();
- application->switchWindow(this_window_name);
+ else if (inputEvent.is(KeyCode::KEY_ENTER) && bottomBar->isActive(BottomBar::Side::CENTER)) {
+ if (state == PinLock::LockState::NewPasscodeInvalid) {
+ lock->consumeState();
+ setVisibleState(lock->getState());
+ return true;
}
- else if (state == PinLock::State::EnterPin) {
- lock.verifyPin();
+ else if (currentPasscodeType == PinLockBox::EnterPasscodeType::ProvideNewPasscode) {
+ buffer = lock->getPin();
+ lock->clearAttempt();
+ LockBox->clear();
+
+ currentPasscodeType = PinLockBox::EnterPasscodeType::ConfirmNewPasscode;
+ setVisibleState(lock->getState());
+ return true;
}
- else if (state == PinLock::State::Blocked) {
- application->switchWindow(gui::name::window::main_window);
+ else if (currentPasscodeType == PinLockBox::EnterPasscodeType::ConfirmNewPasscode) {
+ if (buffer == lock->getPin()) {
+ lock->verify();
+ }
+ else {
+ currentPasscodeType = PinLockBox::EnterPasscodeType::ProvideNewPasscode;
+ lock->clearAttempt();
+ lock->setNewPasscodeInvalidState();
+ LockBox->clear();
+ setVisibleState(lock->getState());
+ }
+ return true;
}
+ lock->verify();
return true;
}
// check if any of the lower inheritance onInput methods catch the event
@@ 150,14 180,14 @@ namespace gui
void PinLockWindow::buildPinLockBox()
{
- auto lockType = lock.getLockType();
+ auto lockType = lock->getLockType();
if (lockType == PinLock::LockType::Screen) {
LockBox = std::make_unique<ScreenLockBox>(this);
}
- else if (lockType == PinLock::LockType::PUK) {
+ else if (lockType == PinLock::LockType::SimPuk) {
LockBox = std::make_unique<PukLockBox>(this);
}
- else if (lockType == PinLock::LockType::SIM) {
+ else if (lockType == PinLock::LockType::SimPin) {
LockBox = std::make_unique<SimLockBox>(this);
}
assert(LockBox != nullptr);
M module-apps/application-desktop/windows/PinLockWindow.hpp => module-apps/application-desktop/windows/PinLockWindow.hpp +6 -3
@@ 19,15 19,18 @@ namespace gui
const std::string this_window_name;
std::string lockTimeoutApplication = "";
std::unique_ptr<PinLockBox> LockBox = nullptr;
- PinLock::LockType currentLock = PinLock::LockType::Unknown;
+ PinLockBox::EnterPasscodeType currentPasscodeType = PinLockBox::EnterPasscodeType::ProvidePasscode;
+
+ std::vector<unsigned int> buffer;
+ std::function<void(const std::vector<unsigned int> &)> callbackBuffer = nullptr;
// method hides or show widgets and sets bars according to provided state
- void setVisibleState(const PinLock::State state);
+ void setVisibleState(const PinLock::LockState state);
void buildPinLockBox();
void invalidate() noexcept;
public:
- PinLockWindow(app::Application *app, const std::string &window_name, PinLock &lock);
+ PinLockWindow(app::Application *app, const std::string &window_name);
void onBeforeShow(ShowMode mode, SwitchData *data) override;
bool onInput(const InputEvent &inputEvent) override;
M module-apps/application-desktop/windows/PukLockBox.cpp => module-apps/application-desktop/windows/PukLockBox.cpp +74 -45
@@ 15,42 15,58 @@ namespace lock_style = style::window::pin_lock;
namespace gui
{
- void PukLockBox::popChar(uint32_t charNum)
+ void PukLockBox::popChar(unsigned int charNum)
{
- LockWindow->pinLabels[charNum]->clear();
+ rebuildPinLabels(charNum);
}
- void PukLockBox::putChar(uint32_t charNum)
+ void PukLockBox::putChar(unsigned int charNum)
{
- LockWindow->pinLabels[charNum]->setText("*");
+ rebuildPinLabels(++charNum);
}
void PukLockBox::buildLockBox(unsigned int pinSize)
{
LockWindow->buildImages("pin_lock", "pin_lock_info");
LockWindow->buildInfoText(lock_style::info_text_h_puk);
- buildPinLabels(pinSize);
+ buildPinLabels(0);
}
void PukLockBox::buildPinLabels(unsigned int pinSize)
{
- // labels with stars for displaying entered digits
- const uint32_t pinLabelWidth = style::window_width - 2 * lock_style::pin_label_x;
- LockWindow->pinLabel = new gui::Label(
- LockWindow, lock_style::pin_label_x, lock_style::pin_label_y, pinLabelWidth, lock_style::label_size);
- LockWindow->pinLabel->setEdges(RectangleEdge::Bottom);
-
- LockWindow->buildPinLabels(LockWindow->pinLabel, pinSize, lock_style::label_size);
- for (auto label : LockWindow->pinLabels) {
- label->setEdges(RectangleEdge::None);
- }
+ auto itemBuilder = []() {
+ auto label = new gui::Image("dot_12px_hard_alpha_W_G");
+ return label;
+ };
+
+ LockWindow->buildPinLabels(itemBuilder,
+ pinSize,
+ lock_style::pin_label_x,
+ lock_style::pin_label_y,
+ style::window_width - 2 * lock_style::pin_label_x);
+ LockWindow->pinLabelsBox->setEdges(RectangleEdge::Bottom);
}
- void PukLockBox::setVisibleStateEnterPin()
+
+ void PukLockBox::rebuildPinLabels(unsigned int pinSize)
{
- LockWindow->clearPinLabels();
- LockWindow->pinLabel->setVisible(true);
+ LockWindow->pinLabelsBox->erase();
+ buildPinLabels(pinSize);
+ }
+ void PukLockBox::setVisibleStateEnterPin(EnterPasscodeType type)
+ {
+ LockWindow->pinLabelsBox->setVisible(true);
LockWindow->infoText->clear();
- LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_blocked"));
- LockWindow->infoText->addText("\n");
- LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_type_puk"));
+
+ switch (type) {
+ case PinLockBox::EnterPasscodeType::ProvidePasscode:
+ LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_blocked"));
+ LockWindow->infoText->addText("\n");
+ LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_type_puk"));
+ break;
+ case PinLockBox::EnterPasscodeType::ProvideNewPasscode:
+ LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_enter_pin"));
+ break;
+ case PinLockBox::EnterPasscodeType::ConfirmNewPasscode:
+ LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_confirm_pin"));
+ }
LockWindow->infoText->setVisible(true);
LockWindow->setImagesVisible(true, false);
@@ 58,43 74,52 @@ namespace gui
}
void PukLockBox::setVisibleStateVerifiedPin()
{
- LockWindow->clearPinLabels();
- LockWindow->pinLabel->setVisible(false);
+ LockWindow->pinLabelsBox->setVisible(false);
LockWindow->infoText->setVisible(false);
}
- void PukLockBox::setVisibleStateInvalidPin()
+ void PukLockBox::setVisibleStateInvalidPin(PasscodeErrorType type, unsigned int value)
{
- LockWindow->clearPinLabels();
- LockWindow->pinLabel->setVisible(false);
-
+ LockWindow->pinLabelsBox->setVisible(false);
LockWindow->infoText->clear();
- LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_wrong_puk"));
- LockWindow->infoText->addText("\n");
- LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_you_have"));
- LockWindow->infoText->addText(" ");
- LockWindow->infoText->addText(std::to_string(LockWindow->lock.getRemainingAttempts()));
- LockWindow->infoText->addText(" ");
- if (LockWindow->lock.getRemainingAttempts() > 1) {
- LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_attempt_left_plural"));
- }
- else {
- LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_attempt_left_singular"));
- LockWindow->infoText->addText("\n\n");
- LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_warning1"));
- LockWindow->infoText->addText("\n");
- LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_warning2"));
+ switch (type) {
+ case PinLockBox::PasscodeErrorType::InvalidPasscode:
+
+ LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_wrong_puk"));
LockWindow->infoText->addText("\n");
- LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_warning3"));
+ LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_you_have"));
+ LockWindow->infoText->addText(" ");
+ LockWindow->infoText->addText(std::to_string(value));
+ LockWindow->infoText->addText(" ");
+
+ if (value > 1) {
+ LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_attempt_left_plural"));
+ }
+ else {
+ LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_attempt_left_singular"));
+ LockWindow->infoText->addText("\n\n");
+ LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_warning1"));
+ LockWindow->infoText->addText("\n");
+ LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_warning2"));
+ LockWindow->infoText->addText("\n");
+ LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_warning3"));
+ }
+ break;
+ case PinLockBox::PasscodeErrorType::NewPasscodeConfirmFailed:
+ LockWindow->infoText->setText(utils::localize.get("app_desktop_sim_wrong_pin"));
+ break;
+ case PinLockBox::PasscodeErrorType::UnhandledError:
+ LOG_ERROR("No use case for UnhandledError in PukLockBox");
+ break;
}
- LockWindow->infoText->setVisible(true);
+ LockWindow->infoText->setVisible(true);
LockWindow->setImagesVisible(false, true);
LockWindow->setBottomBarWidgetsActive(true, true, false);
}
void PukLockBox::setVisibleStateBlocked()
{
- LockWindow->pinLabel->setVisible(false);
+ LockWindow->pinLabelsBox->setVisible(false);
LockWindow->infoText->clear();
LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_blocked_info1"));
@@ 106,4 131,8 @@ namespace gui
LockWindow->setBottomBarWidgetsActive(true, false, false);
}
+ void PukLockBox::clear()
+ {
+ rebuildPinLabels(0);
+ }
} // namespace gui
M module-apps/application-desktop/windows/PukLockBox.hpp => module-apps/application-desktop/windows/PukLockBox.hpp +9 -8
@@ 4,7 4,6 @@
#pragma once
#include "PinLockBox.hpp"
-#include "Label.hpp"
namespace gui
{
@@ 21,15 20,17 @@ namespace gui
private:
PinLockBaseWindow *LockWindow;
- void popChar(uint32_t charNum) override final;
- void putChar(uint32_t charNum) override final;
+ void popChar(unsigned int charNum) final;
+ void putChar(unsigned int charNum) final;
+ virtual void clear() final;
- void setVisibleStateEnterPin() override final;
- void setVisibleStateVerifiedPin() override final;
- void setVisibleStateInvalidPin() override final;
- void setVisibleStateBlocked() override final;
+ void setVisibleStateEnterPin(EnterPasscodeType type) final;
+ void setVisibleStateVerifiedPin() final;
+ void setVisibleStateInvalidPin(PasscodeErrorType type, unsigned int value) final;
+ void setVisibleStateBlocked() final;
- void buildLockBox(unsigned int pinSize) override final;
+ void buildLockBox(unsigned int pinSize) final;
void buildPinLabels(unsigned int pinSize);
+ void rebuildPinLabels(unsigned int pinSize);
};
} // namespace gui
M module-apps/application-desktop/windows/ScreenLockBox.cpp => module-apps/application-desktop/windows/ScreenLockBox.cpp +83 -28
@@ 14,13 14,34 @@ namespace lock_style = style::window::pin_lock;
namespace gui
{
- void ScreenLockBox::popChar(uint32_t charNum)
+
+ ScreenLockBox::PinLabel::PinLabel(Item *parent, uint32_t w, uint32_t h) : HBox(parent, 0, 0, w, h)
+ {}
+ void ScreenLockBox::PinLabel::setVisibleState(bool isImageVisible)
{
- LockWindow->pinLabels[charNum]->clear();
+ if (isImageVisible && image == nullptr) {
+ image = new gui::Image("dot_12px_hard_alpha_W_G");
+ image->setVisible(true);
+ image->activeItem = false;
+ addWidget(image);
+ }
+ else if (!isImageVisible && image != nullptr) {
+ erase(image);
+ image = nullptr;
+ }
}
- void ScreenLockBox::putChar(uint32_t charNum)
+
+ void ScreenLockBox::popChar(unsigned int charNum)
{
- LockWindow->pinLabels[charNum]->setText("*");
+ if (charNum < pinLabels.size()) {
+ pinLabels[charNum]->setVisibleState(false);
+ }
+ }
+ void ScreenLockBox::putChar(unsigned int charNum)
+ {
+ if (charNum < pinLabels.size()) {
+ pinLabels[charNum]->setVisibleState(true);
+ }
}
void ScreenLockBox::buildLockBox(unsigned int pinSize)
{
@@ 30,20 51,35 @@ namespace gui
}
void ScreenLockBox::buildPinLabels(unsigned int pinSize)
{
- // labels with stars for displaying entered digits
- const uint32_t pinLabelWidth = style::window_width - 2 * lock_style::pin_label_x_screen;
- LockWindow->pinLabel = new gui::Label(
- LockWindow, lock_style::pin_label_x_screen, lock_style::pin_label_y, pinLabelWidth, lock_style::label_size);
- LockWindow->pinLabel->setEdges(RectangleEdge::None);
-
- LockWindow->buildPinLabels(LockWindow->pinLabel, pinSize, lock_style::label_size_screen);
- for (auto label : LockWindow->pinLabels) {
- label->setEdges(RectangleEdge::Bottom);
+ constexpr auto pinLabelWidth = style::window::default_body_width;
+ pinLabels.clear();
+
+ if (pinSize == 0) {
+ return;
+ }
+
+ unsigned int singleLabelWidth = lock_style::label_size;
+ unsigned int maxNoMarginsLabelsWidth = pinLabelWidth - pinSize * 2 * lock_style::label_margins;
+
+ if (pinSize * singleLabelWidth > maxNoMarginsLabelsWidth) {
+ singleLabelWidth = maxNoMarginsLabelsWidth / pinSize;
}
+
+ auto itemBuilder = [this, singleLabelWidth]() {
+ auto label = new PinLabel(nullptr, singleLabelWidth, lock_style::label_size);
+ label->setEdges(RectangleEdge::Bottom);
+ label->setMargins(Margins(lock_style::label_margins, 0, lock_style::label_margins, 0));
+ pinLabels.push_back(label);
+ return label;
+ };
+
+ LockWindow->buildPinLabels(
+ itemBuilder, pinSize, style::window::default_left_margin, lock_style::pin_label_y_screen, pinLabelWidth);
+ LockWindow->pinLabelsBox->setEdges(RectangleEdge::None);
}
- void ScreenLockBox::setVisibleStateEnterPin()
+ void ScreenLockBox::setVisibleStateEnterPin(EnterPasscodeType type)
{
- LockWindow->pinLabel->setVisible(true);
+ LockWindow->pinLabelsBox->setVisible(true);
LockWindow->infoText->clear();
LockWindow->infoText->addText(utils::localize.get("app_desktop_screen_enter_passcode"));
@@ 54,30 90,42 @@ namespace gui
}
void ScreenLockBox::setVisibleStateVerifiedPin()
{
- LockWindow->clearPinLabels();
- LockWindow->pinLabel->setVisible(false);
+ clear();
+ LockWindow->pinLabelsBox->setVisible(false);
LockWindow->titleLabel->setVisible(false);
}
- void ScreenLockBox::setVisibleStateInvalidPin()
+ void ScreenLockBox::setVisibleStateInvalidPin(PasscodeErrorType type, unsigned int value)
{
- LockWindow->clearPinLabels();
- LockWindow->pinLabel->setVisible(false);
-
+ clear();
+ LockWindow->pinLabelsBox->setVisible(false);
+ LockWindow->infoText->clear();
LockWindow->titleLabel->setVisible(true);
- LockWindow->titleLabel->setText(utils::localize.get("app_desktop_screen_wrong_pin"));
+ switch (type) {
+ case PinLockBox::PasscodeErrorType::InvalidPasscode:
+ LockWindow->titleLabel->setText(utils::localize.get("app_desktop_screen_wrong_pin"));
- LockWindow->infoText->clear();
- LockWindow->infoText->addText(utils::localize.get(utils::localize.get("app_desktop_screen_allowed_attempts")));
- LockWindow->infoText->addText("\n");
- LockWindow->infoText->addText(std::to_string(LockWindow->lock.getRemainingAttempts()));
- LockWindow->infoText->setVisible(true);
+ LockWindow->infoText->addText(utils::localize.get(utils::localize.get("app_desktop_sim_you_have")));
+ LockWindow->infoText->addText(" ");
+ LockWindow->infoText->addText(std::to_string(value));
+ LockWindow->infoText->addText(" ");
+ LockWindow->infoText->addText(
+ utils::localize.get(utils::localize.get("app_desktop_sim_attempt_left_plural")));
+ break;
+ case PinLockBox::PasscodeErrorType::NewPasscodeConfirmFailed:
+ LockWindow->titleLabel->setText(utils::localize.get("app_desktop_screen_wrong_passcode"));
+ break;
+ case PinLockBox::PasscodeErrorType::UnhandledError:
+ LOG_ERROR("No use case for UnhandledError");
+ break;
+ }
+ LockWindow->infoText->setVisible(true);
LockWindow->setImagesVisible(false, true);
LockWindow->setBottomBarWidgetsActive(false, true, true);
}
void ScreenLockBox::setVisibleStateBlocked()
{
- LockWindow->pinLabel->setVisible(false);
+ LockWindow->pinLabelsBox->setVisible(false);
LockWindow->titleLabel->setVisible(false);
LockWindow->infoText->clear();
@@ 87,4 135,11 @@ namespace gui
LockWindow->setImagesVisible(false, true);
LockWindow->setBottomBarWidgetsActive(false, true, false);
}
+
+ void ScreenLockBox::clear()
+ {
+ for (unsigned i = 0; i < pinLabels.size(); i++) {
+ popChar(i);
+ }
+ }
} // namespace gui
M module-apps/application-desktop/windows/ScreenLockBox.hpp => module-apps/application-desktop/windows/ScreenLockBox.hpp +19 -9
@@ 4,8 4,8 @@
#pragma once
#include "PinLockBox.hpp"
-#include "Label.hpp"
-
+#include "BoxLayout.hpp"
+#include "Image.hpp"
namespace gui
{
class PinLockBaseWindow;
@@ 20,16 20,26 @@ namespace gui
{}
private:
+ struct PinLabel : public HBox
+ {
+ gui::Image *image = nullptr;
+ PinLabel(Item *parent, uint32_t w, uint32_t h);
+ void setVisibleState(bool isImageVisible);
+ };
+
+ std::vector<PinLabel *> pinLabels;
+
PinLockBaseWindow *LockWindow;
- void popChar(uint32_t charNum) override final;
- void putChar(uint32_t charNum) override final;
+ void popChar(unsigned int charNum) final;
+ void putChar(unsigned int charNum) final;
+ virtual void clear() final;
- void setVisibleStateEnterPin() override final;
- void setVisibleStateVerifiedPin() override final;
- void setVisibleStateInvalidPin() override final;
- void setVisibleStateBlocked() override final;
+ void setVisibleStateEnterPin(EnterPasscodeType type) final;
+ void setVisibleStateVerifiedPin() final;
+ void setVisibleStateInvalidPin(PasscodeErrorType type, unsigned int value) final;
+ void setVisibleStateBlocked() final;
- void buildLockBox(unsigned int pinSize) override final;
+ void buildLockBox(unsigned int pinSize) final;
void buildPinLabels(unsigned int pinSize);
};
} // namespace gui
M module-apps/application-desktop/windows/SimLockBox.cpp => module-apps/application-desktop/windows/SimLockBox.cpp +80 -48
@@ 7,6 7,9 @@
#include "application-desktop/widgets/PinLock.hpp"
#include "application-desktop/data/AppDesktopStyle.hpp"
#include "gui/widgets/Label.hpp"
+#include "RichTextParser.hpp"
+#include "FontManager.hpp"
+
#include <i18/i18.hpp>
#include <Style.hpp>
@@ 15,50 18,60 @@ namespace lock_style = style::window::pin_lock;
namespace gui
{
- void SimLockBox::popChar(uint32_t charNum)
+ void SimLockBox::popChar(unsigned int charNum)
{
- LockWindow->pinLabels[charNum]->clear();
+ rebuildPinLabels(charNum);
}
- void SimLockBox::putChar(uint32_t charNum)
+ void SimLockBox::putChar(unsigned int charNum)
{
- LockWindow->pinLabels[charNum]->setText("*");
+ rebuildPinLabels(++charNum);
}
void SimLockBox::buildLockBox(unsigned int pinSize)
{
LockWindow->buildImages("pin_lock", "pin_lock_info");
LockWindow->buildInfoText(lock_style::info_text_h_sim);
- buildPinLabels(pinSize);
+ buildPinLabels(0);
}
void SimLockBox::buildPinLabels(unsigned int pinSize)
{
- // labels with stars for displaying entered digits
- const uint32_t pinLabelWidth = style::window_width - 2 * lock_style::pin_label_x;
- LockWindow->pinLabel = new gui::Label(
- LockWindow, lock_style::pin_label_x, lock_style::pin_label_y, pinLabelWidth, lock_style::label_size);
- LockWindow->pinLabel->setEdges(RectangleEdge::Bottom);
-
- LockWindow->buildPinLabels(LockWindow->pinLabel, pinSize, lock_style::label_size);
- for (auto label : LockWindow->pinLabels) {
- label->setEdges(RectangleEdge::None);
- }
+ auto itemBuilder = []() {
+ auto label = new gui::Image("dot_12px_hard_alpha_W_G");
+ return label;
+ };
+
+ LockWindow->buildPinLabels(itemBuilder,
+ pinSize,
+ lock_style::pin_label_x,
+ lock_style::pin_label_y,
+ style::window_width - 2 * lock_style::pin_label_x);
+ LockWindow->pinLabelsBox->setEdges(RectangleEdge::Bottom);
}
- void SimLockBox::setVisibleStateEnterPin()
+
+ void SimLockBox::rebuildPinLabels(unsigned int pinSize)
{
- LockWindow->pinLabel->setVisible(true);
+ LockWindow->pinLabelsBox->erase();
+ buildPinLabels(pinSize);
+ }
+ void SimLockBox::setVisibleStateEnterPin(EnterPasscodeType type)
+ {
+ LockWindow->pinLabelsBox->setVisible(true);
LockWindow->infoText->clear();
- LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_to_unlock"));
- LockWindow->infoText->addText(" ");
- LockWindow->infoText->addText(LockWindow->lock.getLockInfo(PinLock::InfoName::LockName));
- LockWindow->infoText->addText(" ");
- LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_card"));
- LockWindow->infoText->addText("\n");
- LockWindow->infoText->addText("( ");
- LockWindow->infoText->addText(LockWindow->lock.getLockInfo(PinLock::InfoName::PhoneNum));
- LockWindow->infoText->addText(" )");
- LockWindow->infoText->addText("\n");
- LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_type_pin"));
+
+ switch (type) {
+ case PinLockBox::EnterPasscodeType::ProvidePasscode:
+ LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_to_unlock"));
+ LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_card"));
+ LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_type_pin"));
+ break;
+ case PinLockBox::EnterPasscodeType::ProvideNewPasscode:
+ LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_enter_pin"));
+ break;
+ case PinLockBox::EnterPasscodeType::ConfirmNewPasscode:
+ LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_confirm_pin"));
+ break;
+ }
LockWindow->infoText->setVisible(true);
LockWindow->setImagesVisible(true, false);
@@ 66,37 79,51 @@ namespace gui
}
void SimLockBox::setVisibleStateVerifiedPin()
{
- LockWindow->clearPinLabels();
LockWindow->infoText->clear();
LockWindow->infoText->setVisible(false);
- LockWindow->pinLabel->setVisible(false);
+ LockWindow->pinLabelsBox->setVisible(false);
}
- void SimLockBox::setVisibleStateInvalidPin()
+ void SimLockBox::setVisibleStateInvalidPin(PasscodeErrorType type, unsigned int value)
{
- LockWindow->clearPinLabels();
- LockWindow->pinLabel->setVisible(false);
+ LockWindow->pinLabelsBox->setVisible(false);
LockWindow->infoText->clear();
- LockWindow->infoText->addText(utils::localize.get(utils::localize.get("app_desktop_sim_wrong_pin")));
- LockWindow->infoText->addText("\n");
- LockWindow->infoText->addText(utils::localize.get(utils::localize.get("app_desktop_sim_you_have")));
- LockWindow->infoText->addText(" ");
- LockWindow->infoText->addText(std::to_string(LockWindow->lock.getRemainingAttempts()));
- LockWindow->infoText->addText(" ");
- if (LockWindow->lock.getRemainingAttempts() > 1) {
- LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_attempt_left_plural"));
+
+ switch (type) {
+ case PinLockBox::PasscodeErrorType::InvalidPasscode:
+ LockWindow->infoText->addText(utils::localize.get(utils::localize.get("app_desktop_sim_wrong_pin")));
+ LockWindow->infoText->addText("\n");
+ LockWindow->infoText->addText(utils::localize.get(utils::localize.get("app_desktop_sim_you_have")));
+ LockWindow->infoText->addText(" ");
+ LockWindow->infoText->addText(std::to_string(value));
+ LockWindow->infoText->addText(" ");
+ if (value > 1) {
+ LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_attempt_left_plural"));
+ }
+ else {
+ LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_attempt_left_singular"));
+ }
+ LockWindow->infoText->setVisible(true);
+
+ LockWindow->setImagesVisible(false, true);
+ LockWindow->setBottomBarWidgetsActive(true, true, true);
+ break;
+ case PinLockBox::PasscodeErrorType::NewPasscodeConfirmFailed:
+ LockWindow->infoText->setText(utils::localize.get("app_desktop_sim_wrong_pin"));
+ break;
+ case PinLockBox::PasscodeErrorType::UnhandledError: {
+ TextFormat format(FontManager::getInstance().getFont(style::window::font::medium));
+ text::RichTextParser rtParser;
+ auto parsedText = rtParser.parse(utils::localize.get("app_desktop_sim_cme_error"), &format);
+ LockWindow->infoText->setText(std::move(parsedText));
+ LockWindow->infoText->addText(std::to_string(value));
+ break;
}
- else {
- LockWindow->infoText->addText(utils::localize.get("app_desktop_sim_attempt_left_singular"));
}
- LockWindow->infoText->setVisible(true);
-
- LockWindow->setImagesVisible(false, true);
- LockWindow->setBottomBarWidgetsActive(true, true, true);
}
void SimLockBox::setVisibleStateBlocked()
{
- LockWindow->pinLabel->setVisible(false);
+ LockWindow->pinLabelsBox->setVisible(false);
LockWindow->infoText->clear();
LockWindow->infoText->addText(utils::localize.get(utils::localize.get("app_desktop_puk_lock1")));
LockWindow->infoText->setVisible(true);
@@ 104,4 131,9 @@ namespace gui
LockWindow->setImagesVisible(false, true);
LockWindow->setBottomBarWidgetsActive(true, true, true);
}
+
+ void SimLockBox::clear()
+ {
+ rebuildPinLabels(0);
+ }
} // namespace gui
M module-apps/application-desktop/windows/SimLockBox.hpp => module-apps/application-desktop/windows/SimLockBox.hpp +9 -8
@@ 4,7 4,6 @@
#pragma once
#include "PinLockBox.hpp"
-#include "Label.hpp"
namespace gui
{
@@ 21,15 20,17 @@ namespace gui
private:
PinLockBaseWindow *LockWindow;
- void popChar(uint32_t charNum) override final;
- void putChar(uint32_t charNum) override final;
+ void popChar(unsigned int charNum) final;
+ void putChar(unsigned int charNum) final;
+ virtual void clear() final;
- void setVisibleStateEnterPin() override final;
- void setVisibleStateVerifiedPin() override final;
- void setVisibleStateInvalidPin() override final;
- void setVisibleStateBlocked() override final;
+ void setVisibleStateEnterPin(EnterPasscodeType type) final;
+ void setVisibleStateVerifiedPin() final;
+ void setVisibleStateInvalidPin(PasscodeErrorType type, unsigned int value) final;
+ void setVisibleStateBlocked() final;
- void buildLockBox(unsigned int pinSize) override final;
+ void buildLockBox(unsigned int pinSize) final;
void buildPinLabels(unsigned int pinSize);
+ void rebuildPinLabels(unsigned int pinSize);
};
} // namespace gui
M module-services/service-appmgr/CMakeLists.txt => module-services/service-appmgr/CMakeLists.txt +1 -0
@@ 4,6 4,7 @@ message( "${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}" )
set(SOURCES
ApplicationManifest.cpp
Controller.cpp
+ data/SimActionsParams.cpp
model/ApplicationManager.cpp
model/ApplicationHandle.cpp
model/ApplicationsRegistry.cpp
A module-services/service-appmgr/data/SimActionsParams.cpp => module-services/service-appmgr/data/SimActionsParams.cpp +43 -0
@@ 0,0 1,43 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include <service-appmgr/data/SimActionsParams.hpp>
+
+using namespace app::manager::actions;
+
+PasscodeParams::PasscodeParams(Store::GSM::SIM _sim, unsigned int _attempts, std::string _passcodeName)
+ : sim{_sim}, attempts{_attempts}, passcodeName{std::move(_passcodeName)}
+{}
+
+Store::GSM::SIM PasscodeParams::getSim() const noexcept
+{
+ return sim;
+}
+unsigned int PasscodeParams::getAttempts() const noexcept
+{
+ return attempts;
+}
+const std::string &PasscodeParams::getPasscodeName() const noexcept
+{
+ return passcodeName;
+}
+
+SimStateParams::SimStateParams(Store::GSM::SIM _sim) : sim{_sim}
+{}
+
+Store::GSM::SIM SimStateParams::getSim() const noexcept
+{
+ return sim;
+}
+
+UnhandledCMEParams::UnhandledCMEParams(Store::GSM::SIM _sim, unsigned int _cmeCode) : sim{_sim}, cmeCode{_cmeCode}
+{}
+
+Store::GSM::SIM UnhandledCMEParams::getSim() const noexcept
+{
+ return sim;
+}
+unsigned int UnhandledCMEParams::getCMECode() const noexcept
+{
+ return cmeCode;
+}
M module-services/service-appmgr/model/ApplicationManager.cpp => module-services/service-appmgr/model/ApplicationManager.cpp +19 -0
@@ 260,6 260,13 @@ namespace app::manager
handleAction(actionMsg);
return std::make_shared<sys::ResponseMessage>();
});
+
+ auto convertibleToActionHandler = [this](sys::Message *request) { return handleMessageAsAction(request); };
+ connect(typeid(CellularSimRequestPinMessage), convertibleToActionHandler);
+ connect(typeid(CellularSimRequestPukMessage), convertibleToActionHandler);
+ connect(typeid(CellularUnlockSimMessage), convertibleToActionHandler);
+ connect(typeid(CellularBlockSimMessage), convertibleToActionHandler);
+ connect(typeid(CellularDisplayCMEMessage), convertibleToActionHandler);
}
sys::ReturnCodes ApplicationManager::SwitchPowerModeHandler(const sys::ServicePowerMode mode)
@@ 643,6 650,18 @@ namespace app::manager
return true;
}
+ auto ApplicationManager::handleMessageAsAction(sys::Message *request) -> std::shared_ptr<sys::ResponseMessage>
+ {
+ auto actionMsg = dynamic_cast<manager::actions::ConvertibleToAction *>(request);
+ if (!actionMsg) {
+ return std::make_shared<sys::ResponseMessage>(sys::ReturnCodes::Failure);
+ }
+ auto action = actionMsg->toAction();
+ handleAction(action.get());
+
+ return std::make_shared<sys::ResponseMessage>();
+ }
+
void ApplicationManager::onPhoneLocked()
{
#ifdef AUTO_PHONE_LOCK_ENABLED
M module-services/service-appmgr/service-appmgr/Actions.hpp => module-services/service-appmgr/service-appmgr/Actions.hpp +6 -1
@@ 24,8 24,13 @@ namespace app::manager
{
Launch,
Call,
+ RequestPin,
+ RequestPuk,
+ RequestPinChange,
+ UnlockSim,
+ BlockSim,
+ DisplayCMEError,
UserAction // The last enumerator in the Action enum.
- // All user-defined actions shall have values greater than UserAction.
};
class ConvertibleToAction
A module-services/service-appmgr/service-appmgr/data/SimActionsParams.hpp => module-services/service-appmgr/service-appmgr/data/SimActionsParams.hpp +59 -0
@@ 0,0 1,59 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <service-appmgr/service-appmgr/Actions.hpp>
+#include <module-utils/common_data/EventStore.hpp>
+
+namespace app::manager::actions
+{
+ /** Action parameters for
+ * RequestPinAction
+ * RequestPukAction
+ * ChangePinAction
+ */
+ class PasscodeParams : public ActionParams
+ {
+ Store::GSM::SIM sim;
+ unsigned int attempts;
+ /// passcodeName stands for PIN1/PIN2 or PUK1/PUK2 type
+ std::string passcodeName;
+
+ public:
+ PasscodeParams(Store::GSM::SIM _sim, unsigned int _attempts, std::string _passcodeName);
+
+ [[nodiscard]] Store::GSM::SIM getSim() const noexcept;
+ [[nodiscard]] unsigned int getAttempts() const noexcept;
+ [[nodiscard]] const std::string &getPasscodeName() const noexcept;
+ };
+
+ /** Action parameters for
+ * SimUnlockedAction
+ * SimBlockedAction
+ */
+ class SimStateParams : public ActionParams
+ {
+ Store::GSM::SIM sim;
+
+ public:
+ explicit SimStateParams(Store::GSM::SIM _sim);
+
+ [[nodiscard]] Store::GSM::SIM getSim() const noexcept;
+ };
+
+ /** Action parameters for
+ * UnhandledCMEError
+ */
+ class UnhandledCMEParams : public ActionParams
+ {
+ Store::GSM::SIM sim;
+ unsigned int cmeCode;
+
+ public:
+ UnhandledCMEParams(Store::GSM::SIM _sim, unsigned int _cmeCode);
+
+ [[nodiscard]] Store::GSM::SIM getSim() const noexcept;
+ [[nodiscard]] unsigned int getCMECode() const noexcept;
+ };
+} // namespace app::manager::actions
M module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp => module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp +1 -1
@@ 120,6 120,7 @@ namespace app::manager
auto handleDisplayLanguageChange(DisplayLanguageChangeRequest *msg) -> bool;
auto handleInputLanguageChange(InputLanguageChangeRequest *msg) -> bool;
auto handlePowerSavingModeInit() -> bool;
+ auto handleMessageAsAction(sys::Message *request) -> std::shared_ptr<sys::ResponseMessage>;
void requestApplicationClose(ApplicationHandle &app, bool isCloseable);
void onApplicationSwitch(ApplicationHandle &app,
@@ 140,7 141,6 @@ namespace app::manager
// defined in settings database application
// manager is sending signal to power manager and changing window to
// the desktop window in the blocked state.
-
// Temporary solution - to be replaced with ActionsMiddleware.
std::tuple<ApplicationName, actions::ActionId, actions::ActionParamsPtr> pendingAction;
};
M module-services/service-cellular/service-cellular/CellularMessage.hpp => module-services/service-cellular/service-cellular/CellularMessage.hpp +170 -0
@@ 17,6 17,10 @@
#include <memory>
#include <string>
+#include <service-appmgr/service-appmgr/messages/ActionRequest.hpp>
+#include <service-appmgr/service-appmgr/Actions.hpp>
+#include <service-appmgr/service-appmgr/data/SimActionsParams.hpp>
+
class CellularMessage : public sys::DataMessage
{
public:
@@ 293,6 297,172 @@ class CellularSimVerifyPinRequestMessage : public CellularSimMessage
std::vector<unsigned int> pukValue;
};
+class CellularSimPasscodeRequest : public CellularMessage
+{
+ protected:
+ app::manager::actions::PasscodeParams params;
+
+ CellularSimPasscodeRequest(Store::GSM::SIM _sim, unsigned int _attempts, std::string _passcodeName)
+ : CellularMessage(MessageType::CellularSimResponse), params(_sim, _attempts, std::move(_passcodeName))
+ {}
+};
+
+class CellularSimRequestPinMessage : public CellularSimPasscodeRequest,
+ public app::manager::actions::ConvertibleToAction
+{
+ public:
+ CellularSimRequestPinMessage(Store::GSM::SIM _sim, unsigned int _attempts, std::string _passcodeName)
+ : CellularSimPasscodeRequest(_sim, _attempts, std::move(_passcodeName))
+ {}
+
+ [[nodiscard]] auto toAction() const -> std::unique_ptr<app::manager::ActionRequest>
+ {
+ return std::make_unique<app::manager::ActionRequest>(
+ sender, app::manager::actions::RequestPin, std::make_unique<app::manager::actions::PasscodeParams>(params));
+ }
+};
+
+class CellularSimRequestPukMessage : public CellularSimPasscodeRequest,
+ public app::manager::actions::ConvertibleToAction
+{
+ public:
+ CellularSimRequestPukMessage(Store::GSM::SIM _sim, unsigned int _attempts, std::string _passcodeName)
+ : CellularSimPasscodeRequest(_sim, _attempts, std::move(_passcodeName))
+ {}
+
+ [[nodiscard]] auto toAction() const -> std::unique_ptr<app::manager::ActionRequest>
+ {
+ return std::make_unique<app::manager::ActionRequest>(
+ sender, app::manager::actions::RequestPuk, std::make_unique<app::manager::actions::PasscodeParams>(params));
+ }
+};
+
+class CellularUnlockSimMessage : public CellularMessage, public app::manager::actions::ConvertibleToAction
+{
+ app::manager::actions::SimStateParams params;
+
+ public:
+ CellularUnlockSimMessage(Store::GSM::SIM _sim) : CellularMessage(MessageType::CellularSimResponse), params(_sim)
+ {}
+
+ [[nodiscard]] auto toAction() const -> std::unique_ptr<app::manager::ActionRequest>
+ {
+ return std::make_unique<app::manager::ActionRequest>(
+ sender, app::manager::actions::UnlockSim, std::make_unique<app::manager::actions::SimStateParams>(params));
+ }
+};
+
+class CellularBlockSimMessage : public CellularMessage, public app::manager::actions::ConvertibleToAction
+{
+ app::manager::actions::SimStateParams params;
+
+ public:
+ explicit CellularBlockSimMessage(Store::GSM::SIM _sim)
+ : CellularMessage(MessageType::CellularSimResponse), params(_sim)
+ {}
+
+ [[nodiscard]] auto toAction() const -> std::unique_ptr<app::manager::ActionRequest>
+ {
+ return std::make_unique<app::manager::ActionRequest>(
+ sender, app::manager::actions::BlockSim, std::make_unique<app::manager::actions::SimStateParams>(params));
+ }
+};
+
+class CellularDisplayCMEMessage : public CellularMessage, public app::manager::actions::ConvertibleToAction
+{
+ app::manager::actions::UnhandledCMEParams params;
+
+ public:
+ CellularDisplayCMEMessage(Store::GSM::SIM _sim, unsigned int _cmeCode)
+ : CellularMessage(MessageType::CellularSimResponse), params(_sim, _cmeCode)
+ {}
+
+ [[nodiscard]] auto toAction() const -> std::unique_ptr<app::manager::ActionRequest>
+ {
+ return std::make_unique<app::manager::ActionRequest>(
+ sender,
+ app::manager::actions::DisplayCMEError,
+ std::make_unique<app::manager::actions::UnhandledCMEParams>(params));
+ }
+};
+
+class CellularSimDataMessage : public CellularMessage
+{
+ Store::GSM::SIM sim = Store::GSM::SIM::NONE;
+
+ public:
+ explicit CellularSimDataMessage(Store::GSM::SIM _sim) : CellularMessage{MessageType::CellularSimResponse}, sim{_sim}
+ {}
+ [[nodiscard]] Store::GSM::SIM getSim() const noexcept
+ {
+ return sim;
+ }
+};
+
+class CellularSimPinDataMessage : public CellularSimDataMessage
+{
+ std::vector<unsigned int> pinValue;
+
+ public:
+ CellularSimPinDataMessage(Store::GSM::SIM _sim, std::vector<unsigned int> _pinValue)
+ : CellularSimDataMessage{_sim}, pinValue{std::move(_pinValue)}
+ {}
+
+ [[nodiscard]] const std::vector<unsigned int> &getPin() const noexcept
+ {
+ return pinValue;
+ }
+};
+
+class CellularSimNewPinDataMessage : public CellularSimDataMessage
+{
+ std::vector<unsigned int> oldPin;
+ std::vector<unsigned int> newPin;
+
+ public:
+ CellularSimNewPinDataMessage(Store::GSM::SIM _sim,
+ std::vector<unsigned int> _oldPin,
+ std::vector<unsigned int> _newPin)
+ : CellularSimDataMessage{_sim}, oldPin{std::move(_oldPin)}, newPin{std::move(_newPin)}
+ {}
+
+ [[nodiscard]] const std::vector<unsigned int> &getOldPin() const noexcept
+ {
+ return oldPin;
+ }
+ [[nodiscard]] const std::vector<unsigned int> &getNewPin() const noexcept
+ {
+ return newPin;
+ }
+};
+
+class CellularSimPukDataMessage : public CellularSimDataMessage
+{
+ std::vector<unsigned int> puk;
+ std::vector<unsigned int> newPin;
+
+ public:
+ CellularSimPukDataMessage(Store::GSM::SIM _sim, std::vector<unsigned int> _puk, std::vector<unsigned int> _newPin)
+ : CellularSimDataMessage{_sim}, puk{std::move(_puk)}, newPin{std::move(_newPin)}
+ {}
+
+ [[nodiscard]] const std::vector<unsigned int> &getPuk() const noexcept
+ {
+ return puk;
+ }
+ [[nodiscard]] const std::vector<unsigned int> &getNewPin() const noexcept
+ {
+ return newPin;
+ }
+};
+
+class CellularSimAbortMessage : public CellularSimDataMessage
+{
+ public:
+ explicit CellularSimAbortMessage(Store::GSM::SIM _sim) : CellularSimDataMessage{_sim}
+ {}
+};
+
class CellularGetChannelMessage : public sys::DataMessage
{
public:
M module-services/service-desktop/ServiceDesktop.cpp => module-services/service-desktop/ServiceDesktop.cpp +1 -0
@@ 4,6 4,7 @@
#include "service-desktop/DesktopMessages.hpp"
#include "service-desktop/ServiceDesktop.hpp"
#include "service-desktop/WorkerDesktop.hpp"
+#include "service-cellular/CellularMessage.hpp"
#include "endpoints/factoryReset/FactoryReset.hpp"
#include "endpoints/backup/BackupRestore.hpp"
#include "endpoints/update/UpdateMuditaOS.hpp"