M .github/workflows/main.yml => .github/workflows/main.yml +0 -6
@@ 20,12 20,6 @@ jobs:
fetch-depth: 0
- name: check commit messages
run: ./tools/check_commit_messages.py
- build:
- if: github.event.pull_request.draft == false
- runs-on: self-hosted
- steps:
- - name: build
- run: echo "Placeholder for old CI scripts"
check_copyright_and_style:
name: check copyright and style
if: github.event.pull_request.draft == false
M .github/workflows/releases.yaml => .github/workflows/releases.yaml +21 -6
@@ 27,13 27,17 @@ jobs:
popd
- name: "Build and package for RT1051"
id: build_release_package
+ env:
+ ASSETS_LOGIN: ${{ secrets.ASSETS_LOGIN }}
+ ASSETS_TOKEN: ${{ secrets.ASSETS_TOKEN }}
run: |
./configure.sh rt1051 RelWithDebInfo && \
pushd build-rt1051-RelWithDebInfo && \
export JOBS=${JOBS:-`nproc`} && \
echo "JOBS=${JOBS}" && \
make -j ${JOBS} && \
- make -j ${JOBS} package && \
+ make package-update VERBOSE=1 && \
+ make package-standalone && \
popd && \
./print_last_changes.sh && \
uptime
@@ 48,15 52,26 @@ jobs:
draft: true
prerelease: true
body: ${{steps.build_release_package.outputs.release_notes }}
- - name: Upload Release Package
- id: upload-release-package
+ - name: Upload Standalone Package
+ id: upload-stanalone-package
+ uses: actions/upload-release-asset@v1.0.2
+ env:
+ GITHUB_TOKEN: ${{ secrets.GitHub_PAT }}
+ with:
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
+ # here we have to use relative path with starting "./"
+ asset_path: ./${{ steps.build_release_package.outputs.package_path }}/${{ steps.build_release_package.outputs.package-standalone }}
+ asset_name: ${{ steps.build_release_package.outputs.package-standalone }}
+ asset_content_type: ${{ steps.build_release_package.outputs.standalone-mime_type }}
+ - name: Upload Update Package
+ id: upload-update-package
uses: actions/upload-release-asset@v1.0.2
env:
GITHUB_TOKEN: ${{ secrets.GitHub_PAT }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
# here we have to use relative path with starting "./"
- asset_path: ./${{ steps.build_release_package.outputs.package_path }}/${{steps.build_release_package.outputs.package}}
- asset_name: ${{ steps.build_release_package.outputs.package }}
- asset_content_type: ${{ steps.build_release_package.outputs.mime_type }}
+ asset_path: ./${{ steps.build_release_package.outputs.package_path }}/${{ steps.build_release_package.outputs.package-update }}
+ asset_name: ${{ steps.build_release_package.outputs.package-update }}
+ asset_content_type: ${{ steps.build_release_package.outputs.update-mime_type }}
M CMakeLists.txt => CMakeLists.txt +55 -22
@@ 269,24 269,48 @@ if (${PROJECT_TARGET} STREQUAL "TARGET_RT1051")
)
# download the bootloader
- add_custom_target(ecoboot.bin
- COMMAND ${CMAKE_SOURCE_DIR}/tools/download_asset.py
- -w ${CMAKE_BINARY_DIR}/update ecoboot download
- > ${CMAKE_BINARY_DIR}/update/download_info.txt
- BYPRODUCTS update/ecoboot.bin
- COMMENT "Downloading ecoboot.bin"
- )
+ set(ECOBOOT_FILE ${CMAKE_BINARY_DIR}/ecoboot.bin)
+ set(ECOBOOT_DOWNLOAD_LOG ${CMAKE_BINARY_DIR}/download_info.txt)
+
+ if(DEFINED ENV{ASSETS_LOGIN} AND DEFINED ENV{ASSETS_TOKEN})
+ message("ecooboot download with tokens")
+ add_custom_command(OUTPUT ${ECOBOOT_FILE}
+ COMMAND ${CMAKE_SOURCE_DIR}/tools/download_asset.py
+ -l $ENV{ASSETS_LOGIN}
+ -t $ENV{ASSETS_TOKEN}
+ -w ${CMAKE_BINARY_DIR} ecoboot download
+ > ${ECOBOOT_DOWNLOAD_LOG}
+ COMMENT "Downloading ecoboot.bin"
+ BYPRODUCTS ${ECOBOOT_FILE} ${ECOBOOT_DOWNLOAD_LOG}
+ )
+ else()
+ message("ecoboot download with git")
+ add_custom_command(OUTPUT ${ECOBOOT_FILE}
+ COMMAND ${CMAKE_SOURCE_DIR}/tools/download_asset.py
+ -w ${CMAKE_BINARY_DIR} ecoboot download
+ > ${ECOBOOT_DOWNLOAD_LOG}
+ COMMENT "Downloading ecoboot.bin"
+ BYPRODUCTS ${ECOBOOT_FILE} ${ECOBOOT_DOWNLOAD_LOG}
+ )
+ endif()
+
+ add_custom_target(ecoboot.bin DEPENDS ${ECOBOOT_FILE})
+
# generate version.json file (runs CMake script at build time)
- add_custom_target(
- version.json
+ set(VERSION_JSON ${CMAKE_BINARY_DIR}/version.json)
+ add_custom_command(OUTPUT ${VERSION_JSON}
COMMAND ${CMAKE_COMMAND}
-DSRC_DIR=${CMAKE_SOURCE_DIR}
+ -DECOBOOT_DOWNLOAD_LOG=${ECOBOOT_DOWNLOAD_LOG}
-B ${CMAKE_BINARY_DIR}
-P ${CMAKE_SOURCE_DIR}/config/GenUpdateVersionJson.cmake
- DEPENDS ecoboot.bin
+ DEPENDS ecoboot.bin ${ECOBOOT_DOWNLOAD_LOG}
+ BYPRODUCTS ${VERSION_JSON}
)
- install(FILES ${CMAKE_BINARY_DIR}/update/ecoboot.bin DESTINATION "./" COMPONENT Update)
- install(FILES ${CMAKE_BINARY_DIR}/update/version.json DESTINATION "./" COMPONENT Update)
+ add_custom_target(version.json DEPENDS ${VERSION_JSON})
+
+ multicomp_install(PROGRAMS ${ECOBOOT_FILE} DESTINATION "./" COMPONENTS Standalone Update)
+ multicomp_install(FILES ${VERSION_JSON} DESTINATION "./" COMPONENTS Standalone Update)
set(CPACK_SYSTEM_NAME "RT1051")
# allow both standalone and update packages in RT1051 config
@@ 403,19 427,23 @@ if (${PROJECT_TARGET} STREQUAL "TARGET_RT1051")
add_custom_target(package-standalone
COMMAND zip -rq ${CMAKE_BINARY_DIR}/${PACKAGE_STANDALONE_FILE_NAME} "."
WORKING_DIRECTORY ${PACKAGE_STAGING_DIRECTORY}/Standalone
- DEPENDS package-standalone-staged
+ DEPENDS ${ECOBOOT_FILE} package-standalone-staged PurePhone
)
+ set(UPDATE_STAGING_DIRECTORY ${PACKAGE_STAGING_DIRECTORY}/Update)
add_custom_target(package-update-checksums
COMMAND rhash
- -u ${PACKAGE_STAGING_DIRECTORY}/Update/checksums.txt
- -r ${PACKAGE_STAGING_DIRECTORY}/Update
+ -u checksums.txt
+ -r .
+ WORKING_DIRECTORY ${UPDATE_STAGING_DIRECTORY}
DEPENDS package-update-staged
)
+ set(PACKAGE_UPDATE_FILE_NAME ${PACKAGE_COMMON_NAME}-Update.tar)
+ set(PACKAGE_UPDATE_MIME "application/x-tar")
add_custom_target(package-update
COMMAND tar
- -czf ${CMAKE_BINARY_DIR}/${PACKAGE_COMMON_NAME}-Update.tar.gz
+ -cf ${CMAKE_BINARY_DIR}/${PACKAGE_UPDATE_FILE_NAME}
-C ${PACKAGE_STAGING_DIRECTORY}/Update "."
- DEPENDS package-update-staged package-update-checksums
+ DEPENDS ecoboot.bin version.json PurePhone package-update-staged package-update-checksums
)
elseif (${PROJECT_TARGET} STREQUAL "TARGET_Linux")
set(PACKAGE_STANDALONE_FILE_NAME ${PACKAGE_COMMON_NAME}-Standalone.tar.gz)
@@ 429,9 457,14 @@ elseif (${PROJECT_TARGET} STREQUAL "TARGET_Linux")
endif()
if (NOT "$ENV{GITHUB_WORKSPACE}" STREQUAL "")
- message("set-output name=package::${PACKAGE_STANDALONE_FILE_NAME}")
- message("::set-output name=package::${PACKAGE_STANDALONE_FILE_NAME}")
-
- message("set-output name=mime_type::${PACKAGE_STANDALONE_MIME}")
- message("::set-output name=mime_type::${PACKAGE_STANDALONE_MIME}")
+ message("set-output name=package-standalone::${PACKAGE_STANDALONE_FILE_NAME}")
+ message("::set-output name=package-standalone::${PACKAGE_STANDALONE_FILE_NAME}")
+ message("set-output name=standalone-mime_type::${PACKAGE_STANDALONE_MIME}")
+ message("::set-output name=standalone-mime_type::${PACKAGE_STANDALONE_MIME}")
+
+ message("set-output name=package-update::${PACKAGE_UPDATE_FILE_NAME}")
+ message("::set-output name=package-update::${PACKAGE_UPDATE_FILE_NAME}")
+ message("set-output name=update-mime_type::${PACKAGE_UPDATE_MIME}")
+ message("::set-output name=update-mime_type::${PACKAGE_UPDATE_MIME}")
+
endif()
A => +0 -0
M changelog.md => changelog.md +3 -1
@@ 5,7 5,9 @@
### Added
* Add hardware in the loop tests.
-* Add empty APN settings window.
+* Add APN settings window.
+* Add New/Edit APN window
+* Add APN options window
### Changed
M config/GenUpdateVersionJson.cmake => config/GenUpdateVersionJson.cmake +2 -2
@@ 8,7 8,7 @@ include(Version)
set(BOOTLOADER_INCLUDED "true")
set(BOOTLOADER_FILENAME "ecoboot.bin")
execute_process(
- COMMAND grep "release:" "${CMAKE_BINARY_DIR}/update/download_info.txt"
+ COMMAND grep "release:" "${ECOBOOT_DOWNLOAD_LOG}"
COMMAND awk "{print $2}"
OUTPUT_VARIABLE BOOTLOADER_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
@@ 16,6 16,6 @@ execute_process(
configure_file(
${SRC_DIR}/config/version.json.cmake_template
- ${CMAKE_BINARY_DIR}/update/version.json
+ ${CMAKE_BINARY_DIR}/version.json
@ONLY
)
M doc/development_workflow.md => doc/development_workflow.md +1 -0
@@ 53,6 53,7 @@ Before submitting a Pull Request please go through some basic checks:
- test your changes on both Linux and RT1051 platforms (please pay special attention to the things you might break unintentionally, e.g. when working on calling, check call log too,
- run unit tests (`make check`),
+- [run static analysis](static_analysis.md)
- check if your code formatting complies with [`.clang-format`](../clang-format),
- whenever you add third-party software to MuditaOS source code, please make sure that the software component is added to a dedicated [section in `LICENSE.md` file on MuditaOS GitHub repository](../LICENSE.md) with a link to the text of the license where applicable.
A doc/static_analysis.md => doc/static_analysis.md +31 -0
@@ 0,0 1,31 @@
+# Static code analysis
+
+The Static code analysis is a method of debugging that is done by examining the source code without executing the program.
+
+Before submitting the Pull Request a developer should run static code analyzer tool and make sure that his code complies with the Coding Standards.
+
+## Clang-tidy
+
+The clang-tidy is a clang-based C++ “linter” tool. Its purpose is to provide an extensible framework for diagnosing and fixing typical programming errors, like style violations, interface misuse, or bugs that can be deduced via static analysis.
+
+### Install clang-tidy
+
+#### Linux Ubuntu
+
+The clang-tidy tool is available from the APT repository.
+
+`$ sudo apt install clang-tidy`
+
+### Run clang-tidy
+
+If `run-clang-tidy` program is installed, a CMake target called `clang-tidy` is available.
+
+In order to run `clang-tidy` analyzer on the MuditaOS repository, follow the steps:
+```
+$ cd <path/to/MuditaOS>
+$ ./configure.sh <platform> <build_type>
+$ cd <path/to/build/dir>
+$ make clang-tidy
+```
+
+The results of the analysis are available under `$(pwd)/StaticAnalysis` directory.
A image/assets/images/dead_battery_W_G.vpi => image/assets/images/dead_battery_W_G.vpi +0 -0
M image/assets/lang/English.json => image/assets/lang/English.json +13 -1
@@ 352,7 352,6 @@
"app_settings_network_sim_none": "No Sim",
"app_settings_network_voice_over_lte" : "VoLTE (experimental)",
"app_settings_network_apn_settings" : "APN settings",
- "app_settings_network_apn_settings_no_apns" : "<text align='center' color='9'>No APNs yet.<p>Press <b>left arrow</b> to add new.</p></text>",
"app_settings_toggle_on": "ON",
"app_settings_toggle_off": "OFF",
"app_settings_security_lock_screen_passcode": "Lock screen passcode",
@@ 363,6 362,19 @@
"app_settings_security_wrong_passcode": "Wrong passcode!",
"app_settings_security_passcode_changed_successfully": "Passcode changed successfully!",
"app_settings_security_passcode_disabled": "Passcode disabled!",
+ "app_settings_apn_settings_no_apns" : "<text align='center' color='9'>No APNs yet.<p>Press <b>left arrow</b> to add new.</p></text>",
+ "app_settings_apn_options" : "Options",
+ "app_settings_apn_options_delete" : "Delete",
+ "app_settings_apn_options_edit" : "Edit",
+ "app_settings_apn_options_set_as_default" : "Set as default",
+ "app_settings_new_edit_apn": "New/Edit APN",
+ "app_settings_apn_name": "Name",
+ "app_settings_apn_APN": "APN",
+ "app_settings_apn_username": "UserName",
+ "app_settings_apn_password": "Password",
+ "app_settings_apn_authtype": "Authentication type",
+ "app_settings_apn_apntype": "APN Type",
+ "app_settings_apn_apnprotocol" : "APN Protocol",
"app_phonebook_title_main": "Contacts",
"app_phonebook_search_win_contacts": "Contacts",
"common_search_uc": "Search",
M module-apps/Application.cpp => module-apps/Application.cpp +17 -6
@@ 70,10 70,12 @@ namespace app
uint32_t stackDepth,
sys::ServicePriority priority)
: Service(std::move(name), std::move(parent), stackDepth, priority),
- default_window(gui::name::window::main_window), windowsStack(this), startInBackground{startInBackground},
- callbackStorage{std::make_unique<CallbackStorage>()}, settings(std::make_unique<settings::Settings>(this))
+ default_window(gui::name::window::main_window), windowsStack(this),
+ keyTranslator{std::make_unique<gui::KeyInputSimpleTranslation>()}, startInBackground{startInBackground},
+ callbackStorage{std::make_unique<CallbackStorage>()}, topBarManager{std::make_unique<TopBarManager>()},
+ settings(std::make_unique<settings::Settings>(this))
{
- keyTranslator = std::make_unique<gui::KeyInputSimpleTranslation>();
+ topBarManager->enableIndicators({gui::top_bar::Indicator::Time});
busChannels.push_back(sys::BusChannels::ServiceCellularNotifications);
longPressTimer = std::make_unique<sys::Timer>("LongPress", this, key_timer_ms);
@@ 82,13 84,16 @@ namespace app
connect(typeid(AppRefreshMessage),
[this](sys::Message *msg) -> sys::MessagePointer { return handleAppRefresh(msg); });
- settings->registerValueChange(settings::SystemProperties::timeFormat12,
- [this](std::string value) { timeFormatChanged(value); });
+ settings->registerValueChange(
+ settings::SystemProperties::timeFormat12,
+ [this](std::string value) { timeFormatChanged(value); },
+ settings::SettingsScope::Global);
}
Application::~Application() noexcept
{
windowsStack.windows.clear();
+ settings->unregisterValueChange();
}
Application::State Application::getState()
@@ 496,7 501,8 @@ namespace app
settings->registerValueChange(
settings::SystemProperties::lockScreenPasscodeIsOn,
- [this](const std::string &value) { setLockScreenPasscodeOn(utils::getNumericValue<bool>(value)); });
+ [this](const std::string &value) { setLockScreenPasscodeOn(utils::getNumericValue<bool>(value)); },
+ settings::SettingsScope::Global);
return sys::ReturnCodes::Success;
}
@@ 693,6 699,11 @@ namespace app
item->attachTimer(std::move(timer));
}
+ const gui::top_bar::Configuration &Application::getTopBarConfiguration() const noexcept
+ {
+ return topBarManager->getConfiguration();
+ }
+
void Application::addActionReceiver(manager::actions::ActionId actionId, OnActionReceived &&callback)
{
receivers.insert_or_assign(actionId, std::move(callback));
M module-apps/Application.hpp => module-apps/Application.hpp +4 -0
@@ 25,6 25,7 @@
#include <string> // for string
#include <utility> // for move, pair
#include <vector> // for vector
+#include "TopBarManager.hpp"
#include "WindowsFactory.hpp"
#include "WindowsStack.hpp"
@@ 369,6 370,8 @@ namespace app
void addActionReceiver(manager::actions::ActionId actionId, OnActionReceived &&callback);
+ std::unique_ptr<TopBarManager> topBarManager;
+
/// application's settings
std::unique_ptr<settings::Settings> settings;
virtual void timeFormatChanged(std::string value);
@@ 378,6 381,7 @@ namespace app
bool isTimeFormat12() const noexcept;
void setLockScreenPasscodeOn(bool screenPasscodeOn) noexcept;
bool isLockScreenPasscodeOn() const noexcept;
+ const gui::top_bar::Configuration &getTopBarConfiguration() const noexcept;
};
/// Parameter pack used by application launch action.
M module-apps/CMakeLists.txt => module-apps/CMakeLists.txt +1 -0
@@ 15,6 15,7 @@ set( SOURCES
"Application.cpp"
"GuiTimer.cpp"
"WindowsFactory.cpp"
+ "TopBarManager.cpp"
"AsyncTask.cpp"
"CallbackStorage.cpp"
"windows/AppWindow.cpp"
A module-apps/TopBarManager.cpp => module-apps/TopBarManager.cpp +17 -0
@@ 0,0 1,17 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "TopBarManager.hpp"
+
+namespace app
+{
+ void TopBarManager::enableIndicators(const gui::top_bar::Indicators &indicators)
+ {
+ topBarConfiguration.enable(indicators);
+ }
+
+ auto TopBarManager::getConfiguration() const noexcept -> const gui::top_bar::Configuration &
+ {
+ return topBarConfiguration;
+ }
+} // namespace app
A module-apps/TopBarManager.hpp => module-apps/TopBarManager.hpp +19 -0
@@ 0,0 1,19 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <TopBar.hpp>
+
+namespace app
+{
+ class TopBarManager
+ {
+ public:
+ void enableIndicators(const gui::top_bar::Indicators &indicators);
+ [[nodiscard]] auto getConfiguration() const noexcept -> const gui::top_bar::Configuration &;
+
+ private:
+ gui::top_bar::Configuration topBarConfiguration;
+ };
+} // namespace app
M module-apps/application-alarm-clock/windows/AlarmClockMainWindow.cpp => module-apps/application-alarm-clock/windows/AlarmClockMainWindow.cpp +0 -1
@@ 32,7 32,6 @@ namespace app::alarmClock
{
AppWindow::buildInterface();
- topBar->setActive(gui::TopBar::Elements::TIME, true);
bottomBar->setActive(gui::BottomBar::Side::RIGHT, true);
bottomBar->setText(gui::BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
bottomBar->setText(gui::BottomBar::Side::CENTER, utils::localize.get(style::strings::common::Switch));
M module-apps/application-alarm-clock/windows/CustomRepeatWindow.cpp => module-apps/application-alarm-clock/windows/CustomRepeatWindow.cpp +0 -3
@@ 18,9 18,6 @@ namespace app::alarmClock
{
AppWindow::buildInterface();
- topBar->setActive(gui::TopBar::Elements::TIME, true);
- topBar->setActive(gui::TopBar::Elements::SIM, false);
- topBar->setActive(gui::TopBar::Elements::NETWORK_ACCESS_TECHNOLOGY, false);
bottomBar->setActive(gui::BottomBar::Side::RIGHT, true);
bottomBar->setActive(gui::BottomBar::Side::CENTER, true);
bottomBar->setText(gui::BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
M module-apps/application-alarm-clock/windows/NewEditAlarmWindow.cpp => module-apps/application-alarm-clock/windows/NewEditAlarmWindow.cpp +0 -1
@@ 21,7 21,6 @@ namespace app::alarmClock
{
AppWindow::buildInterface();
- topBar->setActive(gui::TopBar::Elements::TIME, true);
bottomBar->setActive(gui::BottomBar::Side::RIGHT, true);
bottomBar->setActive(gui::BottomBar::Side::CENTER, true);
bottomBar->setText(gui::BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
M module-apps/application-antenna/windows/AlgoParamsWindow.cpp => module-apps/application-antenna/windows/AlgoParamsWindow.cpp +0 -4
@@ 39,10 39,6 @@ namespace gui
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::open));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
- topBar->setActive(TopBar::Elements::SIGNAL, true);
- topBar->setActive(TopBar::Elements::TIME, true);
- topBar->setActive(TopBar::Elements::BATTERY, true);
-
setTitle(utils::localize.get("app_desktop_tools_antenna"));
lowBandBox = new gui::VBox(this,
M module-apps/application-antenna/windows/AntennaMainWindow.cpp => module-apps/application-antenna/windows/AntennaMainWindow.cpp +0 -4
@@ 48,10 48,6 @@ namespace gui
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::open));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
- topBar->setActive(TopBar::Elements::SIGNAL, true);
- topBar->setActive(TopBar::Elements::TIME, true);
- topBar->setActive(TopBar::Elements::BATTERY, true);
-
setTitle(utils::localize.get("app_desktop_tools_antenna"));
for (auto title : titlesText) {
M module-apps/application-antenna/windows/ScanModesWindow.cpp => module-apps/application-antenna/windows/ScanModesWindow.cpp +0 -4
@@ 37,10 37,6 @@ namespace gui
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::open));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
- topBar->setActive(TopBar::Elements::SIGNAL, true);
- topBar->setActive(TopBar::Elements::TIME, true);
- topBar->setActive(TopBar::Elements::BATTERY, true);
-
setTitle(utils::localize.get("app_desktop_tools_antenna"));
modeButtonParams.insert(std::pair<uint32_t, std::string>(scanModes::Auto, "AUTO"));
M module-apps/application-calculator/data/CalculatorUtility.cpp => module-apps/application-calculator/data/CalculatorUtility.cpp +70 -0
@@ 15,6 15,9 @@ Result Calculator::calculate(std::string source)
double result = te_interp(source.c_str(), &error);
if (error == 0 && !std::isinf(result) && !std::isnan(result)) {
auto output = utils::to_string(result);
+ if (output.length() > CalculatorConstants::maxStringLength) {
+ output = getValueThatFitsOnScreen(result);
+ }
if (utils::localize.get("app_calculator_decimal_separator") == style::calculator::symbols::strings::comma) {
output.replace(output.find(style::calculator::symbols::strings::full_stop),
std::size(std::string_view(style::calculator::symbols::strings::full_stop)),
@@ 48,3 51,70 @@ std::string Calculator::replaceAllOccurrences(std::string input, const std::stri
}
return input;
}
+
+std::string Calculator::getValueThatFitsOnScreen(double result)
+{
+ auto base = static_cast<long long>(result);
+ auto length = utils::to_string(base).length();
+ if (base < 0) {
+ length -= 1;
+ }
+ if (length > CalculatorConstants::expLength + 1) {
+ return convertToNumberWithPositiveExponent(result, length - 1);
+ }
+ else if (length == CalculatorConstants::expLength + 1) {
+ if (result < 0) {
+ return utils::to_string(getCoefficient(result, CalculatorConstants::veryLowPrecision));
+ }
+ return utils::to_string(getCoefficient(result, CalculatorConstants::lowPrecision));
+ }
+ else if (length == 1 && result < -1) {
+ return utils::to_string(getCoefficient(result, CalculatorConstants::lowPrecision));
+ }
+ else if (result > 1) {
+ return utils::to_string(getCoefficient(result, CalculatorConstants::precision));
+ }
+ else {
+ return convertToNumberWithNegativeExponent(result, base);
+ }
+}
+
+std::string Calculator::convertToNumberWithPositiveExponent(double result, uint32_t exponent)
+{
+ result /= pow(10, exponent);
+ auto exponentLength = utils::to_string(exponent).length();
+ auto decimalPlace = CalculatorConstants::precision - exponentLength - CalculatorConstants::expLength;
+ if (result < 0) {
+ decimalPlace -= 1;
+ }
+ return utils::to_string(getCoefficient(result, decimalPlace)) + "e" + utils::to_string(exponent);
+}
+
+std::string Calculator::convertToNumberWithNegativeExponent(double result, long long base)
+{
+ double frac = (result - base) * pow(10, CalculatorConstants::highPrecision);
+ if (result < 0) {
+ frac *= -1;
+ }
+ auto fractionalPart = static_cast<unsigned long int>(round(frac));
+ auto fracLength = utils::to_string(fractionalPart).length();
+ auto exponent = CalculatorConstants::highPrecision - fracLength + 1;
+ if (exponent > CalculatorConstants::minusExpLength + 1) {
+ result *= pow(10, exponent);
+ auto exponentLength = utils::to_string(exponent).length();
+ auto decimalPlace = CalculatorConstants::precision - exponentLength - CalculatorConstants::minusExpLength;
+ if (result < 0) {
+ decimalPlace -= 1;
+ }
+ return utils::to_string(getCoefficient(result, decimalPlace)) + "e-" + utils::to_string(exponent);
+ }
+ else if (result < 0) {
+ return utils::to_string(getCoefficient(result, CalculatorConstants::lowPrecision));
+ }
+ return utils::to_string(getCoefficient(result, CalculatorConstants::precision));
+}
+
+long double Calculator::getCoefficient(double result, uint32_t precision)
+{
+ return std::roundl(result * pow(10, precision)) / pow(10, precision);
+}
M module-apps/application-calculator/data/CalculatorUtility.hpp => module-apps/application-calculator/data/CalculatorUtility.hpp +15 -0
@@ 4,6 4,17 @@
#pragma once
#include <string>
+namespace CalculatorConstants
+{
+ inline constexpr auto veryLowPrecision = 4;
+ inline constexpr auto lowPrecision = 5;
+ inline constexpr auto precision = 6;
+ inline constexpr auto highPrecision = 8;
+ inline constexpr auto expLength = 1;
+ inline constexpr auto minusExpLength = 2;
+ inline constexpr auto maxStringLength = 7;
+} // namespace CalculatorConstants
+
struct Result
{
std::string equation;
@@ 18,6 29,10 @@ class Calculator
/// @return: new string with replaced all occurrences of given string to the new one in whole input
std::string replaceAllOccurrences(std::string input, const std::string &from, const std::string &to);
std::string prepareEquationForParser(std::string input);
+ std::string getValueThatFitsOnScreen(double result);
+ long double getCoefficient(double result, uint32_t precision);
+ std::string convertToNumberWithPositiveExponent(double result, uint32_t exponent);
+ std::string convertToNumberWithNegativeExponent(double result, long long base);
public:
Result calculate(std::string source);
M module-apps/application-calculator/tests/CalculatorUtility_tests.cpp => module-apps/application-calculator/tests/CalculatorUtility_tests.cpp +47 -0
@@ 93,4 93,51 @@ TEST_CASE("Calculator utilities")
REQUIRE(result.equation == "1.79769e+308*2");
REQUIRE(result.isError);
}
+
+ SECTION("Round to fit in screen")
+ {
+ auto result = calculator.calculate("1.1234512345");
+ REQUIRE(result.value == "1.123451");
+ REQUIRE(!result.isError);
+
+ result = calculator.calculate("0.0567891");
+ REQUIRE(result.value == "0.056789");
+ REQUIRE(!result.isError);
+
+ result = calculator.calculate("-0.056789");
+ REQUIRE(result.value == "-0.05679");
+ REQUIRE(!result.isError);
+
+ result = calculator.calculate("15.556789");
+ REQUIRE(result.value == "15.55679");
+ REQUIRE(!result.isError);
+ }
+
+ SECTION("Change to scientific notation (number > 0)")
+ {
+ auto result = calculator.calculate("12345.55555");
+ REQUIRE(result.value == "1.2346e4");
+ REQUIRE(!result.isError);
+ }
+
+ SECTION("Change to scientific notation (number < 0)")
+ {
+ auto result = calculator.calculate("-12345.55555");
+ REQUIRE(result.value == "-1.235e4");
+ REQUIRE(!result.isError);
+ }
+
+ SECTION("Change to scientific notation (0 < number < 1)")
+ {
+ auto result = calculator.calculate("0.000456712");
+ REQUIRE(result.value == "4.567e-4");
+ REQUIRE(!result.isError);
+ }
+
+ SECTION("Change to scientific notation (-1 < number < 0)")
+ {
+ auto result = calculator.calculate("-0.000456712");
+ REQUIRE(result.value == "-4.57e-4");
+ REQUIRE(!result.isError);
+ }
}
M module-apps/application-calculator/widgets/CalculatorStyle.hpp => module-apps/application-calculator/widgets/CalculatorStyle.hpp +1 -0
@@ 34,6 34,7 @@ namespace style::calculator
inline constexpr auto full_stop = 0x002E;
inline constexpr auto comma = 0x002C;
inline constexpr auto equals = 0x003D;
+ inline constexpr auto zero = 0x0030;
} // namespace codes
namespace strings
M module-apps/application-calculator/windows/CalculatorMainWindow.cpp => module-apps/application-calculator/windows/CalculatorMainWindow.cpp +42 -7
@@ 63,8 63,15 @@ namespace gui
if (!event.isShortPress()) {
return false;
}
+ if (event.is(gui::KeyCode::KEY_0) && mathOperationInput->getText() == "0") {
+ return true;
+ }
auto lastChar = mathOperationInput->getText()[mathOperationInput->getText().length() - 1];
bool lastCharIsSymbol = isSymbol(lastChar);
+ if (lastChar == style::calculator::symbols::codes::zero && isSymbol(getPenultimate()) &&
+ !isDecimalSeparator(getPenultimate()) && event.is(gui::KeyCode::KEY_0)) {
+ return true;
+ }
if (event.keyCode == gui::KeyCode::KEY_UP) {
writeEquation(lastCharIsSymbol, style::calculator::symbols::strings::plus);
return true;
@@ 89,6 96,15 @@ namespace gui
}
return true;
}
+ if (lastChar == style::calculator::symbols::codes::zero && isSymbol(getPenultimate()) &&
+ !isDecimalSeparator(getPenultimate()) && !event.is(gui::KeyCode::KEY_0) &&
+ !event.is(gui::KeyCode::KEY_PND) && !event.is(gui::KeyCode::KEY_ENTER)) {
+ mathOperationInput->removeChar();
+ return false;
+ }
+ if (!event.is(gui::KeyCode::KEY_0) && mathOperationInput->getText() == "0") {
+ mathOperationInput->clear();
+ }
return false;
};
}
@@ 103,21 119,36 @@ namespace gui
character == style::calculator::symbols::codes::full_stop;
}
+ bool CalculatorMainWindow::isDecimalSeparator(uint32_t character)
+ {
+ return character == style::calculator::symbols::codes::comma ||
+ character == style::calculator::symbols::codes::full_stop;
+ }
+
+ uint32_t CalculatorMainWindow::getPenultimate()
+ {
+ if (mathOperationInput->getText().length() > 1) {
+ return mathOperationInput->getText()[mathOperationInput->getText().length() - 2];
+ }
+ return 0;
+ }
+
void CalculatorMainWindow::writeEquation(bool lastCharIsSymbol, const UTF8 &symbol)
{
if (!mathOperationInput->getText().empty()) {
if (lastCharIsSymbol && symbol != style::calculator::symbols::strings::minus) {
- mathOperationInput->setRichText(
- std::string(mathOperationInput->getText()).erase(mathOperationInput->getText().length() - 1) +
- symbol.c_str());
+ if (!isSymbol(getPenultimate()) && mathOperationInput->getText().length() > 1) {
+ mathOperationInput->removeChar();
+ mathOperationInput->addText(symbol);
+ }
}
else {
- mathOperationInput->setRichText(mathOperationInput->getText() + symbol);
+ mathOperationInput->addText(symbol);
}
}
else if (symbol == style::calculator::symbols::strings::minus) {
- mathOperationInput->setRichText(mathOperationInput->getText() + symbol);
+ mathOperationInput->addText(symbol);
}
}
@@ 126,7 157,11 @@ namespace gui
if (!mathOperationInput->getText().empty()) {
std::vector<int> symbolsIndexes;
auto input = std::string(mathOperationInput->getText()).erase(mathOperationInput->getText().length() - 1);
- symbolsIndexes.push_back(input.find_last_of(style::calculator::symbols::strings::minus));
+ auto exponentIndex = input.find_last_of('e');
+ auto minusIndex = input.find_last_of(style::calculator::symbols::strings::minus);
+ if (minusIndex != exponentIndex + 1) {
+ symbolsIndexes.push_back(minusIndex);
+ }
symbolsIndexes.push_back(input.find_last_of(style::calculator::symbols::strings::plus));
symbolsIndexes.push_back(input.find_last_of(style::calculator::symbols::strings::division));
symbolsIndexes.push_back(input.find_last_of(style::calculator::symbols::strings::multiplication));
@@ 156,7 191,7 @@ namespace gui
if (inputEvent.keyCode == gui::KeyCode::KEY_ENTER) {
auto result = Calculator().calculate(std::string(mathOperationInput->getText()));
- mathOperationInput->setRichText(result.value);
+ mathOperationInput->setText(result.value);
clearInput = result.isError;
return true;
}
M module-apps/application-calculator/windows/CalculatorMainWindow.hpp => module-apps/application-calculator/windows/CalculatorMainWindow.hpp +2 -0
@@ 22,6 22,8 @@ namespace gui
void applyInputCallback();
bool isPreviousNumberDecimal();
bool isSymbol(uint32_t character);
+ bool isDecimalSeparator(uint32_t character);
+ uint32_t getPenultimate();
public:
CalculatorMainWindow(app::Application *app, std::string name);
M module-apps/application-calendar/ApplicationCalendar.cpp => module-apps/application-calendar/ApplicationCalendar.cpp +1 -1
@@ 147,7 147,7 @@ namespace app
void ApplicationCalendar::destroyUserInterface()
{}
- void ApplicationCalendar::switchToNoEventsWindow(const std::string &title, const TimePoint &dateFilter)
+ void ApplicationCalendar::switchToNoEventsWindow(const std::string &title, const calendar::TimePoint &dateFilter)
{
if (equivalentWindow == EquivalentWindow::DayEventsWindow) {
popToWindow(gui::name::window::main_window);
M module-apps/application-calendar/ApplicationCalendar.hpp => module-apps/application-calendar/ApplicationCalendar.hpp +2 -1
@@ 55,7 55,8 @@ namespace app
}
void createUserInterface() override;
void destroyUserInterface() override;
- void switchToNoEventsWindow(const std::string &title = "", const TimePoint &dateFilter = TimePoint());
+ void switchToNoEventsWindow(const std::string &title = "",
+ const calendar::TimePoint &dateFilter = calendar::TimePoint());
static const std::map<Reminder, const char *> reminderOptions;
static const std::map<Repeat, const char *> repeatOptions;
M module-apps/application-calendar/data/CalendarData.hpp => module-apps/application-calendar/data/CalendarData.hpp +3 -3
@@ 42,7 42,7 @@ class DayMonthData : public gui::SwitchData
{
protected:
std::string dayMonth;
- TimePoint dateFilter;
+ calendar::TimePoint dateFilter;
public:
DayMonthData() = default;
@@ 52,12 52,12 @@ class DayMonthData : public gui::SwitchData
return dayMonth;
};
- TimePoint getDateFilter()
+ calendar::TimePoint getDateFilter()
{
return dateFilter;
};
- virtual void setData(std::string dayMonthText, const TimePoint &dateNumb)
+ virtual void setData(std::string dayMonthText, const calendar::TimePoint &dateNumb)
{
dayMonth = dayMonthText;
dateFilter = dateNumb;
M module-apps/application-calendar/data/dateCommon.hpp => module-apps/application-calendar/data/dateCommon.hpp +35 -35
@@ 9,13 9,13 @@
#include <Utils.hpp>
#include <random>
-using namespace std::chrono;
-using namespace std::chrono_literals;
-
-using Clock = system_clock;
-using TimePoint = time_point<Clock>;
-using YearMonthDay = date::year_month_day;
-using YearMonthDayLast = date::year_month_day_last;
+namespace calendar
+{
+ using Clock = std::chrono::system_clock;
+ using TimePoint = std::chrono::time_point<Clock>;
+ using YearMonthDay = date::year_month_day;
+ using YearMonthDayLast = date::year_month_day_last;
+} // namespace calendar
inline constexpr auto max_month_day = 48;
@@ 43,7 43,7 @@ enum class Repeat
yearly
};
-inline constexpr TimePoint TIME_POINT_INVALID = date::sys_days{date::January / 1 / 1970};
+inline constexpr calendar::TimePoint TIME_POINT_INVALID = date::sys_days{date::January / 1 / 1970};
inline constexpr uint32_t yearDigitsNumb = 4, monthDigitsNumb = 2, dayDigitsNumb = 2, HourDigitsNumb = 2,
MinDigitsNumb = 2, SecDigitsNumb = 2;
@@ 88,34 88,34 @@ inline time_t GetAsUTCTime(int year, int month, int day, int hour = 0, int minut
return basetime + GetDiffLocalWithUTCTime();
}
-inline TimePoint TimePointFromTimeT(const time_t &time)
+inline calendar::TimePoint TimePointFromTimeT(const time_t &time)
{
- return system_clock::from_time_t(time);
+ return std::chrono::system_clock::from_time_t(time);
}
-inline time_t TimePointToTimeT(const TimePoint &tp)
+inline time_t TimePointToTimeT(const calendar::TimePoint &tp)
{
- return system_clock::to_time_t(tp);
+ return std::chrono::system_clock::to_time_t(tp);
}
-inline TimePoint TimePointNow()
+inline calendar::TimePoint TimePointNow()
{
utils::time::Timestamp timestamp;
return TimePointFromTimeT(timestamp.getTime());
}
-inline std::string TimePointToString(const TimePoint &tp)
+inline std::string TimePointToString(const calendar::TimePoint &tp)
{
- return date::format("%F %T", time_point_cast<seconds>(tp));
+ return date::format("%F %T", std::chrono::time_point_cast<std::chrono::seconds>(tp));
}
-inline auto TimePointToHourMinSec(const TimePoint &tp)
+inline auto TimePointToHourMinSec(const calendar::TimePoint &tp)
{
auto dp = date::floor<date::days>(tp);
return date::make_time(tp - dp);
}
-inline uint32_t TimePointToHour24H(const TimePoint &tp)
+inline uint32_t TimePointToHour24H(const calendar::TimePoint &tp)
{
auto time = TimePointToTimeT(tp);
utils::time::Timestamp timestamp(time);
@@ 123,7 123,7 @@ inline uint32_t TimePointToHour24H(const TimePoint &tp)
return hour;
}
-inline uint32_t TimePointToMinutes(const TimePoint &tp)
+inline uint32_t TimePointToMinutes(const calendar::TimePoint &tp)
{
auto time = TimePointToTimeT(tp);
utils::time::Timestamp timestamp(time);
@@ 131,7 131,7 @@ inline uint32_t TimePointToMinutes(const TimePoint &tp)
return minute;
}
-inline TimePoint getFirstWeekDay(const TimePoint &tp)
+inline calendar::TimePoint getFirstWeekDay(const calendar::TimePoint &tp)
{
date::year_month_day yearMonthDay = date::year_month_day{date::floor<date::days>(tp)};
auto hourV = TimePointToHour24H(tp);
@@ 146,12 146,12 @@ inline TimePoint getFirstWeekDay(const TimePoint &tp)
return finalDateTime;
}
-inline std::string TimePointToString(const TimePoint &tp, date::months months)
+inline std::string TimePointToString(const calendar::TimePoint &tp, date::months months)
{
date::year_month_day yearMonthDay = date::year_month_day{date::floor<date::days>(tp)};
date::year_month_day yearMonthDayLast = yearMonthDay.year() / yearMonthDay.month() / date::last;
- TimePoint timePoint;
+ calendar::TimePoint timePoint;
if ((static_cast<unsigned>(yearMonthDay.month()) + months.count()) <= 12) {
if (yearMonthDayLast.day() == yearMonthDay.day()) {
@@ 173,41 173,41 @@ inline std::string TimePointToString(const TimePoint &tp, date::months months)
timePoint = date::sys_days{yearMonthDay.year() / yearMonthDay.month() / yearMonthDay.day()};
}
}
- return date::format("%F %T", time_point_cast<seconds>(timePoint));
+ return date::format("%F %T", std::chrono::time_point_cast<std::chrono::seconds>(timePoint));
}
-inline std::string TimePointToLocalizedDateString(const TimePoint &tp, const std::string format = "")
+inline std::string TimePointToLocalizedDateString(const calendar::TimePoint &tp, const std::string format = "")
{
auto time = TimePointToTimeT(tp);
utils::time::Date timestamp(time);
return timestamp.str(format);
}
-inline std::string TimePointToLocalizedTimeString(const TimePoint &tp, const std::string format = "")
+inline std::string TimePointToLocalizedTimeString(const calendar::TimePoint &tp, const std::string format = "")
{
auto time = TimePointToTimeT(tp);
utils::time::Time timestamp(time);
return timestamp.str(format);
}
-inline TimePoint TimePointFromString(const char *s1)
+inline calendar::TimePoint TimePointFromString(const char *s1)
{
- TimePoint tp;
+ calendar::TimePoint tp;
std::istringstream(s1) >> date::parse("%F %T", tp);
return tp;
}
-inline YearMonthDay TimePointToYearMonthDay(const TimePoint &tp)
+inline calendar::YearMonthDay TimePointToYearMonthDay(const calendar::TimePoint &tp)
{
return date::year_month_day{date::floor<date::days>(tp)};
}
-inline TimePoint TimePointFromYearMonthDay(const YearMonthDay &ymd)
+inline calendar::TimePoint TimePointFromYearMonthDay(const calendar::YearMonthDay &ymd)
{
return date::sys_days{ymd.year() / ymd.month() / ymd.day()};
}
-inline time_t TimePointToMin(const TimePoint &tp)
+inline time_t TimePointToMin(const calendar::TimePoint &tp)
{
auto time = TimePointToTimeT(tp);
auto duration = new utils::time::Duration(time);
@@ 215,7 215,7 @@ inline time_t TimePointToMin(const TimePoint &tp)
return minutes;
}
-inline uint32_t TimePointToHour12H(const TimePoint &tp)
+inline uint32_t TimePointToHour12H(const calendar::TimePoint &tp)
{
auto time = TimePointToTimeT(tp);
utils::time::Timestamp timestamp(time);
@@ 226,7 226,7 @@ inline uint32_t TimePointToHour12H(const TimePoint &tp)
return hour;
}
-inline std::string TimePointToHourString12H(const TimePoint &tp)
+inline std::string TimePointToHourString12H(const calendar::TimePoint &tp)
{
auto hour =
utils::time::Timestamp(TimePointToTimeT(tp)).get_UTC_date_time_sub_value(utils::time::GetParameters::Hour);
@@ 234,14 234,14 @@ inline std::string TimePointToHourString12H(const TimePoint &tp)
return utils::to_string(hour12h);
}
-inline std::string TimePointToHourString24H(const TimePoint &tp)
+inline std::string TimePointToHourString24H(const calendar::TimePoint &tp)
{
auto hour =
utils::time::Timestamp(TimePointToTimeT(tp)).get_UTC_date_time_sub_value(utils::time::GetParameters::Hour);
return utils::to_string(hour);
}
-inline std::string TimePointToMinutesString(const TimePoint &tp)
+inline std::string TimePointToMinutesString(const calendar::TimePoint &tp)
{
auto minute = TimePointToMinutes(tp);
auto minuteString = std::to_string(minute);
@@ 252,9 252,9 @@ inline std::string TimePointToMinutesString(const TimePoint &tp)
}
// 0: Monday, 1: Tuesday ... 6: Sunday
-inline unsigned int WeekdayIndexFromTimePoint(const TimePoint &tp)
+inline unsigned int WeekdayIndexFromTimePoint(const calendar::TimePoint &tp)
{
- auto ymw = date::year_month_weekday{floor<date::days>(tp)};
+ auto ymw = date::year_month_weekday{std::chrono::floor<date::days>(tp)};
return ymw.weekday().iso_encoding() - 1;
}
M module-apps/application-calendar/models/AllEventsModel.cpp => module-apps/application-calendar/models/AllEventsModel.cpp +2 -2
@@ 83,8 83,8 @@ auto AllEventsModel::handleQueryResponse(db::QueryResult *queryResult) -> bool
auto eventShift = app->getEventShift();
if (eventShift) {
for (auto &record : records) {
- record.date_from += hours(eventShift);
- record.date_till += hours(eventShift);
+ record.date_from += std::chrono::hours(eventShift);
+ record.date_till += std::chrono::hours(eventShift);
}
}
return this->updateRecords(std::move(records));
M module-apps/application-calendar/models/DayEventsModel.cpp => module-apps/application-calendar/models/DayEventsModel.cpp +3 -3
@@ 82,8 82,8 @@ auto DayEventsModel::handleQueryResponse(db::QueryResult *queryResult) -> bool
auto eventShift = app->getEventShift();
if (eventShift) {
for (auto &record : records) {
- record.date_from += hours(eventShift);
- record.date_till += hours(eventShift);
+ record.date_from += std::chrono::hours(eventShift);
+ record.date_till += std::chrono::hours(eventShift);
}
}
return updateRecords(std::move(records));
@@ 95,7 95,7 @@ auto DayEventsModel::handleQueryResponse(db::QueryResult *queryResult) -> bool
return false;
}
-void DayEventsModel::setFilters(TimePoint from, TimePoint till, const std::string &dayMonth)
+void DayEventsModel::setFilters(calendar::TimePoint from, calendar::TimePoint till, const std::string &dayMonth)
{
this->filterFrom = from;
this->filterTill = till;
M module-apps/application-calendar/models/DayEventsModel.hpp => module-apps/application-calendar/models/DayEventsModel.hpp +3 -3
@@ 15,13 15,13 @@ class DayEventsModel : public app::DatabaseModel<EventsRecord>,
{
app::Application *application = nullptr;
std::string dayMonthTitle;
- TimePoint filterFrom = TIME_POINT_INVALID;
- TimePoint filterTill = TIME_POINT_INVALID;
+ calendar::TimePoint filterFrom = TIME_POINT_INVALID;
+ calendar::TimePoint filterTill = TIME_POINT_INVALID;
public:
DayEventsModel(app::Application *app);
- void setFilters(TimePoint from, TimePoint till, const std::string &dayMonth);
+ void setFilters(calendar::TimePoint from, calendar::TimePoint till, const std::string &dayMonth);
bool updateRecords(std::vector<EventsRecord> records) override;
auto handleQueryResponse(db::QueryResult *) -> bool;
M module-apps/application-calendar/widgets/EventDateItem.cpp => module-apps/application-calendar/widgets/EventDateItem.cpp +3 -3
@@ 149,7 149,7 @@ namespace gui
return true;
}
- YearMonthDay EventDateItem::validateDate()
+ calendar::YearMonthDay EventDateItem::validateDate()
{
auto actualDate = TimePointToYearMonthDay(TimePointNow());
uint32_t day;
@@ 185,7 185,7 @@ namespace gui
}
month = std::clamp(static_cast<unsigned>(month), 1u, static_cast<unsigned>(date::dec));
- YearMonthDayLast max_date = date::year(year) / date::month(month) / date::last;
+ calendar::YearMonthDayLast max_date = date::year(year) / date::month(month) / date::last;
if (day > static_cast<unsigned>(max_date.day())) {
dayInput->setText(std::to_string(static_cast<unsigned>(max_date.day())));
}
@@ 194,7 194,7 @@ namespace gui
return date::year(year) / date::month(month) / date::day(day);
}
- const YearMonthDay EventDateItem::getChosenDate()
+ const calendar::YearMonthDay EventDateItem::getChosenDate()
{
return validateDate();
}
M module-apps/application-calendar/widgets/EventDateItem.hpp => module-apps/application-calendar/widgets/EventDateItem.hpp +2 -2
@@ 24,12 24,12 @@ namespace gui
void buildInterface();
void applyItemSpecificProperties(gui::Text *item);
void applyCallbacks();
- YearMonthDay validateDate();
+ calendar::YearMonthDay validateDate();
public:
EventDateItem();
- const YearMonthDay getChosenDate();
+ const calendar::YearMonthDay getChosenDate();
// virtual methods from Item
bool onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) override;
};
M module-apps/application-calendar/widgets/EventTimeItem.cpp => module-apps/application-calendar/widgets/EventTimeItem.cpp +3 -3
@@ 433,9 433,9 @@ namespace gui
}
}
- TimePoint EventTimeItem::calculateEventTime(YearMonthDay date,
- std::chrono::hours hours,
- std::chrono::minutes minutes)
+ calendar::TimePoint EventTimeItem::calculateEventTime(calendar::YearMonthDay date,
+ std::chrono::hours hours,
+ std::chrono::minutes minutes)
{
return TimePointFromYearMonthDay(date) + hours + minutes;
}
M module-apps/application-calendar/widgets/EventTimeItem.hpp => module-apps/application-calendar/widgets/EventTimeItem.hpp +3 -1
@@ 43,7 43,9 @@ namespace gui
std::chrono::minutes end_hour,
uint32_t start_minutes,
uint32_t end_minutes);
- TimePoint calculateEventTime(YearMonthDay date, std::chrono::hours hours, std::chrono::minutes minutes);
+ calendar::TimePoint calculateEventTime(calendar::YearMonthDay date,
+ std::chrono::hours hours,
+ std::chrono::minutes minutes);
public:
EventTimeItem(const std::string &description,
M module-apps/application-calendar/widgets/MonthBox.cpp => module-apps/application-calendar/widgets/MonthBox.cpp +1 -1
@@ 58,7 58,7 @@ namespace gui
auto mainWindow = dynamic_cast<CalendarMainWindow *>(parent);
if (mainWindow->returnedFromWindow) {
focusChangedCallback = [=](Item &item) {
- YearMonthDay date = monthFilterValue.year() / monthFilterValue.month() / date::last;
+ calendar::YearMonthDay date = monthFilterValue.year() / monthFilterValue.month() / date::last;
if (unsigned(date.day()) < mainWindow->dayFocusedBefore) {
setFocusOnElement(unsigned(date.day()) - 1);
}
M module-apps/application-calendar/windows/AllEventsWindow.cpp => module-apps/application-calendar/windows/AllEventsWindow.cpp +0 -1
@@ 34,7 34,6 @@ namespace gui
{
AppWindow::buildInterface();
- topBar->setActive(gui::TopBar::Elements::TIME, true);
bottomBar->setActive(gui::BottomBar::Side::RIGHT, true);
bottomBar->setText(gui::BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
bottomBar->setText(gui::BottomBar::Side::CENTER, utils::localize.get(style::strings::common::open));
M module-apps/application-calendar/windows/AllEventsWindow.hpp => module-apps/application-calendar/windows/AllEventsWindow.hpp +1 -1
@@ 16,7 16,7 @@ namespace gui
gui::Image *leftArrowImage = nullptr;
gui::Image *newDayEventImage = nullptr;
- TimePoint dateFilter = TimePointNow();
+ calendar::TimePoint dateFilter = TimePointNow();
gui::ListView *allEventsList = nullptr;
std::shared_ptr<AllEventsModel> allEventsModel = nullptr;
M module-apps/application-calendar/windows/CalendarMainWindow.cpp => module-apps/application-calendar/windows/CalendarMainWindow.cpp +8 -8
@@ 100,9 100,9 @@ namespace gui
}
case KeyCode::KEY_LEFT: {
LOG_DEBUG("Call borderCallback -> go to the previous element");
- auto it = monthBox->getNavigationFocusedItem();
- if (monthBox->nextNavigationItem(std::prev(it)) != nullptr) {
- monthBox->setFocusItem(monthBox->nextNavigationItem(std::prev(it)));
+ auto it = std::prev(monthBox->getNavigationFocusedItem());
+ if (it != monthBox->children.end() && (*it)->isActive()) {
+ monthBox->setFocusItem(*it);
}
else {
monthBox->setFocusOnLastElement();
@@ 111,9 111,9 @@ namespace gui
}
case KeyCode::KEY_RIGHT: {
LOG_DEBUG("Call borderCallback -> go to the next element");
- auto it = monthBox->getNavigationFocusedItem();
- if (monthBox->nextNavigationItem(std::next(it)) != nullptr) {
- monthBox->setFocusItem(monthBox->nextNavigationItem(std::next(it)));
+ auto it = std::next(monthBox->getNavigationFocusedItem());
+ if (it != monthBox->children.end() && (*it)->isActive()) {
+ monthBox->setFocusItem(*it);
}
else {
monthBox->setFocusOnElement(0);
@@ 197,8 197,8 @@ namespace gui
void CalendarMainWindow::filterRequest()
{
- YearMonthDay date_from = actualDate.year() / actualDate.month() / 1;
- YearMonthDay date_till = date_from + date::months{1};
+ calendar::YearMonthDay date_from = actualDate.year() / actualDate.month() / 1;
+ calendar::YearMonthDay date_till = date_from + date::months{1};
auto filter_from = TimePointFromYearMonthDay(date_from);
auto filter_till = TimePointFromYearMonthDay(date_till);
LOG_DEBUG("filter: %s", TimePointToString(filter_till).c_str());
M module-apps/application-calendar/windows/CustomRepeatWindow.cpp => module-apps/application-calendar/windows/CustomRepeatWindow.cpp +0 -1
@@ 28,7 28,6 @@ namespace gui
{
AppWindow::buildInterface();
- topBar->setActive(gui::TopBar::Elements::TIME, true);
bottomBar->setActive(gui::BottomBar::Side::RIGHT, true);
bottomBar->setText(gui::BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
M module-apps/application-calendar/windows/DayEventsWindow.cpp => module-apps/application-calendar/windows/DayEventsWindow.cpp +0 -1
@@ 64,7 64,6 @@ namespace gui
{
AppWindow::buildInterface();
- topBar->setActive(gui::TopBar::Elements::TIME, true);
bottomBar->setActive(gui::BottomBar::Side::RIGHT, true);
bottomBar->setText(gui::BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
bottomBar->setText(gui::BottomBar::Side::CENTER, utils::localize.get(style::strings::common::open));
M module-apps/application-calendar/windows/DayEventsWindow.hpp => module-apps/application-calendar/windows/DayEventsWindow.hpp +1 -1
@@ 19,7 19,7 @@ namespace gui
class DayEventsWindow : public gui::AppWindow
{
std::string dayMonthTitle;
- TimePoint filterFrom;
+ calendar::TimePoint filterFrom;
gui::Image *leftArrowImage = nullptr;
gui::Image *newDayEventImage = nullptr;
gui::ListView *dayEventsList = nullptr;
M module-apps/application-calendar/windows/EventDetailWindow.cpp => module-apps/application-calendar/windows/EventDetailWindow.cpp +0 -1
@@ 28,7 28,6 @@ namespace gui
{
AppWindow::buildInterface();
- topBar->setActive(gui::TopBar::Elements::TIME, true);
bottomBar->setActive(gui::BottomBar::Side::RIGHT, true);
bottomBar->setActive(gui::BottomBar::Side::LEFT, true);
bottomBar->setText(gui::BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
M module-apps/application-calendar/windows/EventReminderWindow.cpp => module-apps/application-calendar/windows/EventReminderWindow.cpp +11 -4
@@ 38,14 38,21 @@ namespace gui
buildInterface();
}
+ top_bar::Configuration EventReminderWindow::configureTopBar(top_bar::Configuration appConfiguration)
+ {
+ using namespace top_bar;
+ appConfiguration.enable({Indicator::Signal,
+ Indicator::Time,
+ Indicator::Battery,
+ Indicator::SimCard,
+ Indicator::NetworkAccessTechnology});
+ return appConfiguration;
+ }
+
void EventReminderWindow::buildInterface()
{
AppWindow::buildInterface();
- topBar->setActive(TopBar::Elements::BATTERY, true);
- topBar->setActive(TopBar::Elements::SIGNAL, true);
- topBar->setActive(gui::TopBar::Elements::TIME, true);
-
bottomBar->setActive(gui::BottomBar::Side::CENTER, true);
bottomBar->setText(gui::BottomBar::Side::CENTER, utils::localize.get(style::strings::common::ok));
bottomBar->setBorderColor(ColorNoColor);
M module-apps/application-calendar/windows/EventReminderWindow.hpp => module-apps/application-calendar/windows/EventReminderWindow.hpp +1 -0
@@ 42,6 42,7 @@ namespace gui
void rebuild() override;
void buildInterface() override;
void destroyInterface() override;
+ top_bar::Configuration configureTopBar(top_bar::Configuration appConfiguration) override;
auto handleSwitchData(SwitchData *data) -> bool override;
};
M module-apps/application-calendar/windows/NewEditEventWindow.cpp => module-apps/application-calendar/windows/NewEditEventWindow.cpp +0 -1
@@ 25,7 25,6 @@ namespace gui
{
AppWindow::buildInterface();
- topBar->setActive(gui::TopBar::Elements::TIME, true);
bottomBar->setActive(gui::BottomBar::Side::RIGHT, true);
bottomBar->setActive(gui::BottomBar::Side::CENTER, true);
bottomBar->setText(gui::BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
M module-apps/application-call/ApplicationCall.cpp => module-apps/application-call/ApplicationCall.cpp +6 -0
@@ 33,6 33,12 @@ namespace app
ApplicationCall::ApplicationCall(std::string name, std::string parent, StartInBackground startInBackground)
: Application(name, parent, startInBackground, app::call_stack_size)
{
+ using namespace gui::top_bar;
+ topBarManager->enableIndicators({Indicator::Signal,
+ Indicator::Time,
+ Indicator::Battery,
+ Indicator::SimCard,
+ Indicator::NetworkAccessTechnology});
addActionReceiver(manager::actions::Call, [this](auto &&data) {
switchWindow(window::name_call, std::forward<decltype(data)>(data));
return msgHandled();
M module-apps/application-call/windows/CallWindow.cpp => module-apps/application-call/windows/CallWindow.cpp +0 -4
@@ 58,10 58,6 @@ namespace gui
{
AppWindow::buildInterface();
- topBar->setActive(gui::TopBar::Elements::BATTERY, true);
- topBar->setActive(gui::TopBar::Elements::SIGNAL, true);
- topBar->setActive(gui::TopBar::Elements::TIME, true);
-
bottomBar->setActive(BottomBar::Side::CENTER, true);
bottomBar->setActive(BottomBar::Side::RIGHT, true);
M module-apps/application-call/windows/EnterNumberWindow.cpp => module-apps/application-call/windows/EnterNumberWindow.cpp +0 -4
@@ 58,10 58,6 @@ namespace gui
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get("common_add"));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get("app_call_clear"));
- topBar->setActive(TopBar::Elements::SIGNAL, true);
- topBar->setActive(TopBar::Elements::BATTERY, true);
- topBar->setActive(TopBar::Elements::TIME, true);
-
numberLabel = new gui::Label(this, numberLabel::x, numberLabel::y, numberLabel::w, numberLabel::h);
numberLabel->setPenWidth(numberLabel::borderW);
numberLabel->setFont(style::window::font::largelight);
M module-apps/application-calllog/windows/CallLogDetailsWindow.cpp => module-apps/application-calllog/windows/CallLogDetailsWindow.cpp +0 -2
@@ 82,8 82,6 @@ namespace gui
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::call));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
- topBar->setActive(TopBar::Elements::TIME, true);
-
// NOTE: height of all labels is set using decorators
// Information
M module-apps/application-calllog/windows/CallLogMainWindow.cpp => module-apps/application-calllog/windows/CallLogMainWindow.cpp +0 -2
@@ 47,8 47,6 @@ namespace gui
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::open));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
- topBar->setActive(TopBar::Elements::TIME, true);
-
list = new gui::ListView(this, mainWindow::x, mainWindow::y, mainWindow::w, mainWindow::h, calllogModel);
setFocusItem(list);
M module-apps/application-desktop/ApplicationDesktop.cpp => module-apps/application-desktop/ApplicationDesktop.cpp +24 -4
@@ 8,6 8,7 @@
#include "windows/MenuWindow.hpp"
#include "windows/PinLockWindow.hpp"
#include "windows/PowerOffWindow.hpp"
+#include "windows/DeadBatteryWindow.hpp"
#include "windows/LockedInfoWindow.hpp"
#include "windows/Reboot.hpp"
#include "windows/Update.hpp"
@@ 37,6 38,12 @@ namespace app
ApplicationDesktop::ApplicationDesktop(std::string name, std::string parent, StartInBackground startInBackground)
: Application(name, parent, startInBackground), lockHandler(this)
{
+ using namespace gui::top_bar;
+ topBarManager->enableIndicators({Indicator::Signal,
+ Indicator::Time,
+ Indicator::Battery,
+ Indicator::SimCard,
+ Indicator::NetworkAccessTechnology});
busChannels.push_back(sys::BusChannels::ServiceDBNotifications);
addActionReceiver(app::manager::actions::RequestPin, [this](auto &&data) {
@@ 88,6 95,11 @@ namespace app
handleLowBatteryNotification(std::move(data));
return msgHandled();
});
+
+ addActionReceiver(app::manager::actions::SystemBrownout, [this](auto &&data) {
+ switchWindow(app::window::name::dead_battery, std::move(data));
+ return msgHandled();
+ });
}
ApplicationDesktop::~ApplicationDesktop()
@@ 317,11 329,15 @@ namespace app
std::make_shared<sdesktop::UpdateOsMessage>(updateos::UpdateMessageType::UpdateCheckForUpdateOnce);
sys::Bus::SendUnicast(msgToSend, service::name::service_desktop, this);
- settings->registerValueChange(settings::SystemProperties::activeSim,
- [this](std::string value) { activeSimChanged(value); });
+ settings->registerValueChange(
+ settings::SystemProperties::activeSim,
+ [this](std::string value) { activeSimChanged(value); },
+ settings::SettingsScope::Global);
Store::GSM::get()->selected = Store::GSM::SIM::NONE;
- settings->registerValueChange(settings::SystemProperties::lockPassHash,
- [this](std::string value) { lockPassHashChanged(value); });
+ settings->registerValueChange(
+ settings::SystemProperties::lockPassHash,
+ [this](std::string value) { lockPassHashChanged(value); },
+ settings::SettingsScope::Global);
return sys::ReturnCodes::Success;
}
@@ 329,6 345,7 @@ namespace app
sys::ReturnCodes ApplicationDesktop::DeinitHandler()
{
LOG_INFO("DeinitHandler");
+ settings->unregisterValueChange();
return sys::ReturnCodes::Success;
}
@@ 347,6 364,9 @@ namespace app
windowsFactory.attach(desktop_poweroff, [](Application *app, const std::string newname) {
return std::make_unique<gui::PowerOffWindow>(app);
});
+ windowsFactory.attach(dead_battery, [](Application *app, const std::string newname) {
+ return std::make_unique<gui::DeadBatteryWindow>(app);
+ });
windowsFactory.attach(desktop_locked, [](Application *app, const std::string newname) {
return std::make_unique<gui::LockedInfoWindow>(app);
});
M module-apps/application-desktop/ApplicationDesktop.hpp => module-apps/application-desktop/ApplicationDesktop.hpp +2 -1
@@ 107,7 107,8 @@ namespace app
manager::actions::ShowMMIPush,
manager::actions::ShowMMIResult,
manager::actions::DisplayCMEError,
- manager::actions::DisplayLowBatteryNotification}};
+ manager::actions::DisplayLowBatteryNotification,
+ manager::actions::SystemBrownout}};
}
};
M module-apps/application-desktop/CMakeLists.txt => module-apps/application-desktop/CMakeLists.txt +1 -0
@@ 27,6 27,7 @@ target_sources( ${PROJECT_NAME}
"${CMAKE_CURRENT_LIST_DIR}/windows/PinLockWindow.cpp"
"${CMAKE_CURRENT_LIST_DIR}/windows/MenuWindow.cpp"
"${CMAKE_CURRENT_LIST_DIR}/windows/PowerOffWindow.cpp"
+ "${CMAKE_CURRENT_LIST_DIR}/windows/DeadBatteryWindow.cpp"
"${CMAKE_CURRENT_LIST_DIR}/windows/LockedInfoWindow.cpp"
"${CMAKE_CURRENT_LIST_DIR}/windows/Reboot.cpp"
"${CMAKE_CURRENT_LIST_DIR}/windows/Update.cpp"
A module-apps/application-desktop/windows/DeadBatteryWindow.cpp => module-apps/application-desktop/windows/DeadBatteryWindow.cpp +53 -0
@@ 0,0 1,53 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "DeadBatteryWindow.hpp"
+#include "InputEvent.hpp"
+#include "gui/widgets/Image.hpp"
+#include "gui/widgets/BottomBar.hpp"
+#include "gui/widgets/TopBar.hpp"
+#include "log/log.hpp"
+#include <application-desktop/windows/Names.hpp>
+#include <service-appmgr/model/ApplicationManager.hpp>
+#include <service-appmgr/Controller.hpp>
+
+namespace gui
+{
+ namespace
+ {
+ constexpr inline auto SHUTDOWN_TIMER_MS = 500;
+ constexpr inline auto IMG_POS_X = 176;
+ constexpr inline auto IMG_POS_Y = 250;
+ } // namespace
+
+ DeadBatteryWindow::DeadBatteryWindow(app::Application *app) : AppWindow(app, app::window::name::dead_battery)
+ {
+ buildInterface();
+ }
+
+ void DeadBatteryWindow::rebuild()
+ {
+ destroyInterface();
+ buildInterface();
+ }
+
+ void DeadBatteryWindow::buildInterface()
+ {
+ AppWindow::buildInterface();
+ bottomBar->setVisible(false);
+ topBar->setVisible(false);
+
+ image = new gui::Image(this, IMG_POS_X, IMG_POS_Y, 0, 0, "dead_battery_W_G");
+ }
+
+ void DeadBatteryWindow::onBeforeShow(ShowMode mode, SwitchData *data)
+ {
+ app::manager::Controller::sendAction(application, app::manager::actions::CloseSystem);
+ }
+
+ void DeadBatteryWindow::destroyInterface()
+ {
+ erase();
+ image = nullptr;
+ }
+} /* namespace gui */
A module-apps/application-desktop/windows/DeadBatteryWindow.hpp => module-apps/application-desktop/windows/DeadBatteryWindow.hpp +24 -0
@@ 0,0 1,24 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <vector>
+#include "AppWindow.hpp"
+
+namespace gui
+{
+ class DeadBatteryWindow : public AppWindow
+ {
+ public:
+ explicit DeadBatteryWindow(app::Application *app);
+ void rebuild() override;
+ void buildInterface() override;
+ void destroyInterface() override;
+ void onBeforeShow(ShowMode mode, SwitchData *data) override;
+
+ private:
+ gui::Image *image = nullptr;
+ };
+
+} /* namespace gui */
M module-apps/application-desktop/windows/DesktopMainWindow.cpp => module-apps/application-desktop/windows/DesktopMainWindow.cpp +20 -6
@@ 35,8 35,6 @@ namespace gui
AppWindow::buildInterface();
bottomBar->setActive(BottomBar::Side::CENTER, true);
- topBar->setActive(
- {{TopBar::Elements::SIGNAL, true}, {TopBar::Elements::LOCK, true}, {TopBar::Elements::BATTERY, true}});
using namespace style::desktop;
@@ 75,6 73,20 @@ namespace gui
notifications = nullptr;
}
+ top_bar::Configuration DesktopMainWindow::configureTopBar(top_bar::Configuration appConfiguration)
+ {
+ auto app = getAppDesktop();
+ const auto isLocked = app->lockHandler.isScreenLocked();
+ updateTopBarConfiguration(isLocked, appConfiguration);
+ return appConfiguration;
+ }
+
+ void DesktopMainWindow::updateTopBarConfiguration(bool isScreenLocked, top_bar::Configuration &configuration)
+ {
+ configuration.set(top_bar::Indicator::Lock, isScreenLocked);
+ configuration.set(top_bar::Indicator::Time, !isScreenLocked);
+ }
+
DesktopMainWindow::DesktopMainWindow(app::Application *app) : AppWindow(app, app::window::name::desktop_main_window)
{
buildInterface();
@@ 89,13 101,18 @@ namespace gui
void DesktopMainWindow::setVisibleState()
{
auto app = getAppDesktop();
+ applyToTopBar([isLocked = app->lockHandler.isScreenLocked()](top_bar::Configuration configuration) {
+ updateTopBarConfiguration(isLocked, configuration);
+ return configuration;
+ });
+
if (app->lockHandler.isScreenLocked()) {
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get("app_desktop_unlock"));
bottomBar->setActive(BottomBar::Side::RIGHT, false);
bottomBar->setText(BottomBar::Side::LEFT,
utils::localize.get("app_desktop_emergency"),
app->lockHandler.isScreenBlocked());
- topBar->setActive(TopBar::Elements::LOCK, true);
+
inputCallback = nullptr;
setFocusItem(nullptr);
buildNotifications(app);
@@ 104,8 121,6 @@ namespace gui
std::make_shared<TimersProcessingStopMessage>(), service::name::service_time, application);
}
else {
- topBar->setActive(TopBar::Elements::LOCK, false);
-
if (!buildNotifications(app)) {
LOG_ERROR("Couldn't fit in all notifications");
}
@@ 146,7 161,6 @@ namespace gui
if (inputEvent.is(KeyCode::KEY_PND)) {
app->lockHandler.lockScreen();
setVisibleState();
- application->setSuspendFlag(true);
return true;
}
// long press of '0' key is translated to '+'
M module-apps/application-desktop/windows/DesktopMainWindow.hpp => module-apps/application-desktop/windows/DesktopMainWindow.hpp +3 -0
@@ 81,11 81,14 @@ namespace gui
void rebuild() override;
void buildInterface() override;
void destroyInterface() override;
+ top_bar::Configuration configureTopBar(top_bar::Configuration appConfiguration) override;
+
bool updateTime(const UTF8 &timeStr) override;
bool updateTime(const uint32_t ×tamp, bool mode24H) override;
private:
void invalidate() noexcept;
+ static void updateTopBarConfiguration(bool isScreenLocked, top_bar::Configuration &configuration);
gui::KeyInputMappedTranslation translator;
};
M module-apps/application-desktop/windows/LockWindow.cpp => module-apps/application-desktop/windows/LockWindow.cpp +0 -1
@@ 14,7 14,6 @@ namespace gui
void LockWindow::build()
{
buildBottomBar();
- buildTopBar();
buildTitleBar();
buildInfoTexts();
}
M module-apps/application-desktop/windows/LockWindow.hpp => module-apps/application-desktop/windows/LockWindow.hpp +0 -1
@@ 58,7 58,6 @@ namespace gui
protected:
virtual void buildBottomBar();
virtual void buildTitleBar() = 0;
- virtual void buildTopBar() = 0;
private:
[[nodiscard]] auto getText(TextType type) noexcept -> gui::Text *;
M module-apps/application-desktop/windows/LockedInfoWindow.cpp => module-apps/application-desktop/windows/LockedInfoWindow.cpp +7 -4
@@ 34,10 34,6 @@ void LockedInfoWindow::setVisibleState()
bottomBar->setActive(BottomBar::Side::LEFT, true);
bottomBar->setActive(BottomBar::Side::CENTER, false);
bottomBar->setActive(BottomBar::Side::RIGHT, true);
-
- topBar->setActive(TopBar::Elements::LOCK, true);
- topBar->setActive(TopBar::Elements::BATTERY, true);
- topBar->setActive(TopBar::Elements::SIGNAL, true);
}
bool LockedInfoWindow::onInput(const InputEvent &inputEvent)
@@ 61,6 57,13 @@ void LockedInfoWindow::rebuild()
buildInterface();
}
+top_bar::Configuration LockedInfoWindow::configureTopBar(top_bar::Configuration appConfiguration)
+{
+ appConfiguration.enable(top_bar::Indicator::Lock);
+ appConfiguration.disable(top_bar::Indicator::Time);
+ return appConfiguration;
+}
+
void LockedInfoWindow::buildInterface()
{
namespace lock_style = style::window::pin_lock;
M module-apps/application-desktop/windows/LockedInfoWindow.hpp => module-apps/application-desktop/windows/LockedInfoWindow.hpp +1 -0
@@ 25,5 25,6 @@ namespace gui
void rebuild() override;
void buildInterface() override;
void destroyInterface() override;
+ top_bar::Configuration configureTopBar(top_bar::Configuration appConfiguration) override;
};
} /* namespace gui */
M => +0 -3
@@ 149,9 149,6 @@ namespace gui
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::open));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
topBar->setActive(TopBar::Elements::SIGNAL, true);
topBar->setActive(TopBar::Elements::BATTERY, true);
auto app = dynamic_cast<app::ApplicationDesktop *>(application);
assert(app);
M module-apps/application-desktop/windows/MmiPullWindow.cpp => module-apps/application-desktop/windows/MmiPullWindow.cpp +0 -2
@@ 37,8 37,6 @@ MmiPullWindow::MmiPullWindow(app::Application *app, const std::string &name) : g
{
AppWindow::buildInterface();
- topBar->setActive(TopBar::Elements::TIME, true);
- topBar->setActive(TopBar::Elements::SIM, false);
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get("app_desktop_replay"));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
text = new Text(
M module-apps/application-desktop/windows/MmiPushWindow.cpp => module-apps/application-desktop/windows/MmiPushWindow.cpp +0 -2
@@ 30,8 30,6 @@ namespace style::desktop
MmiPushWindow::MmiPushWindow(app::Application *app, const std::string &name) : gui::AppWindow(app, name)
{
AppWindow::buildInterface();
- topBar->setActive(TopBar::Elements::TIME, true);
- topBar->setActive(TopBar::Elements::SIM, false);
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::ok));
icon = new Image(this, style::desktop::image::x, style::desktop::image::y, "");
icon->set("info_big_circle_W_G");
M module-apps/application-desktop/windows/Names.hpp => module-apps/application-desktop/windows/Names.hpp +9 -8
@@ 7,13 7,14 @@
namespace app::window::name
{
inline constexpr auto desktop_main_window = gui::name::window::main_window;
- inline constexpr auto desktop_menu = "MenuWindow";
- inline constexpr auto desktop_reboot = "Reboot";
- inline constexpr auto desktop_poweroff = "PowerOffWindow";
- inline constexpr auto desktop_pin_lock = "PinLockWindow";
- inline constexpr auto desktop_locked = "LockedInfoWindow";
- inline constexpr auto desktop_update = "Update";
- inline constexpr auto desktop_mmi_pull = "MmiPullWindow";
- inline constexpr auto desktop_mmi_push = "MmiPushWindow";
+ inline constexpr auto desktop_menu = "MenuWindow";
+ inline constexpr auto desktop_reboot = "Reboot";
+ inline constexpr auto desktop_poweroff = "PowerOffWindow";
+ inline constexpr auto dead_battery = "DeadBatteryWindow";
+ inline constexpr auto desktop_pin_lock = "PinLockWindow";
+ inline constexpr auto desktop_locked = "LockedInfoWindow";
+ inline constexpr auto desktop_update = "Update";
+ inline constexpr auto desktop_mmi_pull = "MmiPullWindow";
+ inline constexpr auto desktop_mmi_push = "MmiPushWindow";
inline constexpr auto desktop_mmi_internal = "MmiInternalMsgWindow";
}; // namespace app::window::name
M module-apps/application-desktop/windows/PinLockBaseWindow.cpp => module-apps/application-desktop/windows/PinLockBaseWindow.cpp +6 -7
@@ 32,7 32,12 @@ namespace gui
}
return std::string{};
}
-
+ top_bar::Configuration PinLockBaseWindow::configureTopBar(top_bar::Configuration appConfiguration)
+ {
+ appConfiguration.enable(top_bar::Indicator::Lock);
+ appConfiguration.disable(top_bar::Indicator::Time);
+ return appConfiguration;
+ }
void PinLockBaseWindow::restore() noexcept
{
LockWindow::restore();
@@ 91,10 96,4 @@ namespace gui
title->setPenWidth(2);
}
- void PinLockBaseWindow::buildTopBar()
- {
- topBar->setActive(TopBar::Elements::SIGNAL, true);
- topBar->setActive(TopBar::Elements::BATTERY, true);
- topBar->setActive(TopBar::Elements::LOCK, true);
- }
} // namespace gui
M module-apps/application-desktop/windows/PinLockBaseWindow.hpp => module-apps/application-desktop/windows/PinLockBaseWindow.hpp +3 -1
@@ 12,6 12,9 @@ namespace gui
public:
PinLockBaseWindow(app::Application *app, std::string name) : LockWindow(app, name)
{}
+
+ top_bar::Configuration configureTopBar(top_bar::Configuration appConfiguration) override;
+
void buildImages(const std::string &lockImg, const std::string &infoImg);
[[nodiscard]] auto getToken(Token token) const -> std::string;
void restore() noexcept override;
@@ 25,6 28,5 @@ namespace gui
private:
void buildBottomBar() override;
void buildTitleBar() override;
- void buildTopBar() override;
};
} // namespace gui
M module-apps/application-desktop/windows/PowerOffWindow.cpp => module-apps/application-desktop/windows/PowerOffWindow.cpp +2 -19
@@ 4,7 4,6 @@
#include "InputEvent.hpp"
#include "gui/widgets/BottomBar.hpp"
#include "gui/widgets/TopBar.hpp"
-#include "GuiTimer.hpp"
#include "log/log.hpp"
// module-utils
@@ 15,6 14,7 @@
// services
#include <service-appmgr/model/ApplicationManager.hpp>
+#include <service-appmgr/Controller.hpp>
#include "service-cellular/ServiceCellular.hpp"
#include <Style.hpp>
@@ 142,7 142,7 @@ namespace gui
infoLabel->setVisible(false);
application->refreshWindow(RefreshModes::GUI_REFRESH_DEEP);
- scheduleSystemShutdown();
+ app::manager::Controller::sendAction(application, app::manager::actions::CloseSystem);
return true;
};
@@ 160,23 160,6 @@ namespace gui
};
}
- // Temporary solution for shutting down the system.
- // The former solution removed from service-gui during its refactor.
- // To be reimplemented in SystemManager in upcoming commits.
- void PowerOffWindow::scheduleSystemShutdown()
- {
- constexpr auto SystemShutdownDelayInMs = 500;
- auto powerOffTimer = std::make_unique<app::GuiTimer>("PowerOffTimer", application);
- powerOffTimer->setInterval(SystemShutdownDelayInMs);
- timerCallback = [this](Item &, Timer &timer) {
- detachTimer(timer);
- sys::SystemManager::CloseSystem(application);
- return true;
- };
- powerOffTimer->start();
- application->connect(std::move(powerOffTimer), this);
- }
-
void PowerOffWindow::destroyInterface()
{
erase();
M module-apps/application-desktop/windows/PowerOffWindow.hpp => module-apps/application-desktop/windows/PowerOffWindow.hpp +0 -3
@@ 27,9 27,6 @@ namespace gui
gui::Image *powerImage = nullptr;
gui::Image *powerDownImage = nullptr;
State state = State::Return;
-
- void scheduleSystemShutdown();
-
public:
PowerOffWindow(app::Application *app);
void onBeforeShow(ShowMode mode, SwitchData *data) override;
M module-apps/application-meditation/windows/MeditationListViewWindows.cpp => module-apps/application-meditation/windows/MeditationListViewWindows.cpp +0 -2
@@ 64,7 64,6 @@ void MeditationOptionsWindow::buildInterface()
MeditationListViewWindow::buildInterface();
setTitle(utils::localize.get("common_options"));
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::Switch));
- topBar->setActive(TopBar::Elements::TIME, true);
}
PreparationTimeWindow::PreparationTimeWindow(app::Application *app)
@@ 79,5 78,4 @@ void PreparationTimeWindow::buildInterface()
MeditationListViewWindow::buildInterface();
setTitle(utils::localize.get("app_meditation_preparation_time"));
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::select));
- topBar->setActive(TopBar::Elements::TIME, true);
}
M module-apps/application-meditation/windows/MeditationTimerWindow.cpp => module-apps/application-meditation/windows/MeditationTimerWindow.cpp +5 -1
@@ 112,7 112,11 @@ auto MeditationTimerWindow::onInput(const InputEvent &inputEvent) -> bool
void MeditationTimerWindow::setWidgetVisible(bool tBar, bool bBar, bool counter)
{
- topBar->setActive(TopBar::Elements::TIME, tBar);
+ applyToTopBar([tBar](top_bar::Configuration configuration) {
+ configuration.set(top_bar::Indicator::Time, tBar);
+ return configuration;
+ });
+
title->setVisible(tBar);
bottomBar->setActive(BottomBar::Side::CENTER, bBar);
bottomBar->setActive(BottomBar::Side::LEFT, bBar);
M module-apps/application-messages/windows/MessagesMainWindow.cpp => module-apps/application-messages/windows/MessagesMainWindow.cpp +0 -2
@@ 64,8 64,6 @@ namespace gui
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::open));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
- topBar->setActive(TopBar::Elements::TIME, true);
-
setTitle(utils::localize.get("app_messages_title_main"));
leftArrowImage = new gui::Image(this, 30, 62, 0, 0, "arrow_left");
M module-apps/application-messages/windows/NewMessage.cpp => module-apps/application-messages/windows/NewMessage.cpp +0 -3
@@ 188,9 188,6 @@ namespace gui
bottomBar->setText(BottomBar::Side::LEFT, utils::localize.get(style::strings::common::options));
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::select));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
- topBar->setActive(TopBar::Elements::BATTERY, false);
- topBar->setActive(TopBar::Elements::SIM, false);
- topBar->setActive(TopBar::Elements::SIGNAL, false);
setTitle(utils::localize.get("sms_title_message"));
M module-apps/application-messages/windows/SMSTemplatesWindow.cpp => module-apps/application-messages/windows/SMSTemplatesWindow.cpp +0 -2
@@ 44,8 44,6 @@ namespace gui
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::use));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
- topBar->setActive(TopBar::Elements::TIME, true);
-
namespace style = style::messages::templates::list;
list = new gui::ListView(this, style::x, style::y, style::w, style::h, smsTemplateModel);
M module-apps/application-messages/windows/SMSThreadViewWindow.cpp => module-apps/application-messages/windows/SMSThreadViewWindow.cpp +0 -1
@@ 29,7 29,6 @@ namespace gui
{
AppWindow::buildInterface();
setTitle(utils::localize.get("app_messages_title_main"));
- topBar->setActive(TopBar::Elements::TIME, true);
bottomBar->setText(BottomBar::Side::LEFT, utils::localize.get(style::strings::common::options));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
M module-apps/application-music-player/windows/MusicPlayerAllSongsWindow.cpp => module-apps/application-music-player/windows/MusicPlayerAllSongsWindow.cpp +0 -2
@@ 54,8 54,6 @@ namespace gui
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get("app_music_player_play"));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
- topBar->setActive(TopBar::Elements::TIME, true);
-
songsList = new gui::ListView(this,
musicPlayerStyle::allSongsWindow::x,
musicPlayerStyle::allSongsWindow::y,
M module-apps/application-music-player/windows/MusicPlayerEmptyWindow.cpp => module-apps/application-music-player/windows/MusicPlayerEmptyWindow.cpp +0 -2
@@ 33,8 33,6 @@ namespace gui
bottomBar->setText(BottomBar::Side::LEFT, utils::localize.get("app_music_player_music_library"));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get("app_music_player_quit"));
- topBar->setActive(TopBar::Elements::TIME, true);
-
img = new gui::Image(this, noteImg::x, noteImg::y, "note");
text = new Text(this, infoText::x, infoText::y, infoText::w, infoText::h);
M module-apps/application-notes/windows/NoteEditWindow.cpp => module-apps/application-notes/windows/NoteEditWindow.cpp +0 -2
@@ 85,8 85,6 @@ namespace app::notes
bottomBar->setActive(gui::BottomBar::Side::RIGHT, true);
bottomBar->setText(gui::BottomBar::Side::RIGHT, utils::localize.get(::style::strings::common::back));
- topBar->setActive(gui::TopBar::Elements::TIME, true);
-
setFocusItem(edit);
}
M module-apps/application-notes/windows/NoteMainWindow.cpp => module-apps/application-notes/windows/NoteMainWindow.cpp +0 -1
@@ 54,7 54,6 @@ namespace app::notes
bottomBar->setText(gui::BottomBar::Side::CENTER, utils::localize.get(::style::strings::common::open));
bottomBar->setActive(gui::BottomBar::Side::RIGHT, true);
bottomBar->setText(gui::BottomBar::Side::RIGHT, utils::localize.get(::style::strings::common::back));
- topBar->setActive(gui::TopBar::Elements::TIME, true);
namespace windowStyle = app::notes::style::main_window;
leftArrowImage = new gui::Image(this,
M module-apps/application-notes/windows/NotePreviewWindow.cpp => module-apps/application-notes/windows/NotePreviewWindow.cpp +0 -2
@@ 79,8 79,6 @@ namespace app::notes
bottomBar->setActive(gui::BottomBar::Side::RIGHT, true);
bottomBar->setText(gui::BottomBar::Side::RIGHT, utils::localize.get(::style::strings::common::back));
- topBar->setActive(gui::TopBar::Elements::TIME, true);
-
setFocusItem(note);
}
M module-apps/application-phonebook/windows/PhonebookContactDetails.cpp => module-apps/application-phonebook/windows/PhonebookContactDetails.cpp +0 -1
@@ 25,7 25,6 @@ namespace gui
void PhonebookContactDetails::buildInterface()
{
AppWindow::buildInterface();
- topBar->setActive(TopBar::Elements::TIME, true);
bottomBar->setText(BottomBar::Side::LEFT, utils::localize.get(style::strings::common::options));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
M module-apps/application-phonebook/windows/PhonebookIceContacts.cpp => module-apps/application-phonebook/windows/PhonebookIceContacts.cpp +0 -1
@@ 25,7 25,6 @@ namespace gui
{
AppWindow::buildInterface();
- topBar->setActive(TopBar::Elements::TIME, true);
setTitle(utils::localize.get("app_phonebook_ice_contacts_title"));
contactsListIce = new gui::ListView(this,
M module-apps/application-phonebook/windows/PhonebookMainWindow.cpp => module-apps/application-phonebook/windows/PhonebookMainWindow.cpp +0 -1
@@ 30,7 30,6 @@ namespace gui
{
AppWindow::buildInterface();
- topBar->setActive(TopBar::Elements::TIME, true);
setTitle(utils::localize.get("app_phonebook_title_main"));
leftArrowImage = new gui::Image(this,
phonebookStyle::mainWindow::leftArrowImage::x,
M module-apps/application-phonebook/windows/PhonebookSearch.cpp => module-apps/application-phonebook/windows/PhonebookSearch.cpp +0 -1
@@ 16,7 16,6 @@ namespace gui
void PhonebookSearch::buildInterface()
{
AppWindow::buildInterface();
- topBar->setActive(TopBar::Elements::TIME, true);
setTitle(utils::localize.get("app_phonebook_title_main"));
M module-apps/application-phonebook/windows/PhonebookSearchResults.cpp => module-apps/application-phonebook/windows/PhonebookSearchResults.cpp +0 -2
@@ 40,8 40,6 @@ namespace gui
bottomBar->setActive(BottomBar::Side::RIGHT, true);
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
- topBar->setActive(TopBar::Elements::TIME, true);
-
setTitle(utils::localize.get("common_results_prefix"));
}
M module-apps/application-settings-new/ApplicationSettings.cpp => module-apps/application-settings-new/ApplicationSettings.cpp +42 -15
@@ 5,7 5,8 @@
#include "windows/AddDeviceWindow.hpp"
#include "windows/AllDevicesWindow.hpp"
-#include "windows/APNSettingsWindow.hpp"
+#include "windows/ApnSettingsWindow.hpp"
+#include "windows/ApnOptionsWindow.hpp"
#include "windows/BluetoothWindow.hpp"
#include "windows/SettingsMainWindow.hpp"
#include "windows/DisplayAndKeypadWindow.hpp"
@@ 28,6 29,7 @@
#include "windows/QuotesOptionsWindow.hpp"
#include "windows/ChangePasscodeWindow.hpp"
#include "windows/SystemMainWindow.hpp"
+#include "windows/NewApnWindow.hpp"
#include "Dialog.hpp"
@@ 37,9 39,9 @@
#include <service-bluetooth/service-bluetooth/messages/Status.hpp>
#include <service-bluetooth/messages/BondedDevices.hpp>
#include <service-bluetooth/messages/DeviceName.hpp>
-#include <application-settings-new/data/BondedDevicesData.hpp>
-#include <application-settings-new/data/PhoneNameData.hpp>
#include <service-db/agents/settings/SystemSettings.hpp>
+#include <application-settings-new/data/ApnListData.hpp>
+#include <application-settings-new/data/BondedDevicesData.hpp>
#include <application-settings-new/data/PhoneNameData.hpp>
#include <module-services/service-db/agents/settings/SystemSettings.hpp>
#include <service-db/Settings.hpp>
@@ 66,17 68,10 @@ namespace app
Store::GSM::get()->sim == selectedSim) {
selectedSimNumber = CellularServiceAPI::GetOwnNumber(this);
}
- settings->registerValueChange(settings::operators_on,
- [this](const std::string &value) { operatorOnChanged(value); });
-
- settings->registerValueChange(::settings::Cellular::volte_on,
- [this](const std::string &value) { volteChanged(value); });
}
ApplicationSettingsNew::~ApplicationSettingsNew()
{
- settings->unregisterValueChange(settings::operators_on);
- settings->unregisterValueChange(::settings::Cellular::volte_on);
}
// Invoked upon receiving data message
@@ 152,13 147,29 @@ namespace app
return sys::MessageNone{};
});
+ connect(typeid(CellularGetAPNResponse), [&](sys::Message *msg) {
+ if (gui::window::name::apn_settings == getCurrentWindow()->getName()) {
+ auto apns = dynamic_cast<CellularGetAPNResponse *>(msg);
+ if (apns != nullptr) {
+ auto apnsData = std::make_unique<gui::ApnListData>(apns->getAPNs());
+ switchWindow(gui::window::name::apn_settings, std::move(apnsData));
+ }
+ }
+ return sys::MessageNone{};
+ });
+
createUserInterface();
setActiveWindow(gui::name::window::main_window);
- settings->registerValueChange(::settings::SystemProperties::lockPassHash, [this](std::string value) {
- lockPassHash = utils::getNumericValue<unsigned int>(value);
- });
+ settings->registerValueChange(settings::operators_on,
+ [this](const std::string &value) { operatorOnChanged(value); });
+ settings->registerValueChange(::settings::Cellular::volte_on,
+ [this](const std::string &value) { volteChanged(value); });
+ settings->registerValueChange(
+ ::settings::SystemProperties::lockPassHash,
+ [this](std::string value) { lockPassHash = utils::getNumericValue<unsigned int>(value); },
+ ::settings::SettingsScope::Global);
return ret;
}
@@ 210,7 221,10 @@ namespace app
app, static_cast<ApplicationSettingsNew *>(app), static_cast<ApplicationSettingsNew *>(app));
});
windowsFactory.attach(gui::window::name::apn_settings, [](Application *app, const std::string &name) {
- return std::make_unique<gui::APNSettingsWindow>(app);
+ return std::make_unique<gui::ApnSettingsWindow>(app);
+ });
+ windowsFactory.attach(gui::window::name::apn_options, [](Application *app, const std::string &name) {
+ return std::make_unique<gui::ApnOptionsWindow>(app);
});
windowsFactory.attach(gui::window::name::messages, [](Application *app, const std::string &name) {
return std::make_unique<gui::MessagesWindow>(app);
@@ 233,9 247,18 @@ namespace app
windowsFactory.attach(gui::window::name::security, [](Application *app, const std::string &name) {
return std::make_unique<gui::SecurityMainWindow>(app);
});
+ windowsFactory.attach(gui::window::name::change_passcode, [](Application *app, const std::string &name) {
+ return std::make_unique<gui::ChangePasscodeWindow>(app);
+ });
+ windowsFactory.attach(gui::window::name::dialog_confirm, [](Application *app, const std::string &name) {
+ return std::make_unique<gui::DialogConfirm>(app, gui::window::name::dialog_confirm);
+ });
windowsFactory.attach(gui::window::name::system, [](Application *app, const std::string &name) {
return std::make_unique<gui::SystemMainWindow>(app);
});
+ windowsFactory.attach(gui::window::name::new_apn, [](Application *app, const std::string &name) {
+ return std::make_unique<gui::NewApnWindow>(app);
+ });
}
void ApplicationSettingsNew::destroyUserInterface()
@@ 258,17 281,20 @@ namespace app
void ApplicationSettingsNew::operatorOnChanged(const std::string &value)
{
+ LOG_DEBUG("[ApplicationSettingsNew::operatorOnChanged] value=%s", value.c_str());
if (!value.empty()) {
operatorsOn = utils::getNumericValue<bool>(value);
}
}
bool ApplicationSettingsNew::getOperatorsOn() const noexcept
{
+ LOG_DEBUG("[ApplicationSettingsNew::getOperatorsOn] %d", operatorsOn);
return operatorsOn;
}
void ApplicationSettingsNew::setOperatorsOn(bool value)
{
operatorsOn = value;
+ LOG_DEBUG("[ApplicationSettingsNew::setOperatorsOn] to %d", operatorsOn);
settings->setValue(settings::operators_on, std::to_string(value));
}
@@ 293,7 319,8 @@ namespace app
void ApplicationSettingsNew::setLockPassHash(unsigned int value)
{
lockPassHash = value;
- settings->setValue(::settings::SystemProperties::lockPassHash, std::to_string(value));
+ settings->setValue(
+ ::settings::SystemProperties::lockPassHash, std::to_string(value), ::settings::SettingsScope::Global);
}
auto ApplicationSettingsNew::getCurrentValues() -> settingsInterface::ScreenLightSettings::Values
M module-apps/application-settings-new/ApplicationSettings.hpp => module-apps/application-settings-new/ApplicationSettings.hpp +3 -0
@@ 17,6 17,7 @@ namespace gui::window::name
inline constexpr auto network = "Network";
inline constexpr auto apn_settings = "APNSettings";
+ inline constexpr auto apn_options = "APNOptions";
inline constexpr auto phone_modes = "PhoneModes";
inline constexpr auto apps_and_tools = "AppsAndTools";
inline constexpr auto security = "Security";
@@ 55,6 56,8 @@ namespace gui::window::name
inline constexpr auto about_your_pure = "AboutYourPure";
inline constexpr auto certification = "Certification";
+ inline constexpr auto new_apn = "NewApn";
+
} // namespace gui::window::name
namespace app
M module-apps/application-settings-new/CMakeLists.txt => module-apps/application-settings-new/CMakeLists.txt +10 -1
@@ 15,13 15,17 @@ target_sources( ${PROJECT_NAME}
PRIVATE
ApplicationSettings.cpp
+ models/ApnSettingsModel.cpp
+ models/NewApnModel.cpp
widgets/timeWidget.cpp
widgets/ChangePasscodeLockHandler.cpp
widgets/QuoteWidget.cpp
+ widgets/ApnInputWidget.cpp
windows/SettingsMainWindow.cpp
windows/AddDeviceWindow.cpp
windows/AllDevicesWindow.cpp
- windows/APNSettingsWindow.cpp
+ windows/ApnSettingsWindow.cpp
+ windows/ApnOptionsWindow.cpp
windows/BaseSettingsWindow.cpp
windows/BluetoothWindow.cpp
windows/FontSizeWindow.cpp
@@ 42,12 46,16 @@ target_sources( ${PROJECT_NAME}
windows/QuotesAddWindow.cpp
windows/SecurityMainWindow.cpp
windows/ChangePasscodeWindow.cpp
+ windows/NewApnWindow.cpp
widgets/SpinBox.cpp
widgets/SpinBoxOptionSetting.cpp
windows/SystemMainWindow.cpp
PUBLIC
ApplicationSettings.hpp
+ widgets/ChangePasscodeLockHandler.hpp
+ widgets/ApnInputWidget.hpp
+ windows/NewApnWindow.hpp
windows/SettingsMainWindow.hpp
windows/BaseSettingsWindow.hpp
windows/FontSizeWindow.hpp
@@ 61,6 69,7 @@ target_sources( ${PROJECT_NAME}
widgets/SettingsStyle.hpp
windows/AutolockWindow.hpp
windows/WallpaperWindow.hpp
+ windows/ChangePasscodeWindow.hpp
windows/SystemMainWindow.hpp
)
A module-apps/application-settings-new/data/ApnListData.hpp => module-apps/application-settings-new/data/ApnListData.hpp +27 -0
@@ 0,0 1,27 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <service-cellular/PacketDataTypes.hpp>
+#include <SwitchData.hpp>
+
+#include <vector>
+
+namespace gui
+{
+
+ class ApnListData : public SwitchData
+ {
+ public:
+ explicit ApnListData(std::vector<std::shared_ptr<packet_data::APN::Config>> apns) : apns(std::move(apns))
+ {}
+ [[nodiscard]] auto getAPNs() const noexcept -> const std::vector<std::shared_ptr<packet_data::APN::Config>> &
+ {
+ return apns;
+ }
+
+ private:
+ std::vector<std::shared_ptr<packet_data::APN::Config>> apns;
+ };
+} // namespace gui
M module-apps/application-settings-new/data/QuoteSwitchData.hpp => module-apps/application-settings-new/data/QuoteSwitchData.hpp +2 -2
@@ 3,9 3,9 @@
#pragma once
-#include "application-settings-new/model/QuotesModel.hpp"
+#include "application-settings-new/models/QuotesModel.hpp"
-#include <module-gui/gui/SwitchData.hpp>
+#include <SwitchData.hpp>
#include <json/json11.hpp>
#include <utility>
A module-apps/application-settings-new/data/SettingsInternals.hpp => module-apps/application-settings-new/data/SettingsInternals.hpp +30 -0
@@ 0,0 1,30 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <cstdint>
+
+namespace settingsInternals
+{
+ enum class ListItemName
+ {
+ Name,
+ APN,
+ Proxy,
+ Port,
+ Username,
+ Password,
+
+ Server,
+ MMSC,
+ MmsProxy,
+ MmsPort,
+ MCC,
+ MNC,
+ AuthType,
+ ApnType,
+ ApnProtocol
+ };
+
+} // namespace settingsInternals
A module-apps/application-settings-new/data/SettingsItemData.hpp => module-apps/application-settings-new/data/SettingsItemData.hpp +23 -0
@@ 0,0 1,23 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <service-cellular/service-cellular/PacketDataTypes.hpp>
+#include <ListItem.hpp>
+#include <SwitchData.hpp>
+
+class ApnItemData : public gui::SwitchData
+{
+ public:
+ ApnItemData(std::shared_ptr<packet_data::APN::Config> Apn) : apn(std::move(Apn)){};
+ ApnItemData() : apn(nullptr){};
+
+ auto getApn() -> std::shared_ptr<packet_data::APN::Config>
+ {
+ return apn;
+ }
+
+ private:
+ std::shared_ptr<packet_data::APN::Config> apn;
+};
A module-apps/application-settings-new/models/ApnSettingsModel.cpp => module-apps/application-settings-new/models/ApnSettingsModel.cpp +28 -0
@@ 0,0 1,28 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "ApnSettingsModel.hpp"
+#include <service-cellular/PacketDataCellularMessage.hpp>
+#include <service-cellular/ServiceCellular.hpp>
+
+ApnSettingsModel::ApnSettingsModel(app::Application *application) : application{application}
+{}
+
+void ApnSettingsModel::requestAPNList()
+{
+ sys::Bus::SendUnicast(std::make_shared<CellularGetAPNMessage>(), ServiceCellular::serviceName, application);
+}
+
+void ApnSettingsModel::saveAPN(std::shared_ptr<packet_data::APN::Config> apn)
+{
+ sys::Bus::SendUnicast(std::make_shared<CellularSetAPNMessage>(apn), ServiceCellular::serviceName, application);
+}
+
+void ApnSettingsModel::removeAPN(std::shared_ptr<packet_data::APN::Config> apn)
+{}
+
+void ApnSettingsModel::setAsDefaultAPN(std::shared_ptr<packet_data::APN::Config> apn)
+{
+ apn->apnType = packet_data::APN::APNType::Default;
+ sys::Bus::SendUnicast(std::make_shared<CellularSetAPNMessage>(apn), ServiceCellular::serviceName, application);
+}
A module-apps/application-settings-new/models/ApnSettingsModel.hpp => module-apps/application-settings-new/models/ApnSettingsModel.hpp +21 -0
@@ 0,0 1,21 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <service-cellular/PacketDataTypes.hpp>
+#include <module-apps/Application.hpp>
+
+class ApnSettingsModel
+{
+ public:
+ ApnSettingsModel(app::Application *application);
+
+ void requestAPNList();
+ void saveAPN(std::shared_ptr<packet_data::APN::Config> apn);
+ void removeAPN(std::shared_ptr<packet_data::APN::Config> apn);
+ void setAsDefaultAPN(std::shared_ptr<packet_data::APN::Config> apn);
+
+ private:
+ app::Application *application = nullptr;
+};
A module-apps/application-settings-new/models/NewApnModel.cpp => module-apps/application-settings-new/models/NewApnModel.cpp +133 -0
@@ 0,0 1,133 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "NewApnModel.hpp"
+
+#include "application-settings-new/widgets/ApnInputWidget.hpp"
+
+#include <ListView.hpp>
+#include <time/ScopedTime.hpp>
+#include <BottomBar.hpp>
+
+NewApnModel::NewApnModel(app::Application *app) : application(app)
+{}
+
+auto NewApnModel::requestRecordsCount() -> unsigned int
+{
+ return internalData.size();
+}
+
+auto NewApnModel::getMinimalItemHeight() const -> unsigned int
+{
+ return style::settings::widget::apnInputWidget::h;
+}
+
+void NewApnModel::requestRecords(const uint32_t offset, const uint32_t limit)
+{
+ setupModel(offset, limit);
+ list->onProviderDataUpdate();
+}
+
+auto NewApnModel::getItem(gui::Order order) -> gui::ListItem *
+{
+ return getRecord(order);
+}
+
+void NewApnModel::createData()
+{
+ auto app = application;
+
+ internalData.emplace_back(new gui::ApnInputWidget(
+ settingsInternals::ListItemName::Name,
+ [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text); },
+ [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); },
+ [app]() { app->getCurrentWindow()->selectSpecialCharacter(); },
+ [this]() { this->apnDataChanged(); }));
+
+ internalData.emplace_back(new gui::ApnInputWidget(
+ settingsInternals::ListItemName::APN,
+ [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text); },
+ [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); },
+ [app]() { app->getCurrentWindow()->selectSpecialCharacter(); },
+ [this]() { this->apnDataChanged(); }));
+
+ internalData.emplace_back(new gui::ApnInputWidget(
+ settingsInternals::ListItemName::Username,
+ [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text); },
+ [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); },
+ [app]() { app->getCurrentWindow()->selectSpecialCharacter(); },
+ [this]() { this->apnDataChanged(); }));
+
+ internalData.emplace_back(new gui::ApnInputWidget(
+ settingsInternals::ListItemName::Password,
+ [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text); },
+ [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); },
+ [app]() { app->getCurrentWindow()->selectSpecialCharacter(); },
+ [this]() { this->apnDataChanged(); }));
+
+ internalData.emplace_back(new gui::ApnInputWidget(
+ settingsInternals::ListItemName::AuthType,
+ [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text); },
+ [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); },
+ [app]() { app->getCurrentWindow()->selectSpecialCharacter(); },
+ [this]() { this->apnDataChanged(); }));
+
+ internalData.emplace_back(new gui::ApnInputWidget(
+ settingsInternals::ListItemName::ApnType,
+ [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text); },
+ [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); },
+ [app]() { app->getCurrentWindow()->selectSpecialCharacter(); },
+ [this]() { this->apnDataChanged(); }));
+
+ internalData.emplace_back(new gui::ApnInputWidget(
+ settingsInternals::ListItemName::ApnProtocol,
+ [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text); },
+ [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); },
+ [app]() { app->getCurrentWindow()->selectSpecialCharacter(); },
+ [this]() { this->apnDataChanged(); }));
+
+ for (auto item : internalData) {
+ item->deleteByList = false;
+ }
+}
+
+void NewApnModel::clearData()
+{
+ list->clear();
+
+ eraseInternalData();
+
+ createData();
+
+ list->rebuildList();
+}
+
+void NewApnModel::saveData(std::shared_ptr<packet_data::APN::Config> apnRecord)
+{
+ for (auto item : internalData) {
+ if (item->onSaveCallback) {
+ item->onSaveCallback(apnRecord);
+ }
+ }
+}
+
+void NewApnModel::loadData(std::shared_ptr<packet_data::APN::Config> apnRecord)
+{
+ for (auto item : internalData) {
+ if (item->onLoadCallback) {
+ item->onLoadCallback(apnRecord);
+ }
+ }
+}
+
+void NewApnModel::apnDataChanged()
+{
+ for (auto item : internalData) {
+ if (item->onEmptyCallback && !item->onEmptyCallback()) {
+ application->getCurrentWindow()->setBottomBarActive(gui::BottomBar::Side::CENTER, true); // SAVE button
+ return;
+ }
+ }
+ application->getCurrentWindow()->setBottomBarActive(gui::BottomBar::Side::CENTER, false); // SAVE button
+ return;
+}
A module-apps/application-settings-new/models/NewApnModel.hpp => module-apps/application-settings-new/models/NewApnModel.hpp +35 -0
@@ 0,0 1,35 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "application-settings-new/data/SettingsItemData.hpp"
+#include "application-settings-new/widgets/ApnListItem.hpp"
+#include "application-settings-new/widgets/SettingsStyle.hpp"
+#include "InternalModel.hpp"
+#include "Application.hpp"
+
+#include <ListItemProvider.hpp>
+
+class NewApnModel : public app::InternalModel<gui::ApnListItem *>, public gui::ListItemProvider
+{
+ app::Application *application = nullptr;
+
+ public:
+ NewApnModel(app::Application *app);
+
+ void clearData();
+ void saveData(std::shared_ptr<packet_data::APN::Config> apnRecord);
+ void loadData(std::shared_ptr<packet_data::APN::Config> apnRecord);
+
+ void createData();
+
+ [[nodiscard]] auto requestRecordsCount() -> unsigned int override;
+
+ [[nodiscard]] auto getMinimalItemHeight() const -> unsigned int override;
+
+ auto getItem(gui::Order order) -> gui::ListItem * override;
+
+ void requestRecords(const uint32_t offset, const uint32_t limit) override;
+ void apnDataChanged();
+};
R module-apps/application-settings-new/model/QuotesModel.cpp => module-apps/application-settings-new/models/QuotesModel.cpp +2 -3
@@ 3,9 3,8 @@
#include "application-settings-new/windows/QuotesMainWindow.hpp"
#include "application-settings-new/ApplicationSettings.hpp"
-#include "application-settings-new/model/QuotesRepository.hpp"
-#include "application-settings-new/model/QuotesModel.hpp"
-#include "application-settings-new/model/QuotesModel.hpp"
+#include "QuotesRepository.hpp"
+#include "QuotesModel.hpp"
#include <InputEvent.hpp>
#include <i18n/i18n.hpp>
R module-apps/application-settings-new/model/QuotesModel.hpp => module-apps/application-settings-new/models/QuotesModel.hpp +0 -0
R module-apps/application-settings-new/model/QuotesRepository.cpp => module-apps/application-settings-new/models/QuotesRepository.cpp +0 -3
@@ 1,9 1,6 @@
// Copyright (c) 2017-2021, 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 "QuotesRepository.hpp"
#include <module-utils/gsl/gsl_util>
R module-apps/application-settings-new/model/QuotesRepository.hpp => module-apps/application-settings-new/models/QuotesRepository.hpp +0 -0
A module-apps/application-settings-new/widgets/ApnInputWidget.cpp => module-apps/application-settings-new/widgets/ApnInputWidget.cpp +221 -0
@@ 0,0 1,221 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "ApnInputWidget.hpp"
+#include <Span.hpp>
+#include "application-settings-new/widgets/SettingsStyle.hpp"
+#include <i18n/i18n.hpp>
+#include <utility>
+
+namespace gui
+{
+ ApnInputWidget::ApnInputWidget(settingsInternals::ListItemName listItemName,
+ std::function<void(const UTF8 &)> bottomBarTemporaryMode,
+ std::function<void()> bottomBarRestoreFromTemporaryMode,
+ std::function<void()> selectSpecialCharacter,
+ std::function<void()> contentChanged,
+ unsigned int lines)
+ : listItemName(listItemName), checkTextContent(std::move(contentChanged))
+ {
+
+ setMinimumSize(style::settings::widget::apnInputWidget::w,
+ style::settings::widget::apnInputWidget::title_label_h +
+ style::settings::widget::apnInputWidget::span_size +
+ style::settings::widget::apnInputWidget::input_text_h * lines);
+
+ setMargins(gui::Margins(0, style::margins::huge, 0, 0));
+
+ vBox = new VBox(this, 0, 0, 0, 0);
+ vBox->setEdges(RectangleEdge::None);
+
+ titleLabel = new Label(vBox);
+ titleLabel->setMinimumSize(style::settings::widget::apnInputWidget::w,
+ style::settings::widget::apnInputWidget::title_label_h);
+ titleLabel->setEdges(RectangleEdge::None);
+ titleLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Top));
+ titleLabel->setFont(style::window::font::verysmall);
+ titleLabel->activeItem = false;
+
+ inputText = new TextFixedSize(vBox, 0, 0, 0, 0);
+ inputText->setMinimumSize(style::settings::widget::apnInputWidget::w,
+ style::settings::widget::apnInputWidget::input_text_h * lines);
+ inputText->setMargins(Margins(0, style::settings::widget::apnInputWidget::span_size, 0, 0));
+ inputText->setUnderlinePadding(style::settings::widget::apnInputWidget::underline_padding);
+
+ inputText->setEdges(RectangleEdge::None);
+ inputText->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Top));
+ inputText->setFont(style::window::font::medium);
+ inputText->setInputMode(new InputMode(
+ {InputMode::ABC, InputMode::abc, InputMode::digit},
+ [=](const UTF8 &text) { bottomBarTemporaryMode(text); },
+ [=]() { bottomBarRestoreFromTemporaryMode(); },
+ [=]() { selectSpecialCharacter(); }));
+ inputText->setPenFocusWidth(style::window::default_border_focus_w);
+ inputText->setPenWidth(style::window::default_border_no_focus_w);
+ inputText->setEditMode(EditMode::Edit);
+
+ applyItemNameSpecificSettings();
+
+ focusChangedCallback = [&](Item &item) {
+ setFocusItem(focus ? vBox : nullptr);
+
+ auto tempText = inputText->getText();
+
+ if (focus) {
+ inputText->setFont(style::window::font::mediumbold);
+ inputText->setText(tempText);
+ }
+ else {
+ inputText->setFont(style::window::font::medium);
+ inputText->setText(tempText);
+ }
+ return true;
+ };
+
+ inputCallback = [&](Item &item, const InputEvent &event) {
+ auto result = inputText->onInput(event);
+ if (checkTextContent != nullptr) {
+ checkTextContent();
+ }
+ return result;
+ };
+ setEdges(RectangleEdge::None);
+ }
+
+ auto ApnInputWidget::onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) -> bool
+ {
+ vBox->setPosition(0, 0);
+ vBox->setSize(newDim.w, newDim.h);
+
+ return true;
+ }
+
+ void ApnInputWidget::applyItemNameSpecificSettings()
+ {
+ switch (listItemName) {
+
+ case settingsInternals::ListItemName::Name:
+ nameHandler();
+ break;
+
+ case settingsInternals::ListItemName::APN:
+ apnHandler();
+ break;
+
+ case settingsInternals::ListItemName::Username:
+ usernameHandler();
+ break;
+
+ case settingsInternals::ListItemName::Password:
+ passwordNumberHandler();
+ break;
+
+ case settingsInternals::ListItemName::AuthType:
+ authtypeHandler();
+ break;
+
+ case settingsInternals::ListItemName::ApnType:
+ apntypeHandler();
+ break;
+
+ case settingsInternals::ListItemName::ApnProtocol:
+ protocolHandler();
+ break;
+
+ default:
+ LOG_ERROR("Incorrect List Item Name!");
+ break;
+ }
+ }
+
+ void ApnInputWidget::nameHandler()
+ {
+ titleLabel->setText(utils::localize.get("app_settings_apn_name"));
+ inputText->setTextType(TextType::SingleLine);
+ onSaveCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ apnRecord->apn = inputText->getText();
+ };
+ onLoadCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ inputText->setText(apnRecord->apn);
+ };
+ onEmptyCallback = [&]() { return inputText->isEmpty(); };
+ }
+
+ void ApnInputWidget::apnHandler()
+ {
+ titleLabel->setText(utils::localize.get("app_settings_apn_APN"));
+ inputText->setTextType(TextType::SingleLine);
+ onSaveCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ apnRecord->ip = inputText->getText();
+ };
+ onLoadCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ inputText->setText(apnRecord->ip);
+ };
+ onEmptyCallback = [&]() { return inputText->isEmpty(); };
+ }
+
+ void ApnInputWidget::usernameHandler()
+ {
+ titleLabel->setText(utils::localize.get("app_settings_apn_username"));
+ inputText->setTextType(TextType::SingleLine);
+ onSaveCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ apnRecord->username = inputText->getText();
+ };
+ onLoadCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ inputText->setText(apnRecord->username);
+ };
+ onEmptyCallback = [&]() { return inputText->isEmpty(); };
+ }
+
+ void ApnInputWidget::passwordNumberHandler()
+ {
+ titleLabel->setText(utils::localize.get("app_settings_apn_password"));
+ inputText->setTextType(TextType::SingleLine);
+ onSaveCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ apnRecord->password = inputText->getText();
+ };
+ onLoadCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ inputText->setText(apnRecord->password);
+ };
+ onEmptyCallback = [&]() { return inputText->isEmpty(); };
+ }
+
+ void ApnInputWidget::authtypeHandler()
+ {
+ titleLabel->setText(utils::localize.get("app_settings_apn_authtype"));
+ inputText->setTextType(TextType::SingleLine);
+ onSaveCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ apnRecord->setAuthMethod(inputText->getText());
+ };
+ onLoadCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ inputText->setText(apnRecord->getAuthMethod());
+ };
+ onEmptyCallback = [&]() { return inputText->isEmpty(); };
+ }
+
+ void ApnInputWidget::apntypeHandler()
+ {
+ titleLabel->setText(utils::localize.get("app_settings_apn_apntype"));
+ inputText->setTextType(TextType::SingleLine);
+ onSaveCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ apnRecord->setApnType(inputText->getText());
+ };
+ onLoadCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ inputText->setText(apnRecord->getApnType());
+ };
+ onEmptyCallback = [&]() { return inputText->isEmpty(); };
+ }
+ void ApnInputWidget::protocolHandler()
+ {
+ titleLabel->setText(utils::localize.get("app_settings_apn_apnprotocol"));
+ inputText->setTextType(TextType::SingleLine);
+ onSaveCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ apnRecord->setApnProtocol(inputText->getText());
+ };
+ onLoadCallback = [&](std::shared_ptr<packet_data::APN::Config> apnRecord) {
+ inputText->setText(apnRecord->getApnProtocol());
+ };
+ onEmptyCallback = [&]() { return inputText->isEmpty(); };
+ }
+
+} /* namespace gui */
A module-apps/application-settings-new/widgets/ApnInputWidget.hpp => module-apps/application-settings-new/widgets/ApnInputWidget.hpp +44 -0
@@ 0,0 1,44 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "application-settings-new/data/SettingsInternals.hpp"
+#include "application-settings-new//widgets/ApnListItem.hpp"
+
+#include <ListItem.hpp>
+#include <Text.hpp>
+#include <TextFixedSize.hpp>
+
+namespace gui
+{
+ class ApnInputWidget : public ApnListItem
+ {
+ settingsInternals::ListItemName listItemName;
+
+ public:
+ ApnInputWidget(settingsInternals::ListItemName listItemName,
+ std::function<void(const UTF8 &text)> bottomBarTemporaryMode = nullptr,
+ std::function<void()> bottomBarRestoreFromTemporaryMode = nullptr,
+ std::function<void()> selectSpecialCharacter = nullptr,
+ std::function<void()> contentChanged = nullptr,
+ unsigned int lines = 1);
+
+ private:
+ VBox *vBox = nullptr;
+ Label *titleLabel = nullptr;
+ TextFixedSize *inputText = nullptr;
+ std::function<void()> checkTextContent = nullptr;
+
+ void applyItemNameSpecificSettings();
+ auto onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) -> bool override;
+ void nameHandler();
+ void apnHandler();
+ void usernameHandler();
+ void passwordNumberHandler();
+ void authtypeHandler();
+ void apntypeHandler();
+ void protocolHandler();
+ };
+
+} /* namespace gui */
A module-apps/application-settings-new/widgets/ApnListItem.hpp => module-apps/application-settings-new/widgets/ApnListItem.hpp +18 -0
@@ 0,0 1,18 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "application-settings-new/data/SettingsItemData.hpp"
+
+namespace gui
+{
+ class ApnListItem : public ListItem
+ {
+ public:
+ std::function<void(std::shared_ptr<packet_data::APN::Config> apnRecord)> onSaveCallback = nullptr;
+ std::function<void(std::shared_ptr<packet_data::APN::Config> apnRecord)> onLoadCallback = nullptr;
+ std::function<bool()> onEmptyCallback = nullptr;
+ };
+
+} /* namespace gui */
M module-apps/application-settings-new/widgets/SettingsStyle.hpp => module-apps/application-settings-new/widgets/SettingsStyle.hpp +20 -0
@@ 28,7 28,18 @@ namespace style
inline constexpr auto before_noon = "AM";
inline constexpr auto after_noon = "PM";
} // namespace time
+
+ namespace apnInputWidget
+ {
+ inline constexpr uint32_t w = style::window::default_body_width;
+ inline constexpr uint32_t h = 63;
+ inline constexpr uint32_t title_label_h = 20;
+ inline constexpr uint32_t input_text_h = 37;
+ inline constexpr uint32_t span_size = 6;
+ inline constexpr int32_t underline_padding = 4;
+ } // namespace apnInputWidget
} // namespace widget
+
namespace window
{
namespace leftArrowImage
@@ 70,6 81,15 @@ namespace style
inline constexpr auto separator_h = 55;
} // namespace nightshift
+
+ namespace newApn
+ {
+ inline constexpr uint32_t x = style::window::default_left_margin;
+ inline constexpr uint32_t y = style::header::height;
+ inline constexpr uint32_t w = style::listview::body_width_with_scroll;
+ inline constexpr uint32_t h = style::window_height - y - style::footer::height;
+ } // namespace newApn
+
} // namespace window
}; // namespace settings
} // namespace style
D module-apps/application-settings-new/windows/APNSettingsWindow.cpp => module-apps/application-settings-new/windows/APNSettingsWindow.cpp +0 -61
@@ 1,61 0,0 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#include "APNSettingsWindow.hpp"
-#include "application-settings-new/ApplicationSettings.hpp"
-#include "application-settings-new/widgets/SettingsStyle.hpp"
-#include "OptionSetting.hpp"
-
-#include <InputEvent.hpp>
-
-namespace gui
-{
-
- APNSettingsWindow::APNSettingsWindow(app::Application *app) : OptionWindow(app, gui::window::name::apn_settings)
- {
- buildInterface();
- }
-
- auto APNSettingsWindow::onInput(const InputEvent &inputEvent) -> bool
- {
-
- if (inputEvent.isShortPress()) {
- if (inputEvent.is(KeyCode::KEY_LEFT)) {
- // switch to new/edit APN window
- }
- }
-
- return AppWindow::onInput(inputEvent);
- }
- void APNSettingsWindow::buildInterface()
- {
- setTitle(utils::localize.get("app_settings_network_apn_settings"));
-
- topBar->setActive(TopBar::Elements::SIGNAL, false);
- topBar->setActive(TopBar::Elements::BATTERY, false);
- topBar->setActive(TopBar::Elements::SIM, false);
-
- leftArrowImage = new gui::Image(this,
- style::settings::window::leftArrowImage::x,
- style::settings::window::leftArrowImage::y,
- style::settings::window::leftArrowImage::w,
- style::settings::window::leftArrowImage::h,
- "arrow_left");
- crossImage = new gui::Image(this,
- style::settings::window::crossImage::x,
- style::settings::window::crossImage::y,
- style::settings::window::crossImage::w,
- style::settings::window::crossImage::h,
- "cross");
- emptyListIcon = new Icon(this,
- 0,
- style::header::height,
- style::window_width,
- style::window_height - style::header::height - style::footer::height,
- "phonebook_empty_grey_circle_W_G",
- utils::localize.get("app_settings_network_apn_settings_no_apns"));
-
- bottomBar->setActive(gui::BottomBar::Side::CENTER, false);
- }
-
-} // namespace gui
M module-apps/application-settings-new/windows/AllDevicesWindow.cpp => module-apps/application-settings-new/windows/AllDevicesWindow.cpp +0 -4
@@ 71,10 71,6 @@ namespace gui
gui::option::SettingRightItem::Bt));
}
- topBar->setActive(TopBar::Elements::SIGNAL, false);
- topBar->setActive(TopBar::Elements::BATTERY, false);
- topBar->setActive(TopBar::Elements::SIM, false);
-
leftArrowImage = new gui::Image(this,
style::settings::window::leftArrowImage::x,
style::settings::window::leftArrowImage::y,
A module-apps/application-settings-new/windows/ApnOptionsWindow.cpp => module-apps/application-settings-new/windows/ApnOptionsWindow.cpp +73 -0
@@ 0,0 1,73 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "ApnOptionsWindow.hpp"
+
+#include "application-settings-new/ApplicationSettings.hpp"
+#include "application-settings-new/data/SettingsItemData.hpp"
+#include "application-settings-new/models/ApnSettingsModel.hpp"
+#include "OptionSetting.hpp"
+
+namespace gui
+{
+ ApnOptionsWindow::ApnOptionsWindow(app::Application *app) : BaseSettingsWindow(app, window::name::apn_options)
+ {
+ setTitle(utils::localize.get("app_settings_apn_options"));
+ apnSettingsModel = new ApnSettingsModel(application);
+ }
+
+ auto ApnOptionsWindow::buildOptionsList() -> std::list<gui::Option>
+ {
+ std::list<gui::Option> optionsList;
+
+ optionsList.emplace_back(std::make_unique<gui::option::OptionSettings>(
+ utils::localize.get("app_settings_apn_options_edit"),
+ [=](gui::Item &item) {
+ std::unique_ptr<gui::SwitchData> data = std::make_unique<ApnItemData>(apn);
+ application->switchWindow(gui::window::name::new_apn, gui::ShowMode::GUI_SHOW_INIT, std::move(data));
+ return true;
+ },
+ nullptr,
+ this));
+
+ optionsList.emplace_back(std::make_unique<gui::option::OptionSettings>(
+ utils::localize.get("app_settings_apn_options_delete"),
+ [=](gui::Item &item) {
+ apnSettingsModel->removeAPN(apn);
+ return true;
+ },
+ nullptr,
+ this));
+
+ optionsList.emplace_back(std::make_unique<gui::option::OptionSettings>(
+ utils::localize.get("app_settings_apn_options_set_as_default"),
+ [=](gui::Item &item) {
+ apnSettingsModel->setAsDefaultAPN(apn);
+ return true;
+ },
+ nullptr,
+ this));
+
+ return optionsList;
+ }
+
+ auto ApnOptionsWindow::handleSwitchData(SwitchData *data) -> bool
+ {
+ if (data == nullptr) {
+ return false;
+ }
+
+ auto item = dynamic_cast<ApnItemData *>(data);
+ if (item == nullptr) {
+ return false;
+ }
+
+ apn = item->getApn();
+ if (apn == nullptr) {
+ apn = std::make_shared<packet_data::APN::Config>();
+ return true;
+ }
+
+ return true;
+ }
+} // namespace gui
A module-apps/application-settings-new/windows/ApnOptionsWindow.hpp => module-apps/application-settings-new/windows/ApnOptionsWindow.hpp +25 -0
@@ 0,0 1,25 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "application-settings-new/models/ApnSettingsModel.hpp"
+#include "BaseSettingsWindow.hpp"
+
+#include <service-cellular/PacketDataTypes.hpp>
+
+namespace gui
+{
+
+ class ApnOptionsWindow : public BaseSettingsWindow
+ {
+ public:
+ ApnOptionsWindow(app::Application *app);
+
+ private:
+ auto buildOptionsList() -> std::list<gui::Option> override;
+ auto handleSwitchData(SwitchData *data) -> bool override;
+ std::shared_ptr<packet_data::APN::Config> apn;
+ ApnSettingsModel *apnSettingsModel = nullptr;
+ };
+} // namespace gui
A module-apps/application-settings-new/windows/ApnSettingsWindow.cpp => module-apps/application-settings-new/windows/ApnSettingsWindow.cpp +135 -0
@@ 0,0 1,135 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "ApnSettingsWindow.hpp"
+#include "application-settings-new/ApplicationSettings.hpp"
+#include "application-settings-new/data/ApnListData.hpp"
+#include "application-settings-new/models/ApnSettingsModel.hpp"
+#include "application-settings-new/widgets/SettingsStyle.hpp"
+#include "application-settings-new/data/SettingsItemData.hpp"
+#include "OptionSetting.hpp"
+
+#include <InputEvent.hpp>
+
+namespace gui
+{
+
+ ApnSettingsWindow::ApnSettingsWindow(app::Application *app) : OptionWindow(app, gui::window::name::apn_settings)
+ {
+ buildInterface();
+ }
+
+ void ApnSettingsWindow::buildInterface()
+ {
+ setTitle(utils::localize.get("app_settings_network_apn_settings"));
+
+ leftArrowImage = new gui::Image(this,
+ style::settings::window::leftArrowImage::x,
+ style::settings::window::leftArrowImage::y,
+ style::settings::window::leftArrowImage::w,
+ style::settings::window::leftArrowImage::h,
+ "arrow_left");
+ crossImage = new gui::Image(this,
+ style::settings::window::crossImage::x,
+ style::settings::window::crossImage::y,
+ style::settings::window::crossImage::w,
+ style::settings::window::crossImage::h,
+ "cross");
+ emptyListIcon = new Icon(this,
+ 0,
+ style::header::height,
+ style::window_width,
+ style::window_height - style::header::height - style::footer::height,
+ "phonebook_empty_grey_circle_W_G",
+ utils::localize.get("app_settings_apn_settings_no_apns"));
+
+ bottomBar->setText(BottomBar::Side::LEFT, utils::localize.get(style::strings::common::options));
+
+ auto apnSettingsModel = new ApnSettingsModel(application);
+ apnSettingsModel->requestAPNList();
+ }
+ auto ApnSettingsWindow::handleSwitchData(SwitchData *data) -> bool
+ {
+ if (data == nullptr) {
+ LOG_ERROR("Received nullptr");
+ return false;
+ }
+
+ const auto newData = dynamic_cast<ApnListData *>(data);
+ if (newData == nullptr) {
+ LOG_ERROR("Received nullptr");
+ return false;
+ }
+
+ apns = newData->getAPNs();
+ if (apns.empty()) {
+ emptyListIcon->setVisible(true);
+ return false;
+ }
+
+ return true;
+ }
+
+ void ApnSettingsWindow::onBeforeShow(ShowMode mode, SwitchData *data)
+ {
+ clearOptions();
+ bottomBar->setActive(gui::BottomBar::Side::LEFT, false);
+ bottomBar->setActive(gui::BottomBar::Side::CENTER, false);
+ emptyListIcon->setVisible(false);
+
+ if (apns.empty()) {
+ return;
+ }
+
+ addOptions(optionsList(apns));
+ bottomBar->setActive(gui::BottomBar::Side::LEFT, true);
+ bottomBar->setActive(gui::BottomBar::Side::CENTER, true);
+ }
+
+ auto ApnSettingsWindow::onInput(const InputEvent &inputEvent) -> bool
+ {
+ if (AppWindow::onInput(inputEvent)) {
+ return true;
+ }
+ if (!inputEvent.isShortPress()) {
+ return false;
+ }
+ if (inputEvent.is(gui::KeyCode::KEY_LEFT)) {
+ auto apnRecord = std::make_shared<packet_data::APN::Config>();
+ std::unique_ptr<gui::SwitchData> data = std::make_unique<ApnItemData>(apnRecord);
+ application->switchWindow(gui::window::name::new_apn, gui::ShowMode::GUI_SHOW_INIT, std::move(data));
+ return true;
+ }
+ if (inputEvent.is(gui::KeyCode::KEY_LF)) {
+ auto apnRecord = std::make_shared<packet_data::APN::Config>();
+ std::unique_ptr<gui::SwitchData> data = std::make_unique<ApnItemData>(apnRecord);
+ application->switchWindow(gui::window::name::apn_options, gui::ShowMode::GUI_SHOW_INIT, std::move(data));
+ return true;
+ }
+
+ return false;
+ }
+
+ auto ApnSettingsWindow::optionsList(std::vector<std::shared_ptr<packet_data::APN::Config>> apnsList)
+ -> std::list<Option>
+ {
+ std::list<gui::Option> optionsList;
+
+ for (const auto &apn : apnsList) {
+ optionsList.emplace_back(std::make_unique<gui::option::OptionSettings>(
+ (apn->apnType == packet_data::APN::APNType::Default) ? "<b>" + apn->apn + "</b>" : apn->apn,
+ [=](gui::Item &item) {
+ LOG_DEBUG("APN: %s", apn->apn.c_str());
+ std::unique_ptr<gui::SwitchData> apnData = std::make_unique<ApnItemData>(apn);
+ application->switchWindow(
+ gui::window::name::new_apn, gui::ShowMode::GUI_SHOW_INIT, std::move(apnData));
+ return true;
+ },
+ nullptr,
+ nullptr));
+ }
+
+ return optionsList;
+ }
+
+} // namespace gui
R module-apps/application-settings-new/windows/APNSettingsWindow.hpp => module-apps/application-settings-new/windows/ApnSettingsWindow.hpp +7 -2
@@ 5,20 5,25 @@
#include "OptionWindow.hpp"
#include <Icon.hpp>
+#include <service-cellular/PacketDataTypes.hpp>
namespace gui
{
- class APNSettingsWindow : public OptionWindow
+ class ApnSettingsWindow : public OptionWindow
{
public:
- APNSettingsWindow(app::Application *app);
+ ApnSettingsWindow(app::Application *app);
private:
void buildInterface() override;
+ auto handleSwitchData(SwitchData *data) -> bool override;
+ void onBeforeShow(ShowMode mode, SwitchData *data) override;
auto onInput(const InputEvent &inputEvent) -> bool override;
+ auto optionsList(std::vector<std::shared_ptr<packet_data::APN::Config>> vector) -> std::list<Option>;
Image *leftArrowImage = nullptr;
Image *crossImage = nullptr;
Icon *emptyListIcon = nullptr;
+ std::vector<std::shared_ptr<packet_data::APN::Config>> apns;
};
}; // namespace gui
M module-apps/application-settings-new/windows/AppsAndToolsWindow.cpp => module-apps/application-settings-new/windows/AppsAndToolsWindow.cpp +0 -4
@@ 33,10 33,6 @@ namespace gui
gui::option::Arrow::Enabled});
};
- topBar->setActive(TopBar::Elements::SIGNAL, false);
- topBar->setActive(TopBar::Elements::BATTERY, false);
- topBar->setActive(TopBar::Elements::SIM, false);
-
addMenu(i18("app_settings_apps_messages"), gui::window::name::messages);
addMenu(i18("app_settings_apps_torch"), gui::window::name::torch);
M module-apps/application-settings-new/windows/BaseSettingsWindow.cpp => module-apps/application-settings-new/windows/BaseSettingsWindow.cpp +0 -3
@@ 16,9 16,6 @@ namespace gui
bottomBar->setActive(BottomBar::Side::RIGHT, true);
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
- topBar->setActive(TopBar::Elements::BATTERY, false);
- topBar->setActive(TopBar::Elements::SIM, false);
- topBar->setActive(TopBar::Elements::TIME, true);
}
void BaseSettingsWindow::destroyInterface()
M module-apps/application-settings-new/windows/BluetoothWindow.cpp => module-apps/application-settings-new/windows/BluetoothWindow.cpp +0 -2
@@ 15,8 15,6 @@ namespace gui
BluetoothWindow::BluetoothWindow(app::Application *app) : OptionWindow(app, gui::window::name::bluetooth)
{
- topBar->setActive(TopBar::Elements::BATTERY, false);
- topBar->setActive(TopBar::Elements::SIM, false);
sys::Bus::SendUnicast(
std::make_shared<::message::bluetooth::RequestStatus>(), service::name::bluetooth, application);
}
M module-apps/application-settings-new/windows/ChangePasscodeWindow.cpp => module-apps/application-settings-new/windows/ChangePasscodeWindow.cpp +0 -8
@@ 76,14 76,6 @@ namespace gui
setTitle(utils::localize.get("app_settings_security_change_passcode"));
}
- void ChangePasscodeWindow::buildTopBar()
- {
- topBar->setActive(TopBar::Elements::SIM, false);
- topBar->setActive(TopBar::Elements::LOCK, false);
- topBar->setActive(TopBar::Elements::BATTERY, false);
- topBar->setActive(TopBar::Elements::TIME, true);
- }
-
void ChangePasscodeWindow::destroyInterface()
{
erase();
M module-apps/application-settings-new/windows/ChangePasscodeWindow.hpp => module-apps/application-settings-new/windows/ChangePasscodeWindow.hpp +0 -1
@@ 21,7 21,6 @@ namespace gui
void buildBottomBar() override;
void buildInterface() override;
void buildTitleBar() override;
- void buildTopBar() override;
void destroyInterface() override;
void onBeforeShow(ShowMode mode, SwitchData *data) override;
void processPasscode();
M module-apps/application-settings-new/windows/DisplayLightWindow.cpp => module-apps/application-settings-new/windows/DisplayLightWindow.cpp +2 -3
@@ 13,14 13,13 @@
namespace gui
{
-
DisplayLightWindow::DisplayLightWindow(app::Application *app, app::settingsInterface::ScreenLightSettings *settings)
: BaseSettingsWindow(app, window::name::display_light), screenLightSettings(settings)
{
auto values = screenLightSettings->getCurrentValues();
isDisplayLightSwitchOn = values.lightOn;
- isAutoLightSwitchOn = values.mode;
+ isAutoLightSwitchOn = values.mode == screen_light_control::ScreenLightMode::Automatic;
brightnessValue = values.parameters.manualModeBrightness;
setTitle(utils::localize.get("app_settings_display_display_light"));
@@ 85,7 84,7 @@ namespace gui
};
auto spinner = std::make_unique<gui::SpinBoxOptionSettings>(
- utils::translateI18("app_settings_display_light_brightness") + " " + std::to_string(brightnessStep),
+ utils::translateI18("app_settings_display_light_brightness") + " " + utils::to_string(brightnessStep),
brightnessValue * brightnessStep,
std::ceil(screen_light_control::Parameters::MAX_BRIGHTNESS / brightnessStep),
setBrightness,
M module-apps/application-settings-new/windows/MessagesWindow.cpp => module-apps/application-settings-new/windows/MessagesWindow.cpp +0 -3
@@ 64,9 64,6 @@ namespace gui
};
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::select));
- topBar->setActive(TopBar::Elements::SIGNAL, false);
- topBar->setActive(TopBar::Elements::BATTERY, false);
- topBar->setActive(TopBar::Elements::SIM, false);
addMenuSwitch(utils::translateI18("app_settings_show_unread_first"), "");
addMenu(utils::translateI18("app_settings_Templates"), gui::window::name::templates);
M module-apps/application-settings-new/windows/NetworkWindow.cpp => module-apps/application-settings-new/windows/NetworkWindow.cpp +0 -3
@@ 122,9 122,6 @@ namespace gui
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::select));
- topBar->setActive(TopBar::Elements::SIGNAL, false);
- topBar->setActive(TopBar::Elements::BATTERY, false);
- topBar->setActive(TopBar::Elements::SIM, false);
return optList;
}
void NetworkWindow::rebuild()
A module-apps/application-settings-new/windows/NewApnWindow.cpp => module-apps/application-settings-new/windows/NewApnWindow.cpp +119 -0
@@ 0,0 1,119 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "NewApnWindow.hpp"
+#include "application-settings-new/ApplicationSettings.hpp"
+
+#include <Dialog.hpp>
+#include <messages/DialogMetadataMessage.hpp>
+
+namespace gui
+{
+
+ NewApnWindow::NewApnWindow(app::Application *app)
+ : AppWindow(app, gui::window::name::new_apn), newApnModel{std::make_shared<NewApnModel>(app)}
+ {
+ buildInterface();
+ }
+
+ void NewApnWindow::rebuild()
+ {
+ destroyInterface();
+ buildInterface();
+ }
+
+ void NewApnWindow::buildInterface()
+ {
+ AppWindow::buildInterface();
+
+ bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::save));
+ bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
+
+ setTitle(utils::localize.get("app_settings_new_edit_apn"));
+
+ list = new gui::ListView(this,
+ style::settings::window::newApn::x,
+ style::settings::window::newApn::y,
+ style::settings::window::newApn::w,
+ style::settings::window::newApn::h,
+ newApnModel);
+ setFocusItem(list);
+ apnSettingsModel = new ApnSettingsModel(application);
+ }
+
+ void NewApnWindow::destroyInterface()
+ {
+ erase();
+ }
+
+ void NewApnWindow::onBeforeShow(ShowMode mode, SwitchData *data)
+ {
+ if (mode != ShowMode::GUI_SHOW_RETURN) {
+ newApnModel->clearData();
+ }
+
+ if (mode == ShowMode::GUI_SHOW_INIT) {
+ list->rebuildList();
+ }
+
+ if (apn != nullptr) {
+ newApnModel->loadData(apn);
+ }
+ }
+
+ auto NewApnWindow::handleSwitchData(SwitchData *data) -> bool
+ {
+ setSaveButtonVisible(false);
+
+ if (data == nullptr) {
+ return false;
+ }
+
+ auto *item = dynamic_cast<ApnItemData *>(data);
+ if (item == nullptr) {
+ return false;
+ }
+
+ apn = item->getApn();
+ if (apn == nullptr) {
+ apn = std::make_shared<packet_data::APN::Config>();
+ return true;
+ }
+
+ return true;
+ }
+
+ void NewApnWindow::setSaveButtonVisible(bool visible)
+ {
+ bottomBar->setActive(BottomBar::Side::CENTER, visible);
+ }
+
+ auto NewApnWindow::onInput(const InputEvent &inputEvent) -> bool
+ {
+ if (!inputEvent.isShortPress()) {
+ return false;
+ }
+ if (inputEvent.is(gui::KeyCode::KEY_ENTER)) {
+ if (apn != nullptr) {
+ newApnModel->saveData(apn);
+ }
+ verifyAndSave();
+ return true;
+ }
+
+ return AppWindow::onInput(inputEvent);
+ }
+
+ auto NewApnWindow::verifyAndSave() -> bool
+ {
+ if (apn == nullptr) {
+ LOG_DEBUG("APN record not found");
+ return false;
+ }
+ apnSettingsModel->saveAPN(apn);
+ LOG_DEBUG("APN record saved : \"%s\" ", apn->apn.c_str());
+
+ return true;
+ }
+
+} // namespace gui
A module-apps/application-settings-new/windows/NewApnWindow.hpp => module-apps/application-settings-new/windows/NewApnWindow.hpp +35 -0
@@ 0,0 1,35 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "application-settings-new/models/ApnSettingsModel.hpp"
+#include "application-settings-new/models/NewApnModel.hpp"
+
+#include <AppWindow.hpp>
+#include <ListView.hpp>
+#include <Text.hpp>
+
+namespace gui
+{
+ class NewApnWindow : public AppWindow
+ {
+ public:
+ NewApnWindow(app::Application *app);
+
+ private:
+ auto onInput(const InputEvent &inputEvent) -> bool override;
+ void onBeforeShow(ShowMode mode, SwitchData *data) override;
+ auto handleSwitchData(SwitchData *data) -> bool override;
+ void rebuild() override;
+ void buildInterface() override;
+ void destroyInterface() override;
+ auto verifyAndSave() -> bool;
+ void setSaveButtonVisible(bool visible);
+ std::shared_ptr<packet_data::APN::Config> apn;
+ std::shared_ptr<NewApnModel> newApnModel;
+ ApnSettingsModel *apnSettingsModel = nullptr;
+ gui::ListView *list = nullptr;
+ };
+
+} /* namespace gui */
M module-apps/application-settings-new/windows/NightshiftWindow.cpp => module-apps/application-settings-new/windows/NightshiftWindow.cpp +0 -3
@@ 16,9 16,6 @@ namespace gui
{
AppWindow::buildInterface();
- topBar->setActive(TopBar::Elements::SIM, false);
- topBar->setActive(TopBar::Elements::TIME, true);
-
setTitle(utils::localize.get("app_settings_title_nightshift"));
body = new gui::VBox(this,
M module-apps/application-settings-new/windows/PhoneNameWindow.cpp => module-apps/application-settings-new/windows/PhoneNameWindow.cpp +0 -2
@@ 22,8 22,6 @@ namespace gui
void PhoneNameWindow::buildInterface()
{
AppWindow::buildInterface();
- topBar->setActive(TopBar::Elements::SIM, false);
- topBar->setActive(TopBar::Elements::TIME, true);
setTitle(utils::localize.get("app_settings_bluetooth_phone_name"));
M module-apps/application-settings-new/windows/QuotesAddWindow.cpp => module-apps/application-settings-new/windows/QuotesAddWindow.cpp +1 -1
@@ 6,7 6,7 @@
#include "application-settings-new/ApplicationSettings.hpp"
#include "application-settings-new/data/QuoteSwitchData.hpp"
-#include "application-settings-new/model/QuotesRepository.hpp"
+#include "application-settings-new/models/QuotesRepository.hpp"
#include <i18n/i18n.hpp>
#include <widgets/Text.hpp>
M module-apps/application-settings-new/windows/QuotesAddWindow.hpp => module-apps/application-settings-new/windows/QuotesAddWindow.hpp +1 -1
@@ 5,7 5,7 @@
#include "BaseSettingsWindow.hpp"
#include "QuotesMainWindow.hpp"
-#include "application-settings-new/model/QuotesModel.hpp"
+#include "application-settings-new/models/QuotesModel.hpp"
namespace gui
{
M module-apps/application-settings-new/windows/QuotesMainWindow.cpp => module-apps/application-settings-new/windows/QuotesMainWindow.cpp +2 -2
@@ 2,8 2,8 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "QuotesMainWindow.hpp"
-#include "application-settings-new/model/QuotesRepository.hpp"
-#include "application-settings-new/model/QuotesModel.hpp"
+#include "application-settings-new/models/QuotesRepository.hpp"
+#include "application-settings-new/models/QuotesModel.hpp"
#include "application-settings-new/ApplicationSettings.hpp"
#include "application-settings-new/widgets/SettingsStyle.hpp"
#include "OptionSetting.hpp"
M module-apps/application-settings-new/windows/QuotesMainWindow.hpp => module-apps/application-settings-new/windows/QuotesMainWindow.hpp +1 -1
@@ 5,7 5,7 @@
#include "BaseSettingsWindow.hpp"
#include "application-settings-new/widgets/QuoteWidget.hpp"
-#include "application-settings-new/model/QuotesModel.hpp"
+#include "application-settings-new/models/QuotesModel.hpp"
#include <purefs/filesystem_paths.hpp>
#include <module-gui/gui/widgets/ListView.hpp>
M module-apps/application-settings-new/windows/QuotesOptionsWindow.cpp => module-apps/application-settings-new/windows/QuotesOptionsWindow.cpp +2 -2
@@ 3,11 3,11 @@
#include "QuotesOptionsWindow.hpp"
#include "OptionSetting.hpp"
-#include "application-settings-new/model/QuotesRepository.hpp"
+#include "application-settings-new/models/QuotesRepository.hpp"
#include "application-settings-new/ApplicationSettings.hpp"
#include "DialogMetadataMessage.hpp"
#include "QuotesMainWindow.hpp"
-#include "application-settings-new/model/QuotesRepository.hpp"
+#include "application-settings-new/models/QuotesRepository.hpp"
#include "application-settings-new/ApplicationSettings.hpp"
#include "application-settings-new/widgets/QuoteWidget.hpp"
M module-apps/application-settings/ApplicationSettings.cpp => module-apps/application-settings/ApplicationSettings.cpp +12 -8
@@ 47,16 47,10 @@ namespace app
switchWindow(app::sim_select);
return msgHandled();
});
- settings->registerValueChange(settings::SystemProperties::lockPassHash,
- [this](std::string value) { lockPassChanged(value); });
- settings->registerValueChange(settings::SystemProperties::timeDateFormat,
- [this](std::string value) { timeDateChanged(value); });
}
ApplicationSettings::~ApplicationSettings()
{
- settings->unregisterValueChange(settings::SystemProperties::lockPassHash);
- settings->unregisterValueChange(settings::SystemProperties::timeDateFormat);
}
// Invoked upon receiving data message
@@ 104,6 98,15 @@ namespace app
if (ret != sys::ReturnCodes::Success)
return ret;
+ settings->registerValueChange(
+ settings::SystemProperties::lockPassHash,
+ [this](std::string value) { lockPassChanged(value); },
+ settings::SettingsScope::Global);
+ settings->registerValueChange(
+ settings::SystemProperties::timeDateFormat,
+ [this](std::string value) { timeDateChanged(value); },
+ settings::SettingsScope::Global);
+
createUserInterface();
setActiveWindow(gui::name::window::main_window);
@@ 173,13 176,14 @@ namespace app
void ApplicationSettings::setPin(unsigned int value)
{
- settings->setValue(settings::SystemProperties::lockPassHash, std::to_string(value));
+ settings->setValue(
+ settings::SystemProperties::lockPassHash, std::to_string(value), settings::SettingsScope::Global);
lockPassHash = value;
}
void ApplicationSettings::clearPin()
{
- settings->setValue(settings::SystemProperties::lockPassHash, "");
+ settings->setValue(settings::SystemProperties::lockPassHash, "", settings::SettingsScope::Global);
lockPassHash = 0U;
}
M module-apps/application-settings/windows/BtScanWindow.cpp => module-apps/application-settings/windows/BtScanWindow.cpp +0 -2
@@ 57,8 57,6 @@ namespace gui
bottomBar->setActive(BottomBar::Side::RIGHT, true);
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::select));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
- topBar->setActive(TopBar::Elements::SIGNAL, true);
- topBar->setActive(TopBar::Elements::BATTERY, true);
setTitle(utils::localize.get("BT_scan_results"));
M module-apps/application-settings/windows/BtWindow.cpp => module-apps/application-settings/windows/BtWindow.cpp +0 -2
@@ 59,8 59,6 @@ namespace gui
bottomBar->setActive(BottomBar::Side::RIGHT, true);
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::select));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
- topBar->setActive(TopBar::Elements::SIGNAL, true);
- topBar->setActive(TopBar::Elements::BATTERY, true);
setTitle(utils::localize.get("app_settings_bt"));
M module-apps/application-settings/windows/CellularPassthroughWindow.cpp => module-apps/application-settings/windows/CellularPassthroughWindow.cpp +0 -2
@@ 31,8 31,6 @@ namespace gui
bottomBar->setActive(BottomBar::Side::RIGHT, true);
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::select));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
- topBar->setActive(TopBar::Elements::SIGNAL, true);
- topBar->setActive(TopBar::Elements::BATTERY, true);
setTitle(utils::localize.get("app_settings_cellular_passthrough"));
M module-apps/application-settings/windows/CellularPassthroughWindow.hpp => module-apps/application-settings/windows/CellularPassthroughWindow.hpp +1 -3
@@ 30,8 30,6 @@ namespace gui
} // namespace cellular_passthrough
} // namespace window
- using namespace bsp::cellular::USB;
-
class CellularPassthroughWindow : public AppWindow
{
private:
@@ 76,7 74,7 @@ namespace gui
CellularPassthroughWindow::State getInitialState();
- bool set(PassthroughState pass_to_set, BootPinState dfu_to_set);
+ bool set(bsp::cellular::USB::PassthroughState pass_to_set, bsp::cellular::USB::BootPinState dfu_to_set);
void setWindowState(State state);
M module-apps/application-settings/windows/DateTimeWindow.cpp => module-apps/application-settings/windows/DateTimeWindow.cpp +0 -3
@@ 52,9 52,6 @@ namespace gui
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::select));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
- topBar->setActive(TopBar::Elements::SIGNAL, true);
- topBar->setActive(TopBar::Elements::BATTERY, true);
-
setTitle(utils::localize.get("app_settings_date_and_time"));
// create date widgets
M module-apps/application-settings/windows/EinkModeWindow.cpp => module-apps/application-settings/windows/EinkModeWindow.cpp +0 -2
@@ 27,8 27,6 @@ namespace gui
bottomBar->setActive(BottomBar::Side::RIGHT, true);
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::select));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
- topBar->setActive(TopBar::Elements::SIGNAL, true);
- topBar->setActive(TopBar::Elements::BATTERY, true);
setTitle("Change eink mode");
auto label = new Label(this, 100, 200, 300, 50, "Change mode on click");
M module-apps/application-settings/windows/FotaWindow.cpp => module-apps/application-settings/windows/FotaWindow.cpp +0 -3
@@ 37,9 37,6 @@ namespace gui
AppWindow::buildInterface();
setTitle("Modem Firmware update (FOTA)");
- topBar->setActive(TopBar::Elements::SIGNAL, true);
- topBar->setActive(TopBar::Elements::BATTERY, true);
-
bottomBar->setActive(BottomBar::Side::CENTER, true);
bottomBar->setActive(BottomBar::Side::RIGHT, true);
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get("Go"));
M module-apps/application-settings/windows/Info.cpp => module-apps/application-settings/windows/Info.cpp +0 -2
@@ 36,8 36,6 @@ namespace gui
AppWindow::buildInterface();
bottomBar->setActive(BottomBar::Side::RIGHT, true);
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
- topBar->setActive(TopBar::Elements::SIGNAL, true);
- topBar->setActive(TopBar::Elements::BATTERY, true);
setTitle("Info");
M module-apps/application-settings/windows/LanguageWindow.cpp => module-apps/application-settings/windows/LanguageWindow.cpp +0 -3
@@ 49,9 49,6 @@ namespace gui
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::select));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
- topBar->setActive(TopBar::Elements::SIGNAL, true);
- topBar->setActive(TopBar::Elements::BATTERY, true);
-
setTitle(utils::localize.get("app_settings_title_languages"));
const auto &langList = loader.getAvailableDisplayLanguages();
for (const auto &lang : langList) {
M module-apps/application-settings/windows/TestMessageWindow.cpp => module-apps/application-settings/windows/TestMessageWindow.cpp +0 -3
@@ 61,9 61,6 @@ namespace gui
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::select));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
- topBar->setActive(TopBar::Elements::SIGNAL, true);
- topBar->setActive(TopBar::Elements::BATTERY, true);
-
receivedLabel = new gui::Label(this, 10, 50, 480 - 20, 50, "Received SMS");
receivedLabel->setAlignment(
gui::Alignment(gui::Alignment::Vertical::Center, gui::Alignment::Horizontal::Center));
M module-apps/application-special-input/windows/SpecialInputMainWindow.cpp => module-apps/application-special-input/windows/SpecialInputMainWindow.cpp +0 -2
@@ 36,8 36,6 @@ void SpecialInputMainWindow::buildInterface()
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
bottomBar->setText(BottomBar::Side::LEFT, utils::localize.get(style::strings::common::emoji));
- topBar->setActive(TopBar::Elements::TIME, true);
-
charList = new gui::ListView(this,
specialInputStyle::specialInputListView::x,
specialInputStyle::specialInputListView::y,
M module-apps/windows/AppWindow.cpp => module-apps/windows/AppWindow.cpp +16 -4
@@ 49,10 49,22 @@ namespace gui
title->setEllipsis(Ellipsis::Right);
title->visible = false;
- topBar = new gui::TopBar(this, 0, 0, 480, 50);
- topBar->setActive(TopBar::Elements::LOCK, false);
- topBar->setActive(TopBar::Elements::BATTERY, false);
- topBar->setActive(TopBar::Elements::SIGNAL, false);
+ auto config = configureTopBar(application->getTopBarConfiguration());
+ topBar = new gui::top_bar::TopBar(this, 0, 0, 480, 50);
+ topBar->configure(std::move(config));
+ }
+
+ top_bar::Configuration AppWindow::configureTopBar(top_bar::Configuration appConfiguration)
+ {
+ return appConfiguration;
+ }
+
+ void AppWindow::applyToTopBar(TopBarConfigurationChangeFunction configChange)
+ {
+ if (configChange) {
+ auto newConfiguration = configChange(topBar->getConfiguration());
+ topBar->configure(std::move(newConfiguration));
+ }
}
bool AppWindow::setSIM()
M module-apps/windows/AppWindow.hpp => module-apps/windows/AppWindow.hpp +21 -5
@@ 40,12 40,17 @@ namespace gui
/**
* Information bar for signal, battery and lock icon on the top of the screen.
*/
- gui::TopBar *topBar = nullptr;
+ gui::top_bar::TopBar *topBar = nullptr;
/**
* Pointer to the application object that owns the window.
*/
app::Application *application = nullptr;
+ /**
+ * A function that applies configuration changes to the current top bar configuration.
+ */
+ using TopBarConfigurationChangeFunction = std::function<top_bar::Configuration(top_bar::Configuration)>;
+
public:
AppWindow() = delete;
AppWindow(app::Application *app, std::string name);
@@ 54,10 59,7 @@ namespace gui
{
return application;
};
- void setApplication(app::Application *app)
- {
- application = app;
- };
+
virtual bool onDatabaseMessage(sys::Message *msg);
bool updateBatteryCharger(bool charging);
@@ 76,6 78,20 @@ namespace gui
void destroyInterface() override;
bool onInput(const InputEvent &inputEvent) override;
void accept(GuiVisitor &visitor) override;
+
+ /**
+ * Configure the top bar using window-specific configuration.
+ * @param appConfiguration Application-wide top bar configuration that it to be modified.
+ * @return window-specific configuration of the top bar.
+ */
+ virtual top_bar::Configuration configureTopBar(top_bar::Configuration appConfiguration);
+
+ /**
+ * Applies configuration change on the current top bar configuration.
+ * @param configChange The function that contains the top bar configuration changes.
+ */
+ void applyToTopBar(TopBarConfigurationChangeFunction configChange);
+
/// Setting bottom bar temporary text
/// @param text - bottomBar text
/// @param overwriteOthers - set or not other bottomBar texts to "" (default true)
M module-apps/windows/Dialog.cpp => module-apps/windows/Dialog.cpp +0 -6
@@ 50,7 50,6 @@ Dialog::Dialog(app::Application *app, const std::string &name) : gui::AppWindow(
{
AppWindow::buildInterface();
- topBar->setActive(TopBar::Elements::TIME, true);
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
setTitle("");
@@ 77,9 76,6 @@ void Dialog::onBeforeShow(ShowMode mode, SwitchData *data)
DialogConfirm::DialogConfirm(app::Application *app, const std::string &name) : Dialog(app, name)
{
- topBar->setActive(TopBar::Elements::BATTERY, true);
- topBar->setActive(TopBar::Elements::SIGNAL, true);
-
bottomBar->setActive(BottomBar::Side::RIGHT, false);
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::ok));
setFocusItem(icon);
@@ 169,8 165,6 @@ void DialogYesNoIconTxt::onBeforeShow(ShowMode mode, SwitchData *data)
if (auto metadata = dynamic_cast<DialogMetadataMessage *>(data); metadata != nullptr) {
DialogYesNo::onBeforeShow(mode, metadata);
iconText->setText(metadata->get().iconText);
- topBar->setActive(TopBar::Elements::BATTERY, false);
- topBar->setActive(TopBar::Elements::SIM, false);
setFocusItem(no);
}
}
M module-apps/windows/OptionWindow.cpp => module-apps/windows/OptionWindow.cpp +0 -2
@@ 63,8 63,6 @@ namespace gui
bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::select));
bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
- topBar->setActive(TopBar::Elements::SIGNAL, true);
- topBar->setActive(TopBar::Elements::BATTERY, true);
setTitle(name);
optionsList = new gui::ListView(this,
M module-audio/Audio/StreamQueuedEventsListener.cpp => module-audio/Audio/StreamQueuedEventsListener.cpp +2 -1
@@ 5,7 5,8 @@
using namespace audio;
-StreamQueuedEventsListener::StreamQueuedEventsListener(std::shared_ptr<Queue> eventsQueue) : queue(eventsQueue)
+StreamQueuedEventsListener::StreamQueuedEventsListener(std::shared_ptr<cpp_freertos::Queue> eventsQueue)
+ : queue(eventsQueue)
{}
void StreamQueuedEventsListener::onEvent(Stream *stream, Stream::Event event, Stream::EventSourceMode source)
M module-audio/Audio/StreamQueuedEventsListener.hpp => module-audio/Audio/StreamQueuedEventsListener.hpp +2 -4
@@ 13,8 13,6 @@
namespace audio
{
- using namespace cpp_freertos;
-
class StreamQueuedEventsListener : public Stream::EventListener
{
private:
@@ 29,7 27,7 @@ namespace audio
using queuedEvent = std::pair<Stream *, Stream::Event>;
static constexpr auto listenerElementSize = sizeof(EventStorage);
- StreamQueuedEventsListener(std::shared_ptr<Queue> eventsQueue);
+ StreamQueuedEventsListener(std::shared_ptr<cpp_freertos::Queue> eventsQueue);
void onEvent(Stream *stream, Stream::Event event, Stream::EventSourceMode source);
@@ 39,7 37,7 @@ namespace audio
std::size_t getEventsCount() const;
private:
- std::shared_ptr<Queue> queue;
+ std::shared_ptr<cpp_freertos::Queue> queue;
};
}; // namespace audio
M module-bsp/board/linux/battery-charger/battery_charger.cpp => module-bsp/board/linux/battery-charger/battery_charger.cpp +81 -95
@@ 1,21 1,5 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-/*
- * battery_charger.cpp
- *
- * Created on: Jul 1, 2019
- * Author: kuba
- */
-#include <stdint.h>
-
-extern "C"
-{
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-}
-
#include <sys/stat.h>
#include <fcntl.h>
#include <module-utils/common_data/EventStore.hpp>
@@ 23,114 7,116 @@ extern "C"
#include "board.h"
#include "bsp/battery-charger/battery_charger.hpp"
-#define BSP_BATTERY_CHARGER_I2C_ADDR (0xD2 >> 1)
-#define BSP_FUEL_GAUGE_I2C_ADDR (0x6C >> 1)
-#define BSP_TOP_CONTROLLER_I2C_ADDR (0xCC >> 1)
-
-static xQueueHandle qHandleIrq = NULL;
-static TaskHandle_t battery_worker_handle = NULL;
-
-static uint8_t battLevel = 100;
-static bool plugged = false;
-namespace bsp
+namespace bsp::battery_charger
{
+ namespace
+ {
+ xQueueHandle IRQQueueHandle = nullptr;
+ TaskHandle_t batteryWorkerHandle = nullptr;
+ constexpr auto batteryFIFO = "/tmp/fifoBattKeys";
+ constexpr auto fifoFileAccessRights = 0666;
+ constexpr auto fifoBuffSize = 10;
+ constexpr auto queueTimeoutTicks = 100;
+ constexpr auto taskDelay = 50;
+
+ StateOfCharge battLevel = 100;
+ constexpr StateOfCharge fullBattery = 100;
+ bool plugged = false;
+
+ constexpr auto chargerPlugStateChange = 'p';
+ constexpr auto batteryLevelUp = ']';
+ constexpr auto batteryLevelDown = '[';
+
+ void battery_worker(void *parameters)
+ {
+ mkfifo(batteryFIFO, fifoFileAccessRights);
+
+ // Open FIFO for write only
+ int fd = open(batteryFIFO, O_RDONLY | O_NONBLOCK);
+
+ while (true) {
+ std::uint8_t buff[fifoBuffSize];
+ std::int32_t readBytes = read(fd, buff, fifoBuffSize);
+
+ if (readBytes > 0) {
+ std::uint8_t notification = 0;
+ switch (static_cast<char>(buff[0])) {
+ case chargerPlugStateChange:
+ notification = static_cast<std::uint8_t>(batteryIRQSource::INOKB);
+ plugged = !plugged;
+ break;
+ case batteryLevelUp:
+ notification = static_cast<std::uint8_t>(batteryIRQSource::INTB);
+ if (battLevel < fullBattery)
+ battLevel++;
+ else {
+ // second 100% in a row
+ if (plugged && Store::Battery::get().level == fullBattery) {
+ Store::Battery::modify().state = Store::Battery::State::PluggedNotCharging;
+ }
+ }
+ break;
+ case batteryLevelDown:
+ notification = static_cast<std::uint8_t>(batteryIRQSource::INTB);
+ if (battLevel >= 1)
+ battLevel--;
+ if (plugged && Store::Battery::get().level == fullBattery) {
+ // charging but not 100% anymore
+ Store::Battery::modify().state = Store::Battery::State::Charging;
+ }
+ break;
+ }
+ xQueueSend(IRQQueueHandle, ¬ification, queueTimeoutTicks);
+ }
+ vTaskDelay(taskDelay);
+ }
+ }
+ } // namespace
- static void battery_worker(void *pvp);
-
- int battery_Init(xQueueHandle qHandle)
+ int init(xQueueHandle queueHandle)
{
- qHandleIrq = qHandle;
- if (xTaskCreate(battery_worker, "battery", 512, qHandle, 0, &battery_worker_handle) != pdPASS) {
+ IRQQueueHandle = queueHandle;
+ if (xTaskCreate(battery_worker, "battery", 512, queueHandle, 0, &batteryWorkerHandle) != pdPASS) {
return 1;
}
Store::Battery::modify().level = battLevel;
return 0;
}
- void battery_Deinit(void)
+ void deinit()
{
- qHandleIrq = NULL;
- vTaskDelete(battery_worker_handle);
+ IRQQueueHandle = nullptr;
+ vTaskDelete(batteryWorkerHandle);
}
- void battery_getBatteryLevel(uint8_t &levelPercent)
+
+ StateOfCharge getBatteryLevel()
{
- levelPercent = battLevel;
Store::Battery::modify().level = battLevel;
+ return battLevel;
}
- void battery_getChargeStatus(bool &status)
+ bool getChargeStatus()
{
- status = plugged;
+ bool status = plugged;
if (status) {
Store::Battery::modify().state = Store::Battery::State::Charging;
}
else {
Store::Battery::modify().state = Store::Battery::State::Discharging;
}
+ return status;
}
// TODO function unused in linux driver, left for compatibility with target driver
- void battery_ClearAllIRQs(void)
+ void clearAllIRQs()
{}
// TODO function unused in linux driver, left for compatibility with target driver
- void battery_clearFuelGuageIRQ(void)
+ void clearFuelGuageIRQ()
{}
- static void battery_worker(void *pvp)
- {
-
- const char *myfifo = "/tmp/fifoBattKeys";
-
- // Creating the named file(FIFO)
- // mkfifo(<pathname>, <permission>)
- mkfifo(myfifo, 0666);
-
- // Open FIFO for write only
- int fd;
- fd = open(myfifo, O_RDONLY | O_NONBLOCK);
-
- while (1) {
- uint8_t buff[10];
- int32_t readedBytes = read(fd, buff, 10);
-
- if (readedBytes > 0) {
-
- uint8_t notification = 0;
- switch (buff[0]) {
- case 'p':
- notification = static_cast<uint8_t>(bsp::batteryIRQSource::INOKB);
- plugged = 1 - plugged;
- break;
- case ']':
- notification = static_cast<uint8_t>(bsp::batteryIRQSource::INTB);
- if (battLevel < 100)
- battLevel++;
- else {
- // second 100% in a row
- if (plugged && Store::Battery::get().level == 100) {
- Store::Battery::modify().state = Store::Battery::State::PluggedNotCharging;
- }
- }
- break;
- case '[':
- notification = static_cast<uint8_t>(bsp::batteryIRQSource::INTB);
- if (battLevel >= 1)
- battLevel--;
- if (plugged && Store::Battery::get().level == 100) {
- // charging but not 100% anymore
- Store::Battery::modify().state = Store::Battery::State::Charging;
- }
- break;
- }
- xQueueSend(qHandleIrq, ¬ification, 100);
- }
- vTaskDelay(50);
- }
- }
-
- std::uint16_t battery_getStatusRegister()
+ std::uint16_t getStatusRegister()
{
return static_cast<std::uint16_t>(batteryINTBSource::SOCOnePercentChange);
}
-} // namespace bsp
+} // namespace bsp::battery_charger
M module-bsp/board/linux/usb_cdc/usb_cdc.cpp => module-bsp/board/linux/usb_cdc/usb_cdc.cpp +1 -2
@@ 32,7 32,6 @@ namespace bsp
{
LOG_INFO("[ServiceDesktop:BSP_Driver] Start reading on fd:%d", fd);
char inputData[SERIAL_BUFFER_LEN];
- static std::string receiveMsg;
while (1) {
if (uxQueueSpacesAvailable(USBReceiveQueue) != 0) {
@@ 61,7 60,7 @@ namespace bsp
continue;
}
#endif
- receiveMsg = std::string(inputData, inputData + length);
+ std::string *receiveMsg = new std::string(inputData, inputData + length);
xQueueSend(USBReceiveQueue, &receiveMsg, portMAX_DELAY);
}
else {
A module-bsp/board/rt1051/bsp/battery-charger/MAX77818.hpp => module-bsp/board/rt1051/bsp/battery-charger/MAX77818.hpp +160 -0
@@ 0,0 1,160 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+#pragma once
+
+namespace bsp::battery_charger
+{
+
+ constexpr inline auto BATTERY_CHARGER_I2C_ADDR = 0xD2 >> 1;
+ constexpr inline auto FUEL_GAUGE_I2C_ADDR = 0x6C >> 1;
+ constexpr inline auto TOP_CONTROLLER_I2C_ADDR = 0xCC >> 1;
+
+ enum class Registers
+ {
+ TOP_CONTROLL_PMIC_ID_REG = 0x20,
+ TOP_CONTROLL_PMIC_VER_REG = 0x21,
+ TOP_CONTROLL_IRQ_SRC_REG = 0x22,
+ TOP_CONTROLL_IRQ_MASK_REG = 0x23,
+ SYSTEM_IRQ_REG = 0x24,
+
+ STATUS_REG = 0x00,
+ VALRT_Th_REG = 0x01,
+ TALRT_Th_REG = 0x02,
+ SALRT_Th_REG = 0x03,
+ AtRate_REG = 0x04,
+ RepCap_REG = 0x05,
+ RepSOC_REG = 0x06,
+ Age_REG = 0x07,
+ TEMP_REG = 0x08,
+ VCELL_REG = 0x09,
+ Current_REG = 0x0A,
+ AvgCurrent_REG = 0x0B,
+ QResidual_REG = 0x0C,
+ MixSOC_REG = 0x0D,
+ AvSOC_REG = 0x0E,
+ MixCap_REG = 0x0F,
+
+ FullCAP_REG = 0x10,
+ TTE_REG = 0x11,
+ QRtable00_REG = 0x12,
+ FullSOCthr_REG = 0x13,
+ RSLOW_REG = 0x14,
+ AvgTA_REG = 0x16,
+ Cycles_REG = 0x17,
+ DesignCap_REG = 0x18,
+ AvgVCELL_REG = 0x19,
+ MaxMinTemp_REG = 0x1A,
+ MaxMinVolt_REG = 0x1B,
+ MaxMinCurr_REG = 0x1C,
+ CONFIG_REG = 0x1D,
+ CONFIG2_REG = 0xBB,
+ ICHGTERM_REG = 0x1E,
+ AvCap_REG = 0x1F,
+
+ TTF_REG = 0x20,
+ DevName_REG = 0x21,
+ QRtable10_REG = 0x22,
+ FullCAPNom_REG = 0x23,
+ TempNom_REG = 0x24,
+ TempLim_REG = 0x25,
+ AIN0_REG = 0x27,
+ LearnCFG_REG = 0x28,
+ FilterCFG_REG = 0x29,
+ RelaxCFG_REG = 0x2A,
+ MiscCFG_REG = 0x2B,
+ TGAIN_REG = 0x2C,
+ TOFF_REG = 0x2D,
+ CGAIN_REG = 0x2E,
+ COFF_REG = 0x2F,
+
+ QRtable20_REG = 0x32,
+ AtTTF_REG = 0x33,
+ FullCapRep_REG = 0x35,
+ lavgEmpty_REG = 0x36,
+ FCTC_REG = 0x37,
+ RCOMP0_REG = 0x38,
+ TempCo_REG = 0x39,
+ VEmpty_REG = 0x3A,
+ TIMER_REG = 0x3E,
+ SHDNTIMER_REG = 0x3F,
+
+ QRtable30_REG = 0x42,
+ dQ_acc_REG = 0x45,
+ dP_acc_REG = 0x46,
+ ConvgCfg_REG = 0x49,
+ VFRemCap_REG = 0x4A,
+ QH_REG = 0x4D,
+ CHG_INT_REG = 0xb0,
+ CHG_INT_OK = 0xb2
+ };
+
+ // STATUS register bits
+ enum STATUS
+ {
+ Inm = (1 << 0),
+ POR = (1 << 1),
+ SPR_2 = (1 << 2),
+ BST = (1 << 3),
+ Isysmx = (1 << 4),
+ SPR_5 = (1 << 5),
+ ThmHot = (1 << 6),
+ dSOCi = (1 << 7),
+ Vmn = (1 << 8),
+ Tmn = (1 << 9),
+ Smn = (1 << 10),
+ Bi = (1 << 11),
+ Vmx = (1 << 12),
+ Tmx = (1 << 13),
+ Smx = (1 << 14),
+ Br = (1 << 15),
+ };
+
+ /// CHG_INT registers from documentation
+ enum class CHG_INT
+ {
+ BYP_I = (1 << 0),
+ RSVD = (1 << 1),
+ BATP_I = (1 << 2),
+ BAT_I = (1 << 3),
+ CHG_I = (1 << 4),
+ WCIN_I = (1 << 5),
+ CHGIN_I = (1 << 6),
+ AICL_I = (1 << 7),
+ };
+
+ // CONFIG register bits
+ enum class CONFIG
+ {
+ Ber = 1 << 0,
+ Bei = 1 << 1,
+ Aen = 1 << 2,
+ FTHRM = 1 << 3,
+ ETHRM = 1 << 4,
+ SPR_5 = 1 << 5,
+ I2CSH = 1 << 6,
+ SHDN = 1 << 7,
+ Tex = 1 << 8,
+ Ten = 1 << 9,
+ AINSH = 1 << 10,
+ SPR_11 = 1 << 11,
+ Vs = 1 << 12,
+ Ts = 1 << 13,
+ Ss = 1 << 14,
+ SPR_15 = 1 << 15
+ };
+
+ // CONFIG2 register bits
+ enum class CONFIG2
+ {
+ ISysNCurr = 1 << 0,
+ OCVQen = 1 << 4,
+ LdMdl = 1 << 5,
+ TAlrtEn = 1 << 6,
+ dSOCen = 1 << 7,
+ ThmHotAlrtEn = 1 << 8,
+ ThmHotEn = 1 << 9,
+ FCThmHot = 1 << 10,
+ SPR = 1 << 11
+ };
+
+} // namespace bsp::battery_charger
M module-bsp/board/rt1051/bsp/battery-charger/battery_charger.cpp => module-bsp/board/rt1051/bsp/battery-charger/battery_charger.cpp +339 -481
@@ 1,586 1,444 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-/*
- * battery_charger.cpp
- *
- * Created on: Jun 28, 2019
- * Author: kuba
- */
-
-extern "C"
-{
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-}
-
#include "bsp/battery-charger/battery_charger.hpp"
+#include "MAX77818.hpp"
+#include <purefs/filesystem_paths.hpp>
#include "bsp/BoardDefinitions.hpp"
#include "common_data/EventStore.hpp"
#include "drivers/gpio/DriverGPIO.hpp"
#include "drivers/i2c/DriverI2C.hpp"
-#include <cstdio>
#include <purefs/filesystem_paths.hpp>
-#include "fsl_common.h"
-#define BSP_BATTERY_CHARGER_I2C_ADDR (0xD2 >> 1)
-#define BSP_FUEL_GAUGE_I2C_ADDR (0x6C >> 1)
-#define BSP_TOP_CONTROLLER_I2C_ADDR (0xCC >> 1)
-
-static const uint32_t i2cSubaddresSize = 1;
+#include <utility>
-namespace configs
+namespace bsp::battery_charger
{
- const auto battery_cfgFile = purefs::dir::getCurrentOSPath() / "batteryAdjustementConfig.cfg";
- const auto battery_cfgFilePrev = purefs::dir::getCurrentOSPath() / "batteryAdjustementConfig_old.cfg";
-} // namespace configs
+ namespace
+ {
+ constexpr std::uint32_t i2cSubaddresSize = 1;
-static const uint16_t BATT_SERVICE_AVG_CURRENT_PERIOD =
- 0x00; //< 0.1758 ms * 2^(2 + BATT_SERVICE_AVG_CURRENT_PERIOD) == 700ms
-static const uint16_t BATT_SERVICE_AVG_CELL_VOLTAGE_PERIOD =
- 0x00; //< 0.1758 ms * 2^(6 + BATT_SERVICE_AVG_CELL_VOLTAGE_PERIOD) == 11.25 s
-static const uint16_t BATT_SERVICE_AVG_MIXING_PERIOD =
- 0x0D; //< 0.1758 ms * 2^(5 + BATT_SERVICE_AVG_MIXING_PERIOD) == 12.8 h
-static const uint16_t BATT_SERVICE_AVG_TEMP_PERIOD =
- 0x01; //< 0.1758 ms * 2^(11 + BATT_SERVICE_AVG_TEMP_PERIOD) == 12 min
-static const uint16_t BATT_SERVICE_AVG_NEMPTY_PERIOD = 0x00;
+ const auto cfgFile = purefs::dir::getCurrentOSPath() / "batteryAdjustementConfig.cfg";
+ const auto cfgFilePrev = purefs::dir::getCurrentOSPath() / "batteryAdjustementConfig_old.cfg";
-static const uint16_t battery_nominalCapacitymAh = 3000;
+ constexpr std::uint16_t BATT_SERVICE_AVG_CURRENT_PERIOD =
+ 0x00; //< 0.1758 ms * 2^(2 + BATT_SERVICE_AVG_CURRENT_PERIOD) == 700ms
+ constexpr std::uint16_t BATT_SERVICE_AVG_CELL_VOLTAGE_PERIOD =
+ 0x00; //< 0.1758 ms * 2^(6 + BATT_SERVICE_AVG_CELL_VOLTAGE_PERIOD) == 11.25 s
+ constexpr std::uint16_t BATT_SERVICE_AVG_MIXING_PERIOD =
+ 0x0D; //< 0.1758 ms * 2^(5 + BATT_SERVICE_AVG_MIXING_PERIOD) == 12.8 h
+ constexpr std::uint16_t BATT_SERVICE_AVG_TEMP_PERIOD =
+ 0x01; //< 0.1758 ms * 2^(11 + BATT_SERVICE_AVG_TEMP_PERIOD) == 12 min
+ constexpr std::uint16_t BATT_SERVICE_AVG_NEMPTY_PERIOD = 0x00;
-static const uint8_t battery_fullyChargedPercent = 100;
-static const uint8_t battery_DischargedPercent = 15;
+ constexpr auto ENABLE_ALL_IRQ_MASK = 0xf8;
-static const uint8_t battery_maxTemperatureDegrees = 50;
-static const uint8_t battery_minTemperatureDegrees = 5;
+ constexpr std::uint16_t nominalCapacitymAh = 3000;
-static constexpr inline uint16_t battery_maxVoltagemV = 4200;
-static constexpr inline uint16_t battery_minVoltagemV = 3600;
+ constexpr std::uint8_t fullyChargedPercent = 100;
+ constexpr std::uint8_t DischargedPercent = 15;
-using namespace drivers;
+ constexpr std::uint8_t maxTemperatureDegrees = 50;
+ constexpr std::uint8_t minTemperatureDegrees = 5;
-static std::shared_ptr<drivers::DriverI2C> i2c;
-static std::shared_ptr<drivers::DriverGPIO> gpio;
+ constexpr std::uint16_t maxVoltagemV = 4200;
+ constexpr std::uint16_t minVoltagemV = 3600;
-static bsp::batteryRetval battery_loadConfiguration(void);
+ std::shared_ptr<drivers::DriverI2C> i2c;
+ std::shared_ptr<drivers::DriverGPIO> gpio;
-static bsp::batteryRetval battery_storeConfiguration(void);
+ drivers::I2CAddress fuelGaugeAddress = {FUEL_GAUGE_I2C_ADDR, 0, i2cSubaddresSize};
+ drivers::I2CAddress batteryChargerAddress = {BATTERY_CHARGER_I2C_ADDR, 0, i2cSubaddresSize};
+ drivers::I2CAddress topControllerAddress = {TOP_CONTROLLER_I2C_ADDR, 0, i2cSubaddresSize};
-static int battery_fuelGaugeWrite(bsp::batteryChargerRegisters registerAddress, uint16_t value);
+ xQueueHandle IRQQueueHandle = nullptr;
-static int battery_fuelGaugeRead(bsp::batteryChargerRegisters registerAddress, uint16_t *value);
+ int fuelGaugeWrite(Registers registerAddress, std::uint16_t value)
+ {
+ fuelGaugeAddress.subAddress = static_cast<std::uint32_t>(registerAddress);
+ auto ret = i2c->Write(fuelGaugeAddress, reinterpret_cast<std::uint8_t *>(&value), sizeof(std::uint16_t));
-static int battery_chargerWrite(bsp::batteryChargerRegisters registerAddress, uint8_t value);
+ if (ret != sizeof(std::uint16_t)) {
+ return kStatus_Fail;
+ }
+ return kStatus_Success;
+ }
-static int battery_chargerRead(bsp::batteryChargerRegisters registerAddress, uint8_t *value);
+ std::pair<int, std::uint16_t> fuelGaugeRead(Registers registerAddress)
+ {
+ std::uint16_t value;
+ int status = kStatus_Success;
+ fuelGaugeAddress.subAddress = static_cast<std::uint32_t>(registerAddress);
+ auto ret = i2c->Read(fuelGaugeAddress, reinterpret_cast<std::uint8_t *>(&value), sizeof(std::uint16_t));
+
+ if (ret != sizeof(std::uint16_t)) {
+ status = kStatus_Fail;
+ }
+ return std::make_pair(status, value);
+ }
-static int battery_chargerTopControllerWrite(bsp::batteryChargerRegisters registerAddress, uint8_t value);
+ int chargerWrite(Registers registerAddress, std::uint8_t value)
+ {
+ batteryChargerAddress.subAddress = static_cast<std::uint32_t>(registerAddress);
+ auto ret =
+ i2c->Write(batteryChargerAddress, reinterpret_cast<std::uint8_t *>(&value), sizeof(std::uint8_t));
-static int battery_chargerTopControllerRead(bsp::batteryChargerRegisters registerAddress, uint8_t *value);
+ if (ret != sizeof(std::uint8_t)) {
+ return kStatus_Fail;
+ }
+ return kStatus_Success;
+ }
-static bsp::batteryRetval battery_setAvgCalcPeriods(void);
+ std::pair<int, std::uint8_t> chargerRead(Registers registerAddress)
+ {
+ std::uint8_t value;
+ int status = kStatus_Success;
+ batteryChargerAddress.subAddress = static_cast<std::uint32_t>(registerAddress);
+ auto ret = i2c->Read(batteryChargerAddress, &value, sizeof(std::uint8_t));
+
+ if (ret != sizeof(std::uint8_t)) {
+ status = kStatus_Fail;
+ }
+ return std::make_pair(status, value);
+ }
-static bsp::batteryRetval battery_setAvgCalcPeriods(void);
+ int chargerTopControllerWrite(Registers registerAddress, std::uint8_t value)
+ {
+ topControllerAddress.subAddress = static_cast<std::uint32_t>(registerAddress);
+ auto ret = i2c->Write(topControllerAddress, reinterpret_cast<std::uint8_t *>(&value), sizeof(std::uint8_t));
-static bsp::batteryRetval battery_setNominalBatteryCapacity(uint16_t capacity);
+ if (ret != sizeof(std::uint8_t)) {
+ return kStatus_Fail;
+ }
+ return kStatus_Success;
+ }
-static bsp::batteryRetval battery_setChargingDischargingThresholds(uint8_t chargedThresholdPercent,
- uint8_t dischargedThresholdPercent);
+ std::pair<int, std::uint8_t> chargerTopControllerRead(Registers registerAddress)
+ {
+ std::uint8_t value;
+ int status = kStatus_Success;
+ topControllerAddress.subAddress = static_cast<std::uint32_t>(registerAddress);
+ auto ret = i2c->Read(topControllerAddress, &value, sizeof(std::uint8_t));
+ if (ret != sizeof(std::uint8_t)) {
+ status = kStatus_Fail;
+ }
+ return std::make_pair(status, value);
+ }
-static bsp::batteryRetval battery_setTemperatureThresholds(uint8_t maxTemperatureDegrees,
- uint8_t minTemperatureDegrees);
+ batteryRetval loadConfiguration()
+ {
+ auto fd = std::fopen(cfgFile.c_str(), "r");
+ if (fd == nullptr) {
+ LOG_WARN("Configuration file [%s] could not be opened. Trying to open file [%s]",
+ cfgFile.c_str(),
+ cfgFilePrev.c_str());
+ fd = std::fopen(cfgFilePrev.c_str(), "r");
+ if (fd == nullptr) {
+ LOG_WARN("Configuration file [%s] could not be opened.", cfgFilePrev.c_str());
+ return batteryRetval::ChargerError;
+ }
+ }
+
+ std::uint16_t regValue = 0;
+ for (auto i = 0; i < 0xff; ++i) {
+ if (std::fread(®Value, sizeof(regValue), 1, fd) != sizeof(regValue)) {
+ LOG_ERROR("Reading register 0x%x failed.", i);
+ std::fclose(fd);
+ return batteryRetval::ChargerError;
+ }
+
+ if (fuelGaugeWrite(static_cast<Registers>(i), regValue) != kStatus_Success) {
+ LOG_ERROR("Writing register 0x%x failed.", i);
+ std::fclose(fd);
+ return batteryRetval::ChargerError;
+ }
+ }
-static bsp::batteryRetval battery_setServiceVoltageThresholds(uint16_t maxVoltage_mV, uint16_t minVoltage_mV);
+ std::fclose(fd);
+ return batteryRetval::OK;
+ }
-static bsp::batteryRetval battery_enableFuelGuageIRQs(void);
+ batteryRetval storeConfiguration()
+ {
+ // TODO:M.P procedure below seems to crash system, it should be fixed.
+ if (ff_rename(cfgFile.c_str(), cfgFilePrev.c_str(), false) != 0) {
+ LOG_ERROR("Could not move configuration file");
+ return batteryRetval::ChargerError;
+ }
+
+ auto fd = std::fopen(cfgFile.c_str(), "w");
+ if (fd == nullptr) {
+ LOG_ERROR("Could not open configuration file");
+ return batteryRetval::ChargerError;
+ }
+
+ for (unsigned int i = 0; i < 0xff; ++i) {
+ auto regVal = fuelGaugeRead(static_cast<Registers>(i));
+ if (regVal.first != kStatus_Success) {
+ LOG_ERROR("Reading register 0x%x failed.", i);
+ std::fclose(fd);
+ return batteryRetval::ChargerError;
+ }
+
+ if (std::fwrite(®Val.second, sizeof(regVal.second), 1, fd) != sizeof(regVal.second)) {
+ LOG_ERROR("Storing register 0x%x failed.", i);
+ std::fclose(fd);
+ std::remove(cfgFile.c_str());
+ return batteryRetval::ChargerError;
+ }
+ }
-static bsp::batteryRetval battery_enableTopIRQs(void);
+ std::fclose(fd);
+ return batteryRetval::OK;
+ }
-static bsp::batteryRetval battery_configureAlerts();
+ batteryRetval setAvgCalcPeriods()
+ {
+ std::uint16_t regVal = 0;
+ regVal |= (BATT_SERVICE_AVG_CURRENT_PERIOD << 0);
+ regVal |= (BATT_SERVICE_AVG_CELL_VOLTAGE_PERIOD << 4);
+ regVal |= (BATT_SERVICE_AVG_MIXING_PERIOD << 7);
+ regVal |= (BATT_SERVICE_AVG_TEMP_PERIOD << 11);
+ regVal |= (BATT_SERVICE_AVG_NEMPTY_PERIOD << 14);
+
+ if (fuelGaugeWrite(Registers::FilterCFG_REG, regVal) != kStatus_Success) {
+ LOG_ERROR("setAvgCalcPeriods failed.");
+ return batteryRetval::ChargerError;
+ }
+ return batteryRetval::OK;
+ }
-static void s_BSP_BatteryChargerIrqPinsInit();
+ batteryRetval setNominalBatteryCapacity(std::uint16_t capacity)
+ {
+ std::uint16_t regVal = capacity * 2;
-static xQueueHandle qHandleIrq = NULL;
+ if (fuelGaugeWrite(Registers::DesignCap_REG, regVal) != kStatus_Success) {
+ LOG_ERROR("setNominalBatteryCapacity failed.");
+ return batteryRetval::ChargerError;
+ }
+ return batteryRetval::OK;
+ }
-namespace bsp
-{
+ batteryRetval setChargingDischargingThresholds(std::uint8_t chargedThresholdPercent,
+ std::uint8_t dischargedThresholdPercent)
+ {
+ uint16_t regVal = (chargedThresholdPercent << 8) | dischargedThresholdPercent;
- // STATUS register bits
- enum B_STATUS
- {
- Inm = (1 << 0),
- POR = (1 << 1),
- SPR_2 = (1 << 2),
- BST = (1 << 3),
- Isysmx = (1 << 4),
- SPR_5 = (1 << 5),
- ThmHot = (1 << 6),
- dSOCi = (1 << 7),
- Vmn = (1 << 8),
- Tmn = (1 << 9),
- Smn = (1 << 10),
- Bi = (1 << 11),
- Vmx = (1 << 12),
- Tmx = (1 << 13),
- Smx = (1 << 14),
- Br = (1 << 15),
- };
-
- /// CHG_INT registers from documentation
- enum B_CHG_INT
- {
- BYP_I = (1 << 0),
- RSVD = (1 << 1),
- BATP_I = (1 << 2),
- BAT_I = (1 << 3),
- CHG_I = (1 << 4),
- WCIN_I = (1 << 5),
- CHGIN_I = (1 << 6),
- AICL_I = (1 << 7),
- };
-
- // CONFIG register bits
- enum class B_CONFIG
- {
- Ber = 1 << 0,
- Bei = 1 << 1,
- Aen = 1 << 2,
- FTHRM = 1 << 3,
- ETHRM = 1 << 4,
- SPR_5 = 1 << 5,
- I2CSH = 1 << 6,
- SHDN = 1 << 7,
- Tex = 1 << 8,
- Ten = 1 << 9,
- AINSH = 1 << 10,
- SPR_11 = 1 << 11,
- Vs = 1 << 12,
- Ts = 1 << 13,
- Ss = 1 << 14,
- SPR_15 = 1 << 15
- };
-
- uint16_t battery_get_CHG_INT_OK();
-
- int battery_Init(xQueueHandle qHandle)
+ if (fuelGaugeWrite(Registers::SALRT_Th_REG, regVal) != kStatus_Success) {
+ LOG_ERROR("setChargingDischargingThresholds failed.");
+ return batteryRetval::ChargerError;
+ }
+ return batteryRetval::OK;
+ }
+
+ batteryRetval setTemperatureThresholds(std::uint8_t maxTemperatureDegrees, std::uint8_t minTemperatureDegrees)
+ {
+ std::uint16_t regVal = (maxTemperatureDegrees << 8) | minTemperatureDegrees;
+
+ if (fuelGaugeWrite(Registers::TALRT_Th_REG, regVal) != kStatus_Success) {
+ LOG_ERROR("setTemperatureThresholds failed.");
+ return batteryRetval::ChargerError;
+ }
+ return batteryRetval::OK;
+ }
+
+ batteryRetval setServiceVoltageThresholds(std::uint16_t maxVoltage_mV, std::uint16_t minVoltage_mV)
+ {
+ std::uint16_t regVal = ((maxVoltage_mV / 20) << 8) | (minVoltage_mV / 20);
+
+ if (fuelGaugeWrite(Registers::VALRT_Th_REG, regVal) != kStatus_Success) {
+
+ LOG_ERROR("setServiceVoltageThresholds failed.");
+ return batteryRetval::ChargerError;
+ }
+ return batteryRetval::OK;
+ }
+
+ batteryRetval enableFuelGuageIRQs()
+ {
+ std::uint16_t regVal = static_cast<std::uint16_t>(CONFIG2::dSOCen);
+
+ if (fuelGaugeWrite(Registers::CONFIG2_REG, regVal) != kStatus_Success) {
+ LOG_ERROR("enableFuelGuageIRQs failed.");
+ return batteryRetval::ChargerError;
+ }
+
+ return batteryRetval::OK;
+ }
+
+ batteryRetval configureAlerts()
+ {
+ std::uint16_t regVal = static_cast<std::uint16_t>(CONFIG::Aen);
+
+ if (fuelGaugeWrite(Registers::CONFIG_REG, regVal) != kStatus_Success) {
+ LOG_ERROR("configureAlerts failed.");
+ return batteryRetval::ChargerError;
+ }
+
+ return batteryRetval::OK;
+ }
+
+ batteryRetval enableTopIRQs()
+ {
+ std::uint8_t val = ENABLE_ALL_IRQ_MASK;
+
+ if (chargerTopControllerWrite(Registers::TOP_CONTROLL_IRQ_MASK_REG, val) != kStatus_Success) {
+ LOG_ERROR("enableIRQs read failed.");
+ return batteryRetval::ChargerError;
+ }
+
+ return batteryRetval::OK;
+ }
+
+ void IRQPinsInit()
+ {
+ gpio =
+ drivers::DriverGPIO::Create(static_cast<drivers::GPIOInstances>(BoardDefinitions::BATTERY_CHARGER_GPIO),
+ drivers::DriverGPIOParams{});
+
+ drivers::DriverGPIOPinParams INOKBPinConfig;
+ INOKBPinConfig.dir = drivers::DriverGPIOPinParams::Direction::Input;
+ INOKBPinConfig.irqMode = drivers::DriverGPIOPinParams::InterruptMode::IntRisingOrFallingEdge;
+ INOKBPinConfig.defLogic = 0;
+ INOKBPinConfig.pin = static_cast<std::uint32_t>(BoardDefinitions::BATTERY_CHARGER_INOKB_PIN);
+ gpio->ConfPin(INOKBPinConfig);
+
+ drivers::DriverGPIOPinParams INTBPinConfig;
+ INTBPinConfig.dir = drivers::DriverGPIOPinParams::Direction::Input;
+ INTBPinConfig.irqMode = drivers::DriverGPIOPinParams::InterruptMode::IntFallingEdge;
+ INTBPinConfig.defLogic = 0;
+ INTBPinConfig.pin = static_cast<std::uint32_t>(BoardDefinitions::BATTERY_CHARGER_INTB_PIN);
+ gpio->ConfPin(INTBPinConfig);
+
+ gpio->EnableInterrupt(1 << static_cast<std::uint32_t>(BoardDefinitions::BATTERY_CHARGER_INOKB_PIN));
+ gpio->EnableInterrupt(1 << static_cast<std::uint32_t>(BoardDefinitions::BATTERY_CHARGER_INTB_PIN));
+ }
+ } // namespace
+
+ int init(xQueueHandle queueHandle)
{
- i2c = DriverI2C::Create(
- static_cast<I2CInstances>(BoardDefinitions::BATTERY_CHARGER_I2C),
- DriverI2CParams{.baudrate = static_cast<uint32_t>(BoardDefinitions::BATTERY_CHARGER_I2C_BAUDRATE)});
+ drivers::DriverI2CParams i2cParams;
+ i2cParams.baudrate = static_cast<std::uint32_t>(BoardDefinitions::BATTERY_CHARGER_I2C_BAUDRATE);
+ i2c = drivers::DriverI2C::Create(static_cast<drivers::I2CInstances>(BoardDefinitions::BATTERY_CHARGER_I2C),
+ i2cParams);
- qHandleIrq = qHandle;
+ IRQQueueHandle = queueHandle;
// check Power-On reset bit
- uint16_t status = 0;
- const uint16_t porMask = 0x0002;
- battery_fuelGaugeRead(bsp::batteryChargerRegisters::STATUS_REG, &status);
+ std::uint16_t status = fuelGaugeRead(Registers::STATUS_REG).second;
- if (status & porMask) {
+ if (status & static_cast<std::uint16_t>(STATUS::POR)) {
LOG_INFO("Initializing battery charger");
- battery_loadConfiguration();
- battery_setAvgCalcPeriods();
- battery_setNominalBatteryCapacity(battery_nominalCapacitymAh);
- battery_setChargingDischargingThresholds(battery_fullyChargedPercent, battery_DischargedPercent);
- battery_setTemperatureThresholds(battery_maxTemperatureDegrees, battery_minTemperatureDegrees);
- battery_setServiceVoltageThresholds(battery_maxVoltagemV, battery_minVoltagemV);
+ loadConfiguration();
+ setAvgCalcPeriods();
+ setNominalBatteryCapacity(nominalCapacitymAh);
+ setChargingDischargingThresholds(fullyChargedPercent, DischargedPercent);
+ setTemperatureThresholds(maxTemperatureDegrees, minTemperatureDegrees);
+ setServiceVoltageThresholds(maxVoltagemV, minVoltagemV);
}
- battery_configureAlerts();
- battery_enableFuelGuageIRQs();
+ configureAlerts();
+ enableFuelGuageIRQs();
- uint8_t level = 0;
- bool charging = false;
- battery_getBatteryLevel(level);
- battery_getChargeStatus(charging);
+ StateOfCharge level = getBatteryLevel();
+ bool charging = getChargeStatus();
LOG_INFO("Phone battery start state: %d %d", level, charging);
- battery_ClearAllIRQs();
- battery_enableTopIRQs();
+ clearAllIRQs();
+ enableTopIRQs();
- s_BSP_BatteryChargerIrqPinsInit();
+ IRQPinsInit();
return 0;
}
- void battery_Deinit(void)
+ void deinit()
{
- battery_storeConfiguration();
+ storeConfiguration();
gpio->DisableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::BATTERY_CHARGER_INTB_PIN));
gpio->DisableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::BATTERY_CHARGER_INOKB_PIN));
- gpio->DisableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::BATTERY_CHARGER_WCINOKB));
- qHandleIrq = NULL;
+ IRQQueueHandle = nullptr;
i2c.reset();
gpio.reset();
}
- void battery_getBatteryLevel(uint8_t &levelPercent)
+ StateOfCharge getBatteryLevel()
{
- uint16_t val = 0;
- if (battery_fuelGaugeRead(bsp::batteryChargerRegisters::RepSOC_REG, &val) != kStatus_Success) {
+ auto readout = fuelGaugeRead(Registers::RepSOC_REG);
+ if (readout.first != kStatus_Success) {
LOG_ERROR("failed to get battery percent");
}
- levelPercent = (val & 0xff00) >> 8;
+ StateOfCharge levelPercent = (readout.second & 0xff00) >> 8;
Store::Battery::modify().level = levelPercent;
+ return levelPercent;
}
- void battery_getChargeStatus(bool &status)
+ bool getChargeStatus()
{
- uint8_t val = 0;
+ std::uint8_t val = 0;
// read clears state
- if (battery_chargerRead(bsp::batteryChargerRegisters::CHG_INT_OK, &val) != kStatus_Success) {
+ auto value = chargerRead(Registers::CHG_INT_OK);
+ if (value.first != kStatus_Success) {
LOG_ERROR("failed to read charge status");
}
- status = val & B_CHG_INT::CHGIN_I;
+ bool status = value.second & static_cast<std::uint8_t>(CHG_INT::CHGIN_I);
if (status) {
Store::Battery::modify().state = Store::Battery::State::Charging;
}
else {
Store::Battery::modify().state = Store::Battery::State::Discharging;
}
+ return status;
}
- std::uint16_t battery_getStatusRegister()
+ std::uint16_t getStatusRegister()
{
- uint16_t status = 0;
- battery_fuelGaugeRead(bsp::batteryChargerRegisters::STATUS_REG, &status);
- return status;
+ auto status = fuelGaugeRead(Registers::STATUS_REG);
+ return status.second;
}
- void battery_ClearAllIRQs(void)
+ void clearAllIRQs()
{
- uint8_t val = 0;
- battery_chargerRead(bsp::batteryChargerRegisters::CHG_INT_REG, &val);
- if (val != 0) {
+ auto value = chargerRead(Registers::CHG_INT_REG);
+ if (value.second != 0) {
// write zero to clear irq source
- battery_chargerWrite(bsp::batteryChargerRegisters::CHG_INT_REG, 0);
+ chargerWrite(Registers::CHG_INT_REG, 0);
}
- uint16_t status = battery_getStatusRegister();
+ std::uint16_t status = getStatusRegister();
if (status != 0) {
// write zero to clear irq source
- battery_fuelGaugeWrite(bsp::batteryChargerRegisters::STATUS_REG, 0);
+ fuelGaugeWrite(Registers::STATUS_REG, 0);
}
}
- void battery_clearFuelGuageIRQ(void)
+ void clearFuelGuageIRQ()
{
// write zero to clear interrupt source
- battery_fuelGaugeWrite(bsp::batteryChargerRegisters::STATUS_REG, 0x0000);
+ fuelGaugeWrite(Registers::STATUS_REG, 0x0000);
}
-} // namespace bsp
-
-static int battery_fuelGaugeWrite(bsp::batteryChargerRegisters registerAddress, uint16_t value)
-{
- I2CAddress addr{.deviceAddress = BSP_FUEL_GAUGE_I2C_ADDR,
- .subAddress = static_cast<uint32_t>(registerAddress),
- .subAddressSize = i2cSubaddresSize};
- auto ret = i2c->Write(addr, reinterpret_cast<uint8_t *>(&value), sizeof(uint16_t));
-
- if (ret != sizeof(uint16_t)) {
- return kStatus_Fail;
- }
- else {
- return kStatus_Success;
- }
-}
-
-static int battery_fuelGaugeRead(bsp::batteryChargerRegisters registerAddress, uint16_t *value)
-{
- if (value == NULL) {
- return -1;
- }
-
- I2CAddress addr{.deviceAddress = BSP_FUEL_GAUGE_I2C_ADDR,
- .subAddress = static_cast<uint32_t>(registerAddress),
- .subAddressSize = i2cSubaddresSize};
- auto ret = i2c->Read(addr, reinterpret_cast<uint8_t *>(value), sizeof(uint16_t));
-
- if (ret != sizeof(uint16_t)) {
- return kStatus_Fail;
- }
- else {
- return kStatus_Success;
- }
-}
-
-static int battery_chargerWrite(bsp::batteryChargerRegisters registerAddress, uint8_t value)
-{
-
- I2CAddress addr{.deviceAddress = BSP_BATTERY_CHARGER_I2C_ADDR,
- .subAddress = static_cast<uint32_t>(registerAddress),
- .subAddressSize = i2cSubaddresSize};
- auto ret = i2c->Write(addr, reinterpret_cast<uint8_t *>(&value), sizeof(uint8_t));
-
- if (ret != sizeof(uint8_t)) {
- return kStatus_Fail;
- }
- else {
- return kStatus_Success;
- }
-}
-
-static int battery_chargerRead(bsp::batteryChargerRegisters registerAddress, uint8_t *value)
-{
- if (value == NULL) {
- return -1;
- }
-
- I2CAddress addr{.deviceAddress = BSP_BATTERY_CHARGER_I2C_ADDR,
- .subAddress = static_cast<uint32_t>(registerAddress),
- .subAddressSize = i2cSubaddresSize};
- auto ret = i2c->Read(addr, value, sizeof(uint8_t));
- if (ret != sizeof(uint8_t)) {
- return kStatus_Fail;
- }
- else {
- return kStatus_Success;
- }
-}
-
-static int battery_chargerTopControllerWrite(bsp::batteryChargerRegisters registerAddress, uint8_t value)
-{
-
- I2CAddress addr{.deviceAddress = BSP_TOP_CONTROLLER_I2C_ADDR,
- .subAddress = static_cast<uint32_t>(registerAddress),
- .subAddressSize = i2cSubaddresSize};
- auto ret = i2c->Write(addr, reinterpret_cast<uint8_t *>(&value), sizeof(uint8_t));
- if (ret != sizeof(uint8_t)) {
- return kStatus_Fail;
- }
- else {
- return kStatus_Success;
- }
-}
-
-static int battery_chargerTopControllerRead(bsp::batteryChargerRegisters registerAddress, uint8_t *value)
- __attribute__((used));
-static int battery_chargerTopControllerRead(bsp::batteryChargerRegisters registerAddress, uint8_t *value)
-{
- if (value == NULL) {
- return -1;
- }
-
- I2CAddress addr{.deviceAddress = BSP_TOP_CONTROLLER_I2C_ADDR,
- .subAddress = static_cast<uint32_t>(registerAddress),
- .subAddressSize = i2cSubaddresSize};
- auto ret = i2c->Read(addr, reinterpret_cast<uint8_t *>(value), sizeof(uint8_t));
- if (ret != sizeof(uint8_t)) {
- return kStatus_Fail;
- }
- else {
- return kStatus_Success;
- }
-}
-
-static bsp::batteryRetval battery_loadConfiguration(void)
-{
- auto fd = std::fopen(configs::battery_cfgFile.c_str(), "r");
- if (fd == NULL) {
- LOG_WARN("Configuration file [%s] not found. Searching for file [%s]",
- configs::battery_cfgFile.c_str(),
- configs::battery_cfgFilePrev.c_str());
- fd = std::fopen(configs::battery_cfgFilePrev.c_str(), "r");
- if (fd == NULL) {
- LOG_WARN("Configuration file [%s] not found.", configs::battery_cfgFilePrev.c_str());
- return bsp::batteryRetval::battery_ChargerError;
- }
- }
-
- uint16_t regValue = 0;
- for (uint8_t i = 0; i < 0xff; ++i) {
- if (std::fread(®Value, sizeof(regValue), 1, fd) != sizeof(regValue)) {
- LOG_ERROR("Reading register 0x%x failed.", i);
- std::fclose(fd);
- return bsp::batteryRetval::battery_ChargerError;
- }
-
- if (battery_fuelGaugeWrite(static_cast<bsp::batteryChargerRegisters>(i), regValue) != kStatus_Success) {
- LOG_ERROR("Writing register 0x%x failed.", i);
- std::fclose(fd);
- return bsp::batteryRetval::battery_ChargerError;
+ BaseType_t INOKB_IRQHandler()
+ {
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ if (IRQQueueHandle != nullptr) {
+ std::uint8_t val = static_cast<std::uint8_t>(batteryIRQSource::INOKB);
+ xQueueSendFromISR(IRQQueueHandle, &val, &xHigherPriorityTaskWoken);
}
+ return xHigherPriorityTaskWoken;
}
- return bsp::batteryRetval::battery_OK;
-}
-
-static bsp::batteryRetval battery_storeConfiguration(void)
-{
- // TODO:M.P procedure below seems to crash system, it should be fixed.
- if (rename(configs::battery_cfgFile.c_str(), configs::battery_cfgFilePrev.c_str()) != 0) {
- LOG_ERROR("Could not move configuration file");
- return bsp::batteryRetval::battery_ChargerError;
- }
-
- auto fd = std::fopen(configs::battery_cfgFile.c_str(), "w");
- if (fd == NULL) {
- LOG_ERROR("Could not open configuration file");
- return bsp::batteryRetval::battery_ChargerError;
- }
-
- uint16_t regVal = 0;
- for (unsigned int i = 0; i < 0xff; ++i) {
- if (battery_fuelGaugeRead(static_cast<bsp::batteryChargerRegisters>(i), ®Val) != kStatus_Success) {
- LOG_ERROR("Reading register 0x%x failed.", i);
- std::fclose(fd);
- return bsp::batteryRetval::battery_ChargerError;
- }
-
- if (std::fwrite(®Val, sizeof(regVal), 1, fd) != sizeof(regVal)) {
- LOG_ERROR("Storing register 0x%x failed.", i);
- std::fclose(fd);
- std::remove(configs::battery_cfgFile.c_str());
- return bsp::batteryRetval::battery_ChargerError;
+ BaseType_t INTB_IRQHandler()
+ {
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ if (IRQQueueHandle != nullptr) {
+ std::uint8_t val = static_cast<std::uint8_t>(batteryIRQSource::INTB);
+ xQueueSendFromISR(IRQQueueHandle, &val, &xHigherPriorityTaskWoken);
}
+ return xHigherPriorityTaskWoken;
}
- return bsp::batteryRetval::battery_OK;
-}
-
-static bsp::batteryRetval battery_setAvgCalcPeriods(void)
-{
- uint16_t regVal = 0;
- regVal |= (BATT_SERVICE_AVG_CURRENT_PERIOD << 0);
- regVal |= (BATT_SERVICE_AVG_CELL_VOLTAGE_PERIOD << 4);
- regVal |= (BATT_SERVICE_AVG_MIXING_PERIOD << 7);
- regVal |= (BATT_SERVICE_AVG_TEMP_PERIOD << 11);
- regVal |= (BATT_SERVICE_AVG_NEMPTY_PERIOD << 14);
-
- if (battery_fuelGaugeWrite(bsp::batteryChargerRegisters::FilterCFG_REG, regVal) != kStatus_Success) {
- LOG_ERROR("battery_setAvgCalcPeriods failed.");
- return bsp::batteryRetval::battery_ChargerError;
- }
- return bsp::batteryRetval::battery_OK;
-}
-
-static bsp::batteryRetval battery_setNominalBatteryCapacity(uint16_t capacity)
-{
- uint16_t regVal = capacity * 2;
-
- if (battery_fuelGaugeWrite(bsp::batteryChargerRegisters::DesignCap_REG, regVal) != kStatus_Success) {
- LOG_ERROR("battery_setNominalBatteryCapacity failed.");
- return bsp::batteryRetval::battery_ChargerError;
- }
- return bsp::batteryRetval::battery_OK;
-}
-
-static bsp::batteryRetval battery_setChargingDischargingThresholds(uint8_t chargedThresholdPercent,
- uint8_t dischargedThresholdPercent)
-{
- uint16_t regVal = (chargedThresholdPercent << 8) | dischargedThresholdPercent;
-
- if (battery_fuelGaugeWrite(bsp::batteryChargerRegisters::SALRT_Th_REG, regVal) != kStatus_Success) {
- LOG_ERROR("battery_setChargingDischargingThresholds failed.");
- return bsp::batteryRetval::battery_ChargerError;
- }
- return bsp::batteryRetval::battery_OK;
-}
-
-static bsp::batteryRetval battery_setTemperatureThresholds(uint8_t maxTemperatureDegrees, uint8_t minTemperatureDegrees)
-{
- uint16_t regVal = (maxTemperatureDegrees << 8) | minTemperatureDegrees;
-
- if (battery_fuelGaugeWrite(bsp::batteryChargerRegisters::TALRT_Th_REG, regVal) != kStatus_Success) {
- LOG_ERROR("battery_setTemperatureThresholds failed.");
- return bsp::batteryRetval::battery_ChargerError;
- }
- return bsp::batteryRetval::battery_OK;
-}
-
-static bsp::batteryRetval battery_setServiceVoltageThresholds(uint16_t maxVoltage_mV, uint16_t minVoltage_mV)
-{
- uint16_t regVal = ((maxVoltage_mV / 20) << 8) | (minVoltage_mV / 20);
-
- if (battery_fuelGaugeWrite(bsp::batteryChargerRegisters::VALRT_Th_REG, regVal) != kStatus_Success) {
-
- LOG_ERROR("battery_setServiceVoltageThresholds failed.");
- return bsp::batteryRetval::battery_ChargerError;
- }
- return bsp::batteryRetval::battery_OK;
-}
-
-static bsp::batteryRetval battery_enableFuelGuageIRQs(void)
-{
- uint16_t regVal = 0;
- // set dSOCen bit
- regVal |= (1 << 7);
- if (battery_fuelGaugeWrite(bsp::batteryChargerRegisters::CONFIG2_REG, regVal) != kStatus_Success) {
- LOG_ERROR("battery_enableFuelGuageIRQs failed.");
- return bsp::batteryRetval::battery_ChargerError;
- }
-
- return bsp::batteryRetval::battery_OK;
-}
-
-static bsp::batteryRetval battery_configureAlerts()
-{
- auto regVal = static_cast<std::uint16_t>(bsp::B_CONFIG::Aen); // Enable alerts
-
- if (battery_fuelGaugeWrite(bsp::batteryChargerRegisters::CONFIG_REG, regVal) != kStatus_Success) {
- LOG_ERROR("battery_configureAlerts failed.");
- return bsp::batteryRetval::battery_ChargerError;
- }
-
- return bsp::batteryRetval::battery_OK;
-}
-
-static bsp::batteryRetval battery_enableTopIRQs(void)
-{
- uint8_t val = 0xf8;
-
- if (battery_chargerTopControllerWrite(bsp::batteryChargerRegisters::TOP_CONTROLL_IRQ_MASK_REG, val) !=
- kStatus_Success) {
- LOG_ERROR("battery_enableIRQs read failed.");
- return bsp::batteryRetval::battery_ChargerError;
- }
-
- return bsp::batteryRetval::battery_OK;
-}
-
-BaseType_t BSP_BatteryChargerINOKB_IRQHandler()
-{
- BaseType_t xHigherPriorityTaskWoken = pdFALSE;
- if (qHandleIrq != NULL) {
- uint8_t val = static_cast<uint8_t>(bsp::batteryIRQSource::INOKB);
- xQueueSendFromISR(qHandleIrq, &val, &xHigherPriorityTaskWoken);
- }
- return xHigherPriorityTaskWoken;
-}
-
-BaseType_t BSP_BatteryChargerINTB_IRQHandler()
-{
- BaseType_t xHigherPriorityTaskWoken = pdFALSE;
- if (qHandleIrq != NULL) {
- uint8_t val = static_cast<uint8_t>(bsp::batteryIRQSource::INTB);
- xQueueSendFromISR(qHandleIrq, &val, &xHigherPriorityTaskWoken);
- }
- return xHigherPriorityTaskWoken;
-}
-
-static void s_BSP_BatteryChargerIrqPinsInit()
-{
-
- gpio = DriverGPIO::Create(static_cast<GPIOInstances>(BoardDefinitions::BATTERY_CHARGER_GPIO), DriverGPIOParams{});
-
- gpio->ConfPin(DriverGPIOPinParams{.dir = DriverGPIOPinParams::Direction::Input,
- .irqMode = DriverGPIOPinParams::InterruptMode::IntRisingOrFallingEdge,
- .defLogic = 0,
- .pin = static_cast<uint32_t>(BoardDefinitions::BATTERY_CHARGER_INOKB_PIN)});
-
- gpio->ConfPin(DriverGPIOPinParams{.dir = DriverGPIOPinParams::Direction::Input,
- .irqMode = DriverGPIOPinParams::InterruptMode::IntRisingOrFallingEdge,
- .defLogic = 0,
- .pin = static_cast<uint32_t>(BoardDefinitions::BATTERY_CHARGER_WCINOKB)});
-
- gpio->ConfPin(DriverGPIOPinParams{.dir = DriverGPIOPinParams::Direction::Input,
- .irqMode = DriverGPIOPinParams::InterruptMode::IntFallingEdge,
- .defLogic = 0,
- .pin = static_cast<uint32_t>(BoardDefinitions::BATTERY_CHARGER_INTB_PIN)});
- gpio->EnableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::BATTERY_CHARGER_WCINOKB));
- gpio->EnableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::BATTERY_CHARGER_INOKB_PIN));
- gpio->EnableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::BATTERY_CHARGER_INTB_PIN));
-}
+} // namespace bsp::battery_charger
M module-bsp/board/rt1051/common/irq/irq_gpio.cpp => module-bsp/board/rt1051/common/irq/irq_gpio.cpp +2 -3
@@ 19,7 19,6 @@
#if 0 // TODO:M.P implement the rest of BSP drivers
#include "bsp_cellular.h"
-#include "bsp_battery_charger.h"
#include "bsp_usbc.h"
#include "log.h"
@@ 114,13 113,13 @@ namespace bsp
}
if (irq_mask & (1 << BOARD_BATTERY_CHARGER_INOKB_PIN)) {
- xHigherPriorityTaskWoken |= BSP_BatteryChargerINOKB_IRQHandler();
+ xHigherPriorityTaskWoken |= bsp::battery_charger::INOKB_IRQHandler();
}
if (irq_mask & (1 << BOARD_BATTERY_CHARGER_WCINOKB_PIN)) {}
if (irq_mask & (1 << BOARD_BATTERY_CHARGER_INTB_PIN)) {
- xHigherPriorityTaskWoken |= BSP_BatteryChargerINTB_IRQHandler();
+ xHigherPriorityTaskWoken |= bsp::battery_charger::INTB_IRQHandler();
}
if (irq_mask & (1 << BSP_CELLULAR_SIM_TRAY_INSERTED_PIN)) {
M module-bsp/bsp/battery-charger/battery_charger.hpp => module-bsp/bsp/battery-charger/battery_charger.hpp +28 -102
@@ 1,99 1,25 @@
-/*
- * battery_charger.hpp
- *
- * Created on: Jun 28, 2019
- * Author: kuba
- */
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#ifndef MODULE_BSP_BSP_BATTERY_CHARGER_BATTERY_CHARGER_HPP_
-#define MODULE_BSP_BSP_BATTERY_CHARGER_BATTERY_CHARGER_HPP_
+#pragma once
#include <cstdint>
-namespace bsp{
-
- enum class batteryChargerRegisters{
- TOP_CONTROLL_PMIC_ID_REG = 0x20,
- TOP_CONTROLL_PMIC_VER_REG = 0x21,
- TOP_CONTROLL_IRQ_SRC_REG = 0x22,
- TOP_CONTROLL_IRQ_MASK_REG = 0x23,
- SYSTEM_IRQ_REG = 0x24,
-
- STATUS_REG = 0x00,
- VALRT_Th_REG = 0x01,
- TALRT_Th_REG = 0x02,
- SALRT_Th_REG = 0x03,
- AtRate_REG = 0x04,
- RepCap_REG = 0x05,
- RepSOC_REG = 0x06,
- Age_REG = 0x07,
- TEMP_REG = 0x08,
- VCELL_REG = 0x09,
- Current_REG = 0x0A,
- AvgCurrent_REG = 0x0B,
- QResidual_REG = 0x0C,
- MixSOC_REG = 0x0D,
- AvSOC_REG = 0x0E,
- MixCap_REG = 0x0F,
-
- FullCAP_REG = 0x10,
- TTE_REG = 0x11,
- QRtable00_REG = 0x12,
- FullSOCthr_REG = 0x13,
- RSLOW_REG = 0x14,
- AvgTA_REG = 0x16,
- Cycles_REG = 0x17,
- DesignCap_REG = 0x18,
- AvgVCELL_REG = 0x19,
- MaxMinTemp_REG = 0x1A,
- MaxMinVolt_REG = 0x1B,
- MaxMinCurr_REG = 0x1C,
- CONFIG_REG = 0x1D,
- CONFIG2_REG = 0xBB,
- ICHGTERM_REG = 0x1E,
- AvCap_REG = 0x1F,
-
- TTF_REG = 0x20,
- DevName_REG = 0x21,
- QRtable10_REG = 0x22,
- FullCAPNom_REG = 0x23,
- TempNom_REG = 0x24,
- TempLim_REG = 0x25,
- AIN0_REG = 0x27,
- LearnCFG_REG = 0x28,
- FilterCFG_REG = 0x29,
- RelaxCFG_REG = 0x2A,
- MiscCFG_REG = 0x2B,
- TGAIN_REG = 0x2C,
- TOFF_REG = 0x2D,
- CGAIN_REG = 0x2E,
- COFF_REG = 0x2F,
-
- QRtable20_REG = 0x32,
- AtTTF_REG = 0x33,
- FullCapRep_REG = 0x35,
- lavgEmpty_REG = 0x36,
- FCTC_REG = 0x37,
- RCOMP0_REG = 0x38,
- TempCo_REG = 0x39,
- VEmpty_REG = 0x3A,
- TIMER_REG = 0x3E,
- SHDNTIMER_REG = 0x3F,
-
- QRtable30_REG = 0x42,
- dQ_acc_REG = 0x45,
- dP_acc_REG = 0x46,
- ConvgCfg_REG = 0x49,
- VFRemCap_REG = 0x4A,
- QH_REG = 0x4D,
- CHG_INT_REG = 0xb0,
- CHG_INT_OK = 0xb2
- };
+extern "C"
+{
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+}
+
+namespace bsp::battery_charger
+{
+ using StateOfCharge = std::uint8_t;
enum class batteryRetval{
- battery_OK = 0,
- battery_ChargerError,
- battery_ChargerNotCharging,
- battery_ChargerCharging
+ OK,
+ ChargerError,
+ ChargerNotCharging,
+ ChargerCharging
};
enum class batteryIRQSource{
@@ 107,24 33,24 @@ namespace bsp{
SOCOnePercentChange = 1 << 7
};
- int battery_Init(xQueueHandle qHandle);
+ int init(xQueueHandle queueHandle);
- void battery_Deinit(void);
+ void deinit();
- void battery_getBatteryLevel(uint8_t& levelPercent);
+ StateOfCharge getBatteryLevel();
- void battery_getChargeStatus( bool& status);
+ bool getChargeStatus();
- void battery_ClearAllIRQs(void);
+ void clearAllIRQs();
- void battery_clearFuelGuageIRQ(void);
+ void clearFuelGuageIRQ();
- std::uint16_t battery_getStatusRegister();
-}
+ std::uint16_t getStatusRegister();
+
+ BaseType_t INOKB_IRQHandler();
-BaseType_t BSP_BatteryChargerINOKB_IRQHandler();
+ BaseType_t INTB_IRQHandler();
+} // bsp::battery_charger
-BaseType_t BSP_BatteryChargerINTB_IRQHandler();
-#endif /* MODULE_BSP_BSP_BATTERY_CHARGER_BATTERY_CHARGER_HPP_*/
M module-db/Common/Query.cpp => module-db/Common/Query.cpp +1 -1
@@ 21,7 21,7 @@ bool QueryCallback::handleQueryResponse(QueryResult *response)
return callback(response);
}
-EndpointListener::EndpointListener(EndpointQueryCallbackFunction &&_callback, Context &_context)
+EndpointListener::EndpointListener(EndpointQueryCallbackFunction &&_callback, parserFSM::Context &_context)
: callback{std::move(_callback)}, context{_context}
{}
M module-db/Common/Query.hpp => module-db/Common/Query.hpp +3 -5
@@ 9,13 9,11 @@
#include <log/log.hpp>
#include <module-services/service-desktop/endpoints/Context.hpp>
-using namespace parserFSM;
-
namespace db
{
class QueryResult; // Forward declaration
using QueryCallbackFunction = std::function<bool(db::QueryResult *)>;
- using EndpointQueryCallbackFunction = std::function<bool(db::QueryResult *, Context &)>;
+ using EndpointQueryCallbackFunction = std::function<bool(db::QueryResult *, parserFSM::Context &)>;
class QueryListener
{
@@ 42,13 40,13 @@ namespace db
{
public:
EndpointListener() = default;
- EndpointListener(EndpointQueryCallbackFunction &&_callback, Context &_context);
+ EndpointListener(EndpointQueryCallbackFunction &&_callback, parserFSM::Context &_context);
bool handleQueryResponse(db::QueryResult *result) override;
private:
EndpointQueryCallbackFunction callback;
- Context context;
+ parserFSM::Context context;
};
/// virtual query input interface
M module-db/Interface/AlarmsRecord.hpp => module-db/Interface/AlarmsRecord.hpp +1 -1
@@ 28,7 28,7 @@ namespace db::query::alarms
struct AlarmsRecord : public Record
{
- TimePoint time = TIME_POINT_INVALID;
+ calendar::TimePoint time = TIME_POINT_INVALID;
uint32_t snooze = 0;
AlarmStatus status = AlarmStatus::On;
uint32_t repeat = 0;
M module-db/Interface/EventsRecord.cpp => module-db/Interface/EventsRecord.cpp +5 -4
@@ 70,8 70,8 @@ bool EventsRecordInterface::Add(const EventsRecord &rec)
return false;
}
-std::vector<EventsRecord> EventsRecordInterface::Select(TimePoint filter_from,
- TimePoint filter_till,
+std::vector<EventsRecord> EventsRecordInterface::Select(calendar::TimePoint filter_from,
+ calendar::TimePoint filter_till,
uint32_t offset,
uint32_t limit)
{
@@ 265,12 265,13 @@ uint32_t EventsRecordInterface::GetCount()
return eventsDb->events.count();
}
-uint32_t EventsRecordInterface::GetCountFiltered(TimePoint from, TimePoint till)
+uint32_t EventsRecordInterface::GetCountFiltered(calendar::TimePoint from, calendar::TimePoint till)
{
return eventsDb->events.countFromFilter(from, till);
}
-std::vector<EventsRecord> EventsRecordInterface::SelectFirstUpcoming(TimePoint filter_from, TimePoint filter_till)
+std::vector<EventsRecord> EventsRecordInterface::SelectFirstUpcoming(calendar::TimePoint filter_from,
+ calendar::TimePoint filter_till)
{
auto rows = eventsDb->events.SelectFirstUpcoming(filter_from, filter_till);
M module-db/Interface/EventsRecord.hpp => module-db/Interface/EventsRecord.hpp +9 -6
@@ 41,11 41,11 @@ struct EventsRecord : public Record
{
std::string UID;
std::string title;
- TimePoint date_from;
- TimePoint date_till;
+ calendar::TimePoint date_from;
+ calendar::TimePoint date_till;
uint32_t reminder = 0;
uint32_t repeat = 0;
- TimePoint reminder_fired;
+ calendar::TimePoint reminder_fired;
std::string provider_type;
std::string provider_id;
std::string provider_iCalUid;
@@ 77,15 77,18 @@ class EventsRecordInterface : public RecordInterface<EventsRecord, EventsRecordF
EventsRecord GetByID(uint32_t id) override final;
EventsRecord GetByUID(const std::string &uid);
uint32_t GetCount() override final;
- uint32_t GetCountFiltered(TimePoint from, TimePoint till);
- std::vector<EventsRecord> Select(TimePoint filter_from, TimePoint filter_till, uint32_t offset, uint32_t limit);
+ uint32_t GetCountFiltered(calendar::TimePoint from, calendar::TimePoint till);
+ std::vector<EventsRecord> Select(calendar::TimePoint filter_from,
+ calendar::TimePoint filter_till,
+ uint32_t offset,
+ uint32_t limit);
std::unique_ptr<std::vector<EventsRecord>> GetLimitOffset(uint32_t offset, uint32_t limit) override final;
std::unique_ptr<std::vector<EventsRecord>> GetLimitOffsetByField(uint32_t offset,
uint32_t limit,
EventsRecordField field,
const char *str) override final;
std::vector<EventsRecord> GetLimitOffsetByDate(uint32_t offset, uint32_t limit);
- std::vector<EventsRecord> SelectFirstUpcoming(TimePoint filter_from, TimePoint filter_till);
+ std::vector<EventsRecord> SelectFirstUpcoming(calendar::TimePoint filter_from, calendar::TimePoint filter_till);
std::unique_ptr<db::QueryResult> runQuery(std::shared_ptr<db::Query> query) override;
M module-db/Tables/AlarmsTable.cpp => module-db/Tables/AlarmsTable.cpp +1 -1
@@ 9,7 9,7 @@ AlarmsTableRow::AlarmsTableRow(const AlarmsRecord &rec)
{}
AlarmsTableRow::AlarmsTableRow(
- uint32_t id, TimePoint time, uint32_t snooze, AlarmStatus status, uint32_t repeat, UTF8 path)
+ uint32_t id, calendar::TimePoint time, uint32_t snooze, AlarmStatus status, uint32_t repeat, UTF8 path)
: Record{id}, time{time}, snooze{snooze}, status{status}, repeat{repeat}, path{std::move(path)}
{}
M module-db/Tables/AlarmsTable.hpp => module-db/Tables/AlarmsTable.hpp +3 -2
@@ 25,14 25,15 @@ enum class AlarmStatus
struct AlarmsTableRow : public Record
{
- TimePoint time = TIME_POINT_INVALID;
+ calendar::TimePoint time = TIME_POINT_INVALID;
uint32_t snooze = 0;
AlarmStatus status = AlarmStatus::On;
uint32_t repeat = 0;
UTF8 path;
AlarmsTableRow() = default;
- AlarmsTableRow(uint32_t id, TimePoint time, uint32_t snooze, AlarmStatus status, uint32_t repeat, UTF8 path);
+ AlarmsTableRow(
+ uint32_t id, calendar::TimePoint time, uint32_t snooze, AlarmStatus status, uint32_t repeat, UTF8 path);
explicit AlarmsTableRow(const AlarmsRecord &rec);
explicit AlarmsTableRow(const QueryResult &result);
};
M module-db/Tables/EventsTable.cpp => module-db/Tables/EventsTable.cpp +5 -4
@@ 643,8 643,8 @@ EventsTableRow EventsTable::getByUID(const std::string &UID)
};
}
-std::vector<EventsTableRow> EventsTable::selectByDatePeriod(TimePoint date_filter,
- TimePoint filter_till,
+std::vector<EventsTableRow> EventsTable::selectByDatePeriod(calendar::TimePoint date_filter,
+ calendar::TimePoint filter_till,
uint32_t offset,
uint32_t limit)
{
@@ 770,7 770,7 @@ uint32_t EventsTable::count()
return (*queryRet)[0].getUInt32();
}
-uint32_t EventsTable::countFromFilter(TimePoint from, TimePoint till)
+uint32_t EventsTable::countFromFilter(calendar::TimePoint from, calendar::TimePoint till)
{
auto queryRet = db->query(
"SELECT COUNT(*) FROM events WHERE date_from >= date('%q') AND date_from < date('%q', 'start of day');",
@@ 791,7 791,8 @@ uint32_t EventsTable::countByFieldId(const char *field, uint32_t id)
return 0;
}
-std::vector<EventsTableRow> EventsTable::SelectFirstUpcoming(TimePoint filter_from, TimePoint filter_till)
+std::vector<EventsTableRow> EventsTable::SelectFirstUpcoming(calendar::TimePoint filter_from,
+ calendar::TimePoint filter_till)
{
auto retQuery = db->query("SELECT DATETIME(date_from, '-' || reminder || ' minutes') AS calc_dt, * "
"FROM events "
M module-db/Tables/EventsTable.hpp => module-db/Tables/EventsTable.hpp +7 -7
@@ 14,11 14,11 @@ struct EventsTableRow : public Record
{
std::string UID;
std::string title;
- TimePoint date_from = TIME_POINT_INVALID;
- TimePoint date_till = TIME_POINT_INVALID;
+ calendar::TimePoint date_from = TIME_POINT_INVALID;
+ calendar::TimePoint date_till = TIME_POINT_INVALID;
uint32_t reminder = 0;
uint32_t repeat = 0;
- TimePoint reminder_fired = TIME_POINT_INVALID;
+ calendar::TimePoint reminder_fired = TIME_POINT_INVALID;
std::string provider_type;
std::string provider_id;
std::string provider_iCalUid;
@@ 53,12 53,12 @@ class EventsTable : public Table<EventsTableRow, EventsTableFields>
bool drop();
EventsTableRow getByUID(const std::string &UID);
EventsTableRow getById(uint32_t id) override final;
- std::vector<EventsTableRow> selectByDatePeriod(TimePoint filter_from,
- TimePoint filter_till,
+ std::vector<EventsTableRow> selectByDatePeriod(calendar::TimePoint filter_from,
+ calendar::TimePoint filter_till,
uint32_t offset,
uint32_t limit);
uint32_t count() override final;
- uint32_t countFromFilter(TimePoint from, TimePoint till);
+ uint32_t countFromFilter(calendar::TimePoint from, calendar::TimePoint till);
uint32_t countByFieldId(const char *field, uint32_t id) override final;
std::vector<EventsTableRow> getLimitOffset(uint32_t offset, uint32_t limit) override final;
std::vector<EventsTableRow> getLimitOffsetByField(uint32_t offset,
@@ 67,7 67,7 @@ class EventsTable : public Table<EventsTableRow, EventsTableFields>
const char *str) override final;
std::vector<EventsTableRow> getLimitOffsetByDate(uint32_t offset, uint32_t limit);
- std::vector<EventsTableRow> SelectFirstUpcoming(TimePoint filter_from, TimePoint filter_till);
+ std::vector<EventsTableRow> SelectFirstUpcoming(calendar::TimePoint filter_from, calendar::TimePoint filter_till);
private:
const char *createTableQuery = "CREATE TABLE IF NOT EXISTS events("
M module-db/queries/calendar/QueryEventsGetFiltered.cpp => module-db/queries/calendar/QueryEventsGetFiltered.cpp +4 -1
@@ 5,7 5,10 @@
namespace db::query::events
{
- GetFiltered::GetFiltered(TimePoint filter_from, TimePoint filter_till, uint32_t offset, uint32_t limit)
+ GetFiltered::GetFiltered(calendar::TimePoint filter_from,
+ calendar::TimePoint filter_till,
+ uint32_t offset,
+ uint32_t limit)
: Query(Query::Type::Read), filter_from(filter_from), filter_till(filter_till), offset(offset), limit(limit)
{}
M module-db/queries/calendar/QueryEventsGetFiltered.hpp => module-db/queries/calendar/QueryEventsGetFiltered.hpp +6 -3
@@ 13,11 13,14 @@ namespace db::query::events
class GetFiltered : public Query
{
public:
- GetFiltered(TimePoint filter_from, TimePoint filter_till, uint32_t offset = 0, uint32_t limit = UINT32_MAX);
+ GetFiltered(calendar::TimePoint filter_from,
+ calendar::TimePoint filter_till,
+ uint32_t offset = 0,
+ uint32_t limit = UINT32_MAX);
[[nodiscard]] auto debugInfo() const -> std::string override;
- TimePoint filter_from;
- TimePoint filter_till;
+ calendar::TimePoint filter_from;
+ calendar::TimePoint filter_till;
uint32_t offset;
uint32_t limit;
};
M module-db/queries/calendar/QueryEventsSelectFirstUpcoming.cpp => module-db/queries/calendar/QueryEventsSelectFirstUpcoming.cpp +1 -1
@@ 5,7 5,7 @@
namespace db::query::events
{
- SelectFirstUpcoming::SelectFirstUpcoming(TimePoint filter_from, TimePoint filter_till)
+ SelectFirstUpcoming::SelectFirstUpcoming(calendar::TimePoint filter_from, calendar::TimePoint filter_till)
: Query(Query::Type::Read), filter_from(filter_from), filter_till(filter_till)
{}
M module-db/queries/calendar/QueryEventsSelectFirstUpcoming.hpp => module-db/queries/calendar/QueryEventsSelectFirstUpcoming.hpp +3 -3
@@ 14,11 14,11 @@ namespace db::query::events
class SelectFirstUpcoming : public Query
{
public:
- SelectFirstUpcoming(TimePoint filter_from, TimePoint filter_till);
+ SelectFirstUpcoming(calendar::TimePoint filter_from, calendar::TimePoint filter_till);
[[nodiscard]] auto debugInfo() const -> std::string override;
- TimePoint filter_from;
- TimePoint filter_till;
+ calendar::TimePoint filter_from;
+ calendar::TimePoint filter_till;
};
/// Result of SelectFirstUpcoming query
M module-db/tests/AlarmsRecord_tests.cpp => module-db/tests/AlarmsRecord_tests.cpp +1 -1
@@ 183,7 183,7 @@ TEST_CASE("Alarms Record tests")
}
auto getQuery = [&](uint32_t id,
- TimePoint alarmTime,
+ calendar::TimePoint alarmTime,
uint32_t snooze,
AlarmStatus status,
uint32_t repeat,
M module-db/tests/AlarmsTable_tests.cpp => module-db/tests/AlarmsTable_tests.cpp +5 -5
@@ 138,11 138,11 @@ TEST_CASE("Alarms Table tests")
REQUIRE(alarmsTbl.add(
AlarmsTableRow(5, TimePointFromString("2020-12-11 07:15:00"), 1, AlarmStatus::On, 1, "file2.mp3")));
- const std::array<TimePoint, 5> paramTime{TimePointFromString("2020-12-11 07:15:00"),
- TimePointFromString("2020-11-11 15:10:00"),
- TimePointFromString("2020-11-11 15:15:00"),
- TimePointFromString("2020-11-12 17:10:00"),
- TimePointFromString("2020-11-11 19:25:00")};
+ const std::array<calendar::TimePoint, 5> paramTime{TimePointFromString("2020-12-11 07:15:00"),
+ TimePointFromString("2020-11-11 15:10:00"),
+ TimePointFromString("2020-11-11 15:15:00"),
+ TimePointFromString("2020-11-12 17:10:00"),
+ TimePointFromString("2020-11-11 19:25:00")};
REQUIRE(alarmsTbl.count() == 5);
auto entries = alarmsTbl.getLimitOffset(0, 5);
M module-db/tests/EventsRecord_tests.cpp => module-db/tests/EventsRecord_tests.cpp +8 -3
@@ 22,6 22,8 @@
#include <filesystem>
#include <iostream>
+using namespace std::chrono_literals;
+
static auto remove_events(EventsDB &db) -> bool
{
auto count = db.events.count();
@@ 728,7 730,7 @@ TEST_CASE("Events Record tests")
SECTION("Select first upcoming event")
{
- TimePoint start_date = TimePointFromString("2019-10-19 14:24:00");
+ calendar::TimePoint start_date = TimePointFromString("2019-10-19 14:24:00");
auto nextUpcoming = eventsRecordInterface.SelectFirstUpcoming(start_date, start_date);
REQUIRE(nextUpcoming.size() == 1);
EventsRecord nextEventsRecord = nextUpcoming.at(0);
@@ 797,7 799,9 @@ TEST_CASE("Events Record tests")
getAll(expectedRecords, numberOfEvents);
}
- auto getFiltered = [&](TimePoint filter_from, TimePoint filter_till, std::vector<EventsRecord> expected_records) {
+ auto getFiltered = [&](calendar::TimePoint filter_from,
+ calendar::TimePoint filter_till,
+ std::vector<EventsRecord> expected_records) {
auto query = std::make_shared<db::query::events::GetFiltered>(filter_from, filter_till);
auto ret = eventsRecordInterface.runQuery(query);
auto result = dynamic_cast<db::query::events::GetFilteredResult *>(ret.get());
@@ 1009,7 1013,8 @@ TEST_CASE("Events Record tests")
EditQueryICS(testRecord6.UID, testRecord6);
}
- [[maybe_unused]] auto selectFirstUpcomingEvent = [&](TimePoint filter_from, TimePoint filter_till) {
+ [[maybe_unused]] auto selectFirstUpcomingEvent = [&](calendar::TimePoint filter_from,
+ calendar::TimePoint filter_till) {
auto query = std::make_shared<db::query::events::SelectFirstUpcoming>(filter_from, filter_till);
auto ret = eventsRecordInterface.runQuery(query);
auto result = dynamic_cast<db::query::events::SelectFirstUpcomingResult *>(ret.get());
M module-db/tests/EventsTable_tests.cpp => module-db/tests/EventsTable_tests.cpp +50 -45
@@ 7,12 7,16 @@
#include "Databases/EventsDB.hpp"
#include "Tables/EventsTable.hpp"
-#include <cstdint>
-#include <filesystem>
+#include <vfs.hpp>
+#include <stdint.h>
#include <string>
#include <algorithm>
+#include <iostream>
+#include <purefs/filesystem_paths.hpp>
#include <unistd.h>
+using namespace std::chrono_literals;
+
static auto remove_events(EventsDB &db) -> bool
{
auto count = db.events.count();
@@ 29,12 33,10 @@ TEST_CASE("Events Table tests")
Database::initialize();
- const auto eventsPath = (std::filesystem::path{"user"} / "events.db");
- if (std::filesystem::exists(eventsPath)) {
- REQUIRE(std::filesystem::remove(eventsPath));
- }
+ const auto eventsPath = (purefs::dir::getUserDiskPath() / "events.db").c_str();
+ std::filesystem::remove(eventsPath);
- EventsDB eventsDb{eventsPath.c_str()};
+ EventsDB eventsDb{eventsPath};
REQUIRE(eventsDb.isInitialized());
auto &eventsTbl = eventsDb.events;
@@ 164,8 166,8 @@ TEST_CASE("Events Table tests")
CHECK(eventsTbl.count() == 0);
uint32_t numberOfEvents = 7;
- TimePoint startDate = TimePointFromString("2019-10-20 14:30:00");
- TimePoint endDate = TimePointFromString("2019-10-20 15:30:00");
+ calendar::TimePoint startDate = TimePointFromString("2019-10-20 14:30:00");
+ calendar::TimePoint endDate = TimePointFromString("2019-10-20 15:30:00");
testRow1.date_from = startDate;
testRow1.date_till = endDate;
CHECK(eventsTbl.addDaily(testRow1));
@@ 199,8 201,8 @@ TEST_CASE("Events Table tests")
CHECK(eventsTbl.count() == 0);
uint32_t numberOfEvents = 4;
- TimePoint startDate = TimePointFromString("2019-10-20 14:30:00");
- TimePoint endDate = TimePointFromString("2019-10-20 15:30:00");
+ calendar::TimePoint startDate = TimePointFromString("2019-10-20 14:30:00");
+ calendar::TimePoint endDate = TimePointFromString("2019-10-20 15:30:00");
testRow1.date_from = startDate;
testRow1.date_till = endDate;
CHECK(eventsTbl.addWeekly(testRow1));
@@ 234,8 236,8 @@ TEST_CASE("Events Table tests")
CHECK(eventsTbl.count() == 0);
uint32_t numberOfEvents = 4;
- TimePoint startDate = TimePointFromString("2019-10-20 14:30:00");
- TimePoint endDate = TimePointFromString("2019-10-20 15:30:00");
+ calendar::TimePoint startDate = TimePointFromString("2019-10-20 14:30:00");
+ calendar::TimePoint endDate = TimePointFromString("2019-10-20 15:30:00");
testRow1.date_from = startDate;
testRow1.date_till = endDate;
CHECK(eventsTbl.addTwoWeeks(testRow1));
@@ 269,7 271,7 @@ TEST_CASE("Events Table tests")
CHECK(eventsTbl.count() == 0);
uint32_t numberOfEvents = 12;
- const std::array<TimePoint, 24> dates{
+ const std::array<calendar::TimePoint, 24> dates{
TimePointFromString("2019-01-20 14:30:00"), TimePointFromString("2019-01-20 15:30:00"),
TimePointFromString("2019-02-20 14:30:00"), TimePointFromString("2019-02-20 15:30:00"),
TimePointFromString("2019-03-20 14:30:00"), TimePointFromString("2019-03-20 15:30:00"),
@@ 295,6 297,8 @@ TEST_CASE("Events Table tests")
uint32_t index = 0;
for (auto entry : entries) {
CHECK(entry.title == testRow1.title);
+ CHECK(TimePointToString(entry.date_from) == TimePointToString(dates[index]));
+ CHECK(TimePointToString(entry.date_till) == TimePointToString(dates[index + 1]));
CHECK(entry.reminder == testRow1.reminder);
CHECK(entry.repeat == testRow1.repeat);
CHECK(entry.reminder_fired == testRow1.reminder_fired);
@@ 314,14 318,14 @@ TEST_CASE("Events Table tests")
REQUIRE(eventsTbl.count() == 0);
uint32_t numberOfEvents = 4;
- std::array<TimePoint, 8> dates{TimePointFromString("2019-02-20 14:30:00"),
- TimePointFromString("2019-02-20 15:30:00"),
- TimePointFromString("2020-02-20 14:30:00"),
- TimePointFromString("2020-02-20 15:30:00"),
- TimePointFromString("2021-02-20 14:30:00"),
- TimePointFromString("2021-02-20 15:30:00"),
- TimePointFromString("2022-02-20 14:30:00"),
- TimePointFromString("2022-02-20 15:30:00")};
+ std::array<calendar::TimePoint, 8> dates{TimePointFromString("2019-02-20 14:30:00"),
+ TimePointFromString("2019-02-20 15:30:00"),
+ TimePointFromString("2020-02-20 14:30:00"),
+ TimePointFromString("2020-02-20 15:30:00"),
+ TimePointFromString("2021-02-20 14:30:00"),
+ TimePointFromString("2021-02-20 15:30:00"),
+ TimePointFromString("2022-02-20 14:30:00"),
+ TimePointFromString("2022-02-20 15:30:00")};
testRow1.date_from = dates[0];
testRow1.date_till = dates[1];
@@ 335,6 339,8 @@ TEST_CASE("Events Table tests")
uint32_t index = 0;
for (auto entry : entries) {
CHECK(entry.title == testRow1.title);
+ CHECK(TimePointToString(entry.date_from) == TimePointToString(dates[index]));
+ CHECK(TimePointToString(entry.date_till) == TimePointToString(dates[index + 1]));
CHECK(entry.reminder == testRow1.reminder);
CHECK(entry.repeat == testRow1.repeat);
CHECK(entry.reminder_fired == testRow1.reminder_fired);
@@ 344,7 350,6 @@ TEST_CASE("Events Table tests")
CHECK(entry.isValid());
index += 2;
}
- REQUIRE(index == 2 * numberOfEvents);
}
enum class weekDayOption
@@ 362,8 367,8 @@ TEST_CASE("Events Table tests")
{
auto check_custom_repeat = [&](uint32_t customRepeatOption,
uint32_t numberOfEvents,
- TimePoint originalStartDate,
- TimePoint originalEndDate) {
+ calendar::TimePoint originalStartDate,
+ calendar::TimePoint originalEndDate) {
if (eventsTbl.count() > 0) {
REQUIRE(remove_events(eventsDb));
}
@@ 391,8 396,8 @@ TEST_CASE("Events Table tests")
}
}
- TimePoint expectedStartDate = TimePointFromString("2020-12-07 15:30:00"); // monday
- TimePoint expectedEndDate = TimePointFromString("2020-12-07 16:30:00"); // monday
+ calendar::TimePoint expectedStartDate = TimePointFromString("2020-12-07 14:30:00"); // monday
+ calendar::TimePoint expectedEndDate = TimePointFromString("2020-12-07 15:30:00"); // monday
uint32_t i = 0;
for (uint32_t l = 0; l < numberOfWeeks; l++) {
@@ 434,8 439,8 @@ TEST_CASE("Events Table tests")
uint32_t customRepeatOption =
static_cast<uint32_t>(weekDayOption::monday) + static_cast<uint32_t>(weekDayOption::wednesday);
uint32_t numberOfEvents = 9;
- TimePoint originalStartDate = TimePointFromString("2020-12-10 14:30:00"); // thursday
- TimePoint originalEndDate = TimePointFromString("2020-12-10 15:30:00"); // thursday
+ calendar::TimePoint originalStartDate = TimePointFromString("2020-12-10 14:30:00"); // thursday
+ calendar::TimePoint originalEndDate = TimePointFromString("2020-12-10 15:30:00"); // thursday
check_custom_repeat(customRepeatOption, numberOfEvents, originalStartDate, originalEndDate);
}
@@ 446,8 451,8 @@ TEST_CASE("Events Table tests")
static_cast<uint32_t>(weekDayOption::monday) + static_cast<uint32_t>(weekDayOption::wednesday) +
static_cast<uint32_t>(weekDayOption::tuesday) + static_cast<uint32_t>(weekDayOption::sunday);
uint32_t numberOfEvents = 17;
- TimePoint originalStartDate = TimePointFromString("2020-12-10 14:30:00"); // thursday
- TimePoint originalEndDate = TimePointFromString("2020-12-10 15:30:00"); // thursday
+ calendar::TimePoint originalStartDate = TimePointFromString("2020-12-10 14:30:00"); // thursday
+ calendar::TimePoint originalEndDate = TimePointFromString("2020-12-10 15:30:00"); // thursday
check_custom_repeat(customRepeatOption, numberOfEvents, originalStartDate, originalEndDate);
}
@@ 456,8 461,8 @@ TEST_CASE("Events Table tests")
{
uint32_t customRepeatOption = static_cast<uint32_t>(weekDayOption::saturday);
uint32_t numberOfEvents = 5;
- TimePoint originalStartDate = TimePointFromString("2020-12-10 14:30:00"); // thursday
- TimePoint originalEndDate = TimePointFromString("2020-12-10 15:30:00"); // thursday
+ calendar::TimePoint originalStartDate = TimePointFromString("2020-12-10 14:30:00"); // thursday
+ calendar::TimePoint originalEndDate = TimePointFromString("2020-12-10 15:30:00"); // thursday
check_custom_repeat(customRepeatOption, numberOfEvents, originalStartDate, originalEndDate);
}
@@ 465,8 470,8 @@ TEST_CASE("Events Table tests")
SECTION("Check count from filter")
{
- TimePoint from = TimePointFromString("2019-10-20 14:30:00");
- TimePoint till = TimePointFromString("2019-10-24 14:20:00");
+ calendar::TimePoint from = TimePointFromString("2019-10-20 14:30:00");
+ calendar::TimePoint till = TimePointFromString("2019-10-24 14:20:00");
CHECK(eventsTbl.countFromFilter(from, till) == 4);
}
@@ 511,8 516,8 @@ TEST_CASE("Events Table tests")
CHECK(eventsTbl.count() == 6);
std::string newTitle = "Updated Title", newProviderID = "PurePhoneUpdated";
- TimePoint newDateFrom = TimePointFromString("2020-10-20 15:00:00"),
- newDateTill = TimePointFromString("2020-10-20 16:00:00");
+ calendar::TimePoint newDateFrom = TimePointFromString("2020-10-20 15:00:00"),
+ newDateTill = TimePointFromString("2020-10-20 16:00:00");
uint32_t newReminder = static_cast<uint32_t>(Reminder::one_week_before);
uint32_t newRepeatOption = static_cast<uint32_t>(Repeat::biweekly);
@@ 567,8 572,8 @@ TEST_CASE("Events Table tests")
std::string newTitle = "Updated Title", newProviderType = "PurePhoneUpdate", newProviderID = "newID",
newProvideriCalUid = "new iCalUid";
- TimePoint newDateFrom = TimePointFromString("2020-10-20 15:00:00"),
- newDateTill = TimePointFromString("2020-10-20 16:00:00");
+ calendar::TimePoint newDateFrom = TimePointFromString("2020-10-20 15:00:00"),
+ newDateTill = TimePointFromString("2020-10-20 16:00:00");
uint32_t newReminder = static_cast<uint32_t>(Reminder::one_week_before);
uint32_t newRepeatOption = static_cast<uint32_t>(Repeat::biweekly);
@@ 625,8 630,8 @@ TEST_CASE("Events Table tests")
std::string newTitle = "Updated Title", newProviderType = "PurePhoneUpdate", newProviderID = "newID",
newProvideriCalUid = "new iCalUid";
- TimePoint newDateFrom = TimePointFromString("2020-10-20 15:00:00"),
- newDateTill = TimePointFromString("2020-10-20 16:00:00");
+ calendar::TimePoint newDateFrom = TimePointFromString("2020-10-20 15:00:00"),
+ newDateTill = TimePointFromString("2020-10-20 16:00:00");
uint32_t newReminder = static_cast<uint32_t>(Reminder::one_week_before);
uint32_t newRepeatOption = static_cast<uint32_t>(Repeat::biweekly);
@@ 724,11 729,11 @@ TEST_CASE("Events Table tests")
}
CHECK(eventsTbl.count() == 0);
- TimePoint startDate1 = TimePointFromString("2018-10-20 14:24:00");
- TimePoint startDate2 = TimePointFromString("2020-10-20 14:24:00");
+ calendar::TimePoint startDate1 = TimePointFromString("2018-10-20 14:24:00");
+ calendar::TimePoint startDate2 = TimePointFromString("2020-10-20 14:24:00");
- TimePoint tillDate = TimePointFromString("2030-10-20 15:24:00");
- TimePoint firedDate = TimePointFromString("2018-10-20 14:24:00");
+ calendar::TimePoint tillDate = TimePointFromString("2030-10-20 15:24:00");
+ calendar::TimePoint firedDate = TimePointFromString("2018-10-20 14:24:00");
EventsTableRow testEvent1 = {{1},
.UID = "test1",
M module-db/tests/QueryInterface.cpp => module-db/tests/QueryInterface.cpp +2 -2
@@ 75,9 75,9 @@ TEST_CASE("Query interface")
auto msgJson = json11::Json::parse(testMessage, err);
REQUIRE(err.empty());
- Context context(msgJson);
+ parserFSM::Context context(msgJson);
auto listener = std::make_unique<db::EndpointListener>(
- [=](db::QueryResult *result, Context &context) {
+ [=](db::QueryResult *result, parserFSM::Context &context) {
if (auto SMSResult = dynamic_cast<db::query::SMSGetCountResult *>(result)) {
auto id = SMSResult->getResults();
auto body = json11::Json::object{{"count", static_cast<int>(id)}};
M module-gui/gui/dom/Item2JsonSerializingVisitor.cpp => module-gui/gui/dom/Item2JsonSerializingVisitor.cpp +1 -1
@@ 85,7 85,7 @@ void Item2JsonSerializingVisitor::visit(gui::BottomBar &item)
visit(static_cast<gui::Item &>(item));
}
-void Item2JsonSerializingVisitor::visit(gui::TopBar &item)
+void Item2JsonSerializingVisitor::visit(gui::top_bar::TopBar &item)
{
if (itemName.empty()) {
itemName = magic_enum::enum_name(visitor::Names::TopBar);
M module-gui/gui/dom/Item2JsonSerializingVisitor.hpp => module-gui/gui/dom/Item2JsonSerializingVisitor.hpp +1 -1
@@ 29,7 29,7 @@ namespace gui
void visit(gui::Window &item) override;
void visit(gui::Label &item) override;
void visit(gui::BottomBar &item) override;
- void visit(gui::TopBar &item) override;
+ void visit(gui::top_bar::TopBar &item) override;
public:
/// retrieves current state of the `sink`. The state of the `sink` after call is default-initialized
M module-gui/gui/widgets/BoxLayout.cpp => module-gui/gui/widgets/BoxLayout.cpp +6 -6
@@ 110,7 110,7 @@ namespace gui
/// this if back / front is crappy :|
if (previous) {
for (auto el = children.rbegin(); el != children.rend(); ++el) {
- if ((*el)->visible && (*el)->activeItem) {
+ if ((*el)->isActive()) {
setFocusItem(*el);
break;
}
@@ 118,7 118,7 @@ namespace gui
}
else {
for (auto &el : children) {
- if (el->visible && el->activeItem) {
+ if (el->isActive()) {
setFocusItem(el);
break;
}
@@ 375,7 375,7 @@ namespace gui
std::list<Item *>::iterator BoxLayout::nextNavigationItem(std::list<Item *>::iterator from)
{
return std::find_if(from, this->children.end(), [](auto &el) -> bool {
- if (el->visible && el->activeItem) {
+ if (el->isActive()) {
return true;
}
return false;
@@ 474,7 474,7 @@ namespace gui
bool success = false;
for (auto child : children) {
- if (child->activeItem && child->visible) {
+ if (child->isActive()) {
if (elementNumber == i) {
child->setFocus(true);
@@ 496,7 496,7 @@ namespace gui
auto last = true;
for (auto child = children.rbegin(); child != children.rend(); child++) {
- if ((*child)->activeItem && (*child)->visible && last) {
+ if ((*child)->isActive() && last) {
(*child)->setFocus(true);
focusItem = (*child);
last = false;
@@ 516,7 516,7 @@ namespace gui
if (child == focusItem) {
break;
}
- if (child->activeItem && child->visible) {
+ if (child->isActive()) {
index++;
}
}
M module-gui/gui/widgets/GridLayout.cpp => module-gui/gui/widgets/GridLayout.cpp +44 -47
@@ 22,25 22,34 @@ GridLayout::GridLayout(
auto it = this->getNavigationFocusedItem();
auto distance = std::distance(children.begin(), it);
+
switch (inputEvent.keyCode) {
case KeyCode::KEY_UP: {
- auto realRowSize = calculateRowSizeForBorderTransition(distance);
- this->setFocusItem((*std::next(it, (realRowSize - 1) * this->colSize)));
+ auto col = static_cast<uint32_t>(distance % colSize);
+ Item *item = getFirstActiveItem(getLastColumnIndex(col), (-1) * static_cast<int>(colSize));
+ if (item)
+ this->setFocusItem(item);
return true;
}
case KeyCode::KEY_DOWN: {
- auto realRowSize = calculateRowSizeForBorderTransition(distance);
- this->setFocusItem((*std::prev(it, (realRowSize - 1) * this->colSize)));
+ auto col = static_cast<uint32_t>(distance % colSize);
+ Item *item = getFirstActiveItem(col, static_cast<int>(colSize));
+ if (item)
+ this->setFocusItem(item);
return true;
}
case KeyCode::KEY_LEFT: {
- auto realColSize = calculateColumnSizeForBorderTransition(distance);
- this->setFocusItem((*std::next(it, realColSize - 1)));
+ auto row = static_cast<uint32_t>(distance / colSize);
+ Item *item = getFirstActiveItem(getLastRowIndex(row), -1);
+ if (item)
+ this->setFocusItem(item);
return true;
}
case KeyCode::KEY_RIGHT: {
- auto realColSize = calculateColumnSizeForBorderTransition(distance);
- this->setFocusItem((*std::prev(it, realColSize - 1)));
+ auto row = static_cast<uint32_t>(distance / colSize);
+ Item *item = getFirstActiveItem(colSize * row, 1);
+ if (item)
+ this->setFocusItem(item);
return true;
}
default: {
@@ 50,25 59,6 @@ GridLayout::GridLayout(
};
}
-uint32_t GridLayout::calculateColumnSizeForBorderTransition(const uint32_t currentPosition)
-{
- auto realColSize = colSize;
- if (elementsInIncompletedLastRow) {
- if (((currentPosition / colSize) + 1) >= rowSize)
- realColSize = elementsInIncompletedLastRow;
- }
- return realColSize;
-}
-uint32_t GridLayout::calculateRowSizeForBorderTransition(const uint32_t currentPosition)
-{
- auto realRowSize = rowSize;
- if (elementsInIncompletedLastRow) {
- if (((currentPosition % (colSize)) + 1) > elementsInIncompletedLastRow)
- realRowSize--;
- }
- return realRowSize;
-}
-
void GridLayout::handleItemsOutOfGridLayoutArea(uint32_t maxItemsInArea)
{
for (auto i = maxItemsInArea; i < children.size(); i++) {
@@ 88,16 78,6 @@ void GridLayout::resizeItems()
uint32_t el_in_x = area().w / grid.x;
uint32_t el_in_y = area().h / grid.y;
- elementsInIncompletedLastRow = 0;
- colSize = children.size() < area().w / grid.x ? children.size() : area().w / grid.x;
- rowSize = colSize != 0 ? (children.size() / colSize) : 1;
- if (colSize > 1 && (static_cast<double>(children.size()) / colSize) > 1.0) {
- elementsInIncompletedLastRow = children.size() % colSize;
- }
- if (elementsInIncompletedLastRow > 0) {
- rowSize++;
- }
-
uint32_t strech_x = 0;
uint32_t strech_y = 0;
uint32_t max_elements = el_in_x * el_in_y;
@@ 113,6 93,13 @@ void GridLayout::resizeItems()
handleItemsOutOfGridLayoutArea(max_elements);
return;
}
+
+ colSize = children.size() < area().w / grid.x ? children.size() : area().w / grid.x;
+ rowSize = colSize != 0 ? (children.size() / colSize) : 1;
+ if (colSize > 1 && (static_cast<double>(children.size()) / colSize) > 1.0 && (children.size() % colSize)) {
+ rowSize++;
+ }
+
if (el_in_x > 2)
strech_x = (area().w - grid.x * el_in_x) / (el_in_x - 1);
if (el_in_y > 2)
@@ 149,28 136,38 @@ void GridLayout::setNavigation()
for (auto it = children.begin(); it != children.end(); ++it, ++i) {
if (it != children.begin() && (i + 1) % colSize != 1) {
- (*it)->setNavigationItem(NavigationDirection::LEFT, nextNavigationItem(std::prev(it)));
+ (*it)->setNavigationItem(NavigationDirection::LEFT, getFirstActiveItem(i - 1, -1));
}
if (it != std::prev(children.end()) && (i + 1) % colSize != 0) {
- (*it)->setNavigationItem(NavigationDirection::RIGHT, nextNavigationItem(std::next(it)));
+ (*it)->setNavigationItem(NavigationDirection::RIGHT, getFirstActiveItem(i + 1, 1));
}
if ((i - offset) >= 0) {
- (*it)->setNavigationItem(NavigationDirection::UP, nextNavigationItem(std::prev(it, offset)));
+ (*it)->setNavigationItem(NavigationDirection::UP, getFirstActiveItem(i - offset, (-1) * offset));
}
if ((i + offset) < static_cast<int>(children.size())) {
- (*it)->setNavigationItem(NavigationDirection::DOWN, nextNavigationItem(std::next(it, offset)));
+ (*it)->setNavigationItem(NavigationDirection::DOWN, getFirstActiveItem(i + offset, offset));
}
}
}
-Item *GridLayout::nextNavigationItem(std::list<Item *>::iterator it)
+Item *GridLayout::getFirstActiveItem(uint32_t startposition, int step)
{
- if (it != this->children.end() && (*it)->visible && (*it)->activeItem) {
- return *it;
- }
- else {
- return nullptr;
+ Item *retItem = nullptr;
+ int index = static_cast<int>(startposition);
+ uint32_t row = startposition / colSize;
+ while (index >= 0 && index < static_cast<int>(children.size())) {
+ ///> condition for movement along row (+1,-1 step)
+ if ((step == 1 || step == -1) && (index / colSize != row)) {
+ break;
+ }
+ std::list<Item *>::iterator tmpit = std::next(children.begin(), index);
+ if ((*tmpit)->isActive()) {
+ retItem = *tmpit;
+ break;
+ }
+ index += step;
}
+ return retItem;
}
M module-gui/gui/widgets/GridLayout.hpp => module-gui/gui/widgets/GridLayout.hpp +15 -9
@@ 26,23 26,29 @@ namespace gui
{}
GridLayout() : GridLayout(0, 0, 0, 0, {0, 0})
{}
- /// when reached top -> start from bottom. When reached left, start from right.
- bool navigationRotate = true;
void resizeItems() override;
void setNavigation() override;
- Item *nextNavigationItem(std::list<Item *>::iterator it);
uint32_t rowSize = 0;
uint32_t colSize = 0;
- ///> elementsInIncompletedLastRow describes how many items has been put to last row,
- /// in case when items for last row is not equal to colSize
- uint32_t elementsInIncompletedLastRow = 0;
private:
- uint32_t calculateColumnSizeForBorderTransition(const uint32_t currentPosition);
- uint32_t calculateRowSizeForBorderTransition(const uint32_t currentPosition);
-
void handleItemsOutOfGridLayoutArea(uint32_t maxItemsInArea);
+ Item *getFirstActiveItem(uint32_t startposition, int step);
+ inline uint32_t getLastColumnIndex(uint32_t col)
+ {
+ auto lastcolumnindex = col;
+ while ((lastcolumnindex + colSize) < children.size())
+ lastcolumnindex += colSize;
+ return lastcolumnindex;
+ }
+ inline uint32_t getLastRowIndex(uint32_t row)
+ {
+ uint32_t lastrowindex = colSize * row + (colSize - 1);
+ while (lastrowindex >= children.size())
+ lastrowindex--;
+ return lastrowindex;
+ }
};
}; // namespace gui
M module-gui/gui/widgets/Item.hpp => module-gui/gui/widgets/Item.hpp +5 -0
@@ 344,6 344,11 @@ namespace gui
/// remove timer from item and as a result - destory it
void detachTimer(Timer &timer);
+ /// simple check function to determine if item is active && visible
+ inline bool isActive()
+ {
+ return (activeItem && visible);
+ }
virtual void accept(GuiVisitor &visitor);
protected:
M module-gui/gui/widgets/TopBar.cpp => module-gui/gui/widgets/TopBar.cpp +90 -46
@@ 11,7 11,7 @@
#include "common_data/EventStore.hpp"
-namespace gui
+namespace gui::top_bar
{
namespace networkTechnology
{
@@ 20,14 20,47 @@ namespace gui
constexpr uint32_t w = 130;
constexpr uint32_t h = 20;
} // namespace networkTechnology
- const uint32_t TopBar::signalOffset = 35;
- const uint32_t TopBar::batteryOffset = 413;
- gui::TopBar::TimeMode TopBar::timeMode = TimeMode::TIME_24H;
+
+ static constexpr uint32_t signalOffset = 35;
+ static constexpr uint32_t batteryOffset = 413;
+
+ TopBar::TimeMode TopBar::timeMode = TimeMode::TIME_24H;
uint32_t TopBar::time = 0;
- TopBar::TopBar(Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h) : Rect{parent, x, y, w, h}
+ void Configuration::enable(Indicator indicator)
+ {
+ set(indicator, true);
+ }
+
+ void Configuration::enable(const Indicators &indicators)
+ {
+ for (auto indicator : indicators) {
+ enable(indicator);
+ }
+ }
+
+ void Configuration::disable(Indicator indicator)
{
+ set(indicator, false);
+ }
+
+ void Configuration::set(Indicator indicator, bool enabled)
+ {
+ indicatorStatuses[indicator] = enabled;
+ }
+
+ auto Configuration::isEnabled(Indicator indicator) const -> bool
+ {
+ return indicatorStatuses.at(indicator);
+ }
+
+ auto Configuration::getIndicatorsConfiguration() const noexcept -> const IndicatorStatuses &
+ {
+ return indicatorStatuses;
+ }
+ TopBar::TopBar(Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h) : Rect{parent, x, y, w, h}
+ {
prepareWidget();
setFillColor(ColorFullWhite);
@@ 48,7 81,7 @@ namespace gui
val = batteryBars.size();
}
for (unsigned int i = 0; i < batteryBars.size(); ++i) {
- if (elements.battery) {
+ if (configuration.isEnabled(Indicator::Battery)) {
batteryBars[i]->setVisible(i == val);
}
else {
@@ 59,7 92,6 @@ namespace gui
void TopBar::prepareWidget()
{
-
signal[0] = new gui::Image(this, signalOffset, 17, 0, 0, "signal0");
signal[1] = new gui::Image(this, signalOffset, 17, 0, 0, "signal1");
signal[2] = new gui::Image(this, signalOffset, 17, 0, 0, "signal2");
@@ 111,48 143,56 @@ namespace gui
updateNetworkAccessTechnology();
}
- void TopBar::setActive(std::list<std::pair<TopBar::Elements, bool>> elements)
+ auto TopBar::getConfiguration() const noexcept -> const Configuration &
+ {
+ return configuration;
+ }
+
+ void TopBar::configure(Configuration &&config)
{
- for (auto el : elements) {
- setActive(el.first, el.second);
+ if (config.isEnabled(Indicator::Lock)) {
+ // In current implementation, lock and time indicators are mutually exclusive.
+ // I.e. enabling the lock indicator disables the time indicator.
+ config.disable(Indicator::Time);
+ }
+
+ for (auto [indicator, enabled] : config.getIndicatorsConfiguration()) {
+ setIndicatorStatus(indicator, enabled);
}
+ configuration = std::move(config);
}
- void TopBar::setActive(TopBar::Elements element, bool active)
+ void TopBar::setIndicatorStatus(Indicator indicator, bool enabled)
{
- switch (element) {
- case Elements::BATTERY: {
- elements.battery = active;
- showBattery(elements.battery);
- } break;
- case Elements::LOCK: {
- elements.lock = active;
- lock->setVisible(active);
- if (active)
- timeLabel->setVisible(false);
- } break;
- case Elements::SIGNAL: {
- elements.signal = active;
+ switch (indicator) {
+ case Indicator::Signal:
updateSignalStrength();
- } break;
- case Elements::TIME: {
- elements.time = active;
- timeLabel->setVisible(active);
- if (active)
+ break;
+ case Indicator::Time:
+ timeLabel->setVisible(enabled);
+ if (enabled) {
lock->setVisible(false);
- } break;
- case Elements::SIM:
- elements.sim = active;
+ }
+ break;
+ case Indicator::Lock:
+ lock->setVisible(enabled);
+ if (enabled) {
+ timeLabel->setVisible(false);
+ }
+ break;
+ case Indicator::Battery:
+ showBattery(enabled);
+ break;
+ case Indicator::SimCard:
simSet();
break;
- case Elements::NETWORK_ACCESS_TECHNOLOGY:
- elements.networkAccessTechnology = active;
+ case Indicator::NetworkAccessTechnology:
updateNetworkAccessTechnology();
break;
- };
+ }
}
- uint32_t calculateBatteryBars(uint32_t percentage)
+ uint32_t TopBar::calculateBatteryBars(uint32_t percentage)
{
uint32_t level = 0;
if (percentage <= 5) // level critical
@@ 177,13 217,13 @@ namespace gui
bool TopBar::updateBattery(uint32_t percent)
{
- showBattery(elements.battery);
+ showBattery(configuration.isEnabled(Indicator::Battery));
return true;
}
bool TopBar::updateBattery(bool plugged)
{
- showBattery(elements.battery);
+ showBattery(configuration.isEnabled(Indicator::Battery));
return true;
}
@@ 216,7 256,7 @@ namespace gui
for (uint32_t i = 0; i < signalImgCount; i++) {
signal[i]->setVisible(false);
}
- if (elements.signal) {
+ if (configuration.isEnabled(Indicator::Signal)) {
auto rssiBar = Store::GSM::get()->getSignalStrength().rssiBar;
if (rssiBar < Store::RssiBar::noOfSupprtedBars) {
signal[static_cast<size_t>(rssiBar)]->setVisible(true);
@@ 229,7 269,7 @@ namespace gui
bool TopBar::updateNetworkAccessTechnology()
{
- if (elements.networkAccessTechnology) {
+ if (configuration.isEnabled(Indicator::NetworkAccessTechnology)) {
auto accessTechnology = Store::GSM::get()->getNetwork().accessTechnology;
constexpr auto text2g = "2G";
@@ 258,16 298,16 @@ namespace gui
return true;
}
- void TopBar::setTime(const UTF8 &time)
+ void TopBar::setTime(const UTF8 &value)
{
- timeLabel->setText(time);
+ timeLabel->setText(value);
}
- void TopBar::setTime(const uint32_t &time, bool mode24H)
+ void TopBar::setTime(uint32_t value, bool mode24H)
{
setTime(utils::time::Time());
timeMode = (mode24H ? TimeMode::TIME_24H : TimeMode::TIME_12H);
- this->time = time;
+ time = value;
}
UTF8 TopBar::getTimeString()
@@ 276,13 316,17 @@ namespace gui
return timeLabel->getText();
}
+ uint32_t TopBar::getTime() const noexcept
+ {
+ return time;
+ }
void TopBar::simSet()
{
- if (!sim) {
+ if (sim == nullptr) {
return;
}
- else if (elements.sim) {
+ if (configuration.isEnabled(Indicator::SimCard)) {
return sim->show(Store::GSM::get()->sim);
}
sim->visible = false;
M module-gui/gui/widgets/TopBar.hpp => module-gui/gui/widgets/TopBar.hpp +61 -41
@@ 1,21 1,52 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#ifndef MODULE_GUI_GUI_WIDGETS_TOPBAR_HPP_
-#define MODULE_GUI_GUI_WIDGETS_TOPBAR_HPP_
+#pragma once
#include "Image.hpp"
#include "Label.hpp"
#include "Rect.hpp"
#include "TopBar/SIM.hpp"
#include <common_data/EventStore.hpp>
+
+#include <vector>
#include <map>
-namespace gui
+namespace gui::top_bar
{
+ enum class Indicator
+ {
+ Signal,
+ Time,
+ Lock,
+ Battery,
+ SimCard,
+ NetworkAccessTechnology
+ };
+ using Indicators = std::vector<Indicator>;
+ using IndicatorStatuses = std::map<Indicator, bool>;
- static const uint32_t batteryBarsCount = 6;
- static const uint32_t signalImgCount = 6;
+ /**
+ * Carries the top bar configuration.
+ */
+ class Configuration
+ {
+ public:
+ void enable(Indicator indicator);
+ void enable(const Indicators &indicators);
+ void disable(Indicator indicator);
+ void set(Indicator indicator, bool enabled);
+ [[nodiscard]] auto isEnabled(Indicator indicator) const -> bool;
+ [[nodiscard]] auto getIndicatorsConfiguration() const noexcept -> const IndicatorStatuses &;
+
+ private:
+ IndicatorStatuses indicatorStatuses = {{Indicator::Signal, false},
+ {Indicator::Time, false},
+ {Indicator::Lock, false},
+ {Indicator::Battery, false},
+ {Indicator::SimCard, false},
+ {Indicator::NetworkAccessTechnology, false}};
+ };
/// Header of most of design Windows
///
@@ 31,19 62,10 @@ namespace gui
/// [signal] [title ] [sim] [battery]
class TopBar : public Rect
{
- static const uint32_t signalOffset;
- static const uint32_t batteryOffset;
+ static constexpr uint32_t batteryBarsCount = 6;
+ static constexpr uint32_t signalImgCount = 6;
public:
- enum class Elements
- {
- SIGNAL = 0x01,
- LOCK,
- BATTERY,
- TIME,
- SIM,
- NETWORK_ACCESS_TECHNOLOGY
- };
enum class TimeMode
{
TIME_12H,
@@ 60,32 82,32 @@ namespace gui
std::map<const Store::Battery::State, Image *> batteryChargings = {
{Store::Battery::State::Charging, nullptr}, {Store::Battery::State::PluggedNotCharging, nullptr}};
gui::SIM *sim = nullptr;
- void prepareWidget();
+ Configuration configuration;
static TimeMode timeMode;
+ void prepareWidget();
+
/// show bars in number - 0 bars, 1 bar, 2 bars...
void batteryShowBars(uint32_t val);
- /// elements shown on TopBar
- struct
- {
- bool signal : 1;
- bool lock : 1;
- bool battery : 1;
- bool time : 1;
- bool sim : 1;
- bool networkAccessTechnology : 1;
- } elements = {false, false, false, false, true, true};
+ static uint32_t calculateBatteryBars(uint32_t percentage);
+
+ /**
+ * Sets the status of the top bar indicator.
+ * @param indicator Indicator
+ */
+ void setIndicatorStatus(Indicator indicator, bool enabled);
public:
TopBar(Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h);
/**
- * @brief Hides or shows images.
- * @note LOCK and TIME are located in the same place so only 1 can be active at the same time.
+ * Configures the top bar.
+ * @param configuration Top bar configuration
*/
- void setActive(TopBar::Elements element, bool active);
- void setActive(std::list<std::pair<TopBar::Elements, bool>> elements);
+ void configure(Configuration &&config);
+ [[nodiscard]] auto getConfiguration() const noexcept -> const Configuration &;
+
/**
* @brief Sets charge level of the battery based on percent value. This will cause appropriate image to be
* displayed.
@@ 103,16 125,14 @@ namespace gui
bool updateNetworkAccessTechnology();
void simSet();
- void setTime(const UTF8 &time);
- void setTime(const uint32_t &time, bool mode24H);
+
+ void setTime(const UTF8 &value);
+ void setTime(uint32_t value, bool mode24H);
+
UTF8 getTimeString();
- uint32_t getTime()
- {
- return time;
- };
+ uint32_t getTime() const noexcept;
+
void accept(GuiVisitor &visitor) override;
};
-} /* namespace gui */
-
-#endif /* MODULE_GUI_GUI_WIDGETS_TOPBAR_HPP_ */
+} // namespace gui::top_bar
M module-gui/gui/widgets/visitor/GuiVisitor.hpp => module-gui/gui/widgets/visitor/GuiVisitor.hpp +5 -2
@@ 11,7 11,10 @@ namespace gui
class Window;
class Label;
class BottomBar;
- class TopBar;
+ namespace top_bar
+ {
+ class TopBar;
+ }
/// The general purpose abstract interface for enabling Double-Dispatch behavior throughout `gui::Item`'s
/// inheritance hierarchy.
@@ 24,7 27,7 @@ namespace gui
virtual void visit(gui::Window &item) = 0;
virtual void visit(gui::Label &item) = 0;
virtual void visit(gui::BottomBar &item) = 0;
- virtual void visit(gui::TopBar &item) = 0;
+ virtual void visit(gui::top_bar::TopBar &item) = 0;
virtual ~GuiVisitor() = default;
};
} // namespace gui
M module-gui/test/test-google/test-gui-gridlayout.cpp => module-gui/test/test-google/test-gui-gridlayout.cpp +150 -2
@@ 67,7 67,20 @@ class GridLayoutTesting : public ::testing::Test
Box->addWidget(item);
}
}
-
+ void addItem(gui::BoxLayout *Box,
+ uint32_t item_w,
+ uint32_t item_h,
+ uint32_t id,
+ bool active = true,
+ const gui::Margins &margins = gui::Margins())
+ {
+ auto item = new TestItem(nullptr, 0, 0, item_w, item_h);
+ item->ID = id;
+ item->visible = true;
+ item->setMargins(margins);
+ item->activeItem = active;
+ Box->addWidget(item);
+ }
gui::GridLayout *gridLayout = nullptr;
///> GridLayout test constants
@@ 120,6 133,139 @@ TEST_F(GridLayoutTesting, Navigate_Test)
ASSERT_EQ(1 + expColSize, dynamic_cast<TestItem *>(gridLayout->getFocusItem())->ID)
<< "element with ID " << 1 + expColSize << " should have focus";
}
+
+TEST_F(GridLayoutTesting, Navigate_Test_ActiveItems_1)
+{
+ ///> Test for grid layout with 48 elements (A - active item, N - non active item, NV - non visible item)
+ ///> | 1 A | 2 NA | 3 A | 4 NA | 5 A | 6 NA | 7 A | 8 NA | 9 A | 10 NA | 11 A | 12 NA |
+ ///> | 13 NA | 14 A | 15 NA | 16 A | 17 NA | 18 A | 19 NA | 20 A | 21 NA | 22 A | 23 NA | 24 A |
+ ///> | 25 A | 26 NA | 27 A | 28 NA | 29 A | 30 NA | 31 A | 32 NA | 33 A | 34 NA | 35 A | 36 NA |
+ ///> | 37 NA | 38 A | 39 NA | 40 A | 41 NA | 42 A | 43 NA | 44 A | 45 NA | 46 A | 47 NA | 48 A |
+ ///> | 49 NV | 50 NV | 51 NV | 52 NV |
+ for (uint32_t i = 1; i <= 12; i++) {
+ addItem(gridLayout, testStyle::grid_item_w, testStyle::grid_item_h, i, (i % 2) ? true : false);
+ }
+ for (uint32_t i = 13; i <= 24; i++) {
+ addItem(gridLayout, testStyle::grid_item_w, testStyle::grid_item_h, i, ((i + 1) % 2) ? true : false);
+ }
+ for (uint32_t i = 25; i <= 36; i++) {
+ addItem(gridLayout, testStyle::grid_item_w, testStyle::grid_item_h, i, (i % 2) ? true : false);
+ }
+ for (uint32_t i = 37; i <= 48; i++) {
+ addItem(gridLayout, testStyle::grid_item_w, testStyle::grid_item_h, i, ((i + 1) % 2) ? true : false);
+ }
+ ///> Add some items to exceed grid layout area
+ for (uint32_t i = 49; i <= 52; i++) {
+ addItem(gridLayout, testStyle::grid_item_w, testStyle::grid_item_h, i, true);
+ }
+ gridLayout->setFocus(true);
+ ASSERT_EQ(gridLayout->rowSize, 4) << "row size is not " << 4 << " as expected";
+ ASSERT_EQ(gridLayout->colSize, 12) << "col size is not " << 12 << " as expected";
+ ASSERT_EQ(52, gridLayout->children.size()) << "GridLayout should contain " << 52 << " elements";
+
+ ASSERT_EQ(1, dynamic_cast<TestItem *>(gridLayout->getFocusItem())->ID)
+ << "element with ID " << 1 << " should have focus";
+ moveNTimes(gridLayout, 2, gui::KeyCode::KEY_RIGHT);
+ ASSERT_EQ(5, dynamic_cast<TestItem *>(gridLayout->getFocusItem())->ID)
+ << "element with ID " << 5 << " should have focus";
+ moveNTimes(gridLayout, 1, gui::KeyCode::KEY_DOWN);
+ ASSERT_EQ(5 + (2 * expColSize), dynamic_cast<TestItem *>(gridLayout->getFocusItem())->ID)
+ << "element with ID " << 5 + (2 * expColSize) << " should have focus";
+ moveNTimes(gridLayout, 2, gui::KeyCode::KEY_LEFT);
+ ASSERT_EQ(1 + (2 * expColSize), dynamic_cast<TestItem *>(gridLayout->getFocusItem())->ID)
+ << "element with ID " << 1 + (2 * expColSize) << " should have focus";
+ moveNTimes(gridLayout, 1, gui::KeyCode::KEY_DOWN);
+ ASSERT_EQ(1, dynamic_cast<TestItem *>(gridLayout->getFocusItem())->ID)
+ << "element with ID " << 1 << " should have focus";
+}
+
+TEST_F(GridLayoutTesting, Navigate_Test_ActiveItems_2_BorderCallback)
+{
+ ///> Test for grid layout with 48 elements
+ ///> | 1 A | 2 NA | 3 A | 4 NA | 5 A | 6 NA | 7 A | 8 NA | 9 A | 10 NA | 11 A | 12 NA |
+ ///> | 13 NA | 14 A | 15 NA | 16 A | 17 NA | 18 A | 19 NA | 20 A | 21 NA | 22 A | 23 NA | 24 A |
+ ///> | 25 A | 26 NA | 27 A | 28 NA | 29 A | 30 NA | 31 A | 32 NA | 33 A | 34 NA | 35 A | 36 NA |
+ ///> | 37 NA | 38 A | 39 NA |
+ for (uint32_t i = 1; i <= 12; i++) {
+ addItem(gridLayout, testStyle::grid_item_w, testStyle::grid_item_h, i, (i % 2) ? true : false);
+ }
+ for (uint32_t i = 13; i <= 24; i++) {
+ addItem(gridLayout, testStyle::grid_item_w, testStyle::grid_item_h, i, ((i + 1) % 2) ? true : false);
+ }
+ for (uint32_t i = 25; i <= 36; i++) {
+ addItem(gridLayout, testStyle::grid_item_w, testStyle::grid_item_h, i, (i % 2) ? true : false);
+ }
+ for (uint32_t i = 37; i <= 39; i++) {
+ addItem(gridLayout, testStyle::grid_item_w, testStyle::grid_item_h, i, ((i + 1) % 2) ? true : false);
+ }
+
+ gridLayout->setFocus(true);
+ ASSERT_EQ(gridLayout->rowSize, 4) << "row size is not " << 4 << " as expected";
+ ASSERT_EQ(gridLayout->colSize, 12) << "col size is not " << 12 << " as expected";
+ ASSERT_EQ(39, gridLayout->children.size()) << "GridLayout should contain " << 39 << " elements";
+
+ ASSERT_EQ(1, dynamic_cast<TestItem *>(gridLayout->getFocusItem())->ID)
+ << "element with ID " << 1 << " should have focus";
+ moveNTimes(gridLayout, 2, gui::KeyCode::KEY_LEFT);
+ ASSERT_EQ(9, dynamic_cast<TestItem *>(gridLayout->getFocusItem())->ID)
+ << "element with ID " << 9 << " should have focus";
+ moveNTimes(gridLayout, 1, gui::KeyCode::KEY_UP);
+ ASSERT_EQ(33, dynamic_cast<TestItem *>(gridLayout->getFocusItem())->ID)
+ << "element with ID " << 33 << " should have focus";
+ moveNTimes(gridLayout, 3, gui::KeyCode::KEY_LEFT);
+ ASSERT_EQ(27, dynamic_cast<TestItem *>(gridLayout->getFocusItem())->ID)
+ << "element with ID " << 27 << " should have focus";
+ moveNTimes(gridLayout, 1, gui::KeyCode::KEY_DOWN);
+ ASSERT_EQ(3, dynamic_cast<TestItem *>(gridLayout->getFocusItem())->ID)
+ << "element with ID " << 3 << " should have focus";
+ moveNTimes(gridLayout, 5, gui::KeyCode::KEY_RIGHT);
+ ASSERT_EQ(1, dynamic_cast<TestItem *>(gridLayout->getFocusItem())->ID)
+ << "element with ID " << 1 << " should have focus";
+
+ ///> Test for grid layout with 1 element
+ ///> | 1NA |
+ gridLayout->erase();
+ addItem(gridLayout, testStyle::grid_item_w, testStyle::grid_item_h, 1, false);
+ ASSERT_EQ(gridLayout->children.size(), 1) << "elements size is not " << 1 << " as expected";
+ ASSERT_EQ(gridLayout->rowSize, 1) << "row size is not " << 1 << " as expected";
+ ASSERT_EQ(gridLayout->colSize, 1) << "col size is not " << 1 << " as expected";
+ gridLayout->setFocus(false);
+ gridLayout->setFocus(true);
+ ASSERT_EQ(nullptr, gridLayout->getFocusItem()) << "no element shall be focused";
+ moveNTimes(gridLayout, 1, gui::KeyCode::KEY_LEFT);
+ ASSERT_EQ(nullptr, gridLayout->getFocusItem()) << "no element shall be focused";
+ moveNTimes(gridLayout, 1, gui::KeyCode::KEY_RIGHT);
+ ASSERT_EQ(nullptr, gridLayout->getFocusItem()) << "no element shall be focused";
+ moveNTimes(gridLayout, 1, gui::KeyCode::KEY_UP);
+ ASSERT_EQ(nullptr, gridLayout->getFocusItem()) << "no element shall be focused";
+ moveNTimes(gridLayout, 1, gui::KeyCode::KEY_DOWN);
+ ASSERT_EQ(nullptr, gridLayout->getFocusItem()) << "no element shall be focused";
+ ///> Test for grid layout with 1 element
+ ///> | 1NA | 1A |
+ gridLayout->erase();
+ addItem(gridLayout, testStyle::grid_item_w, testStyle::grid_item_h, 1, false);
+ addItem(gridLayout, testStyle::grid_item_w, testStyle::grid_item_h, 2, true);
+ ASSERT_EQ(gridLayout->children.size(), 2) << "elements size is not " << 2 << " as expected";
+ ASSERT_EQ(gridLayout->rowSize, 1) << "row size is not " << 1 << " as expected";
+ ASSERT_EQ(gridLayout->colSize, 2) << "col size is not " << 2 << " as expected";
+ gridLayout->setFocus(false);
+ gridLayout->setFocus(true);
+ ASSERT_EQ(2, dynamic_cast<TestItem *>(gridLayout->getFocusItem())->ID)
+ << "element with ID " << 2 << " should have focus";
+ moveNTimes(gridLayout, 1, gui::KeyCode::KEY_LEFT);
+ ASSERT_EQ(2, dynamic_cast<TestItem *>(gridLayout->getFocusItem())->ID)
+ << "element with ID " << 2 << " should have focus";
+ moveNTimes(gridLayout, 1, gui::KeyCode::KEY_RIGHT);
+ ASSERT_EQ(2, dynamic_cast<TestItem *>(gridLayout->getFocusItem())->ID)
+ << "element with ID " << 2 << " should have focus";
+ moveNTimes(gridLayout, 1, gui::KeyCode::KEY_UP);
+ ASSERT_EQ(2, dynamic_cast<TestItem *>(gridLayout->getFocusItem())->ID)
+ << "element with ID " << 2 << " should have focus";
+ moveNTimes(gridLayout, 1, gui::KeyCode::KEY_DOWN);
+ ASSERT_EQ(2, dynamic_cast<TestItem *>(gridLayout->getFocusItem())->ID)
+ << "element with ID " << 2 << " should have focus";
+}
+
///> TODO: Enable this test when issue with setFocus will be resolved
TEST_F(GridLayoutTesting, DISABLED_Border_Callback_Test)
{
@@ 149,7 295,7 @@ TEST_F(GridLayoutTesting, DISABLED_Border_Callback_Test)
<< "element with ID " << 37 << " should have focus";
moveNTimes(gridLayout, 1, gui::KeyCode::KEY_LEFT);
ASSERT_EQ(46, dynamic_cast<TestItem *>(gridLayout->getFocusItem())->ID)
- << "element with ID " << 37 << " should have focus";
+ << "element with ID " << 46 << " should have focus";
moveNTimes(gridLayout, 1, gui::KeyCode::KEY_DOWN);
ASSERT_EQ(10, dynamic_cast<TestItem *>(gridLayout->getFocusItem())->ID)
<< "element with ID " << 10 << " should have focus";
@@ 170,6 316,7 @@ TEST_F(GridLayoutTesting, DISABLED_Border_Callback_Test)
ASSERT_EQ(gridLayout->children.size(), 1) << "elements size is not " << 1 << " as expected";
ASSERT_EQ(gridLayout->rowSize, 1) << "row size is not " << 1 << " as expected";
ASSERT_EQ(gridLayout->colSize, 1) << "col size is not " << 1 << " as expected";
+
gridLayout->setFocus(true);
ASSERT_EQ(1, dynamic_cast<TestItem *>(gridLayout->getFocusItem())->ID)
@@ 194,6 341,7 @@ TEST_F(GridLayoutTesting, DISABLED_Border_Callback_Test)
ASSERT_EQ(gridLayout->children.size(), 2) << "elements size is not " << 2 << " as expected";
ASSERT_EQ(gridLayout->rowSize, 1) << "row size is not " << 1 << " as expected";
ASSERT_EQ(gridLayout->colSize, 2) << "col size is not " << 2 << " as expected";
+
gridLayout->setFocus(true);
ASSERT_EQ(1, dynamic_cast<TestItem *>(gridLayout->getFocusItem())->ID)
M module-gui/test/test-google/test-gui-visitor-call.cpp => module-gui/test/test-google/test-gui-visitor-call.cpp +1 -1
@@ 25,7 25,7 @@ class VisitorMock : public gui::GuiVisitor
MOCK_METHOD1(visit, void(gui::Window &item));
MOCK_METHOD1(visit, void(gui::Label &item));
MOCK_METHOD1(visit, void(gui::BottomBar &item));
- MOCK_METHOD1(visit, void(gui::TopBar &item));
+ MOCK_METHOD1(visit, void(gui::top_bar::TopBar &item));
};
class CustomRect : public gui::Rect
M module-services/service-appmgr/model/ApplicationManager.cpp => module-services/service-appmgr/model/ApplicationManager.cpp +30 -9
@@ 34,7 34,8 @@ namespace app::manager
{
namespace
{
- constexpr auto default_application_locktime_ms = 30000;
+ static constexpr auto default_application_locktime_ms = 30000;
+ static constexpr auto shutdown_delay_ms = 500;
}; // namespace
ApplicationManagerBase::ApplicationManagerBase(std::vector<std::unique_ptr<app::ApplicationLauncher>> &&launchers)
@@ 102,16 103,11 @@ namespace app::manager
: Service{serviceName}, ApplicationManagerBase(std::move(launchers)), rootApplicationName{_rootApplicationName},
blockingTimer{std::make_unique<sys::Timer>(
"BlockTimer", this, std::numeric_limits<sys::ms>::max(), sys::Timer::Type::SingleShot)},
+ shutdownDelay{std::make_unique<sys::Timer>("ShutdownDelay", this, shutdown_delay_ms)},
settings(std::make_unique<settings::Settings>(this))
{
registerMessageHandlers();
blockingTimer->connect([this](sys::Timer &) { onPhoneLocked(); });
- settings->registerValueChange(settings::SystemProperties::displayLanguage,
- [this](std::string value) { displayLanguageChanged(value); });
- settings->registerValueChange(settings::SystemProperties::inputLanguage,
- [this](std::string value) { inputLanguageChanged(value); });
- settings->registerValueChange(settings::SystemProperties::lockTime,
- [this](std::string value) { lockTimeChanged(value); });
}
sys::ReturnCodes ApplicationManager::InitHandler()
@@ 120,6 116,18 @@ namespace app::manager
utils::localize.setFallbackLanguage(utils::localize.DefaultLanguage);
utils::localize.setDisplayLanguage(displayLanguage);
utils::localize.setInputLanguage(inputLanguage);
+ settings->registerValueChange(
+ settings::SystemProperties::displayLanguage,
+ [this](std::string value) { displayLanguageChanged(value); },
+ settings::SettingsScope::Global);
+ settings->registerValueChange(
+ settings::SystemProperties::inputLanguage,
+ [this](std::string value) { inputLanguageChanged(value); },
+ settings::SettingsScope::Global);
+ settings->registerValueChange(
+ settings::SystemProperties::lockTime,
+ [this](std::string value) { lockTimeChanged(value); },
+ settings::SettingsScope::Global);
startSystemServices();
startBackgroundApplications();
@@ 161,6 169,7 @@ namespace app::manager
sys::ReturnCodes ApplicationManager::DeinitHandler()
{
+ settings->unregisterValueChange();
closeApplications();
closeServices();
return sys::ReturnCodes::Success;
@@ 248,6 257,7 @@ namespace app::manager
connect(typeid(CellularMMIResponseMessage), convertibleToActionHandler);
connect(typeid(CellularMMIPushMessage), convertibleToActionHandler);
connect(typeid(sys::CriticalBatteryLevelNotification), convertibleToActionHandler);
+ connect(typeid(sys::SystemBrownoutMesssage), convertibleToActionHandler);
}
sys::ReturnCodes ApplicationManager::SwitchPowerModeHandler(const sys::ServicePowerMode mode)
@@ 391,6 401,8 @@ namespace app::manager
auto params = static_cast<ApplicationLaunchData *>(actionMsg->getData().get());
return handleLaunchAction(params);
}
+ case actions::CloseSystem:
+ return handleCloseSystem();
default: {
auto &actionParams = actionMsg->getData();
return handleCustomAction(action, std::move(actionParams));
@@ 415,6 427,14 @@ namespace app::manager
return handleSwitchApplication(&switchRequest);
}
+ auto ApplicationManager::handleCloseSystem() -> bool
+ {
+ shutdownDelay->connect([&](sys::Timer &) { sys::SystemManager::CloseSystem(this); });
+ shutdownDelay->start();
+
+ return true;
+ }
+
auto ApplicationManager::handleCustomAction(actions::ActionId action, actions::ActionParamsPtr &&actionParams)
-> bool
{
@@ 540,7 560,8 @@ namespace app::manager
return false;
}
displayLanguage = requestedLanguage;
- settings->setValue(settings::SystemProperties::displayLanguage, displayLanguage);
+ settings->setValue(
+ settings::SystemProperties::displayLanguage, displayLanguage, settings::SettingsScope::Global);
utils::localize.setDisplayLanguage(displayLanguage);
rebuildActiveApplications();
return true;
@@ 555,7 576,7 @@ namespace app::manager
return false;
}
inputLanguage = requestedLanguage;
- settings->setValue(settings::SystemProperties::inputLanguage, inputLanguage);
+ settings->setValue(settings::SystemProperties::inputLanguage, inputLanguage, settings::SettingsScope::Global);
utils::localize.setInputLanguage(inputLanguage);
return true;
}
M module-services/service-appmgr/service-appmgr/Actions.hpp => module-services/service-appmgr/service-appmgr/Actions.hpp +2 -0
@@ 24,6 24,7 @@ namespace app::manager
{
Home,
Launch,
+ CloseSystem,
Call,
Dial,
ShowCallLog,
@@ 48,6 49,7 @@ namespace app::manager
ShowMMIPush,
DisplayCMEError,
DisplayLowBatteryNotification,
+ SystemBrownout,
UserAction // The last enumerator in the Action enum.
// All user-defined actions shall have values greater than UserAction.
// All system-wide actions shall have values lesser than UserAction.
M module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp => module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp +2 -0
@@ 114,6 114,7 @@ namespace app::manager
auto handleAction(ActionRequest *actionMsg) -> bool;
auto handleHomeAction() -> bool;
auto handleLaunchAction(ApplicationLaunchData *launchParams) -> bool;
+ auto handleCloseSystem() -> bool;
auto handleCustomAction(actions::ActionId action, actions::ActionParamsPtr &&actionParams) -> bool;
auto handleSwitchApplication(SwitchRequest *msg, bool closeCurrentlyFocusedApp = true) -> bool;
auto handleCloseConfirmation(CloseConfirmation *msg) -> bool;
@@ 141,6 142,7 @@ 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.
+ std::unique_ptr<sys::Timer> shutdownDelay;
// Temporary solution - to be replaced with ActionsMiddleware.
std::tuple<ApplicationName, actions::ActionId, actions::ActionParamsPtr> pendingAction;
M module-services/service-cellular/CellularRequestHandler.cpp => module-services/service-cellular/CellularRequestHandler.cpp +2 -0
@@ 22,6 22,8 @@
#include <module-cellular/at/response.hpp>
+using namespace cellular;
+
void CellularRequestHandler::handle(ImeiRequest &request, at::Result &result)
{
if (!request.checkModemResponse(result)) {
M module-services/service-cellular/CellularUrcHandler.cpp => module-services/service-cellular/CellularUrcHandler.cpp +2 -0
@@ 11,6 11,8 @@
#include <service-evtmgr/Constants.hpp>
#include <service-appmgr/Controller.hpp>
+using namespace at::urc;
+
// this static function will be replaced by Settings API
static bool isSettingsAutomaticTimeSyncEnabled()
{
M module-services/service-cellular/CellularUrcHandler.hpp => module-services/service-cellular/CellularUrcHandler.hpp +11 -13
@@ 18,27 18,25 @@
#include <module-cellular/at/UrcResponse.hpp>
#include <module-cellular/at/UrcQiurc.hpp>
-using namespace at::urc;
-
/**
* ServiceCellular helper for handling Urc messages
*/
-class CellularUrcHandler : public UrcHandler
+class CellularUrcHandler : public at::urc::UrcHandler
{
public:
CellularUrcHandler(ServiceCellular &cellularService) : cellularService(cellularService)
{}
- void Handle(Clip &urc) final;
- void Handle(Creg &urc) final;
- void Handle(Cmti &urc) final;
- void Handle(Cusd &urc) final;
- void Handle(Ctze &urc) final;
- void Handle(Qind &urc) final;
- void Handle(Cpin &urc) final;
- void Handle(Qiurc &urc) final;
- void Handle(PoweredDown &urc) final;
- void Handle(UrcResponse &urc) final;
+ void Handle(at::urc::Clip &urc) final;
+ void Handle(at::urc::Creg &urc) final;
+ void Handle(at::urc::Cmti &urc) final;
+ void Handle(at::urc::Cusd &urc) final;
+ void Handle(at::urc::Ctze &urc) final;
+ void Handle(at::urc::Qind &urc) final;
+ void Handle(at::urc::Cpin &urc) final;
+ void Handle(at::urc::Qiurc &urc) final;
+ void Handle(at::urc::PoweredDown &urc) final;
+ void Handle(at::urc::UrcResponse &urc) final;
/**
* Gets the response that should be returned after handling Urc
M module-services/service-cellular/ServiceCellular.cpp => module-services/service-cellular/ServiceCellular.cpp +10 -8
@@ 204,8 204,6 @@ ServiceCellular::ServiceCellular() : sys::Service(serviceName, "", cellularStack
sys::Bus::SendMulticast(msg.value(), sys::BusChannels::ServiceCellularNotifications, this);
};
registerMessageHandlers();
- settings->registerValueChange(settings::Cellular::volte_on,
- [this](const std::string &value) { volteChanged(value); });
packetData = std::make_unique<packet_data::PacketData>(*this);
packetData->loadAPNSettings();
}
@@ 235,6 233,8 @@ sys::ReturnCodes ServiceCellular::InitHandler()
board = EventManagerServiceAPI::GetBoard(this);
state.set(this, State::ST::WaitForStartPermission);
+ settings->registerValueChange(settings::Cellular::volte_on,
+ [this](const std::string &value) { volteChanged(value); });
return sys::ReturnCodes::Success;
}
@@ 297,12 297,12 @@ void ServiceCellular::registerMessageHandlers()
return handleCellularGetActiveContextsMessage(msg);
});
- connect(typeid(CellularGetAPNMessage), [&](sys::Message *request) -> sys::MessagePointer {
- connect(typeid(CellularGetCurrentOperatorMessage), [&](sys::Message *request) -> sys::MessagePointer {
- auto msg = static_cast<CellularGetCurrentOperatorMessage *>(request);
- return handleCellularGetCurrentOperator(msg);
- });
+ connect(typeid(CellularGetCurrentOperatorMessage), [&](sys::Message *request) -> sys::MessagePointer {
+ auto msg = static_cast<CellularGetCurrentOperatorMessage *>(request);
+ return handleCellularGetCurrentOperator(msg);
+ });
+ connect(typeid(CellularGetAPNMessage), [&](sys::Message *request) -> sys::MessagePointer {
auto msg = static_cast<CellularGetAPNMessage *>(request);
return handleCellularGetAPNMessage(msg);
});
@@ 1284,7 1284,9 @@ bool ServiceCellular::handleSimState(at::SimState state, const std::string messa
switch (state) {
case at::SimState::Ready:
Store::GSM::get()->sim = Store::GSM::get()->selected;
- settings->setValue(settings::SystemProperties::activeSim, utils::enumToString(Store::GSM::get()->selected));
+ settings->setValue(settings::SystemProperties::activeSim,
+ utils::enumToString(Store::GSM::get()->selected),
+ settings::SettingsScope::Global);
// SIM causes SIM INIT, only on ready
response =
std::move(std::make_unique<CellularNotificationMessage>(CellularNotificationMessage::Type::SIM_READY));
M module-services/service-cellular/service-cellular/CellularRequestHandler.hpp => module-services/service-cellular/service-cellular/CellularRequestHandler.hpp +8 -10
@@ 6,21 6,19 @@
#include "RequestHandler.hpp"
#include "service-cellular/ServiceCellular.hpp"
-using namespace cellular;
-
-class CellularRequestHandler : public RequestHandler
+class CellularRequestHandler : public cellular::RequestHandler
{
public:
CellularRequestHandler(ServiceCellular &serviceCellular) : cellular(serviceCellular)
{}
- void handle(ImeiRequest &request, at::Result &result) final;
- void handle(UssdRequest &request, at::Result &result) final;
- void handle(CallRequest &request, at::Result &result) final;
- void handle(PasswordRegistrationRequest &request, at::Result &result) final;
- void handle(SupplementaryServicesRequest &request, at::Result &result) final;
- void handle(PinChangeRequest &request, at::Result &result) final;
- void handle(ClirRequest &request, at::Result &result) final;
+ void handle(cellular::ImeiRequest &request, at::Result &result) final;
+ void handle(cellular::UssdRequest &request, at::Result &result) final;
+ void handle(cellular::CallRequest &request, at::Result &result) final;
+ void handle(cellular::PasswordRegistrationRequest &request, at::Result &result) final;
+ void handle(cellular::SupplementaryServicesRequest &request, at::Result &result) final;
+ void handle(cellular::PinChangeRequest &request, at::Result &result) final;
+ void handle(cellular::ClirRequest &request, at::Result &result) final;
private:
ServiceCellular &cellular;
M module-services/service-cellular/service-cellular/PacketDataTypes.hpp => module-services/service-cellular/service-cellular/PacketDataTypes.hpp +64 -2
@@ 5,6 5,10 @@
#include <string>
#include <memory>
+#include <unordered_map>
+#include <map>
+
+#include <Utils.hpp>
namespace packet_data
{
@@ 22,10 26,11 @@ namespace packet_data
*/
enum class APNType
{
- Default, ///< for data traffic
+ Default, ///< only one APN is set as default
IMS, ///< IP Multimedia Subsystem for eg VoLTE
MMS, ///< for MMS service
- Fota ///< for Firmware Update
+ Fota, ///< for Firmware Update
+ Internet //< for data traffic
};
/**
@@ 81,6 86,63 @@ namespace packet_data
std::string password;
std::string ip; /// set after connection
+ std::string getAuthMethod()
+ {
+ return utils::enumToString(authMethod);
+ }
+
+ void setAuthMethod(const std::string &str)
+ {
+ if (str == "NONE")
+ authMethod = AuthMethod::NONE;
+ else if (str == "AUTO")
+ authMethod = AuthMethod::AUTO;
+ else if (str == "CHAP")
+ authMethod = AuthMethod::CHAP;
+ else if (str == "PAP")
+ authMethod = AuthMethod::PAP;
+ else
+ authMethod = AuthMethod::NONE;
+ }
+
+ std::string getApnType()
+ {
+ return utils::enumToString(apnType);
+ }
+
+ void setApnType(const std::string &str)
+ {
+ if (str == "Default")
+ apnType = APNType::Default;
+ else if (str == "Fota")
+ apnType = APNType::Fota;
+ else if (str == "IMS")
+ apnType = APNType::IMS;
+ else if (str == "Internet")
+ apnType = APNType::Internet;
+ else if (str == "MMS")
+ apnType = APNType::MMS;
+ else
+ apnType = APNType::Internet;
+ }
+
+ std::string getApnProtocol()
+ {
+ return utils::enumToString(contextType);
+ }
+
+ void setApnProtocol(const std::string &str)
+ {
+ if (str == "ipv4")
+ contextType = ContextType::ipv4;
+ else if (str == "ipv6")
+ contextType = ContextType::ipv6;
+ else if (str == "ipv4v6")
+ contextType = ContextType::ipv4v6;
+ else
+ contextType = ContextType::ipv4;
+ }
+
bool isEmpty() const noexcept
{
return apn.empty();
M module-services/service-db/DBServiceAPI.cpp => module-services/service-db/DBServiceAPI.cpp +48 -12
@@ 60,7 60,10 @@ auto DBServiceAPI::ThreadGetCount(sys::Service *serv, EntryState state) -> uint3
auto ret = sys::Bus::SendUnicast(msg, service::name::db, serv, DefaultTimeoutInMs);
auto threadResponse = dynamic_cast<DBThreadResponseMessage *>(ret.second.get());
- assert(threadResponse != nullptr);
+ if (threadResponse == nullptr) {
+ LOG_ERROR("DB response error, return code: %s", c_str(ret.first));
+ return 0;
+ }
if ((ret.first == sys::ReturnCodes::Success) && (threadResponse->retCode == 1)) {
return threadResponse->count;
}
@@ 91,7 94,10 @@ auto DBServiceAPI::ContactGetByIDCommon(sys::Service *serv, std::shared_ptr<DBCo
{
auto ret = sys::Bus::SendUnicast(contactMsg, service::name::db, serv, DefaultTimeoutInMs);
auto contactResponse = dynamic_cast<DBContactResponseMessage *>(ret.second.get());
- assert(contactResponse != nullptr);
+ if (contactResponse == nullptr) {
+ LOG_ERROR("DB response error, return code: %s", c_str(ret.first));
+ return nullptr;
+ }
if ((ret.first == sys::ReturnCodes::Success) && (contactResponse->retCode != 0)) {
return std::move(contactResponse->records);
}
@@ 133,7 139,10 @@ auto DBServiceAPI::MatchContactByPhoneNumber(sys::Service *serv, const utils::Ph
auto ret = sys::Bus::SendUnicast(msg, service::name::db, serv, DefaultTimeoutInMs);
auto contactResponse = dynamic_cast<DBContactNumberResponseMessage *>(ret.second.get());
- assert(contactResponse);
+ if (contactResponse == nullptr) {
+ LOG_ERROR("DB response error, return code: %s", c_str(ret.first));
+ return nullptr;
+ }
return std::move(contactResponse->contact);
}
@@ 180,7 189,10 @@ auto DBServiceAPI::ContactAdd(sys::Service *serv, const ContactRecord &rec) -> b
auto ret = sys::Bus::SendUnicast(msg, service::name::db, serv, DefaultTimeoutInMs);
auto contactResponse = dynamic_cast<DBContactResponseMessage *>(ret.second.get());
- assert(contactResponse != nullptr);
+ if (contactResponse == nullptr) {
+ LOG_ERROR("DB response error, return code: %s", c_str(ret.first));
+ return false;
+ }
if ((ret.first == sys::ReturnCodes::Success) && (contactResponse->retCode != 0)) {
return true;
}
@@ 194,7 206,10 @@ auto DBServiceAPI::ContactRemove(sys::Service *serv, uint32_t id) -> bool
auto ret = sys::Bus::SendUnicast(msg, service::name::db, serv, DefaultTimeoutInMs);
auto contactResponse = dynamic_cast<DBContactResponseMessage *>(ret.second.get());
- assert(contactResponse != nullptr);
+ if (contactResponse == nullptr) {
+ LOG_ERROR("DB response error, return code: %s", c_str(ret.first));
+ return false;
+ }
if ((ret.first == sys::ReturnCodes::Success) && (contactResponse->retCode != 0)) {
return true;
}
@@ 207,7 222,10 @@ auto DBServiceAPI::ContactUpdate(sys::Service *serv, const ContactRecord &rec) -
auto ret = sys::Bus::SendUnicast(msg, service::name::db, serv, DefaultTimeoutInMs);
auto contactResponse = dynamic_cast<DBContactResponseMessage *>(ret.second.get());
- assert(contactResponse != nullptr);
+ if (contactResponse == nullptr) {
+ LOG_ERROR("DB response error, return code: %s", c_str(ret.first));
+ return false;
+ }
if ((ret.first == sys::ReturnCodes::Success) && (contactResponse->retCode != 0)) {
return true;
}
@@ 225,7 243,10 @@ auto DBServiceAPI::ContactSearch(sys::Service *serv, UTF8 primaryName, UTF8 alte
auto ret = sys::Bus::SendUnicast(msg, service::name::db, serv, DefaultTimeoutInMs);
auto contactResponse = dynamic_cast<DBContactResponseMessage *>(ret.second.get());
- assert(contactResponse != nullptr);
+ if (contactResponse == nullptr) {
+ LOG_ERROR("DB response error, return code: %s", c_str(ret.first));
+ return nullptr;
+ }
if ((ret.first == sys::ReturnCodes::Success) && (contactResponse->retCode != 0)) {
return std::move(contactResponse->records);
}
@@ 240,7 261,10 @@ auto DBServiceAPI::CalllogAdd(sys::Service *serv, const CalllogRecord &rec) -> C
auto ret = sys::Bus::SendUnicast(msg, service::name::db, serv, DefaultTimeoutInMs);
auto calllogResponse = dynamic_cast<DBCalllogResponseMessage *>(ret.second.get());
- assert(calllogResponse != nullptr);
+ if (calllogResponse == nullptr) {
+ LOG_ERROR("DB response error, return code: %s", c_str(ret.first));
+ return CalllogRecord();
+ }
if ((ret.first == sys::ReturnCodes::Success) && (calllogResponse->retCode != 0)) {
auto records = *calllogResponse->records;
if (!records.empty()) {
@@ 258,7 282,10 @@ auto DBServiceAPI::CalllogRemove(sys::Service *serv, uint32_t id) -> bool
auto ret = sys::Bus::SendUnicast(msg, service::name::db, serv, DefaultTimeoutInMs);
auto calllogResponse = dynamic_cast<DBCalllogResponseMessage *>(ret.second.get());
- assert(calllogResponse != nullptr);
+ if (calllogResponse == nullptr) {
+ LOG_ERROR("DB response error, return code: %s", c_str(ret.first));
+ return false;
+ }
if ((ret.first == sys::ReturnCodes::Success) && (calllogResponse->retCode != 0)) {
return true;
}
@@ 273,7 300,10 @@ auto DBServiceAPI::CalllogUpdate(sys::Service *serv, const CalllogRecord &rec) -
auto ret = sys::Bus::SendUnicast(msg, service::name::db, serv, DefaultTimeoutInMs);
auto calllogResponse = dynamic_cast<DBCalllogResponseMessage *>(ret.second.get());
- assert(calllogResponse != nullptr);
+ if (calllogResponse == nullptr) {
+ LOG_ERROR("DB response error, return code: %s", c_str(ret.first));
+ return false;
+ }
if ((ret.first == sys::ReturnCodes::Success) && (calllogResponse->retCode != 0)) {
return true;
}
@@ 286,7 316,10 @@ auto DBServiceAPI::CalllogGetCount(sys::Service *serv, EntryState state) -> uint
auto ret = sys::Bus::SendUnicast(msg, service::name::db, serv, DefaultTimeoutInMs);
auto calllogResponse = dynamic_cast<DBCalllogResponseMessage *>(ret.second.get());
- assert(calllogResponse != nullptr);
+ if (calllogResponse == nullptr) {
+ LOG_ERROR("DB response error, return code: %s", c_str(ret.first));
+ return 0;
+ }
if ((ret.first == sys::ReturnCodes::Success) && (calllogResponse->retCode != 0)) {
return calllogResponse->count;
}
@@ 310,7 343,10 @@ auto DBServiceAPI::GetCountryCodeByMCC(sys::Service *serv, uint32_t mcc) -> uint
auto ret = sys::Bus::SendUnicast(msg, service::name::db, serv, DefaultTimeoutInMs);
auto response = dynamic_cast<DBCountryCodeResponseMessage *>(ret.second.get());
- assert(response != nullptr);
+ if (response == nullptr) {
+ LOG_ERROR("DB response error, return code: %s", c_str(ret.first));
+ return 0;
+ }
if (ret.first == sys::ReturnCodes::Success) {
return (response->row.country_code);
}
M module-services/service-db/agents/settings/Settings.cpp => module-services/service-db/agents/settings/Settings.cpp +46 -23
@@ 52,9 52,9 @@ namespace settings
{
LOG_DEBUG("handleVariableChanged");
if (auto msg = dynamic_cast<settings::Messages::VariableChanged *>(req)) {
- auto key = msg->getPath().variable;
+ auto key = msg->getPath();
auto val = msg->getValue();
- LOG_DEBUG("handleVariableChanged: (k=v): (%s=%s)", key.c_str(), val.value_or("").c_str());
+ LOG_DEBUG("handleVariableChanged: (k=v): (%s=%s)", key.to_string().c_str(), val.value_or("").c_str());
ValueCb::iterator it_cb = cbValues.find(key);
if (cbValues.end() != it_cb) {
auto [cb, cbWithName] = it_cb->second;
@@ 62,13 62,13 @@ namespace settings
// in case of two callbacks there is a need to duplicate the value
auto value = std::move(val.value_or(""));
cb(std::string{value});
- cbWithName(key, std::move(value));
+ cbWithName(key.variable, std::move(value));
}
else if (nullptr != cb) {
cb(std::move(val.value_or("")));
}
else {
- cbWithName(key, std::move(val.value_or("")));
+ cbWithName(key.variable, std::move(val.value_or("")));
}
}
}
@@ 115,56 115,79 @@ namespace settings
return std::make_shared<sys::ResponseMessage>();
}
- void Settings::registerValueChange(const std::string &variableName, ValueChangedCallback cb)
+ void Settings::registerValueChange(const std::string &variableName, ValueChangedCallback cb, SettingsScope scope)
{
- ValueCb::iterator it_cb = cbValues.find(variableName);
- if (cbValues.end() != it_cb && nullptr != it_cb->second.first) {
- LOG_INFO("Callback function on value change (%s) already exists, rewriting", variableName.c_str());
- }
- cbValues[variableName].first = cb;
EntryPath path;
path.variable = variableName;
path.service = app->GetName();
+ path.scope = scope;
+
+ auto it_cb = cbValues.find(path);
+ if (cbValues.end() != it_cb && nullptr != it_cb->second.first) {
+ LOG_INFO("Callback function on value change (%s) already exists, rewriting", path.to_string().c_str());
+ }
+ cbValues[path].first = cb;
+
auto msg = std::make_shared<settings::Messages::RegisterOnVariableChange>(path);
sendMsg(std::move(msg));
}
- void Settings::registerValueChange(const std::string &variableName, ValueChangedCallbackWithName cb)
+ void Settings::registerValueChange(const std::string &variableName,
+ ValueChangedCallbackWithName cb,
+ SettingsScope scope)
{
- auto it_cb = cbValues.find(variableName);
- if (cbValues.end() != it_cb && nullptr != it_cb->second.second) {
- LOG_INFO("Callback function on value change (%s) already exists, rewriting", variableName.c_str());
- }
- cbValues[variableName].second = cb;
EntryPath path;
path.variable = variableName;
path.service = app->GetName();
+ path.scope = scope;
+
+ auto it_cb = cbValues.find(path);
+ if (cbValues.end() != it_cb && nullptr != it_cb->second.second) {
+ LOG_INFO("Callback function on value change (%s) already exists, rewriting", path.to_string().c_str());
+ }
+ cbValues[path].second = cb;
+
auto msg = std::make_shared<settings::Messages::RegisterOnVariableChange>(path);
sendMsg(std::move(msg));
}
- void Settings::unregisterValueChange(const std::string &variableName)
+ void Settings::unregisterValueChange(const std::string &variableName, SettingsScope scope)
{
- ValueCb::iterator it_cb = cbValues.find(variableName);
+ EntryPath path;
+ path.variable = variableName;
+ path.service = app->GetName();
+ path.scope = scope;
+
+ auto it_cb = cbValues.find(path);
if (cbValues.end() == it_cb) {
- LOG_INFO("Callback function on value change (%s) does not exist", variableName.c_str());
+ LOG_INFO("Callback function on value change (%s) does not exist", path.to_string().c_str());
}
else {
+ LOG_DEBUG("[Settings::unregisterValueChange] %s", path.to_string().c_str());
cbValues.erase(it_cb);
}
- EntryPath path;
- path.variable = variableName;
- path.service = app->GetName();
auto msg = std::make_shared<settings::Messages::UnregisterOnVariableChange>(path);
sendMsg(std::move(msg));
}
- void Settings::setValue(const std::string &variableName, const std::string &variableValue)
+ void Settings::unregisterValueChange()
+ {
+ for (auto it_cb : cbValues) {
+ LOG_DEBUG("[Settings::unregisterValueChange] %s", it_cb.first.to_string().c_str());
+ auto msg = std::make_shared<settings::Messages::UnregisterOnVariableChange>(it_cb.first);
+ sendMsg(std::move(msg));
+ }
+ cbValues.clear();
+ LOG_INFO("Unregistered all settings variable change on application (%s)", app->GetName().c_str());
+ }
+
+ void Settings::setValue(const std::string &variableName, const std::string &variableValue, SettingsScope scope)
{
EntryPath path;
path.variable = variableName;
path.service = app->GetName();
+ path.scope = scope;
auto msg = std::make_shared<settings::Messages::SetVariable>(path, variableValue);
sendMsg(std::move(msg));
}
M module-services/service-db/agents/settings/SettingsAgent.cpp => module-services/service-db/agents/settings/SettingsAgent.cpp +20 -26
@@ 4,8 4,6 @@
#include "SettingsAgent.hpp"
#include "Settings_queries.hpp"
-#include <service-db/SettingsMessages.hpp>
-
#include <Database/Database.hpp>
#include <Service/Service.hpp>
#include <module-sys/Service/Bus.hpp>
@@ 24,16 22,6 @@ SettingsAgent::SettingsAgent(sys::Service *parentService) : DatabaseAgent(parent
void SettingsAgent::initDb()
{
- auto notifications = database->query(settings::Statements::getAllNotifications);
- if (nullptr == notifications || 0 == notifications->getRowCount()) {
- return;
- }
- do {
- variableChangeRecipents[(*notifications)[0].getString()].insert((*notifications)[1].getString());
- /*what about mode/profile
- modeChangeRecipents;
- profileChangeRecipents;*/
- } while (notifications->nextRow());
}
void SettingsAgent::deinitDb()
@@ 95,8 83,7 @@ auto SettingsAgent::getAgentName() -> const std::string
// dbSingleVar
auto SettingsAgent::dbGetValue(settings::EntryPath path) -> std::optional<std::string>
{
- // auto retQuery = database->query(settings::Statements::getValue, path.to_string());
- auto retQuery = database->query(settings::Statements::getValue, path.variable.c_str());
+ auto retQuery = database->query(settings::Statements::getValue, path.to_string().c_str());
if (nullptr == retQuery || 1 != retQuery->getRowCount()) {
return std::string{};
}
@@ 106,17 93,18 @@ auto SettingsAgent::dbGetValue(settings::EntryPath path) -> std::optional<std::s
auto SettingsAgent::dbSetValue(settings::EntryPath path, std::string value) -> bool
{
/// insert or update
- return database->execute(settings::Statements::insertValue, path.variable.c_str(), value.c_str());
+ return database->execute(settings::Statements::insertValue, path.to_string().c_str(), value.c_str());
}
auto SettingsAgent::dbRegisterValueChange(settings::EntryPath path) -> bool
{
- return database->execute(settings::Statements::setNotification, path.variable.c_str(), path.service.c_str());
+ return database->execute(settings::Statements::setNotification, path.to_string().c_str(), path.service.c_str());
}
auto SettingsAgent::dbUnregisterValueChange(settings::EntryPath path) -> bool
{
- return database->execute(settings::Statements::clearNotificationdRow, path.variable.c_str());
+ return database->execute(
+ settings::Statements::clearNotificationdRow, path.to_string().c_str(), path.service.c_str());
}
// db Profile
@@ 223,12 211,13 @@ auto SettingsAgent::handleSetVariable(sys::Message *req) -> sys::MessagePointer
auto oldValue = dbGetValue(path);
if (oldValue.has_value() && oldValue.value() != value) {
dbSetValue(path, value);
- // for (auto service : variableChangeRecipents[path.to_string()]) {
- for (auto service : variableChangeRecipents[path.variable]) {
- if (service != path.service) {
+ LOG_DEBUG("[SettingsAgent::handleSetVariable] %s=%s", path.to_string().c_str(), value.c_str());
+ for (auto regPath : variableChangeRecipents[path.to_string()]) {
+ if (regPath.service != path.service) {
auto updateMsg =
- std::make_shared<settings::Messages::VariableChanged>(path, value, oldValue.value_or(""));
- sys::Bus::SendUnicast(std::move(updateMsg), service, parentService);
+ std::make_shared<settings::Messages::VariableChanged>(regPath, value, oldValue.value_or(""));
+ sys::Bus::SendUnicast(std::move(updateMsg), regPath.service, parentService);
+ LOG_DEBUG("[SettingsAgent::handleSetVariable] notified service: %s", regPath.service.c_str());
}
}
}
@@ 242,14 231,18 @@ auto SettingsAgent::handleRegisterOnVariableChange(sys::Message *req) -> sys::Me
auto path = msg->getPath();
if (dbRegisterValueChange(path)) {
auto it = variableChangeRecipents.find(path.to_string());
- if (variableChangeRecipents.end() == it || it->second.end() == it->second.find(path.service)) {
- variableChangeRecipents[path.to_string()] = {path.service};
+ if (variableChangeRecipents.end() == it || it->second.end() == it->second.find(path)) {
+ variableChangeRecipents[path.to_string()] = {path};
auto currentValue = dbGetValue(path).value_or("");
auto msgValue = std::make_shared<::settings::Messages::VariableChanged>(path, currentValue, "");
sys::Bus::SendUnicast(std::move(msgValue), msg->sender, parentService);
+ LOG_DEBUG("[SettingsAgent::handleRegisterOnVariableChange] %s=%s to %s",
+ path.to_string().c_str(),
+ currentValue.c_str(),
+ msg->sender.c_str());
}
else {
- it->second.insert(path.service);
+ it->second.insert(path);
}
}
}
@@ 263,7 256,8 @@ auto SettingsAgent::handleUnregisterOnVariableChange(sys::Message *req) -> sys::
if (dbUnregisterValueChange(path)) {
auto it = variableChangeRecipents.find(path.to_string());
if (variableChangeRecipents.end() != it) {
- it->second.erase(path.service);
+ it->second.erase(path);
+ LOG_DEBUG("[SettingsAgent::handleUnregisterOnVariableChange] %s", path.to_string().c_str());
}
}
}
M module-services/service-db/agents/settings/SettingsAgent.hpp => module-services/service-db/agents/settings/SettingsAgent.hpp +2 -1
@@ 32,7 32,8 @@ class SettingsAgent : public DatabaseAgent
auto getAgentName() -> const std::string override;
private:
- using MapOfRecipentsToBeNotified = std::map<std::string, std::set<std::string>>;
+ // using MapOfRecipentsToBeNotified = std::map<std::string, std::set<std::string>>;
+ using MapOfRecipentsToBeNotified = std::map<std::string, std::set<settings::EntryPath>>;
MapOfRecipentsToBeNotified variableChangeRecipents;
using SetOfRecipents = std::set<std::string>;
SetOfRecipents profileChangedRecipents;
M module-services/service-db/service-db/Settings.hpp => module-services/service-db/service-db/Settings.hpp +15 -10
@@ 5,6 5,8 @@
#include <module-sys/Service/Message.hpp>
#include <service-db/DBServiceName.hpp>
+#include "SettingsScope.hpp"
+#include "SettingsMessages.hpp"
#include <cstdint>
#include <functional>
@@ 16,11 18,6 @@
namespace settings
{
- namespace Messages
- {
- class SettingsMessage;
- }
-
class Settings
{
public:
@@ 36,10 33,18 @@ namespace settings
Settings(sys::Service *app, const std::string &dbAgentName = service::name::db);
virtual ~Settings();
- void setValue(const std::string &variableName, const std::string &variableValue);
- void registerValueChange(const std::string &variableName, ValueChangedCallback cb);
- void registerValueChange(const std::string &variableName, ValueChangedCallbackWithName cb);
- void unregisterValueChange(const std::string &variableName);
+ void setValue(const std::string &variableName,
+ const std::string &variableValue,
+ SettingsScope scope = SettingsScope::AppLocal);
+ void registerValueChange(const std::string &variableName,
+ ValueChangedCallback cb,
+ SettingsScope scope = SettingsScope::AppLocal);
+ void registerValueChange(const std::string &variableName,
+ ValueChangedCallbackWithName cb,
+ SettingsScope scope = SettingsScope::AppLocal);
+ void unregisterValueChange(const std::string &variableName, SettingsScope scope = SettingsScope::AppLocal);
+ /// unregisters all registered variables (both global and local)
+ void unregisterValueChange();
void getAllProfiles(OnAllProfilesRetrievedCallback cb);
void setCurrentProfile(const std::string &profile);
@@ 61,7 66,7 @@ namespace settings
std::string phoneMode;
std::string profile;
- using ValueCb = std::map<std::string, std::pair<ValueChangedCallback, ValueChangedCallbackWithName>>;
+ using ValueCb = std::map<EntryPath, std::pair<ValueChangedCallback, ValueChangedCallbackWithName>>;
ValueCb cbValues;
ModeChangedCallback cbMode;
OnAllModesRetrievedCallback cbAllModes;
M module-services/service-db/service-db/SettingsMessages.hpp => module-services/service-db/service-db/SettingsMessages.hpp +30 -0
@@ 5,6 5,7 @@
#include <MessageType.hpp>
#include <Service/Message.hpp>
+#include <service-db/SettingsScope.hpp>
#include <list>
#include <memory>
@@ 20,11 21,40 @@ namespace settings
std::string service;
std::string profile;
std::string variable;
+ SettingsScope scope;
[[nodiscard]] auto to_string(std::string sep = "\\") const -> std::string
{
+ if (SettingsScope::Global == scope) {
+ return variable;
+ }
return mode + sep + service + sep + profile + sep + variable;
}
+
+ bool operator<(const EntryPath &other) const
+ {
+ if (mode < other.mode)
+ return true;
+ if (mode > other.mode)
+ return false;
+ if (service < other.service)
+ return true;
+ if (service > other.service)
+ return false;
+ if (profile < other.profile)
+ return true;
+ if (profile > other.profile)
+ return false;
+ if (variable < other.variable)
+ return true;
+ if (variable > other.variable)
+ return false;
+ if (scope < other.scope)
+ return true;
+ if (scope > other.scope)
+ return false;
+ return false;
+ }
};
namespace Messages
A module-services/service-db/service-db/SettingsScope.hpp => module-services/service-db/service-db/SettingsScope.hpp +12 -0
@@ 0,0 1,12 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+namespace settings
+{
+ enum class SettingsScope
+ {
+ Global,
+ AppLocal
+ };
+}
M module-services/service-db/test/test-service-db-settings-messages.cpp => module-services/service-db/test/test-service-db-settings-messages.cpp +4 -4
@@ 118,13 118,13 @@ TEST_CASE("Settings Messages")
settings::Service settings("settings");
settings.InitHandler();
- sys::Bus::SendUnicast(std::make_shared<settings::Messages::RegisterOnVariableChange>(
- settings::EntryPath({"mode", "service", "profile", "variable"})),
+ sys::Bus::SendUnicast(std::make_shared<settings::Messages::RegisterOnVariableChange>(settings::EntryPath(
+ {"mode", "service", "profile", "variable", settings::SettingsScope::AppLocal})),
"db-worker",
&settings);
- sys::Bus::SendUnicast(std::make_shared<settings::Messages::UnregisterOnVariableChange>(
- settings::EntryPath({"mode", "service", "profile", "variable"})),
+ sys::Bus::SendUnicast(std::make_shared<settings::Messages::UnregisterOnVariableChange>(settings::EntryPath(
+ {"mode", "service", "profile", "variable", settings::SettingsScope::AppLocal})),
"db-worker",
&settings);
}
M module-services/service-db/test/test-service-db-settings-testservices.hpp => module-services/service-db/test/test-service-db-settings-testservices.hpp +6 -4
@@ 28,26 28,28 @@ namespace settings
if (auto msg = dynamic_cast<settings::UTMsg::ReqRegValChg *>(req)) {
debug("ReqRegValChg", msg->name, msg->value);
whoRequestedNotifyOnChange = msg->sender;
- mySettings->registerValueChange(msg->name, ([this](std::string value) {
+ mySettings->registerValueChange(msg->name,
+ ([this](std::string value) {
ValueChanged(value);
auto cnf = std::make_shared<settings::UTMsg::CnfValChg>("", value);
sys::Bus::SendUnicast(
std::move(cnf), whoRequestedNotifyOnChange, this);
- }));
+ }),
+ settings::SettingsScope::Global);
auto cnf = std::make_shared<settings::UTMsg::CnfRegValChg>(msg->name, msg->value);
sys::Bus::SendUnicast(std::move(cnf), whoRequestedNotifyOnChange, this);
}
else if (auto msg = dynamic_cast<settings::UTMsg::ReqUnRegValChg *>(req)) {
// unregister
debug("ReqUnRegValChg", msg->name, msg->value);
- mySettings->unregisterValueChange(msg->name);
+ mySettings->unregisterValueChange(msg->name, settings::SettingsScope::Global);
auto cnf = std::make_shared<settings::UTMsg::CnfUnRegValChg>(msg->name, msg->value);
sys::Bus::SendUnicast(std::move(cnf), msg->sender, this);
}
else if (auto msg = dynamic_cast<settings::UTMsg::ReqSetVal *>(req)) {
// set value
debug("ReqSetVal", msg->name, msg->value);
- mySettings->setValue(msg->name, msg->value);
+ mySettings->setValue(msg->name, msg->value, settings::SettingsScope::Global);
auto cnf = std::make_shared<settings::UTMsg::CnfReqSetVal>(msg->name, msg->value);
sys::Bus::SendUnicast(std::move(cnf), msg->sender, this);
}
M module-services/service-desktop/DesktopMessages.cpp => module-services/service-desktop/DesktopMessages.cpp +1 -0
@@ 6,6 6,7 @@
namespace sdesktop::developerMode
{
+ using namespace parserFSM;
void Event::send()
{
MessageHandler::putToSendQueue(context.createSimpleResponse());
M module-services/service-desktop/ServiceDesktop.cpp => module-services/service-desktop/ServiceDesktop.cpp +4 -3
@@ 29,8 29,6 @@ ServiceDesktop::ServiceDesktop() : sys::Service(service::name::service_desktop,
updateOS = std::make_unique<UpdateMuditaOS>(this);
settings = std::make_unique<settings::Settings>(this);
- settings->registerValueChange(updateos::settings::history,
- [this](const std::string &value) { updateOS->setInitialHistory(value); });
}
ServiceDesktop::~ServiceDesktop()
@@ 42,7 40,7 @@ sys::ReturnCodes ServiceDesktop::InitHandler()
{
desktopWorker = std::make_unique<WorkerDesktop>(this);
const bool ret = desktopWorker->init(
- {{sdesktop::RECEIVE_QUEUE_BUFFER_NAME, sizeof(std::string), sdesktop::cdc_queue_len},
+ {{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}});
if (ret == false) {
@@ 116,6 114,9 @@ sys::ReturnCodes ServiceDesktop::InitHandler()
return std::make_shared<sys::ResponseMessage>();
});
+ settings->registerValueChange(updateos::settings::history,
+ [this](const std::string &value) { updateOS->setInitialHistory(value); });
+
return (sys::ReturnCodes::Success);
}
M module-services/service-desktop/WorkerDesktop.cpp => module-services/service-desktop/WorkerDesktop.cpp +5 -6
@@ 30,7 30,7 @@ bool WorkerDesktop::init(std::list<sys::WorkerQueueInfo> queues)
Worker::init(queues);
receiveQueue = Worker::getQueueHandleByName(sdesktop::RECEIVE_QUEUE_BUFFER_NAME);
- parserFSM::MessageHandler::sendQueue = Worker::getQueueHandleByName(sdesktop::SEND_QUEUE_BUFFER_NAME);
+ parserFSM::MessageHandler::setSendQueueHandle(Worker::getQueueHandleByName(sdesktop::SEND_QUEUE_BUFFER_NAME));
return (bsp::usbInit(receiveQueue, this) < 0) ? false : true;
}
@@ 58,16 58,17 @@ bool WorkerDesktop::handleMessage(uint32_t queueID)
LOG_INFO("handleMessage received data from queue: %s", qname.c_str());
- static std::string *sendMsg = nullptr;
- static std::string receivedMsg;
if (qname == sdesktop::RECEIVE_QUEUE_BUFFER_NAME) {
+ std::string *receivedMsg = nullptr;
if (!queue->Dequeue(&receivedMsg, 0)) {
LOG_ERROR("handleMessage failed to receive from \"%s\"", sdesktop::RECEIVE_QUEUE_BUFFER_NAME);
return false;
}
- parser.processMessage(receivedMsg);
+ parser.processMessage(std::move(*receivedMsg));
+ delete receivedMsg;
}
else if (qname == sdesktop::SEND_QUEUE_BUFFER_NAME) {
+ std::string *sendMsg = nullptr;
if (!queue->Dequeue(&sendMsg, 0)) {
LOG_ERROR("handleMessage xQueueReceive failed for %s.", sdesktop::SEND_QUEUE_BUFFER_NAME);
return false;
@@ 75,9 76,7 @@ bool WorkerDesktop::handleMessage(uint32_t queueID)
LOG_DEBUG("handeMessage sending %d bytes using usbCDCSend", static_cast<unsigned int>(sendMsg->length()));
bsp::usbCDCSend(sendMsg);
-
delete sendMsg;
- sendMsg = nullptr;
}
else {
LOG_INFO("handeMessage got message on an unhandled queue");
M module-services/service-desktop/endpoints/EndpointFactory.hpp => module-services/service-desktop/endpoints/EndpointFactory.hpp +13 -14
@@ 19,36 19,35 @@
#include "restore/RestoreEndpoint.hpp"
#include "update/UpdateEndpoint.hpp"
-using namespace parserFSM;
-
class EndpointFactory
{
public:
- static auto create(Context &context, sys::Service *ownerServicePtr) -> std::unique_ptr<Endpoint>
+ static auto create(parserFSM::Context &context, sys::Service *ownerServicePtr)
+ -> std::unique_ptr<parserFSM::Endpoint>
{
LOG_DEBUG("Creating endpoint: %d", static_cast<int>(context.getEndpoint()));
switch (context.getEndpoint()) {
- case EndpointType::update:
+ case parserFSM::EndpointType::update:
return std::make_unique<UpdateEndpoint>(ownerServicePtr);
- case EndpointType::filesystemUpload:
+ case parserFSM::EndpointType::filesystemUpload:
return std::make_unique<FilesystemEndpoint>(ownerServicePtr);
- case EndpointType::backup:
+ case parserFSM::EndpointType::backup:
return std::make_unique<BackupEndpoint>(ownerServicePtr);
- case EndpointType::deviceInfo:
+ case parserFSM::EndpointType::deviceInfo:
return std::make_unique<DeviceInfoEndpoint>(ownerServicePtr);
- case EndpointType::restore:
+ case parserFSM::EndpointType::restore:
return std::make_unique<RestoreEndpoint>(ownerServicePtr);
- case EndpointType::contacts:
+ case parserFSM::EndpointType::contacts:
return std::make_unique<ContactsEndpoint>(ownerServicePtr);
- case EndpointType::messages:
+ case parserFSM::EndpointType::messages:
return std::make_unique<MessagesEndpoint>(ownerServicePtr);
- case EndpointType::factory:
+ case parserFSM::EndpointType::factory:
return std::make_unique<FactoryResetEndpoint>(ownerServicePtr);
- case EndpointType::calllog:
+ case parserFSM::EndpointType::calllog:
return std::make_unique<CalllogEndpoint>(ownerServicePtr);
- case EndpointType::developerMode:
+ case parserFSM::EndpointType::developerMode:
return std::make_unique<DeveloperModeEndpoint>(ownerServicePtr);
- case EndpointType::calendarEvents:
+ case parserFSM::EndpointType::calendarEvents:
return std::make_unique<CalendarEventsEndpoint>(ownerServicePtr);
default:
return nullptr;
M module-services/service-desktop/endpoints/backup/BackupEndpoint.cpp => module-services/service-desktop/endpoints/backup/BackupEndpoint.cpp +2 -0
@@ 18,6 18,8 @@
static bool backupReady = false;
+using namespace parserFSM;
+
auto BackupEndpoint::handle(Context &context) -> void
{
switch (context.getMethod()) {
M module-services/service-desktop/endpoints/backup/BackupEndpoint.hpp => module-services/service-desktop/endpoints/backup/BackupEndpoint.hpp +4 -6
@@ 20,16 20,14 @@ namespace sys
class Service;
} // namespace sys
-using namespace parserFSM;
-
-class BackupEndpoint : public Endpoint
+class BackupEndpoint : public parserFSM::Endpoint
{
public:
BackupEndpoint(sys::Service *ownerServicePtr) : Endpoint(ownerServicePtr)
{
debugName = "BackupEndpoint";
}
- auto handle(Context &context) -> void override;
- auto request(Context &context) -> sys::ReturnCodes;
- auto upload(Context &context) -> sys::ReturnCodes;
+ auto handle(parserFSM::Context &context) -> void override;
+ auto request(parserFSM::Context &context) -> sys::ReturnCodes;
+ auto upload(parserFSM::Context &context) -> sys::ReturnCodes;
};
M module-services/service-desktop/endpoints/calendarEvents/CalendarEventsEndpoint.hpp => module-services/service-desktop/endpoints/calendarEvents/CalendarEventsEndpoint.hpp +4 -6
@@ 7,18 7,16 @@
#include "Service/Service.hpp"
#include "CalendarEventsHelper.hpp"
-using namespace parserFSM;
-
-class CalendarEventsEndpoint : public Endpoint
+class CalendarEventsEndpoint : public parserFSM::Endpoint
{
private:
std::string debugName = "CalendarEventsEndpoint";
- std::unique_ptr<CalendarEventsHelper> helper;
+ std::unique_ptr<parserFSM::CalendarEventsHelper> helper;
public:
CalendarEventsEndpoint(sys::Service *_ownerServicePtr) : Endpoint(_ownerServicePtr)
{
- helper = std::make_unique<CalendarEventsHelper>(ownerServicePtr);
+ helper = std::make_unique<parserFSM::CalendarEventsHelper>(ownerServicePtr);
}
- void handle(Context &context) override;
+ void handle(parserFSM::Context &context) override;
};
M module-services/service-desktop/endpoints/calllog/CalllogEndpoint.hpp => module-services/service-desktop/endpoints/calllog/CalllogEndpoint.hpp +4 -6
@@ 20,18 20,16 @@ namespace sys
class Service;
} // namespace sys
-using namespace parserFSM;
-
-class CalllogEndpoint : public Endpoint
+class CalllogEndpoint : public parserFSM::Endpoint
{
private:
- std::unique_ptr<CalllogHelper> helper;
+ std::unique_ptr<parserFSM::CalllogHelper> helper;
public:
CalllogEndpoint(sys::Service *_ownerServicePtr) : Endpoint(_ownerServicePtr)
{
debugName = "CalllogEndpoint";
- helper = std::make_unique<CalllogHelper>(ownerServicePtr);
+ helper = std::make_unique<parserFSM::CalllogHelper>(ownerServicePtr);
}
- auto handle(Context &context) -> void override;
+ auto handle(parserFSM::Context &context) -> void override;
};
M module-services/service-desktop/endpoints/contacts/ContactsEndpoint.hpp => module-services/service-desktop/endpoints/contacts/ContactsEndpoint.hpp +4 -6
@@ 22,18 22,16 @@ namespace sys
class Service;
} // namespace sys
-using namespace parserFSM;
-
-class ContactsEndpoint : public Endpoint
+class ContactsEndpoint : public parserFSM::Endpoint
{
private:
- std::unique_ptr<ContactHelper> helper;
+ std::unique_ptr<parserFSM::ContactHelper> helper;
public:
ContactsEndpoint(sys::Service *_ownerServicePtr) : Endpoint(_ownerServicePtr)
{
debugName = "ContactsEndpoint";
- helper = std::make_unique<ContactHelper>(ownerServicePtr);
+ helper = std::make_unique<parserFSM::ContactHelper>(ownerServicePtr);
}
- auto handle(Context &context) -> void override;
+ auto handle(parserFSM::Context &context) -> void override;
};
M module-services/service-desktop/endpoints/developerMode/DeveloperModeEndpoint.hpp => module-services/service-desktop/endpoints/developerMode/DeveloperModeEndpoint.hpp +4 -6
@@ 21,18 21,16 @@ namespace sys
class Service;
} // namespace sys
-using namespace parserFSM;
-
-class DeveloperModeEndpoint : public Endpoint
+class DeveloperModeEndpoint : public parserFSM::Endpoint
{
private:
- std::unique_ptr<DeveloperModeHelper> helper;
+ std::unique_ptr<parserFSM::DeveloperModeHelper> helper;
public:
DeveloperModeEndpoint(sys::Service *_ownerServicePtr) : Endpoint(_ownerServicePtr)
{
debugName = "DeveloperModeEndpoint";
- helper = std::make_unique<DeveloperModeHelper>(ownerServicePtr);
+ helper = std::make_unique<parserFSM::DeveloperModeHelper>(ownerServicePtr);
}
- auto handle(Context &context) -> void override;
+ auto handle(parserFSM::Context &context) -> void override;
};
M module-services/service-desktop/endpoints/deviceInfo/DeviceInfoEndpoint.cpp => module-services/service-desktop/endpoints/deviceInfo/DeviceInfoEndpoint.cpp +2 -0
@@ 15,6 15,8 @@
#include <sys/statvfs.h>
#include <purefs/filesystem_paths.hpp>
+using namespace parserFSM;
+
auto DeviceInfoEndpoint::handle(Context &context) -> void
{
switch (context.getMethod()) {
M module-services/service-desktop/endpoints/deviceInfo/DeviceInfoEndpoint.hpp => module-services/service-desktop/endpoints/deviceInfo/DeviceInfoEndpoint.hpp +3 -5
@@ 19,9 19,7 @@ namespace sys
class Service;
} // namespace sys
-using namespace parserFSM;
-
-class DeviceInfoEndpoint : public Endpoint
+class DeviceInfoEndpoint : public parserFSM::Endpoint
{
public:
@@ 29,6 27,6 @@ class DeviceInfoEndpoint : public Endpoint
{
debugName = "DeviceInfoEndpoint";
}
- auto handle(Context &context) -> void override;
- auto getDeviceInfo(Context &context) -> bool;
+ auto handle(parserFSM::Context &context) -> void override;
+ auto getDeviceInfo(parserFSM::Context &context) -> bool;
};
M module-services/service-desktop/endpoints/factoryReset/FactoryResetEndpoint.cpp => module-services/service-desktop/endpoints/factoryReset/FactoryResetEndpoint.cpp +3 -3
@@ 13,7 13,7 @@
#include <memory>
-auto FactoryResetEndpoint::handle(Context &context) -> void
+auto FactoryResetEndpoint::handle(parserFSM::Context &context) -> void
{
if (context.getMethod() == parserFSM::http::Method::post) {
@@ 27,14 27,14 @@ auto FactoryResetEndpoint::handle(Context &context) -> void
context.setResponseBody(json11::Json::object({{parserFSM::json::factoryRequest, false}}));
}
- MessageHandler::putToSendQueue(context.createSimpleResponse());
+ parserFSM::MessageHandler::putToSendQueue(context.createSimpleResponse());
return;
}
else {
context.setResponseBody(json11::Json::object({{parserFSM::json::factoryRequest, false}}));
- MessageHandler::putToSendQueue(context.createSimpleResponse());
+ parserFSM::MessageHandler::putToSendQueue(context.createSimpleResponse());
return;
}
M module-services/service-desktop/endpoints/factoryReset/FactoryResetEndpoint.hpp => module-services/service-desktop/endpoints/factoryReset/FactoryResetEndpoint.hpp +3 -5
@@ 19,9 19,7 @@ namespace sys
class Service;
} // namespace sys
-using namespace parserFSM;
-
-class FactoryResetEndpoint : public Endpoint
+class FactoryResetEndpoint : public parserFSM::Endpoint
{
public:
@@ 29,6 27,6 @@ class FactoryResetEndpoint : public Endpoint
{
debugName = "FactoryResetEndpoint";
}
- auto handle(Context &context) -> void override;
- auto makeFactoryReset(Context &context) -> bool;
+ auto handle(parserFSM::Context &context) -> void override;
+ auto makeFactoryReset(parserFSM::Context &context) -> bool;
};
M module-services/service-desktop/endpoints/filesystem/FilesystemEndpoint.cpp => module-services/service-desktop/endpoints/filesystem/FilesystemEndpoint.cpp +3 -1
@@ 6,6 6,8 @@
#include "service-desktop/ServiceDesktop.hpp"
#include <purefs/filesystem_paths.hpp>
+using namespace parserFSM;
+
auto FilesystemEndpoint::handle(Context &context) -> void
{
LOG_DEBUG("handle");
@@ 68,4 70,4 @@ auto FilesystemEndpoint::run(Context &context) -> sys::ReturnCodes
MessageHandler::putToSendQueue(context.createSimpleResponse());
return returnCode;
-}>
\ No newline at end of file
+}
M module-services/service-desktop/endpoints/filesystem/FilesystemEndpoint.hpp => module-services/service-desktop/endpoints/filesystem/FilesystemEndpoint.hpp +4 -6
@@ 6,14 6,12 @@
#include <module-services/service-desktop/endpoints/Endpoint.hpp>
#include "Service/Service.hpp"
-using namespace parserFSM;
-
-class FilesystemEndpoint : public Endpoint
+class FilesystemEndpoint : public parserFSM::Endpoint
{
public:
FilesystemEndpoint(sys::Service *ownerServicePtr) : Endpoint(ownerServicePtr)
{}
- auto handle(Context &context) -> void override;
- auto run(Context &context) -> sys::ReturnCodes;
- auto getUpdates(Context &context) -> sys::ReturnCodes;
+ auto handle(parserFSM::Context &context) -> void override;
+ auto run(parserFSM::Context &context) -> sys::ReturnCodes;
+ auto getUpdates(parserFSM::Context &context) -> sys::ReturnCodes;
};
M module-services/service-desktop/endpoints/messages/MessagesEndpoint.hpp => module-services/service-desktop/endpoints/messages/MessagesEndpoint.hpp +4 -6
@@ 21,18 21,16 @@ namespace sys
class Service;
} // namespace sys
-using namespace parserFSM;
-
-class MessagesEndpoint : public Endpoint
+class MessagesEndpoint : public parserFSM::Endpoint
{
private:
- std::shared_ptr<MessageHelper> helper;
+ std::shared_ptr<parserFSM::MessageHelper> helper;
public:
MessagesEndpoint(sys::Service *_ownerServicePtr) : Endpoint(_ownerServicePtr)
{
debugName = "MessagesEndpoint";
- helper = std::make_shared<MessageHelper>(ownerServicePtr);
+ helper = std::make_shared<parserFSM::MessageHelper>(ownerServicePtr);
}
- auto handle(Context &context) -> void override;
+ auto handle(parserFSM::Context &context) -> void override;
};
M module-services/service-desktop/endpoints/restore/RestoreEndpoint.cpp => module-services/service-desktop/endpoints/restore/RestoreEndpoint.cpp +2 -0
@@ 14,6 14,8 @@
#include <memory>
+using namespace parserFSM;
+
auto RestoreEndpoint::handle(Context &context) -> void
{
if (context.getMethod() == parserFSM::http::Method::post) {
M module-services/service-desktop/endpoints/restore/RestoreEndpoint.hpp => module-services/service-desktop/endpoints/restore/RestoreEndpoint.hpp +2 -4
@@ 16,14 16,12 @@ namespace sys
class Service;
} // namespace sys
-using namespace parserFSM;
-
-class RestoreEndpoint : public Endpoint
+class RestoreEndpoint : public parserFSM::Endpoint
{
public:
RestoreEndpoint(sys::Service *ownerServicePtr) : Endpoint(ownerServicePtr)
{
debugName = "RestoreEndpoint";
}
- auto handle(Context &context) -> void override;
+ auto handle(parserFSM::Context &context) -> void override;
};
M module-services/service-desktop/endpoints/update/UpdateEndpoint.cpp => module-services/service-desktop/endpoints/update/UpdateEndpoint.cpp +2 -0
@@ 16,6 16,8 @@
#include <filesystem>
#include <memory>
+using namespace parserFSM;
+
auto UpdateEndpoint::handle(Context &context) -> void
{
switch (context.getMethod()) {
M module-services/service-desktop/endpoints/update/UpdateEndpoint.hpp => module-services/service-desktop/endpoints/update/UpdateEndpoint.hpp +4 -6
@@ 20,9 20,7 @@ namespace sys
class Service;
} // namespace sys
-using namespace parserFSM;
-
-class UpdateEndpoint : public Endpoint
+class UpdateEndpoint : public parserFSM::Endpoint
{
public:
@@ 30,7 28,7 @@ class UpdateEndpoint : public Endpoint
{
debugName = "UpdateEndpoint";
}
- auto handle(Context &context) -> void override;
- auto run(Context &context) -> sys::ReturnCodes;
- auto getUpdates(Context &context) -> sys::ReturnCodes;
+ auto handle(parserFSM::Context &context) -> void override;
+ auto run(parserFSM::Context &context) -> sys::ReturnCodes;
+ auto getUpdates(parserFSM::Context &context) -> sys::ReturnCodes;
};
M module-services/service-desktop/parser/MessageHandler.cpp => module-services/service-desktop/parser/MessageHandler.cpp +3 -3
@@ 23,7 23,7 @@ using namespace parserFSM;
xQueueHandle MessageHandler::sendQueue;
-MessageHandler::MessageHandler(std::string &message, sys::Service *OwnerService) : OwnerServicePtr(OwnerService)
+MessageHandler::MessageHandler(const std::string &message, sys::Service *OwnerService) : OwnerServicePtr(OwnerService)
{
try {
messageJson = json11::Json::parse(message, JsonErrorMsg);
@@ 53,10 53,10 @@ void MessageHandler::processMessage()
}
}
-void MessageHandler::putToSendQueue(const std::string msg)
+void MessageHandler::putToSendQueue(const std::string &msg)
{
if (uxQueueSpacesAvailable(sendQueue) != 0) {
- auto *responseString = new std::string(msg);
+ auto responseString = new std::string(msg);
xQueueSend(sendQueue, &responseString, portMAX_DELAY);
}
}
M module-services/service-desktop/parser/MessageHandler.hpp => module-services/service-desktop/parser/MessageHandler.hpp +14 -11
@@ 24,29 24,32 @@ namespace parserFSM
{
class MessageHandler
{
+ static xQueueHandle sendQueue;
+
+ json11::Json messageJson;
+ std::string JsonErrorMsg;
+ sys::Service *OwnerServicePtr = nullptr;
public:
- MessageHandler(std::string &message, sys::Service *OwnerService);
- static xQueueHandle sendQueue;
+ MessageHandler(const std::string &message, sys::Service *OwnerService);
- bool isJSONNull()
+ [[nodiscard]] auto isJSONNull() const -> bool
{
return messageJson.is_null();
};
- bool isValid()
+ [[nodiscard]] auto isValid() const noexcept -> bool
{
return JsonErrorMsg.empty();
}
- std::string &getErrorString()
+ [[nodiscard]] auto getErrorString() const -> const std::string &
{
return JsonErrorMsg;
};
void processMessage();
- static void putToSendQueue(const std::string msg);
-
- private:
- json11::Json messageJson;
- std::string JsonErrorMsg;
- sys::Service *OwnerServicePtr = nullptr;
+ static void putToSendQueue(const std::string &msg);
+ static void setSendQueueHandle(xQueueHandle handle)
+ {
+ sendQueue = handle;
+ }
};
} // namespace parserFSM
M module-services/service-desktop/parser/ParserFSM.cpp => module-services/service-desktop/parser/ParserFSM.cpp +23 -23
@@ 28,10 28,10 @@ using namespace parserFSM;
StateMachine::StateMachine(sys::Service *OwnerService) : OwnerServicePtr(OwnerService)
{}
-void StateMachine::processMessage(std::string &msg)
+void StateMachine::processMessage(std::string &&msg)
{
- receivedMsgPtr = &msg;
- LOG_DEBUG("Msg: %s", receivedMsgPtr->c_str());
+ receivedMsg = std::move(msg);
+ LOG_DEBUG("Msg: %s", receivedMsg.c_str());
switch (state) {
case State::ReceivedPayload:
@@ 58,20 58,20 @@ void StateMachine::parseHeader()
header.clear();
payloadLength = 0;
- auto messageStart = receivedMsgPtr->find(message::endpointChar);
+ auto messageStart = receivedMsg.find(message::endpointChar);
if (messageStart == std::string::npos) {
- LOG_ERROR("This is not a valid endpoint message! Type=%c", receivedMsgPtr->at(0));
+ LOG_ERROR("This is not a valid endpoint message! Type=%c", receivedMsg.at(0));
return;
}
- if (receivedMsgPtr->size() < message::size_header) // header divided in few parts
+ if (receivedMsg.size() < message::size_header) // header divided in few parts
{
state = State::ReceivedPartialHeader;
- header.append(*receivedMsgPtr); // append to whole header string
+ header.append(receivedMsg); // append to whole header string
return;
}
- header = message::getHeader(*receivedMsgPtr);
+ header = message::getHeader(receivedMsg);
payloadLength = message::calcPayloadLength(header);
if (payloadLength == 0) // failed to obtain payload length from msg
{
@@ 82,7 82,7 @@ void StateMachine::parseHeader()
LOG_DEBUG("Payload length: %lu", payloadLength);
- message::removeHeader(*receivedMsgPtr);
+ message::removeHeader(receivedMsg);
parseNewMessage();
}
@@ 91,39 91,39 @@ void StateMachine::parsePartialHeader()
auto previousHeaderLength = header.size();
auto missingHeaderLength = message::size_header - previousHeaderLength;
- if (receivedMsgPtr->size() >= missingHeaderLength) // rest of the message is here
+ if (receivedMsg.size() >= missingHeaderLength) // rest of the message is here
{
- header.append(receivedMsgPtr->substr(0, missingHeaderLength));
+ header.append(receivedMsg.substr(0, missingHeaderLength));
LOG_DEBUG("Header: %s\n", header.c_str());
payloadLength = message::calcPayloadLength(header);
LOG_DEBUG("Payload length: %lu\n", payloadLength);
- message::eraseFront(*receivedMsgPtr, missingHeaderLength);
+ message::eraseFront(receivedMsg, missingHeaderLength);
parseNewMessage();
}
else // the message is even longer :(
{
- header.append(*receivedMsgPtr);
+ header.append(receivedMsg);
}
}
void StateMachine::parseNewMessage()
{
- if (receivedMsgPtr->size() >= payloadLength) {
+ if (receivedMsg.size() >= payloadLength) {
- payload = message::extractPayload(*receivedMsgPtr, payloadLength);
+ payload = message::extractPayload(receivedMsg, payloadLength);
parsePayload();
- if (receivedMsgPtr->size() > payloadLength) { // contains part of new header
- message::eraseFront(*receivedMsgPtr, payloadLength);
+ if (receivedMsg.size() > payloadLength) { // contains part of new header
+ message::eraseFront(receivedMsg, payloadLength);
parseHeader();
}
}
else // message divided in 2 or more packets
{
- payload = receivedMsgPtr->substr(0, std::string::npos); // take rest of the message
+ payload = receivedMsg.substr(0, std::string::npos); // take rest of the message
state = State::ReceivedPartialPayload;
}
}
@@ 133,20 133,20 @@ void StateMachine::parsePartialMessage()
auto previousPayloadLength = payload.size();
auto missingPayloadLength = payloadLength - previousPayloadLength;
- if (receivedMsgPtr->size() >= missingPayloadLength) // rest of the message is here
+ if (receivedMsg.size() >= missingPayloadLength) // rest of the message is here
{
- payload.append(message::extractPayload(*receivedMsgPtr, missingPayloadLength));
+ payload.append(message::extractPayload(receivedMsg, missingPayloadLength));
parsePayload();
- if (receivedMsgPtr->size() > missingPayloadLength) {
- message::eraseFront(*receivedMsgPtr, missingPayloadLength);
+ if (receivedMsg.size() > missingPayloadLength) {
+ message::eraseFront(receivedMsg, missingPayloadLength);
parseHeader();
}
}
else // the message is even longer
{
- payload.append(*receivedMsgPtr);
+ payload.append(receivedMsg);
}
}
M module-services/service-desktop/parser/ParserFSM.hpp => module-services/service-desktop/parser/ParserFSM.hpp +6 -6
@@ 23,21 23,21 @@ namespace parserFSM
class StateMachine
{
public:
- StateMachine(sys::Service *OwnerService);
- void processMessage(std::string &msg);
- State getCurrentState()
+ explicit StateMachine(sys::Service *OwnerService);
+ void processMessage(std::string &&msg);
+ [[nodiscard]] auto getCurrentState() const noexcept -> State
{
return state;
};
- void setState(const parserFSM::State newState)
+ void setState(const parserFSM::State newState) noexcept
{
state = newState;
}
private:
- std::string *receivedMsgPtr = nullptr;
- parserFSM::State state = State::NoMsg;
+ std::string receivedMsg;
+ parserFSM::State state = State::NoMsg;
std::string payload;
std::string header;
unsigned long payloadLength = 0;
M module-services/service-desktop/service-desktop/DesktopMessages.hpp => module-services/service-desktop/service-desktop/DesktopMessages.hpp +1 -1
@@ 71,7 71,7 @@ namespace sdesktop
class Event
{
protected:
- Context context;
+ parserFSM::Context context;
public:
void send();
M module-services/service-desktop/tests/unittest.cpp => module-services/service-desktop/tests/unittest.cpp +25 -21
@@ 48,76 48,80 @@ using namespace parserFSM;
TEST_CASE("Parser Test")
{
StateMachine parser(nullptr);
- std::string testMessage("#00000");
SECTION("Parse message with divided header and payload")
{
- parser.processMessage(testMessage);
+ std::string testMessage("#00000");
+ parser.processMessage(std::move(testMessage));
REQUIRE(parser.getCurrentState() == State::ReceivedPartialHeader);
testMessage = R"(0050{"endpo)";
- parser.processMessage(testMessage);
+ parser.processMessage(std::move(testMessage));
REQUIRE(parser.getCurrentState() == State::ReceivedPartialPayload);
testMessage = R"(int":1, "method":1, "body":{"test":"test"}})";
- parser.processMessage(testMessage);
+ parser.processMessage(std::move(testMessage));
REQUIRE(parser.getCurrentState() == State::ReceivedPayload);
}
SECTION("Parse whole message")
{
- testMessage = R"(#000000050{"endpoint":1, "method":1, "body":{"test":"test"}})";
- parser.processMessage(testMessage);
+ std::string testMessage = R"(#000000050{"endpoint":1, "method":1, "body":{"test":"test"}})";
+ parser.processMessage(std::move(testMessage));
REQUIRE(parser.getCurrentState() == State::ReceivedPayload);
}
SECTION("Parse message with start char detached from mesage")
{
- testMessage = R"(#)";
- parser.processMessage(testMessage);
+ std::string testMessage = R"(#)";
+ parser.processMessage(std::move(testMessage));
REQUIRE(parser.getCurrentState() == State::ReceivedPartialHeader);
testMessage = R"(000000050{"en)";
- parser.processMessage(testMessage);
+ testMessage = R"(000000050{"en)";
+ parser.processMessage(std::move(testMessage));
REQUIRE(parser.getCurrentState() == State::ReceivedPartialPayload);
testMessage = R"(dpoint":1, "method":1, "body":{"test":"test"}})";
- parser.processMessage(testMessage);
+ parser.processMessage(std::move(testMessage));
REQUIRE(parser.getCurrentState() == State::ReceivedPayload);
}
SECTION("Parse message with beginning of another one")
{
- testMessage = R"(#000000050{"endpoint":1, "method":1, "body":{"test":"test"}}#000000050{"end)";
- parser.processMessage(testMessage);
+ std::string testMessage = R"(#000000050{"endpoint":1, "method":1, "body":{"test":"test"}}#000000050{"end)";
+ parser.processMessage(std::move(testMessage));
REQUIRE(parser.getCurrentState() == State::ReceivedPartialPayload);
testMessage = R"(point":1, "method":1, "body":{"test":"test"}})";
- parser.processMessage(testMessage);
+ parser.processMessage(std::move(testMessage));
REQUIRE(parser.getCurrentState() == State::ReceivedPayload);
}
SECTION("Parse junk message")
{
- testMessage = R"({"address": "6 Czeczota St.\n02600 Warsaw"})";
- parser.processMessage(testMessage);
+ std::string testMessage = R"({"address": "6 Czeczota St.\n02600 Warsaw"})";
+ parser.processMessage(std::move(testMessage));
REQUIRE(parser.getCurrentState() == State::NoMsg);
}
SECTION("Parse message with incorrect header length")
{
- testMessage = R"(#000000072{"endpoint":7, "method":2, "uuid":3, "body":{"threadID":1,"unread":false}})";
- parser.processMessage(testMessage);
+ std::string testMessage =
+ R"(#000000072{"endpoint":7, "method":2, "uuid":3, "body":{"threadID":1,"unread":false}})";
+ parser.processMessage(std::move(testMessage));
REQUIRE(parser.getCurrentState() == State::NoMsg);
}
SECTION("Parse message with damaged json ")
{
- testMessage = R"(#000000074{"endpoint":7, "method":2, "uuid":3, "bo}}dy":{"threadID":1,"unread":false)";
- parser.processMessage(testMessage);
+ std::string testMessage =
+ R"(#000000074{"endpoint":7, "method":2, "uuid":3, "bo}}dy":{"threadID":1,"unread":false)";
+ parser.processMessage(std::move(testMessage));
REQUIRE(parser.getCurrentState() == State::NoMsg);
}
SECTION("Parse message with damaged json and incorrect header length")
{
- testMessage = R"(#000000072{"endpoint":7, "method":2, "uuid":3, "bo}}dy":{"threadID":1,"unread":false)";
- parser.processMessage(testMessage);
+ std::string testMessage =
+ R"(#000000072{"endpoint":7, "method":2, "uuid":3, "bo}}dy":{"threadID":1,"unread":false)";
+ parser.processMessage(std::move(testMessage));
REQUIRE(parser.getCurrentState() == State::NoMsg);
}
}
M module-services/service-evtmgr/WorkerEvent.cpp => module-services/service-evtmgr/WorkerEvent.cpp +11 -14
@@ 91,28 91,25 @@ bool WorkerEvent::handleMessage(uint32_t queueID)
if (!queue->Dequeue(¬ification, 0)) {
return false;
}
- if (notification == static_cast<uint8_t>(bsp::batteryIRQSource::INTB)) {
+ if (notification == static_cast<uint8_t>(bsp::battery_charger::batteryIRQSource::INTB)) {
LOG_DEBUG("Battery INTB");
- const auto status = bsp::battery_getStatusRegister();
- if (status & static_cast<std::uint16_t>(bsp::batteryINTBSource::minVAlert)) {
+ const auto status = bsp::battery_charger::getStatusRegister();
+ if (status & static_cast<std::uint16_t>(bsp::battery_charger::batteryINTBSource::minVAlert)) {
auto messageBrownout = std::make_shared<sevm::BatteryBrownoutMessage>();
sys::Bus::SendUnicast(messageBrownout, service::name::system_manager, this->service);
}
- if (status & static_cast<std::uint16_t>(bsp::batteryINTBSource::SOCOnePercentChange)) {
- std::uint8_t battLevel = 0;
- bsp::battery_getBatteryLevel(battLevel);
+ if (status & static_cast<std::uint16_t>(bsp::battery_charger::batteryINTBSource::SOCOnePercentChange)) {
+ bsp::battery_charger::StateOfCharge battLevel = bsp::battery_charger::getBatteryLevel();
auto message = std::make_shared<sevm::BatteryLevelMessage>(battLevel, false);
sys::Bus::SendUnicast(message, service::name::evt_manager, this->service);
battery_level_check::checkBatteryLevelCritical();
}
- bsp::battery_ClearAllIRQs();
+ bsp::battery_charger::clearAllIRQs();
}
- if (notification == static_cast<uint8_t>(bsp::batteryIRQSource::INOKB)) {
- bool status;
- bsp::battery_getChargeStatus(status);
- bsp::battery_ClearAllIRQs();
+ if (notification == static_cast<uint8_t>(bsp::battery_charger::batteryIRQSource::INOKB)) {
+ bsp::battery_charger::clearAllIRQs();
auto message = std::make_shared<sevm::BatteryPlugMessage>();
- message->plugged = status;
+ message->plugged = bsp::battery_charger::getChargeStatus();
sys::Bus::SendUnicast(message, service::name::evt_manager, this->service);
}
}
@@ 193,7 190,7 @@ bool WorkerEvent::init(std::list<sys::WorkerQueueInfo> queuesList)
bsp::vibrator::init();
bsp::keyboard_Init(queues[static_cast<int32_t>(WorkerEventQueues::queueKeyboardIRQ)]->GetQueueHandle());
bsp::headset::Init(queues[static_cast<int32_t>(WorkerEventQueues::queueHeadsetIRQ)]->GetQueueHandle());
- bsp::battery_Init(queues[static_cast<int32_t>(WorkerEventQueues::queueBattery)]->GetQueueHandle());
+ bsp::battery_charger::init(queues[static_cast<int32_t>(WorkerEventQueues::queueBattery)]->GetQueueHandle());
bsp::rtc_Init(queues[static_cast<int32_t>(WorkerEventQueues::queueRTC)]->GetQueueHandle());
bsp::cellular::init(queues[static_cast<int32_t>(WorkerEventQueues::queueCellular)]->GetQueueHandle());
bsp::magnetometer::init(queues[static_cast<int32_t>(WorkerEventQueues::queueMagnetometerIRQ)]->GetQueueHandle());
@@ 216,7 213,7 @@ bool WorkerEvent::deinit(void)
Worker::deinit();
bsp::keyboard_Deinit();
bsp::headset::Deinit();
- bsp::battery_Deinit();
+ bsp::battery_charger::deinit();
bsp::torch::deinit();
bsp::keypad_backlight::deinit();
bsp::eink_frontlight::deinit();
M module-services/service-evtmgr/screen-light-control/ScreenLightControl.hpp => module-services/service-evtmgr/screen-light-control/ScreenLightControl.hpp +2 -3
@@ 5,8 5,7 @@
#include <service-db/service-db/Settings.hpp>
#include "ControlFunctions.hpp"
-
-#include <sstream>
+#include <Utils.hpp>
namespace sys
{
@@ 85,7 84,7 @@ namespace screen_light_control
template <class T> void setScreenLightSettings(const std::string &varName, T value)
{
- settings->setValue(varName, std::to_string(value));
+ settings->setValue(varName, utils::to_string(value));
}
void initFromSettings();
M module-services/service-fota/FotaUrcHandler.cpp => module-services/service-fota/FotaUrcHandler.cpp +2 -0
@@ 3,6 3,8 @@
#include "FotaUrcHandler.hpp"
+using namespace at::urc;
+
void FotaUrcHandler::Handle(Qind &urc)
{
if (urc.isFotaValid()) {
M module-services/service-fota/FotaUrcHandler.hpp => module-services/service-fota/FotaUrcHandler.hpp +11 -13
@@ 8,27 8,25 @@
#include <module-cellular/at/UrcHandler.hpp>
#include <module-cellular/at/UrcQind.hpp>
-using namespace at::urc;
-
/**
* ServiceFota helper for handling Urc messages
*/
-class FotaUrcHandler : public UrcHandler
+class FotaUrcHandler : public at::urc::UrcHandler
{
public:
FotaUrcHandler(FotaService::Service &fotaService) : fotaService(fotaService)
{}
- void Handle(Qind &urc) final;
- virtual void Handle(Clip &urc){};
- virtual void Handle(Creg &urc){};
- virtual void Handle(Cmti &urc){};
- virtual void Handle(Cusd &urc){};
- virtual void Handle(Ctze &urc){};
- virtual void Handle(Cpin &urc){};
- virtual void Handle(Qiurc &urc){};
- virtual void Handle(PoweredDown &urc){};
- virtual void Handle(UrcResponse &urc){};
+ void Handle(at::urc::Qind &urc) final;
+ virtual void Handle(at::urc::Clip &urc){};
+ virtual void Handle(at::urc::Creg &urc){};
+ virtual void Handle(at::urc::Cmti &urc){};
+ virtual void Handle(at::urc::Cusd &urc){};
+ virtual void Handle(at::urc::Ctze &urc){};
+ virtual void Handle(at::urc::Cpin &urc){};
+ virtual void Handle(at::urc::Qiurc &urc){};
+ virtual void Handle(at::urc::PoweredDown &urc){};
+ virtual void Handle(at::urc::UrcResponse &urc){};
private:
FotaService::Service &fotaService;
M module-services/service-time/service-time/CalendarTimeEvents.hpp => module-services/service-time/service-time/CalendarTimeEvents.hpp +1 -1
@@ 27,7 27,7 @@ namespace stm
{
private:
EventsRecord eventRecord;
- TimePoint startTP = TIME_POINT_INVALID;
+ calendar::TimePoint startTP = TIME_POINT_INVALID;
protected:
const std::string timerName() override
M module-services/service-time/timeEvents/CalendarTimeEvents.cpp => module-services/service-time/timeEvents/CalendarTimeEvents.cpp +4 -3
@@ 29,6 29,7 @@ namespace sys
namespace stm
{
+ using namespace std::chrono_literals;
constexpr static auto eventTimerMinSkipInterval = 100ms;
CalendarTimeEvents::CalendarTimeEvents(sys::Service *service) : TimeEvents(service)
@@ 36,8 37,8 @@ namespace stm
bool CalendarTimeEvents::sendNextEventQuery()
{
- TimePoint filterFrom = TimePointNow();
- TimePoint filterTill = filterFrom;
+ calendar::TimePoint filterFrom = TimePointNow();
+ calendar::TimePoint filterTill = filterFrom;
if (startTP != TIME_POINT_INVALID) {
filterFrom = std::min(startTP, filterFrom);
filterTill = filterFrom;
@@ 64,7 65,7 @@ namespace stm
}
eventRecord = records.at(0);
- startTP = eventRecord.date_from - minutes{eventRecord.reminder};
+ startTP = eventRecord.date_from - std::chrono::minutes{eventRecord.reminder};
auto duration = eventRecord.date_from - std::chrono::minutes{eventRecord.reminder} - TimePointNow();
if (duration.count() <= 0) {
duration = std::chrono::milliseconds(eventTimerMinSkipInterval);
M module-sys/SystemManager/SystemManager.cpp => module-sys/SystemManager/SystemManager.cpp +7 -3
@@ 116,7 116,7 @@ namespace sys
// pingPongTimerID = CreateTimer(Ticks::MsToTicks(pingInterval), true);
// ReloadTimer(pingPongTimerID);
- cpuStatisticsTimer = std::make_unique<sys::Timer>("cpuStatistics", this, timerInitInterval.count());
+ cpuStatisticsTimer = std::make_unique<sys::Timer>("cpuStatistics", this, constants::timerInitInterval.count());
cpuStatisticsTimer->connect([&](sys::Timer &) { CpuStatisticsTimerHandler(); });
cpuStatisticsTimer->start();
}
@@ 261,6 261,10 @@ namespace sys
connect(sevm::BatteryBrownoutMessage(), [&](Message *) {
LOG_INFO("Battery Brownout voltage level reached!");
+
+ auto msg = std::make_shared<SystemBrownoutMesssage>();
+ Bus::SendUnicast(msg, app::manager::ApplicationManager::ServiceName, this);
+
return MessageNone{};
});
@@ 284,7 288,7 @@ namespace sys
CellularServiceAPI::ChangeModulePowerState(this, cellular::State::PowerState::On);
auto msg = std::make_shared<CriticalBatteryLevelNotification>(false);
- Bus::SendUnicast(msg, app::manager::ApplicationManager::ServiceName, this);
+ Bus::SendUnicast(std::move(msg), app::manager::ApplicationManager::ServiceName, this);
return MessageNone{};
});
@@ 354,7 358,7 @@ namespace sys
{
if (!cpuStatisticsTimerInit) {
cpuStatisticsTimerInit = true;
- cpuStatisticsTimer->setInterval(timerPeriodInterval.count());
+ cpuStatisticsTimer->setInterval(constants::timerPeriodInterval.count());
}
cpuStatistics->Update();
M module-sys/SystemManager/SystemManager.hpp => module-sys/SystemManager/SystemManager.hpp +6 -3
@@ 26,9 26,12 @@
namespace sys
{
- using namespace std::chrono_literals;
- inline constexpr std::chrono::milliseconds timerInitInterval{30s};
- inline constexpr std::chrono::milliseconds timerPeriodInterval{100ms};
+ namespace constants
+ {
+ using namespace std::chrono_literals;
+ inline constexpr std::chrono::milliseconds timerInitInterval{30s};
+ inline constexpr std::chrono::milliseconds timerPeriodInterval{100ms};
+ } // namespace constants
enum class Code
{
M module-sys/SystemManager/messages/SystemManagerMessage.hpp => module-sys/SystemManager/messages/SystemManagerMessage.hpp +10 -0
@@ 37,4 37,14 @@ namespace sys
bool isActive;
};
+ class SystemBrownoutMesssage : public sys::Message, public app::manager::actions::ConvertibleToAction
+ {
+ public:
+ [[nodiscard]] auto toAction() const -> std::unique_ptr<app::manager::ActionRequest>
+ {
+ return std::make_unique<app::manager::ActionRequest>(
+ service::name::system_manager, app::manager::actions::SystemBrownout, nullptr);
+ }
+ };
+
} // namespace sys
M module-utils/CMakeLists.txt => module-utils/CMakeLists.txt +3 -0
@@ 38,6 38,9 @@ set (SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/Utils.cpp
${CMAKE_CURRENT_SOURCE_DIR}/log/Logger.cpp
${CMAKE_CURRENT_SOURCE_DIR}/log/log.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/log/LoggerBuffer.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/circular_buffer/StringCircularBuffer.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/generators/RandomStringGenerator.cpp
)
add_library(${PROJECT_NAME} STATIC ${SOURCES} ${BOARD_SOURCES})
M module-utils/Utils.hpp => module-utils/Utils.hpp +7 -0
@@ 122,7 122,14 @@ namespace utils
baseAsStr = "-0";
}
}
+
auto fractionalPart = static_cast<unsigned long int>(roundl(frac));
+ auto fractionalPartLength = std::to_string(fractionalPart).length();
+ if (fractionalPartLength > precision) {
+ base += 1;
+ baseAsStr = std::to_string(base);
+ fractionalPart = 0;
+ }
if (fractionalPart == 0) {
if (baseAsStr == "-0") {
return "0";
A module-utils/circular_buffer/StringCircularBuffer.cpp => module-utils/circular_buffer/StringCircularBuffer.cpp +55 -0
@@ 0,0 1,55 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "StringCircularBuffer.hpp"
+
+std::pair<bool, std::string> StringCircularBuffer::get()
+{
+ if (isEmpty()) {
+ return {false, ""};
+ }
+
+ const std::string val = buffer[tail];
+ full = false;
+ tail = (tail + 1) % capacity;
+ --size;
+
+ return {true, val};
+}
+
+void StringCircularBuffer::put(const std::string &item)
+{
+ updateMembersBeforePut();
+ buffer[head] = item;
+ updateMembersAfterPut();
+}
+
+void StringCircularBuffer::put(std::string &&item)
+{
+ updateMembersBeforePut();
+ buffer[head] = std::move(item);
+ updateMembersAfterPut();
+}
+
+void StringCircularBuffer::reset()
+{
+ head = tail;
+ full = false;
+ size = 0;
+}
+
+void StringCircularBuffer::updateMembersAfterPut()
+{
+ head = (head + 1) % capacity;
+ full = head == tail;
+}
+
+void StringCircularBuffer::updateMembersBeforePut()
+{
+ if (full) {
+ tail = (tail + 1) % capacity;
+ }
+ else {
+ ++size;
+ }
+}
A module-utils/circular_buffer/StringCircularBuffer.hpp => module-utils/circular_buffer/StringCircularBuffer.hpp +46 -0
@@ 0,0 1,46 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <memory>
+#include <string>
+
+class StringCircularBuffer
+{
+ public:
+ explicit StringCircularBuffer(size_t size) : buffer(std::make_unique<std::string[]>(size)), capacity(size)
+ {}
+ virtual ~StringCircularBuffer() = default;
+ [[nodiscard]] size_t getCapacity() const noexcept
+ {
+ return capacity;
+ }
+ [[nodiscard]] bool isEmpty() const noexcept
+ {
+ return size == 0;
+ }
+ [[nodiscard]] virtual std::pair<bool, std::string> get();
+ [[nodiscard]] size_t getSize() const noexcept
+ {
+ return size;
+ }
+ [[nodiscard]] bool isFull() const noexcept
+ {
+ return full;
+ }
+ virtual void put(const std::string &item);
+ virtual void put(std::string &&item);
+ void reset();
+
+ private:
+ void updateMembersAfterPut();
+ void updateMembersBeforePut();
+
+ std::unique_ptr<std::string[]> buffer;
+ bool full{false};
+ size_t head{0};
+ size_t capacity;
+ size_t size{0};
+ size_t tail{0};
+};
A module-utils/generators/RandomStringGenerator.cpp => module-utils/generators/RandomStringGenerator.cpp +20 -0
@@ 0,0 1,20 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include <algorithm>
+#include "RandomStringGenerator.hpp"
+
+std::string RandomStringGenerator::getRandomString()
+{
+ const size_t length = lengthDist(rng);
+ std::string str(length, 0);
+ std::generate_n(str.begin(), length, [this]() { return charSet[charDist(rng)]; });
+ return str;
+}
+
+std::vector<std::string> RandomStringGenerator::createRandomStringVector(size_t size)
+{
+ std::vector<std::string> vec(size);
+ std::generate_n(vec.begin(), size, [this]() { return getRandomString(); });
+ return vec;
+}
A module-utils/generators/RandomStringGenerator.hpp => module-utils/generators/RandomStringGenerator.hpp +33 -0
@@ 0,0 1,33 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <random>
+#include <string>
+#include <vector>
+
+class RandomStringGenerator
+{
+ public:
+ RandomStringGenerator(size_t minLength = minRandomStringLength, size_t maxLength = maxRandomStringLength)
+ : minLength(minLength), maxLength(maxLength), lengthDist(minLength, maxLength)
+ {}
+
+ std::string getRandomString();
+ std::vector<std::string> createRandomStringVector(size_t size);
+
+ private:
+ std::uniform_int_distribution<> charDist{0, sizeof(charSet) - 1};
+ std::default_random_engine rng{std::random_device{}()};
+ const size_t minLength;
+ const size_t maxLength;
+ std::uniform_int_distribution<> lengthDist;
+
+ static constexpr auto minRandomStringLength = 1;
+ static constexpr auto maxRandomStringLength = 25;
+ static constexpr char charSet[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
+ 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
+ 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
+ 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
+};
M module-utils/ical/ParserICS.cpp => module-utils/ical/ParserICS.cpp +8 -5
@@ 446,7 446,7 @@ auto Event::timeStringFrom(const std::string &icalTime) const -> std::string
getSecondsFromIcalTime(icalTime);
}
-auto Event::TimePointFromIcalDate(const std::string &icalDateTime) const -> TimePoint
+auto Event::TimePointFromIcalDate(const std::string &icalDateTime) const -> calendar::TimePoint
{
std::string icalDate(getDateFromIcalFormat(icalDateTime));
std::string icalTime(getTimeFromIcalFormat(icalDateTime));
@@ 459,7 459,7 @@ auto Event::TimePointFromIcalDate(const std::string &icalDateTime) const -> Time
return TimePointFromString(dateTime.c_str());
}
-auto Event::TimePointToIcalDate(const TimePoint &tp) const -> std::string
+auto Event::TimePointToIcalDate(const calendar::TimePoint &tp) const -> std::string
{
constexpr uint32_t bufferLimit = 16;
auto time = TimePointToTimeT(tp);
@@ 541,7 541,10 @@ auto Event::validateUID(const std::string &UID) -> bool
return validateDT(DTimestamp);
}
-Event::Event(const std::string &summary, const TimePoint from, TimePoint till, const std::string &uid)
+Event::Event(const std::string &summary,
+ const calendar::TimePoint from,
+ calendar::TimePoint till,
+ const std::string &uid)
{
if (summary.empty()) {
isValid = false;
@@ 595,12 598,12 @@ auto Event::getSummary() const -> std::string
return summary;
}
-auto Event::getDTStartTimePoint() const -> TimePoint
+auto Event::getDTStartTimePoint() const -> calendar::TimePoint
{
return dtstart;
}
-auto Event::getDTEndTimePoint() const -> TimePoint
+auto Event::getDTEndTimePoint() const -> calendar::TimePoint
{
return dtend;
}
M module-utils/ical/ParserICS.hpp => module-utils/ical/ParserICS.hpp +7 -7
@@ 91,8 91,8 @@ class Event
{
std::string uid;
std::string summary;
- TimePoint dtstart;
- TimePoint dtend;
+ calendar::TimePoint dtstart;
+ calendar::TimePoint dtend;
auto isDate(const std::string &dt) -> bool;
auto isTime(const std::string &dt) -> bool;
@@ 112,13 112,13 @@ class Event
[[nodiscard]] auto dateStringFrom(const std::string &icalDate) const -> std::string;
[[nodiscard]] auto timeStringFrom(const std::string &icalTime) const -> std::string;
- [[nodiscard]] auto TimePointFromIcalDate(const std::string &icalDateTime) const -> TimePoint;
- [[nodiscard]] auto TimePointToIcalDate(const TimePoint &tp) const -> std::string;
+ [[nodiscard]] auto TimePointFromIcalDate(const std::string &icalDateTime) const -> calendar::TimePoint;
+ [[nodiscard]] auto TimePointToIcalDate(const calendar::TimePoint &tp) const -> std::string;
public:
bool isValid = true;
Event() = default;
- Event(const std::string &summary, TimePoint from, TimePoint till, const std::string &uid);
+ Event(const std::string &summary, calendar::TimePoint from, calendar::TimePoint till, const std::string &uid);
void setUID(const std::string &property);
void setSummary(const std::string &property);
@@ 127,8 127,8 @@ class Event
[[nodiscard]] auto getUID() const -> std::string;
[[nodiscard]] auto getSummary() const -> std::string;
- [[nodiscard]] auto getDTStartTimePoint() const -> TimePoint;
- [[nodiscard]] auto getDTEndTimePoint() const -> TimePoint;
+ [[nodiscard]] auto getDTStartTimePoint() const -> calendar::TimePoint;
+ [[nodiscard]] auto getDTEndTimePoint() const -> calendar::TimePoint;
[[nodiscard]] auto getDTStartString() const -> std::string;
[[nodiscard]] auto getDTEndString() const -> std::string;
A module-utils/log/LoggerBuffer.cpp => module-utils/log/LoggerBuffer.cpp +37 -0
@@ 0,0 1,37 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "LoggerBuffer.hpp"
+
+std::pair<bool, std::string> LoggerBuffer::get()
+{
+ auto [result, logMsg] = StringCircularBuffer::get();
+ if (!result) {
+ return {result, logMsg};
+ }
+ if (numOfLostBytes > 0) {
+ logMsg += "\r\n" + std::to_string(numOfLostBytes) + " " + lostBytesMessage;
+ numOfLostBytes = 0;
+ }
+ return {true, logMsg};
+}
+
+void LoggerBuffer::put(const std::string &logMsg)
+{
+ updateNumOfLostBytes();
+ StringCircularBuffer::put(logMsg);
+}
+
+void LoggerBuffer::put(std::string &&logMsg)
+{
+ updateNumOfLostBytes();
+ StringCircularBuffer::put(std::move(logMsg));
+}
+
+void LoggerBuffer::updateNumOfLostBytes()
+{
+ if (StringCircularBuffer::isFull()) {
+ auto [_, lostMsg] = StringCircularBuffer::get();
+ numOfLostBytes += lostMsg.length();
+ }
+}
A module-utils/log/LoggerBuffer.hpp => module-utils/log/LoggerBuffer.hpp +23 -0
@@ 0,0 1,23 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "circular_buffer/StringCircularBuffer.hpp"
+
+class LoggerBuffer : public StringCircularBuffer
+{
+ public:
+ using StringCircularBuffer::StringCircularBuffer;
+
+ [[nodiscard]] std::pair<bool, std::string> get() override;
+ void put(const std::string &logMsg) override;
+ void put(std::string &&logMsg) override;
+
+ static constexpr auto lostBytesMessage = "bytes was lost.";
+
+ private:
+ void updateNumOfLostBytes();
+
+ size_t numOfLostBytes{0};
+};
M module-utils/test/CMakeLists.txt => module-utils/test/CMakeLists.txt +10 -0
@@ 75,6 75,16 @@ add_catch2_executable(
module-utils
)
+# Logger buffer tests
+add_catch2_executable(
+ NAME
+ utils-loggerbuffer
+ SRCS
+ test_LoggerBuffer.cpp
+ LIBS
+ module-utils
+)
+
# ParserICS tests
#add_catch2_executable(
# NAME
A module-utils/test/test_LoggerBuffer.cpp => module-utils/test/test_LoggerBuffer.cpp +192 -0
@@ 0,0 1,192 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
+#include <catch2/catch.hpp>
+
+#include "generators/RandomStringGenerator.hpp"
+#include "log/LoggerBuffer.hpp"
+#include <string>
+#include <vector>
+
+using namespace std;
+
+void TestBuffer(const LoggerBuffer &buffer, size_t capacity, size_t numOfMsgs)
+{
+ const bool isEmpty = buffer.isEmpty();
+ REQUIRE((numOfMsgs == 0 ? isEmpty : !isEmpty));
+ const bool isFull = buffer.isFull();
+ REQUIRE((capacity > 0 && capacity == numOfMsgs ? isFull : !isFull));
+ REQUIRE(buffer.getCapacity() == capacity);
+ REQUIRE(buffer.getSize() == numOfMsgs);
+}
+
+size_t GetNumOfBytes(vector<string>::const_iterator startIt, vector<string>::const_iterator endIt)
+{
+ size_t numOfBytes = 0;
+ for (; startIt != endIt; ++startIt) {
+ numOfBytes += startIt->length();
+ }
+ return numOfBytes;
+}
+
+TEST_CASE("LoggerBuffer tests")
+{
+ const size_t capacity = 100;
+ LoggerBuffer buffer(capacity);
+
+ RandomStringGenerator randomStringGenerator;
+
+ auto putMsgFunc = [&](const auto &msg) { buffer.put(msg); };
+ auto getMsgFunc = [&](const auto &originalMsg) {
+ const auto [result, msg] = buffer.get();
+ REQUIRE(result);
+ REQUIRE(msg == originalMsg);
+ };
+ auto putAllMsgsFunc = [&](const vector<string> &msgs) { for_each(msgs.begin(), msgs.end(), putMsgFunc); };
+ auto getAllMsgsFunc = [&](const vector<string> &msgs) { for_each(msgs.begin(), msgs.end(), getMsgFunc); };
+ auto checkLostBytes = [&](size_t numOfBytes, const string &originalMsg) {
+ const auto [result, msg] = buffer.get();
+ REQUIRE(result);
+ REQUIRE(msg.find(originalMsg) != string::npos);
+ REQUIRE(msg.find(to_string(numOfBytes)) != string::npos);
+ REQUIRE(msg.find(LoggerBuffer::lostBytesMessage) != string::npos);
+ };
+
+ SECTION("calling get on empty buffer should return false")
+ {
+ const auto [result, _] = buffer.get();
+ REQUIRE(!result);
+ TestBuffer(buffer, capacity, 0);
+ }
+
+ SECTION("after putting one msg in buffer, get should return this msg")
+ {
+ const string originalMsg = randomStringGenerator.getRandomString();
+ buffer.put(originalMsg);
+ TestBuffer(buffer, capacity, 1);
+ const auto [result, msg] = buffer.get();
+ REQUIRE(result);
+ REQUIRE(msg == originalMsg);
+ TestBuffer(buffer, capacity, 0);
+ }
+
+ SECTION("after filling whole buffer with msgs, caliling get repeatedly should return all these msgs back")
+ {
+ const auto msgs = randomStringGenerator.createRandomStringVector(capacity);
+ putAllMsgsFunc(msgs);
+ TestBuffer(buffer, capacity, msgs.size());
+ getAllMsgsFunc(msgs);
+ TestBuffer(buffer, capacity, 0);
+ }
+
+ SECTION("buffer should be empty after resetting it")
+ {
+ const auto msgs = randomStringGenerator.createRandomStringVector(capacity);
+ putAllMsgsFunc(msgs);
+ TestBuffer(buffer, capacity, msgs.size());
+ buffer.reset();
+ TestBuffer(buffer, capacity, 0);
+ }
+
+ SECTION("when more msgs are put into buffer than its capacity, only last msgs should be returned with get and "
+ "first msg should contain lost bytes message")
+ {
+ const size_t numOfMsgsAboveCapacity = 13;
+ const auto msgs = randomStringGenerator.createRandomStringVector(capacity + numOfMsgsAboveCapacity);
+ putAllMsgsFunc(msgs);
+ auto firstLostMsgIt = msgs.begin();
+ auto firstMsgInBufferIt = firstLostMsgIt + numOfMsgsAboveCapacity;
+ const auto numOfLostBytes = GetNumOfBytes(firstLostMsgIt, firstMsgInBufferIt);
+ checkLostBytes(numOfLostBytes, *firstMsgInBufferIt);
+ for_each(firstMsgInBufferIt + 1, msgs.end(), getMsgFunc);
+ TestBuffer(buffer, capacity, 0);
+ }
+
+ SECTION("each get should reduce number of msgs in buffer")
+ {
+ size_t numOfMsgsInBuffer = capacity;
+ const auto msgs = randomStringGenerator.createRandomStringVector(capacity);
+
+ auto getStartIt = msgs.begin();
+
+ putAllMsgsFunc(msgs);
+ TestBuffer(buffer, capacity, capacity);
+
+ size_t numOfMsgsToGet = 15;
+ for_each(getStartIt, getStartIt + numOfMsgsToGet, getMsgFunc);
+ numOfMsgsInBuffer -= numOfMsgsToGet;
+ TestBuffer(buffer, capacity, numOfMsgsInBuffer);
+ getStartIt += numOfMsgsToGet;
+
+ numOfMsgsToGet = 34;
+ for_each(getStartIt, getStartIt + numOfMsgsToGet, getMsgFunc);
+ numOfMsgsInBuffer -= numOfMsgsToGet;
+ TestBuffer(buffer, capacity, numOfMsgsInBuffer);
+ getStartIt += numOfMsgsToGet;
+
+ for_each(getStartIt, msgs.end(), getMsgFunc);
+ TestBuffer(buffer, capacity, 0);
+ }
+
+ SECTION("put get put get")
+ {
+ const auto msgs = randomStringGenerator.createRandomStringVector(capacity);
+
+ auto putStartIt = msgs.begin();
+ auto getStartIt = msgs.begin();
+
+ size_t numOfMsgsToPut = 37;
+ for_each(putStartIt, putStartIt + numOfMsgsToPut, putMsgFunc);
+ putStartIt += numOfMsgsToPut;
+ size_t numOfMsgsInBuffer = numOfMsgsToPut;
+ TestBuffer(buffer, capacity, numOfMsgsInBuffer);
+
+ size_t numOfMsgsToGet = 25;
+ for_each(getStartIt, getStartIt + numOfMsgsToGet, getMsgFunc);
+ getStartIt += numOfMsgsToGet;
+ numOfMsgsInBuffer -= numOfMsgsToGet;
+ TestBuffer(buffer, capacity, numOfMsgsInBuffer);
+
+ numOfMsgsToPut = msgs.end() - putStartIt;
+ for_each(putStartIt, msgs.end(), putMsgFunc);
+ numOfMsgsInBuffer += numOfMsgsToPut;
+ TestBuffer(buffer, capacity, numOfMsgsInBuffer);
+
+ for_each(getStartIt, msgs.end(), getMsgFunc);
+ TestBuffer(buffer, capacity, 0);
+ }
+
+ SECTION("put get put get - with buffer overflow")
+ {
+ const size_t numOfMsgsAboveCapacity = 43;
+ const auto msgs = randomStringGenerator.createRandomStringVector(capacity + numOfMsgsAboveCapacity);
+
+ auto putStartIt = msgs.begin();
+ auto getStartIt = msgs.begin();
+
+ size_t numOfMsgsToPut = 77;
+ for_each(putStartIt, putStartIt + numOfMsgsToPut, putMsgFunc);
+ putStartIt += numOfMsgsToPut;
+ size_t numOfMsgsInBuffer = numOfMsgsToPut;
+ TestBuffer(buffer, capacity, numOfMsgsInBuffer);
+
+ size_t numOfMsgsToGet = 15;
+ for_each(getStartIt, getStartIt + numOfMsgsToGet, getMsgFunc);
+ getStartIt += numOfMsgsToGet;
+ numOfMsgsInBuffer -= numOfMsgsToGet;
+ TestBuffer(buffer, capacity, numOfMsgsInBuffer);
+
+ numOfMsgsToPut = msgs.end() - putStartIt; // put rest of msgs - more than buffer can hold
+ for_each(putStartIt, msgs.end(), putMsgFunc);
+ numOfMsgsInBuffer = capacity;
+ TestBuffer(buffer, capacity, numOfMsgsInBuffer);
+
+ auto firstLostMsgIt = getStartIt;
+ auto firstMsgInBufferIt = firstLostMsgIt + numOfMsgsAboveCapacity - numOfMsgsToGet;
+ const auto numOfLostBytes = GetNumOfBytes(firstLostMsgIt, firstMsgInBufferIt);
+ checkLostBytes(numOfLostBytes, *firstMsgInBufferIt);
+ for_each(firstMsgInBufferIt + 1, msgs.end(), getMsgFunc);
+ TestBuffer(buffer, capacity, 0);
+ }
+}
M module-utils/time/TimeRangeParser.cpp => module-utils/time/TimeRangeParser.cpp +2 -2
@@ 19,8 19,8 @@ namespace utils::time
return utils::localize.get(utils::time::Locale::getPM());
}
- std::string TimeRangeParser::getCalendarTimeString(TimePoint startDate,
- TimePoint endDate,
+ std::string TimeRangeParser::getCalendarTimeString(calendar::TimePoint startDate,
+ calendar::TimePoint endDate,
Version version,
bool isMode24H)
{
M module-utils/time/TimeRangeParser.hpp => module-utils/time/TimeRangeParser.hpp +2 -2
@@ 20,8 20,8 @@ namespace utils::time
std::string AMPMtoString(bool isAm);
public:
- std::string getCalendarTimeString(TimePoint startDate,
- TimePoint endDate,
+ std::string getCalendarTimeString(calendar::TimePoint startDate,
+ calendar::TimePoint endDate,
Version version = Version::normal,
bool isMode24H = false);
};
M test/harness/harness.py => test/harness/harness.py +5 -1
@@ 72,7 72,11 @@ class Harness:
def send_text(self, text: str):
for letter in text:
- send_char(letter, self.connection)
+ try:
+ send_char(letter, self.connection)
+ except KeyError as e:
+ available = ' '.join((f"'{_}'" for _ in utils.keymap.keys()))
+ raise LookupError(f"Character {e} not present in the keymap\nAvailable characters: {available}")
def send_number(self, number: str):
utils.send_number(number, self.connection)
M test/harness/utils.py => test/harness/utils.py +2 -1
@@ 156,7 156,8 @@ class Timeout(Exception):
@classmethod
@contextmanager
- def limit(cls, seconds):
+ def limit(cls, seconds: int):
+ assert seconds >= 1, "Timeout must be at least 1 second !"
def signal_handler(signum, frame):
raise Timeout("Timed out!")
M test/pytest/conftest.py => test/pytest/conftest.py +1 -1
@@ 54,7 54,7 @@ def harness(request):
Try to init one Pure phone with serial port path or automatically
'''
port_name = request.config.option.port
- TIMEOUT = int(request.config.option.timeout)
+ TIMEOUT = min(1, request.config.option.timeout)
timeout_started = time.time()
RETRY_EVERY_SECONDS = 1.0
M tools/check_commit_messages.py => tools/check_commit_messages.py +1 -1
@@ 33,7 33,7 @@ def validate_commit(commit):
empty_line = lines[1]
body = ''.join(lines[2:]).strip()
- subject_format = r'^\[\w+-\d+\] .+[^.]$'
+ subject_format = r'^\[EGD-\d+\] [A-Z].+[^.]$'
if not re.match(subject_format, subject):
errors.append(f'[{commit.hexsha}] invalid subject "{subject}", should match format "{subject_format}"')
A tools/clang-tidy.cmake => tools/clang-tidy.cmake +19 -0
@@ 0,0 1,19 @@
+find_program(RUN_CLANG_TIDY_COMMAND NAMES run-clang-tidy)
+if (NOT RUN_CLANG_TIDY_COMMAND)
+ message(WARNING "run-clang-tidy can not be found.")
+ return()
+endif()
+
+if (NOT CMAKE_EXPORT_COMPILE_COMMANDS)
+ message(WARNING "Unable to run clang-tidy without the compile commands database.")
+ return()
+endif()
+
+set(STATIC_ANALYSIS_OUTPUT_DIR "StaticAnalysis")
+
+string(TIMESTAMP CURRENT_TIME)
+set(CLANG_TIDY_OUTPUL_FILE "clang-tidy_${CURRENT_TIME}")
+
+add_custom_target(clang-tidy
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${STATIC_ANALYSIS_OUTPUT_DIR}
+ COMMAND ${RUN_CLANG_TIDY_COMMAND} -header-filter='.*' -p ${CMAKE_BINARY_DIR} > "${STATIC_ANALYSIS_OUTPUT_DIR}/${CLANG_TIDY_OUTPUL_FILE}")
M tools/download_asset.py => tools/download_asset.py +2 -2
@@ 52,7 52,7 @@ class Getter(object):
try:
gitConfigReader = self.gitRepo.config_reader()
self.apitoken = gitConfigReader.get_value("user", "apitoken")
- except git.exc.NoOptionError as error:
+ except:
pass
def getGHLogin(self, args=None):
@@ 63,7 63,7 @@ class Getter(object):
try:
gitConfigReader = self.gitRepo.config_reader()
self.ghLogin = gitConfigReader.get_value("user", "githublogin")
- except git.exc.NoOptionError as error:
+ except:
pass
def findWorkDir(self):