M CMakeLists.txt => CMakeLists.txt +1 -0
@@ 26,6 26,7 @@ include(Utils)
include(ModuleUtils)
include(DiskImage)
include(AddPackage)
+include(AutoModuleOption)
message("Selected product: ${PRODUCT}")
message("Selected board: ${BOARD}")
A cmake/modules/AutoModuleOption.cmake => cmake/modules/AutoModuleOption.cmake +46 -0
@@ 0,0 1,46 @@
+# Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+# For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+# function to add:
+# - module library to compilation
+# - module definition to compilation
+# - cmake option enabled by default
+# this way we can enable/disable apps or services in cmake
+function(add_module_options)
+
+ cmake_parse_arguments( _ARG
+ ""
+ "OPTION_PREFIX;CATALOG_PREFIX;DEFINES_LIST_NAME"
+ "IN_MODULE_NAMES"
+ ${ARGN}
+ )
+
+ message("configurables added: ${_ARG_IN_MODULE_NAMES}")
+
+ list(SORT _ARG_IN_MODULE_NAMES)
+ foreach(app IN LISTS _ARG_IN_MODULE_NAMES)
+
+ message("-> configuring option and define for: ${app}")
+
+ string(TOUPPER ${app} app_upper)
+ string(REPLACE "-" "_" app_macro_name ${app_upper})
+
+ #add option for each element from the IN_MODULE_NAMES
+ if (NOT DEFINED ENABLE_${_ARG_OPTION_PREFIX}_${app_macro_name})
+ message(" adding option: ${app}")
+ option(ENABLE_${_ARG_OPTION_PREFIX}_${app_macro_name} "Enable ${_ARG_CATALOG_PREFIX} ${app}" ON)
+ endif()
+
+ # add #define for each application to list
+ if(ENABLE_${_ARG_OPTION_PREFIX}_${app_macro_name})
+ message(" adding definition for: ${app}")
+ add_subdirectory(${_ARG_CATALOG_PREFIX}-${app})
+ list(APPEND _TMP "ENABLE_${_ARG_OPTION_PREFIX}_${app_macro_name}")
+ endif()
+ endforeach()
+
+
+ set(${_ARG_DEFINES_LIST_NAME} ${_TMP} PARENT_SCOPE)
+ message("defines for ${_ARG_DEFINES_LIST_NAME} set to: ${_TMP}")
+
+endfunction()
D config/README.md => config/README.md +0 -20
@@ 1,20 0,0 @@
-Configs description
-====================
-
-# ProjectConfig.cmake
-
-| LOG_USE_COLOR | Result |
-|---:|---:|
-| 0 | No color on RTT log messages |
-| 1 | Color in RTT log, SysView is not parsing it |
-
-| LOG_REDIRECT | Result |
-|---:|---:|
-| RTT_JLINK | RTT log via JLINK on serial|
-| RTT_LUART | RTT log via RT1051 UART on serial|
-| RTT_SYSTEMVIEW | RTT log via JLINK on SystemView |
-
-| SYSTEM_VIEW_ENABLED | Result |
-|---:|---:|
-| 0 | SystemView not enabled and code not included|
-| 1 | SystemView enabled and code included |
A doc/ProjectConfig.md => doc/ProjectConfig.md +88 -0
@@ 0,0 1,88 @@
+Configs description
+====================
+
+# ProjectConfig.cmake
+
+## Logging
+
+### Logging device and configuration
+
+| LOG_USE_COLOR | Result |
+|---:|---:|
+| 0 | No color on RTT log messages |
+| 1 | Color in RTT log, SysView is not parsing it |
+
+| LOG_REDIRECT | Result |
+|---:|---:|
+| RTT_JLINK | RTT log via JLINK on serial|
+| RTT_LUART | RTT log via RT1051 UART on serial|
+| RTT_SYSTEMVIEW | RTT log via JLINK on SystemView |
+
+| SYSTEM_VIEW_ENABLED | Result |
+|---:|---:|
+| 0 | SystemView not enabled and code not included|
+| 1 | SystemView enabled and code included |
+
+### LOG_SENSITIVE_DATA
+
+Enables logging normally disabled sensitive data
+
+## System tracing
+
+## SystemView option
+
+While it's not a perfect solution due to:
+- loads of data (and lost data) sent via RTT
+- no scalling with CPU frequency
+We can to some extent use Segger SystemView. To enable set `SYSTEMVIEW` option to `ON`
+
+### System Profile
+
+MuditaOS have a minimailstic system profiling tool, to enable set: `SYSTEM_PROFILE` to `ON`
+
+System Profile data is being sent via msgpack on RTT. To decode it and see:
+- last 100ms before frequency change load
+- frequency changes in time
+- power usage in time
+As well as logs in one app you can use: [MuditaOSTop](https://github.com/mudita/MuditaOSTop)
+
+Or change printer configuration in `CPUStatistics.cpp` to other than messagepack printer (i.e. logs)
+
+## CurrentMeasurement enable option
+To use direct current polling and have it in logs set `CURRENT_MEASUREMENT` to `ON`
+you can plot this with [plot_current_measurement.py](../tools/plot_current_measurement.py)
+
+# USB
+
+## USB-CDC echo test
+
+To test if USB-CDC works you can set USB-CDC echo with `USBCDC_ECHO`
+
+## Enable/disable USB MTP
+
+- option `ENABLE_USB_MTP` enables USB-MTP protocol, default `ON`
+
+## Mudita USB Vendor/Product IDs
+
+- option `MUDITA_USB_ID` default `ON`
+
+# Config options for the lwext4
+
+Following configurations are for: [lwext4](third-party/lwext4/) - third party ext4 library
+
+## LWEXT4 debug options
+
+- option `LWEXT4_DEBUG_PRINTF` default `ON`
+- option `LWEXT4_DEBUG_ASSERT` default `OFF`
+
+## LWEXT4 sectors cache size
+
+- option `LWEXT4_CACHE_SIZE` default set to `256`
+
+# Development Configuration
+
+- option `WITH_DEVELOPMENT_FEATURES` enables all system development features, which are:
+ - `DEVELOPER_SETTINGS_OPTIONS_DEFAULT`
+ - `ENABLE_DEVELOPER_MODE_ENDPOINT_DEFAULT`
+ - `LOG_SENSITIVE_DATA_ENABLED`
+default: `OFF`
M doc/README.md => doc/README.md +4 -3
@@ 22,7 22,7 @@ Documentation listed below is system documentation listed depending on where it
- System architecture
- Modules
- - Applications
+ - [Applications](../module-apps/ModuleApps.md)
- [Application Desktop](../module-apps/application-desktop/doc/README.md)
- [Notifications](../module-apps/apps-common/notifications/README.md)
- [Audio](../module-audio/README.md)
@@ 35,7 35,7 @@ Documentation listed below is system documentation listed depending on where it
- [GUI](../module-gui/README.md)
- [Modem](../module-cellular/modem/README.md)
- [System](../module-sys/README.md)
-- Services
+- [Services](../module-services/ModuleServices.md)
- [Application Manager](../module-services/service-appmgr/doc/README.md)
- [Bluetooth](../module-services/service-bluetooth/doc/readme.md)
- [Cellular](../module-services/service-cellular/doc/README.md)
@@ 46,11 46,12 @@ Documentation listed below is system documentation listed depending on where it
- Tools
- [MapParser](https://github.com/mudita/misc-tools/blob/master/mapparser/README.md)
- [PureGDB](https://github.com/mudita/misc-tools/blob/master/puregdb/README.md)
+- [System cmake configuration](ProjectConfig.md)
- [Development workflow](development_workflow.md)
- [Contributing](../CONTRIBUTING.md)
- [Internationalization](i18n.md)
## Changelog
- [HOWTO](changelog_howto.md)
-- [Latest changelog](../changelog.md)
+- [The latest changelog](../changelog.md)
M doc/quickstart.md => doc/quickstart.md +5 -3
@@ 110,7 110,7 @@ Please follow github token configuration here: [download assets documentation](.
To configure project we have helper script: `./configure.sh` which essentially passes through basic cmake configuration for each product for each platform.
We highly advise using `ninja` as it has proven better compilation times over make.
-which can be run with the following parameters:
+The script can be run with the following parameters:
```
# command # product # platform # build type
./configure.sh [PurePhone|BellHybrid] [rt1051|linux] [release|debug|relwithdebinfo] [additional cmake parameters and options go here, i.e. -DENABLE_DEVELOPER_MODE_ENDPOINT=1 or "-G Ninja"]
@@ 147,7 147,7 @@ Each run of `configure.sh` creates `build-{PRODUCT}-{PLATFORM}-{OPTMALIZAION}` f
To know more about build targets please see: [build targets documentation](../doc/build_targets.md)
-**WARNING:** our source code is open source, but the project itself is in the progress of fully embracing the community. Currently you:
+**WARNING:** our source code is open source, but the project itself is in the progress of fully embracing the community. Currently, you:
1. can build binaries from the software
2. are not able to create images - due to difficulties with separation of 3rd party proprietary assets
@@ 204,6 204,8 @@ This can be done manually, by editing the `.cmake` files (not recommended though
By using `ENABLE_APP_X` (where `X` is the name of the application) you can enable/disable any application.
+CMake-wide system config documentation is here: [Project config](ProjectConfig.md)
+
#### Catching logs using UART
If you want to catch logs from Mudita Pure from UART please follow these steps:
@@ 220,7 222,7 @@ Please mind that logs on UART are more costly, so these might cause timing issue
The `bootstrap.sh` script installs git hooks for code style checking. `pre-commit.hook`automatically updates style during commit. If you haven't run `bootstrap.sh` and want to use git hooks, you have to copy (or link) `pre-commit.hook` to your git config directory `.git/config/hooks`: `ln -s `pwd`/config/pre-commit.hook .git/hooks/pre-commit`
-By default commit hook only checks if your changes have the appropriate style, if you would like to fix the style automatically during `git commit` you have to configure your git, by adding new variable `user.fixinstage` and setting it to `true` by running
+By default, commit hook only checks if your changes have the appropriate style, if you would like to fix the style automatically during `git commit` you have to configure your git, by adding new variable `user.fixinstage` and setting it to `true` by running
`git config user.fixinstage true`
If you prefer "notification then fix" workflow (so you can examine the changes), use the default hook behaviour (for notifications) and then call `./config/pre-commit.hook --fix`, this checks and fixes files in "stage", files that have status "changed" are not tested.
M module-apps/CMakeLists.txt => module-apps/CMakeLists.txt +7 -17
@@ 30,20 30,10 @@ set(APPLICATIONS
settings
)
-list(SORT APPLICATIONS)
-foreach(app IN LISTS APPLICATIONS)
- string(TOUPPER ${app} app_upper)
- string(REPLACE "-" "_" app_macro_name ${app_upper})
- if (NOT DEFINED ENABLE_APP_${app_macro_name})
- option(ENABLE_APP_${app_macro_name} "Enable application ${app}" ON)
- endif()
-
- if(ENABLE_APP_${app_macro_name})
- message("Enabling application: ${app}")
- add_subdirectory(application-${app})
- list(APPEND ENABLED_APPS_DEFINES "ENABLE_APP_${app_macro_name}")
- endif()
-endforeach()
+add_module_options( OPTION_PREFIX "APP"
+ CATALOG_PREFIX "application"
+ DEFINES_LIST_NAME "ENABLED_APPS_DEFINES"
+ IN_MODULE_NAMES ${APPLICATIONS})
target_compile_definitions(application-desktop PRIVATE "${ENABLED_APPS_DEFINES}")
set(ENABLED_APPS_DEFINES ${ENABLED_APPS_DEFINES} PARENT_SCOPE)
@@ 84,9 74,9 @@ endif()
target_link_libraries(${PROJECT_NAME}
PRIVATE
app
- application-calendar
- application-messages
- application-settings
+ $<$<BOOL:${ENABLE_APP_CALENDAR}>:application-calendar>
+ $<$<BOOL:${ENABLE_APP_MESSAGES}>:application-messages>
+ $<$<BOOL:${ENABLE_APP_SETTINGS}>:application-settings>
apps-common
date::date
eventstore
A module-apps/ModuleApps.md => module-apps/ModuleApps.md +10 -0
@@ 0,0 1,10 @@
+Module apps
+===========
+
+# Adding 3rd party library
+
+Please follow information here: [third party libraries](../third-party/ThirdParty.md)
+
+# Adding tests to service
+
+Please follow information here: [unit tests gathering cmake](../test/AddingUnitTests.md)
M module-apps/application-desktop/CMakeLists.txt => module-apps/application-desktop/CMakeLists.txt +2 -1
@@ 50,8 50,9 @@ target_sources(application-desktop
)
target_link_libraries(application-desktop
- PRIVATE
+ PUBLIC
app
+ PRIVATE
application-messages
i18n
log
M module-apps/application-onboarding/CMakeLists.txt => module-apps/application-onboarding/CMakeLists.txt +18 -8
@@ 1,14 1,14 @@
-include_directories( ${CMAKE_PROJECT_NAME}
- PUBLIC
- "${CMAKE_CURRENT_LIST_DIR}"
-)
+# Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+# For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-include_directories( ${PROJECT_NAME}
- PUBLIC
- "${CMAKE_CURRENT_LIST_DIR}"
+add_library(application-onboarding STATIC)
+
+target_include_directories( application-onboarding
+ PUBLIC
+ ${CMAKE_CURRENT_LIST_DIR}
)
-target_sources(${PROJECT_NAME}
+target_sources(application-onboarding
PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/ApplicationOnBoarding.cpp"
@@ 44,3 44,13 @@ target_sources(${PROJECT_NAME}
"${CMAKE_CURRENT_LIST_DIR}/windows/NoSimSelectedDialogWindow.hpp"
"${CMAKE_CURRENT_LIST_DIR}/style/OnBoardingStyle.hpp"
)
+
+target_link_libraries(application-onboarding
+ PRIVATE
+ app
+ i18n
+ log
+ module-gui
+ PUBLIC
+ apps-common
+)
M module-apps/apps-common/CMakeLists.txt => module-apps/apps-common/CMakeLists.txt +1 -0
@@ 90,6 90,7 @@ add_subdirectory(locks)
target_link_libraries(apps-common
PRIVATE
+ app
date::date
eventstore
Microsoft.GSL::GSL
M module-bluetooth/CMakeLists.txt => module-bluetooth/CMakeLists.txt +1 -1
@@ 62,7 62,7 @@ target_include_directories(
)
target_link_libraries(${PROJECT_NAME}
- application-settings
+ $<$<BOOL:${ENABLE_APP_SETTINGS}>:application-settings>
${BOARD_DIR_LIBRARIES}
module-audio
module-bsp
M module-cellular/at/ErrorCode.hpp => module-cellular/at/ErrorCode.hpp +1 -1
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
M module-db/CMakeLists.txt => module-db/CMakeLists.txt +1 -1
@@ 168,7 168,7 @@ target_link_libraries(${PROJECT_NAME}
utf8
desktop-endpoints
PRIVATE
- application-calendar
+ $<$<BOOL:${ENABLE_APP_CALENDAR}>:application-calendar>
Microsoft.GSL::GSL
rrule
board
M module-db/queries/README.md => module-db/queries/README.md +2 -1
@@ 1,6 1,7 @@
Virtual database query interface.
+================================
-Instead manually creating switch cases for each possible query logic, create one
+Instead, manually creating switch cases for each possible query logic, create one
virtual `query` interface and push `querying` logic to db (where it's implemented)
* db::service accepts `GetByQuery(service, database, query)`
M module-services/CMakeLists.txt => module-services/CMakeLists.txt +24 -12
@@ 5,18 5,30 @@ module_is_test_entity()
add_library(${PROJECT_NAME} STATIC ${SOURCES})
-add_subdirectory( service-antenna )
-add_subdirectory( service-appmgr )
-add_subdirectory( service-audio )
-add_subdirectory( service-bluetooth )
-add_subdirectory( service-cellular )
-add_subdirectory( service-db )
-add_subdirectory( service-desktop )
-add_subdirectory( service-eink )
-add_subdirectory( service-evtmgr )
-add_subdirectory( service-fileindexer )
-add_subdirectory( service-gui )
-add_subdirectory( service-time )
+option(ENABLE_SERVICE_TEST "Enable service test" OFF)
+
+set(SERVICES
+ antenna
+ appmgr
+ audio
+ bluetooth
+ cellular
+ db
+ desktop
+ eink
+ evtmgr
+ fileindexer
+ gui
+ time
+ test
+)
+
+add_module_options( OPTION_PREFIX "SERVICE"
+ CATALOG_PREFIX "service"
+ DEFINES_LIST_NAME "ENABLED_SERVICES_DEFINES"
+ IN_MODULE_NAMES ${SERVICES})
+
+set(ENABLED_SERVICES_DEFINES ${ENABLED_SERVICES_DEFINES} PARENT_SCOPE)
target_link_libraries(${PROJECT_NAME}
PUBLIC
A module-services/ModuleServices.md => module-services/ModuleServices.md +101 -0
@@ 0,0 1,101 @@
+Module services
+===============
+
+All Services in PurePhone are dependent to `Service.hpp` from `module-sys`
+
+Table of Contents
+
+* [Module services](#module-services)
+* [General services documentation](#general-services-documentation)
+* [How to add new service](#how-to-add-new-service)
+ * [To change service startup order](#to-change-service-startup-order)
+ * [To use settings::Settings](#To-use-settingssettings)
+ * [To add timer](#to-add-timer)
+ * [To add 3rd party library](#to-add-3rd-party-library)
+ * [To add tests](#to-add-tests)
+* [More on services configuration](#more-on-services-configuration)
+* [Minimalistic service example](#Example)
+
+# General services documentation
+
+Services documentation is available [in module-sys here](../module-sys/README.md#Services).
+
+# How to add new service
+
+- we do not have strict naming conventions, but please follow others
+- name your service - for example’s sake it will be `test`
+- add new folder `service-test` in `module-services`
+- add folder `include/service-test/` to `service-test`
+ - this folder will contain your service public API - api you want to publish for others to use
+ - add this folder as `PUBLIC` library include
+ - please do add other elements as `PRIVATE` library includes and libraries
+- create `include/service-test/ServiceTest.hpp` - this file will be your service declaration
+- create `ServiceTest.cpp` - this file will be your service entry point and definition
+- add your service to SERVICES list in `module-services/CMakeLists.txt`
+- add your service to list of services to include in product main in which you want to have it
+ - add your service `$<$<BOOL:${ENABLE_SERVICE_TEST}>:service-test>` in `target_link_libraries(${TARGET} ...`
+ - please add conditional compilation to it too in `${TARGET}Main.cpp` (i.e. `PurePhoneMain.cpp`) - all services have `ENABLE_SERVICE_{SERVICE_NAME}` definition exported
+
+**NOTE:** There are no other rules of thumb in terms of folders
+
+- add cmake, the very basic cmake here:
+``` cmake
+project(service-test)
+message("${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}" )
+
+
+set(SOURCES ServiceTest.cpp)
+
+add_library(${PROJECT_NAME} STATIC ${SOURCES})
+
+target_include_directories(${PROJECT_NAME}
+ PRIVATE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+ PUBLIC
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
+)
+
+target_link_libraries(${PROJECT_NAME}
+ PRIVATE
+ PUBLIC
+)
+
+if (${ENABLE_TESTS})
+ add_subdirectory(test)
+endif ()
+```
+- to disable your service by default please add:
+```
+option(ENABLE_SERVICE_TEST "Enable service test" OFF)
+```
+
+## To change service startup order
+
+Please see the [SystemManager services synchronization](./SystemManager/doc/ServicesSynchronization.md) documentation
+
+## To use settings::Settings
+
+Documentation: [settings::Settings](Settings.md)
+
+## To add timer
+
+Documentation [timers](../module-sys/README.md#Timers)
+
+## To add 3rd party library
+
+Documentation: [third party libraries](../third-party/ThirdParty.md)
+
+## To add tests
+
+Documentation: [unit tests gathering cmake](../test/AddingUnitTests.md)
+
+# More on services configuration
+
+While we can enable and disable services, we do not have proper separation for services and API definition.
+This means that whole system compilation will depend on:
+- include paths exported in services
+- APIs from services
+
+# Example
+
+See [service-test example](./service-test/doc/README.md) for ready to copy service example
M module-services/service-appmgr/CMakeLists.txt => module-services/service-appmgr/CMakeLists.txt +1 -1
@@ 72,7 72,7 @@ target_sources(service-appmgr
target_link_libraries(service-appmgr
PRIVATE
- application-special-input
+ $<$<BOOL:${ENABLE_APP_SPECIAL_INPUT}>:application-special-input>
json::json
module-audio
service-cellular
A module-services/service-db/doc/ServiceDB.md => module-services/service-db/doc/ServiceDB.md +22 -0
@@ 0,0 1,22 @@
+Service db
+==========
+
+# Introduction
+
+Service DB reason of existance is to serve data from module-db for system.
+
+# Usage
+
+We have a few features built in service-db
+
+## Query interface
+
+DB Query interface is a way to define a request -> response behavior to service-db. It's strongly recommended to use it asynchronously.
+
+Documentation available [here](../../module-db/queries/README.md)
+
+## database settings agent : settings::Settings
+
+Documentation here: [settings::Settings](Settings.md)
+
+## **deprecated** DBServiceAPI
M module-services/service-db/doc/Settings.md => module-services/service-db/doc/Settings.md +31 -4
@@ 1,9 1,36 @@
-Settings
-========
+settings::Settings
+==================
-# settings::Settings API
+It's a class that aims to store service/app specific non volatile data and provide it in runtime.
+It works with Settings agent provides with a backend to serve all services and apps data to it.
-settings::Settings class aims to store service/app specific non volatile data and provide it in runtime.
+What it essentially does is:
+1. provide with global cache for data on RAM via SettingsCache
+2. provide simple API to get and set value
+
+Caveats:
+1. It's a getter/setter code. While we can build business logic on it we should use system notifications to do so
+2. It doesn't provide us with information if there is data in it - if there is none it will return an empty string
+3. It doesn't provide us with any abstraction to store our own data structures. To do so one will have to i.e. store settings as string dump of i.e. JSON of msgpack
+
+**IMPORTANT:**
+You need to initialize settings::Settings in Service/Application when init function, not in the constructor.
+Please see [module-sys documentation](../../module-sys/README.md#Services)
+
+# How to add settings to use
+
+1. add `settings::Settings` handle to your service i.e. in class definition:
+```
+settings::Settings settings;
+```
+
+Then after/in init handler call:
+```
+settings.init(service::ServiceProxy{service->weak_from_this()});
+```
+To initialize it.
+
+At this moment you can get/set data from settings. Follow [settings Gudeline](#Guideline) for more information
## Guideline
A module-services/service-evtmgr/AppSettingsNotify.cpp => module-services/service-evtmgr/AppSettingsNotify.cpp +31 -0
@@ 0,0 1,31 @@
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "Service/BusProxy.hpp"
+#include <application-settings/ApplicationSettings.hpp>
+
+namespace evm::api
+{
+ void notifySettingsBluetoothAudio(sys::BusProxy &bus, std::shared_ptr<audio::Event> event)
+ {
+ switch (event->getType()) {
+ case audio::EventType::BlutoothA2DPDeviceState: {
+ auto message = std::make_shared<message::bluetooth::ProfileStatus>(
+ bluetooth::AudioProfile::A2DP, (event->getDeviceState() == audio::Event::DeviceState::Connected));
+ bus.sendUnicast(message, app::name_settings);
+ } break;
+ case audio::EventType::BlutoothHSPDeviceState: {
+ auto message = std::make_shared<message::bluetooth::ProfileStatus>(
+ bluetooth::AudioProfile::HSP, (event->getDeviceState() == audio::Event::DeviceState::Connected));
+ bus.sendUnicast(message, app::name_settings);
+ } break;
+ case audio::EventType::BlutoothHFPDeviceState: {
+ auto message = std::make_shared<message::bluetooth::ProfileStatus>(
+ bluetooth::AudioProfile::HFP, (event->getDeviceState() == audio::Event::DeviceState::Connected));
+ bus.sendUnicast(message, app::name_settings);
+ } break;
+ default:
+ break;
+ }
+ }
+} // namespace evm::api
M module-services/service-evtmgr/CMakeLists.txt => module-services/service-evtmgr/CMakeLists.txt +4 -5
@@ 1,6 1,9 @@
project(service-evtmgr)
-set(SOURCES
+add_library(service-evtmgr STATIC)
+
+target_sources(service-evtmgr PRIVATE
+ AppSettingsNotify.cpp
EventManager.cpp
WorkerEventCommon.cpp
api/EventManagerServiceAPI.cpp
@@ 15,10 18,6 @@ set(SOURCES
vibra/Vibra.cpp
)
-add_library(service-evtmgr STATIC)
-
-target_sources(service-evtmgr PRIVATE ${SOURCES})
-
target_include_directories(${PROJECT_NAME}
PUBLIC
"${CMAKE_CURRENT_LIST_DIR}"
M module-services/service-evtmgr/EventManager.cpp => module-services/service-evtmgr/EventManager.cpp +2 -20
@@ 7,6 7,7 @@
#include "service-evtmgr/Constants.hpp"
#include "service-evtmgr/EventManagerCommon.hpp"
#include "service-evtmgr/WorkerEventCommon.hpp"
+#include "service-evtmgr/AppSettingsNotify.hpp"
#include <BaseInterface.hpp>
#include <MessageType.hpp>
@@ 28,7 29,6 @@
#include <service-time/Constants.hpp>
#include <service-time/service-time/TimeMessage.hpp>
#include <service-bluetooth/messages/Status.hpp>
-#include <application-settings/ApplicationSettings.hpp>
#include <cassert>
#include <fstream>
@@ 99,25 99,7 @@ sys::MessagePointer EventManagerCommon::DataReceivedHandler(sys::DataMessage *ms
}
else if (auto msg = dynamic_cast<AudioEventRequest *>(msgl); msg) {
auto event = msg->getEvent();
- switch (event->getType()) {
- case audio::EventType::BlutoothA2DPDeviceState: {
- auto message = std::make_shared<message::bluetooth::ProfileStatus>(
- bluetooth::AudioProfile::A2DP, (event->getDeviceState() == audio::Event::DeviceState::Connected));
- bus.sendUnicast(message, app::name_settings);
- } break;
- case audio::EventType::BlutoothHSPDeviceState: {
- auto message = std::make_shared<message::bluetooth::ProfileStatus>(
- bluetooth::AudioProfile::HSP, (event->getDeviceState() == audio::Event::DeviceState::Connected));
- bus.sendUnicast(message, app::name_settings);
- } break;
- case audio::EventType::BlutoothHFPDeviceState: {
- auto message = std::make_shared<message::bluetooth::ProfileStatus>(
- bluetooth::AudioProfile::HFP, (event->getDeviceState() == audio::Event::DeviceState::Connected));
- bus.sendUnicast(message, app::name_settings);
- } break;
- default:
- break;
- }
+ evm::api::notifySettingsBluetoothAudio(bus, event);
AudioServiceAPI::SendEvent(this, msg->getEvent());
handled = true;
}
A module-services/service-evtmgr/service-evtmgr/AppSettingsNotify.hpp => module-services/service-evtmgr/service-evtmgr/AppSettingsNotify.hpp +17 -0
@@ 0,0 1,17 @@
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include "Audio/AudioCommon.hpp"
+#include <memory>
+
+namespace sys
+{
+ class BusProxy;
+}
+
+namespace evm::api
+{
+ void notifySettingsBluetoothAudio(sys::BusProxy &bus, std::shared_ptr<audio::Event> event);
+} // namespace evm::api
A module-services/service-test/CMakeLists.txt => module-services/service-test/CMakeLists.txt +23 -0
@@ 0,0 1,23 @@
+project(service-test)
+message("${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}" )
+
+
+add_library(${PROJECT_NAME} STATIC)
+target_sources(${PROJECT_NAME} PRIVATE ServiceTest.cpp)
+
+target_include_directories(${PROJECT_NAME}
+ PRIVATE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+ PUBLIC
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
+)
+
+target_link_libraries(${PROJECT_NAME}
+ PRIVATE
+ module-sys
+ PUBLIC
+)
+
+if (${ENABLE_TESTS})
+ add_subdirectory(test)
+endif ()
A module-services/service-test/ServiceTest.cpp => module-services/service-test/ServiceTest.cpp +51 -0
@@ 0,0 1,51 @@
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "service-test/ServiceTest.hpp"
+#include "Timers/TimerFactory.hpp"
+
+namespace service::test
+{
+
+ static std::uint32_t stackSize = 2048;
+ constexpr auto setting_private_value = "private value";
+
+ ServiceTest::ServiceTest() : sys::Service(service::name::service_test, "", stackSize)
+ {
+ LOG_INFO("[ServiceTest] Initializing");
+ }
+
+ sys::ReturnCodes ServiceTest::InitHandler()
+ {
+ settings.init(service::ServiceProxy(shared_from_this()));
+ // set some value to settings
+ settings.setValue(setting_private_value, "it works");
+ // log this value in logs
+ // it will output: "Now we can use settings! it works"
+ LOG_INFO("Now we can use settings! %s", settings.getValue(setting_private_value).c_str());
+
+ // this code will create periodic system timer which will log:
+ // "timers are avesome, periodic timer is active: 1" around each second
+ th = sys::TimerFactory::createPeriodicTimer(
+ this, "my periodic timer", std::chrono::milliseconds(1000), [](sys::Timer &t) {
+ LOG_INFO("timers are avesome, periodic timer is active: %d", t.isActive());
+ });
+ th.start();
+ return sys::ReturnCodes::Success;
+ }
+
+ sys::ReturnCodes ServiceTest::DeinitHandler()
+ {
+ return sys::ReturnCodes::Success;
+ }
+
+ sys::ReturnCodes ServiceTest::SwitchPowerModeHandler(const sys::ServicePowerMode mode)
+ {
+ return sys::ReturnCodes::Success;
+ }
+
+ sys::MessagePointer ServiceTest::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp)
+ {
+ return std::make_shared<sys::ResponseMessage>(sys::ReturnCodes::Unresolved);
+ }
+} // namespace service::test
A module-services/service-test/doc/README.md => module-services/service-test/doc/README.md +10 -0
@@ 0,0 1,10 @@
+examplary test service
+======================
+
+To enable it:
+1. configure the project
+2. run `ccmake .` in the build catalog and set: `ENABLE_SERVICE_TEST` to `ON`
+
+By default, this service will:
+1. add and log variable from settings::Settings
+2. log from a timer each 1000ms
A module-services/service-test/include/service-test/ServiceTest.hpp => module-services/service-test/include/service-test/ServiceTest.hpp +43 -0
@@ 0,0 1,43 @@
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <Timers/TimerHandle.hpp>
+#include <Service/Message.hpp>
+#include <Service/Service.hpp>
+#include <service-db/Settings.hpp>
+
+namespace service::name
+{
+ constexpr auto service_test = "service-test";
+}
+
+namespace service::test
+{
+ class ServiceTest : public sys::Service
+ {
+ settings::Settings settings;
+ sys::TimerHandle th;
+
+ public:
+ ServiceTest();
+ sys::ReturnCodes InitHandler() override;
+ sys::ReturnCodes DeinitHandler() override;
+ sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override;
+ sys::MessagePointer DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp = nullptr) override;
+ };
+} // namespace service::test
+
+namespace sys
+{
+ template <> struct ManifestTraits<service::test::ServiceTest>
+ {
+ static auto GetManifest() -> ServiceManifest
+ {
+ ServiceManifest manifest;
+ manifest.name = service::name::service_test;
+ return manifest;
+ }
+ };
+} // namespace sys
A module-services/service-test/test/CMakeLists.txt => module-services/service-test/test/CMakeLists.txt +7 -0
@@ 0,0 1,7 @@
+add_catch2_executable(
+ NAME
+ service-test
+ SRCS
+ test-MyAwesomeTest.cpp
+ LIBS
+)
A module-services/service-test/test/test-MyAwesomeTest.cpp => module-services/service-test/test/test-MyAwesomeTest.cpp +9 -0
@@ 0,0 1,9 @@
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include <catch2/catch.hpp>
+
+TEST_CASE("successful test")
+{
+ REQUIRE(true);
+}
M module-sys/README.md => module-sys/README.md +42 -15
@@ 12,9 12,16 @@ System manager is responsible for:
* [system shutdown sequence](./SystemManager/doc/SystemCloseSequence.md)
## Services
-In order to crate new custom service you have to inherit from base Service class. Then you have to implement
-several virtual methods which are listed below:
+
+In order to create a new custom service, you have to inherit from the base Service class.
+
+**WARNING:** Services are not started at the moment their constructor is called. This essentially means that `sys::Bus` and every functionality based on bus is not available yet.
+The first moment when you are capable to call `sys::Bus` is `InitHandler()` of application. This is the place where your service initialization code should happen.
+
+Then you have to implement several virtual methods which are listed below:
+
#### `ReturnCodes InitHandler()`
+
This handler is invoked upon creation of the service. It is very important to return proper return code specified in:
```
@@ 40,9 47,9 @@ enum class ServicePowerMode{
};
```
-Important: Currently there is no distinction between `SuspendToRAM` and `SuspendsToNVM`. These two cases should be handled the same. Additionally only `SuspendToNVM` can be received by service.
+Important: Currently there is no distinction between `SuspendToRAM` and `SuspendsToNVM`. These two cases should be handled the same. Additionally, only `SuspendToNVM` can be received by service.
-#### `MessagePointer DataReceivedHandler(DataMessage* msg,ResponseMessage* resp)`
+#### `MessagePointer DataReceivedHandler(DataMessage* msg, ResponseMessage* resp)`
This is the main handler which should handle incoming messages.
If `DataMessage* msg` is not nullptr then it contains valid message which was sent by using blocking Bus API.
If `ResponseMessage* resp` is not nullptr then it contains valid message which was sent by using non-blocking Bus API.
@@ 57,22 64,42 @@ Please check "Caveats & good practices" chapter for more info
Timers are system feature and is Service/Application thread safe. Timer callback life expectancy should be as short as possible for system to work smoothly (as with any other message call)
+**WARNING:** Do not use FreeRTOS timers, without utmost care it can cause data races and obstruct sys::Timres and system in generall.
+
### System Timers
-System have basic coarse sys::Timer capability. There are two ways to handle actions on timer:
-* create a timer via TimerFactory
+
+System has basic coarse sys::Timer capability. There are two ways to handle actions on timer:
+* create a timer via TimerFactory
* assign callback to Timer with method: `void sys::timer::SystemTimer::connect(timer::TimerCallback &&newCallback)`
+* start the timer
+
+example:
+``` c++
+th = sys::TimerFactory::createPeriodicTimer(
+ this, "my periodic timer", std::chrono::milliseconds(1000), [](sys::Timer &t) {
+ LOG_INFO("timers are avesome, periodic timer is active: %d", t.isActive());
+ });
+th.start();
+```
+
+**NOTE:** System timers are RAII. These are automatically destructed when their handles are removed!
+**NOTE:** We do not have real-time system timers. It's possible to implement these, but there is no good mechanism to actually promote thread to be the first to execute in the system.
### GUI Timers
-* Build on top of `SystemTimer` is `GuiTimer` which is meant as a connector between System <=> GUI.
+* Build on top of `SystemTimer` is `GuiTimer` are meant as a connector between System <=> GUI.
### Hints
* Each service can have any amount of timers.
-* For timer to work one have to first start it. Otherwise timer is created and not started.
+* For timer to work one have to first start it. Otherwise, timer is created and not started.
* After creating `GuiTimer` one can `connect` it to `gui::Item` related element with `Application::connect(GuiTimer &&, gui::Item*)` so that timer life-cycle would be same as Item referenced
## Bus
-Bus subsystem was developed in order for services to be able to communicate with each other. Bus consists of four main methods:
+
+**WARNING:** Please mind that safe usage of the bus is available after `InitHandler()` was called
+
+Bus subsystem was developed in order to allow cross-services communication.
+Bus consists of four main methods:
#### `bool SendUnicast(std::shared_ptr<Message> msg,const std::string& service,Service* s)`
Non-blocking variant of sending messages to specified service.
`Service* s` is pointer to API caller.
@@ 92,7 119,7 @@ Send message to all active service except the caller.
M.P: This section is incomplete mainly due to not having enough info about implementation.
As far as I know workers were created as abstraction over FreeRTOS threads and are designed to tightly cooperate with services.
-By design their lifecycle is controlled by services hence this relationship is a little bit similar to process(service)-thread(worker) except
+By design their lifecycle is controlled by services hence this relationship is a little similar to process(service)-thread(worker) except
that workers don't share memory/resources with parent service. They are also separate units of processing as they don't know anything about each other.
From my understanding they are mostly used as a mean of unloading services from doing cpu-intensive work which could block service's `DataReceivedHandler` for too long.
@@ 107,7 134,7 @@ There are three main assumptions:
Most information about design and implementation can be found in [AND_0011_PowerManager](https://docs.google.com/document/d/1G1HUFEPGblu3_VDrDdwF1nVqKwMz6sz1nGOgMEmhJgs/edit#heading=h.gm0is2hpfho6).
-Additionally current implementation of PowerManager(it should be considered as first iteration of development and absolutely it cannot be treated as final solution) is very simple but it proved to be working and it fulfilled current requirements.
+Additionally, the current implementation of PowerManager(it should be considered as the first iteration of development, and absolutely it cannot be treated as a final solution) is very simple, but it proved to be working, and it fulfilled current requirements.
For the time being PowerManager class exposes two methods which are internally used by SystemManager:
#### `int32_t Switch(const Mode mode)`
This method allows for switching CPU to different modes which are listed below:
@@ 129,7 156,7 @@ and it absolutely doesn't correspond to low power idle mode from RT1051's data s
Actual code is implemented in `module-bsp/board/rt1051/bsp/lpm/RT1051LPM.cpp` and `module-bsp/board/rt1051/common/clock_config.cpp`.
-Research was done about using `Suspend` state and it resulted in several conclusions:
+The research was done regarding usage of the `Suspend` state, and it resulted in several conclusions:
* It is not possible to use it in MuditaOS
This is mostly due to software design where app code is executed from external SDRAM. It is almost impossible in current state of the system to
switch to suspend state and gracefully return to normal state when code is placed into SDRAM.
@@ 156,10 183,10 @@ PowerManager and system logic will have to be designed and developed.
#### Core voltage in low power mode
Currently core voltage during operating in low power mode is set to 0.9V. This results in 2,08mA current consumption. This can be lowered even further by lowering it to 0.8V ( resulting in current consumed at around 1.86mA).
-As far as I know setting core voltage to 0.8V is considered to be unstable but it is worth trying/testing.
+As far as I know setting core voltage to 0.8V is considered to be unstable, but it is worth trying/testing.
Core voltage is set in LPM_EnterLowPowerIdle function which can be found in module-bsp/board/rt1051/common/clock_config.cpp.
-For more info please check RT1051 Reference Manual, Chapter 18 "DCDC Converter" and DCDC Register 3 .
+For more info please check RT1051 Reference Manual, Chapter 18 "DCDC Converter" and DCDC Register 3.
# Caveats & good practices #
@@ 173,7 200,7 @@ Some time ago second parameter was added to DataReceivedHandler
`DataReceivedHandler(DataMessage* msg,ResponseMessage* resp)`
This addition was dictated by need of using non-blocking variant of `Bus::SendUnicast` which then can trigger receiving async
response. In this case second parameter is not nullptr used and should contain valid `ResponseMessage`, otherwise
-`ResponseMessage* resp` will be set to nullptr. Additionally by design there won't be the situation where both `DataMessage* msg`
+`ResponseMessage* resp` will be set to nullptr. Additionally, by design there won't be the situation where both `DataMessage* msg`
and `ResponseMessage* resp` are not nullptr. Users of services should be aware of that and always check if params are valid
before using them.
M module-utils/log/doc/logging_engine.md => module-utils/log/doc/logging_engine.md +8 -0
@@ 2,6 2,7 @@
- [Logger](#Logger)
- [Dumping to a file](#Dumping-to-a-file)
+- [System Logs](#System-logs)
## Logger
@@ 31,3 32,10 @@ Current max log file size is 50 MB (after reaching this size no more logs are du
Logs can be accessed using `mount_user_lfs_partition.py` script from `tools` directory.
Additionally, `test/get_os_log.py` script allows getting a log file from a running phone.
+
+## System logs
+
+There are a series of useful system logging capabilities defined in:
+`module-utils/log/api/log/debug.hpp`
+
+Please see doxygen documentation for each parameter.
M products/PurePhone/CMakeLists.txt => products/PurePhone/CMakeLists.txt +22 -13
@@ 48,18 48,19 @@ target_link_libraries(PurePhone
PRIVATE
app
$<$<BOOL:${ENABLE_APP_ANTENNA}>:application-antenna>
- application-calculator
- application-calendar
- application-call
- application-calllog
- application-desktop
- application-meditation
- application-messages
- application-music-player
- application-notes
- application-phonebook
- application-settings
- application-special-input
+ $<$<BOOL:${ENABLE_APP_CALCULATOR}>:application-calculator>
+ $<$<BOOL:${ENABLE_APP_CALENDAR}>:application-calendar>
+ $<$<BOOL:${ENABLE_APP_CALL}>:application-call>
+ $<$<BOOL:${ENABLE_APP_CALLLOG}>:application-calllog>
+ $<$<BOOL:${ENABLE_APP_DESKTOP}>:application-desktop>
+ $<$<BOOL:${ENABLE_APP_MEDITATION}>:application-meditation>
+ $<$<BOOL:${ENABLE_APP_MESSAGES}>:application-messages>
+ $<$<BOOL:${ENABLE_APP_MUSIC_PLAYER}>:application-music-player>
+ $<$<BOOL:${ENABLE_APP_NOTES}>:application-notes>
+ $<$<BOOL:${ENABLE_APP_PHONEBOOK}>:application-phonebook>
+ $<$<BOOL:${ENABLE_APP_SETTINGS}>:application-settings>
+ $<$<BOOL:${ENABLE_APP_SPECIAL_INPUT}>:application-special-input>
+ $<$<BOOL:${ENABLE_APP_ONBOARDING}>:application-onboarding>
pure::time
appmgr
db
@@ 76,6 77,7 @@ target_link_libraries(PurePhone
service-desktop
service-fileindexer
service-time
+ $<$<BOOL:${ENABLE_SERVICE_TEST}>:service-test>
sys
version-header
"$<$<STREQUAL:${PROJECT_TARGET},TARGET_Linux>:iosyscalls>"
@@ 86,7 88,14 @@ if (${PROJECT_TARGET} STREQUAL "TARGET_Linux")
add_dependencies(Pure service_renderer)
endif()
-set_source_files_properties(PurePhoneMain.cpp PROPERTIES COMPILE_DEFINITIONS "${ENABLED_APPS_DEFINES}")
+# set special main.cpp file properties
+set_property(
+ SOURCE PurePhoneMain.cpp
+ APPEND
+ PROPERTY COMPILE_DEFINITIONS
+ ${ENABLED_APPS_DEFINES}
+ ${ENABLED_SERVICES_DEFINES}
+)
strip_executable(PurePhone)
M products/PurePhone/PurePhoneMain.cpp => products/PurePhone/PurePhoneMain.cpp +59 -0
@@ 11,19 11,45 @@
#ifdef ENABLE_APP_ALARM_CLOCK
#include <application-alarm-clock/ApplicationAlarmClock.hpp>
#endif
+#ifdef ENABLE_APP_CALL
#include <application-call/ApplicationCall.hpp>
+#endif
+#ifdef ENABLE_APP_CALLLOG
#include <application-calllog/ApplicationCallLog.hpp>
+#endif
+#ifdef ENABLE_APP_DESKTOP
#include <application-desktop/ApplicationDesktop.hpp>
+#endif
+#ifdef ENABLE_APP_MESSAGES
#include <application-messages/ApplicationMessages.hpp>
+#endif
+#ifdef ENABLE_APP_NOTES
#include <application-notes/ApplicationNotes.hpp>
+#endif
+#ifdef ENABLE_APP_PHONEBOOK
#include <application-phonebook/ApplicationPhonebook.hpp>
+#endif
+#ifdef ENABLE_APP_SETTINGS
#include <application-settings/ApplicationSettings.hpp>
+#endif
+#ifdef ENABLE_APP_SPECIAL_INPUT
#include <application-special-input/ApplicationSpecialInput.hpp>
+#endif
+#ifdef ENABLE_APP_CALENDAR
#include <application-calendar/ApplicationCalendar.hpp>
+#endif
+#ifdef ENABLE_APP_MUSIC_PLAYER
#include <application-music-player/ApplicationMusicPlayer.hpp>
+#endif
+#ifdef ENABLE_APP_MEDITATION
#include <application-meditation/ApplicationMeditation.hpp>
+#endif
+#ifdef ENABLE_APP_CALCULATOR
#include <application-calculator/ApplicationCalculator.hpp>
+#endif
+#ifdef ENABLE_APP_ONBOARDING
#include <application-onboarding/ApplicationOnBoarding.hpp>
+#endif
// modules
#include <module-db/Databases/CountryCodesDB.hpp>
@@ 49,7 75,9 @@
#include <service-gui/ServiceGUI.hpp>
#include <service-gui/Common.hpp>
#include <module-services/service-eink/ServiceEink.hpp>
+#if ENABLE_SERVICE_FILEINDEXER
#include <service-fileindexer/ServiceFileIndexer.hpp>
+#endif
#include <service-desktop/ServiceDesktop.hpp>
#if ENABLE_GSM == 1
@@ 57,6 85,10 @@
#include <service-antenna/ServiceAntenna.hpp>
#endif
+#if ENABLE_SERVICE_TEST
+#include <service-test/ServiceTest.hpp>
+#endif
+
#include <Application.hpp>
#include <ApplicationLauncher.hpp>
#include <log/log.hpp>
@@ 118,22 150,49 @@ int main()
}
std::vector<std::unique_ptr<sys::BaseServiceCreator>> systemServices;
+#ifdef ENABLE_SERVICE_EVTMGR
systemServices.emplace_back(sys::CreatorFor<EventManager>([]() { return dumpLogs(); }));
+#endif
+#ifdef ENABLE_SERVICE_FILEINDEXER
systemServices.emplace_back(sys::CreatorFor<service::ServiceFileIndexer>(std::move(fileIndexerAudioPaths)));
+#endif
+#ifdef ENABLE_SERVICE_DB
systemServices.emplace_back(sys::CreatorFor<ServiceDB>());
+#endif
#if ENABLE_GSM == 0
// For now disable permanently Service cellular when there is no GSM configured
LOG_INFO("ServiceCellular (GSM) - Disabled");
#else
+
+#ifdef ENABLE_SERVICE_ANTENNA
systemServices.emplace_back(sys::CreatorFor<ServiceAntenna>());
+#endif
+#ifdef ENABLE_SERVICE_CELLULAR
systemServices.emplace_back(sys::CreatorFor<ServiceCellular>());
#endif
+#endif
+
+#ifdef ENABLE_SERVICE_AUDIO
systemServices.emplace_back(sys::CreatorFor<ServiceAudio>());
+#endif
+#ifdef ENABLE_SERVICE_BLUETOOTH
systemServices.emplace_back(sys::CreatorFor<ServiceBluetooth>());
+#endif
+#ifdef ENABLE_SERVICE_DESKTOP
systemServices.emplace_back(sys::CreatorFor<ServiceDesktop>());
+#endif
+#ifdef ENABLE_SERVICE_TIME
systemServices.emplace_back(sys::CreatorFor<stm::ServiceTime>(std::make_shared<alarms::AlarmOperationsFactory>()));
+#endif
+#ifdef ENABLE_SERVICE_EINK
systemServices.emplace_back(sys::CreatorFor<service::eink::ServiceEink>());
+#endif
+#ifdef ENABLE_SERVICE_GUI
systemServices.emplace_back(sys::CreatorFor<service::gui::ServiceGUI>());
+#endif
+#if ENABLE_SERVICE_TEST
+ systemServices.emplace_back(sys::CreatorFor<service::test::ServiceTest>());
+#endif
auto sysmgr = std::make_shared<sys::SystemManager>(std::move(systemServices));
sysmgr->StartSystem(
M products/PurePhone/services/appmgr/ApplicationManager.cpp => products/PurePhone/services/appmgr/ApplicationManager.cpp +1 -10
@@ 6,7 6,6 @@
#include <apps-common/popups/data/BluetoothModeParams.hpp>
#include <application-desktop/ApplicationDesktop.hpp>
#include <application-onboarding/ApplicationOnBoarding.hpp>
-#include <application-special-input/ApplicationSpecialInput.hpp>
#include <apps-common/popups/data/PhoneModeParams.hpp>
#include <apps-common/popups/data/PopupRequestParams.hpp>
#include <apps-common/actions/AlarmClockStatusChangeParams.hpp>
@@ 134,15 133,7 @@ namespace app::manager
void ApplicationManager::startBackgroundApplications()
{
- for (const auto &name : std::vector<ApplicationName>{app::special_input}) {
- if (auto app = getApplication(name); app != nullptr) {
- StatusIndicators statusIndicators;
- statusIndicators.phoneMode = phoneModeObserver->getCurrentPhoneMode();
- statusIndicators.bluetoothMode = bluetoothMode;
- statusIndicators.alarmClockStatus = alarmClockStatus;
- app->runInBackground(statusIndicators, this);
- }
- }
+ runAppsInBackground();
}
void ApplicationManager::registerMessageHandlers()
M products/PurePhone/services/appmgr/CMakeLists.txt => products/PurePhone/services/appmgr/CMakeLists.txt +2 -1
@@ 3,6 3,7 @@ add_library(appmgr STATIC)
target_sources(appmgr
PRIVATE
ApplicationManager.cpp
+ $<$<BOOL:${ENABLE_APP_SPECIAL_INPUT}>:RunAppsInBackground.cpp>
models/WallpaperDisplayModel.cpp
include/appmgr/models/WallpaperDisplayModel.hpp
PUBLIC
@@ 17,7 18,7 @@ target_include_directories(appmgr
target_link_libraries(appmgr
PRIVATE
application-desktop
- application-special-input
+ $<$<BOOL:${ENABLE_APP_SPECIAL_INPUT}>:application-special-input>
apps-common
module-apps
module-db
A products/PurePhone/services/appmgr/RunAppsInBackground.cpp => products/PurePhone/services/appmgr/RunAppsInBackground.cpp +22 -0
@@ 0,0 1,22 @@
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include <appmgr/ApplicationManager.hpp>
+#include <application-special-input/ApplicationSpecialInput.hpp>
+
+namespace app::manager
+{
+
+ void ApplicationManager::runAppsInBackground()
+ {
+ for (const auto &name : std::vector<ApplicationName>{app::special_input}) {
+ if (auto app = getApplication(name); app != nullptr) {
+ StatusIndicators statusIndicators;
+ statusIndicators.phoneMode = phoneModeObserver->getCurrentPhoneMode();
+ statusIndicators.bluetoothMode = bluetoothMode;
+ statusIndicators.alarmClockStatus = alarmClockStatus;
+ app->runInBackground(statusIndicators, this);
+ }
+ }
+ }
+} // namespace app::manager
M products/PurePhone/services/appmgr/include/appmgr/ApplicationManager.hpp => products/PurePhone/services/appmgr/include/appmgr/ApplicationManager.hpp +1 -0
@@ 50,6 50,7 @@ namespace app::manager
auto handlePhoneModeChangedAction(ActionEntry &action) -> ActionProcessStatus;
auto handleAction(ActionEntry &action) -> ActionProcessStatus override;
void handleStart(StartAllowedMessage *msg) override;
+ void runAppsInBackground();
std::shared_ptr<sys::phone_modes::Observer> phoneModeObserver;
sys::bluetooth::BluetoothMode bluetoothMode = sys::bluetooth::BluetoothMode::Disabled;
A test/AddingUnitTests.md => test/AddingUnitTests.md +65 -0
@@ 0,0 1,65 @@
+Adding unit tests
+=================
+
+# Preface
+
+We use either:
+- [catch2](./Catch2/README.md)
+- [google tests](./googletest/README.md)
+
+to write unit tests.
+
+You can add as many test targets as you wish.
+
+**IMPORTANT:** All tests are run on the CI on PR's automatically
+
+# How to use
+
+Unit tests are always in catalog `test` or `tests` and should be included with
+
+**NOTE:** see the one letter difference!
+
+```
+if (${ENABLE_TESTS})
+ add_subdirectory(test)
+endif ()
+```
+
+**NOTE:** To see how test gathering works please see: [CMake for UT](CMakeLists.txt)
+
+To add test target use either of functions:
+
+`add_catch2_executable` or `add_gtest_executable`
+
+Both take arguments:
+- `NAME` test name, it will be prefixed with `catch2_` or `googletest_`, depending on your suite choice
+- `SRCS` - sources for your unit tests
+- `INCLUDE` - include directories (`-I`) for your test
+- `LIBS` - libraries you depend on
+- `DEFS` - defines you want to pass to the test
+- `DEPS` - dependencies you want to pass to the test
+- `USE_FS` if this unit test uses FS wrapper - **please** enable only if you really can't create the test without it, adding dependency to FS is not a good practice
+
+# Simple example
+
+**NOTE:** I assume here that:
+- test catalog was created
+- test catalog was included properly
+If not - please read above!
+
+Examplary executable can be added by creating `test/CMakeLists.txt` like that:
+```
+add_catch2_executable(
+ NAME
+ service-my_awesome_test
+ SRCS
+ test-MyAwesomeTest.cpp
+ LIBS
+)
+```
+
+Which will create target:
+`catch2_service-my_awesome_test`
+
+This means you can build it and run with:
+`ninja catch2_service-my_awesome_test && catch2_service-my_awesome_test`
A third-party/ThirdParty.md => third-party/ThirdParty.md +53 -0
@@ 0,0 1,53 @@
+Third-party libraries
+=====================
+
+Third-party libraries which can be included in MuditaOS builds for each and every target
+
+# How to add 3rd-party target
+
+Please mind that we are using CMake library encapsulation technique where we:
+- create interface for the library in cmake
+- build the library with the interface
+- export only the required interface
+
+# Examples
+
+## header only library
+
+- we use `awesome-library` for library name in this example:
+- create folder for library
+- add CMakeLists.txt for library with, where header only lib is in `include` catalog i.e. under: `include/awseome-library/awesome-library.hpp`
+```
+add_library(awesome-library INTERFACE)
+add_library(awesome::library::alias ALIAS awesome-library)
+
+target_include_directories(awesome-library INTERFACE include/)
+```
+
+**NOTE:** You can check out how [sml-utils cmake](sml-utils/CMakeLists.txt) and catalogs are created
+
+## normal libraries
+
+Please note:
+- name `awesome-library` in use here.
+- we use `PRIVATE` in cmake sections while adding sources
+
+How to create the target depends on library, exemplary cmake example can look like that:
+
+```
+add_library(awesome-library)
+target_sources(awesome-library
+ PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/awesome-library.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/awesome-library.h
+)
+
+target_include_directories(awesome-library
+ PUBLIC
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
+)
+
+add_library(awesome::library ALIAS awesome-library)
+```
+
+Where in `src` there is `awesome-library/awesome-library.hpp` header