~aleteoryx/muditaos

ebcd1394123e70a3196ebdbbb4c1443960e8eb64 — Lefucjusz 2 years ago 3193f6f
[CP-1962] Add Harmony color detection

* Added serial number based Harmony color
detection.
* Unified serial number handling for both
products.
43 files changed, 387 insertions(+), 186 deletions(-)

M board/linux/crashdump-serial-number/crashdump_serial_number.cpp
M board/linux/crashdump-serial-number/include/crashdump-serial-number/crashdump_serial_number.hpp
M board/rt1051/crashdump-serial-number/crashdump_serial_number.cpp
M board/rt1051/crashdump-serial-number/include/crashdump-serial-number/crashdump_serial_number.hpp
M harmony_changelog.md
M image/system_a/data/lang/Deutsch.json
M image/system_a/data/lang/English.json
M image/system_a/data/lang/Espanol.json
M image/system_a/data/lang/Francais.json
M image/system_a/data/lang/Polski.json
M module-services/service-db/CMakeLists.txt
M module-services/service-db/agents/settings/FactorySettings.hpp
M module-services/service-db/agents/settings/SettingsAgent.cpp
M module-services/service-db/agents/settings/SettingsAgent.hpp
M module-services/service-db/test/CMakeLists.txt
M module-services/service-db/test/test-factory-settings.cpp
M module-services/service-desktop/DeviceColour.cpp
M module-services/service-desktop/ServiceDesktop.cpp
M module-services/service-desktop/WorkerDesktop.cpp
M module-services/service-desktop/include/service-desktop/DeviceColour.hpp
M module-vfs/src/purefs/fs/filesystem_syscalls.cpp
M products/BellHybrid/CMakeLists.txt
M products/BellHybrid/apps/application-bell-settings/ApplicationBellSettings.cpp
M products/BellHybrid/apps/application-bell-settings/CMakeLists.txt
M products/BellHybrid/apps/application-bell-settings/models/AboutYourBellModel.cpp
M products/BellHybrid/apps/application-bell-settings/models/AboutYourBellModel.hpp
R products/BellHybrid/{serial-number-reader => serial-number-parser}/CMakeLists.txt
A products/BellHybrid/serial-number-parser/SerialNumberParser.cpp
R products/BellHybrid/{serial-number-reader/include/serial-number-reader/SerialNumberReader => serial-number-parser/include/serial-number-parser/SerialNumberParser}.hpp
D products/BellHybrid/serial-number-reader/SerialNumberReader.cpp
A products/BellHybrid/services/db/BellFactorySettings.cpp
M products/BellHybrid/services/db/CMakeLists.txt
M products/BellHybrid/services/db/ServiceDB.cpp
A products/BellHybrid/services/db/include/db/BellFactorySettings.hpp
M products/BellHybrid/services/desktop/endpoints/CMakeLists.txt
M products/BellHybrid/services/desktop/endpoints/deviceInfo/DeviceInfoEndpoint.cpp
M products/BellHybrid/services/desktop/endpoints/include/endpoints/deviceInfo/DeviceInfoEndpoint.hpp
M products/PurePhone/services/db/CMakeLists.txt
R {module-services/service-db/agents/settings/FactorySettings => products/PurePhone/services/db/PureFactorySettings}.cpp
M products/PurePhone/services/db/ServiceDB.cpp
A products/PurePhone/services/db/include/db/PureFactorySettings.hpp
M products/PurePhone/services/db/include/db/ServiceDB.hpp
M products/PurePhone/services/desktop/endpoints/deviceInfo/DeviceInfoEndpoint.cpp
M board/linux/crashdump-serial-number/crashdump_serial_number.cpp => board/linux/crashdump-serial-number/crashdump_serial_number.cpp +12 -4
@@ 5,11 5,19 @@

namespace crashdump
{
    void setSerialNumber(const std::string &)
    {}
    std::string getSerialNumber()
    namespace
    {
        return "";
        std::string serialNumber{};
    }

    void setSerialNumber(const std::string &sn)
    {
        serialNumber = sn;
    }

    const std::string &getSerialNumber()
    {
        return serialNumber;
    }

} // namespace crashdump

M board/linux/crashdump-serial-number/include/crashdump-serial-number/crashdump_serial_number.hpp => board/linux/crashdump-serial-number/include/crashdump-serial-number/crashdump_serial_number.hpp +3 -2
@@ 4,10 4,11 @@
// Dummy file to keep linux variant compiling.

#pragma once

#include <string>

namespace crashdump
{
    void setSerialNumber(const std::string &sn);
    std::string getSerialNumber();

    const std::string &getSerialNumber();
} // namespace crashdump

M board/rt1051/crashdump-serial-number/crashdump_serial_number.cpp => board/rt1051/crashdump-serial-number/crashdump_serial_number.cpp +9 -8
@@ 3,19 3,20 @@

#include <crashdump-serial-number/crashdump_serial_number.hpp>

namespace
{
    std::string serial_number = "0000000000000";
}
namespace crashdump
{
    void setSerialNumber(const std::string &sn)
    namespace
    {
        serial_number = sn;
        std::string serialNumber{};
    }
    std::string getSerialNumber()

    void setSerialNumber(const std::string &sn)
    {
        return serial_number;
        serialNumber = sn;
    }

    const std::string &getSerialNumber()
    {
        return serialNumber;
    }
} // namespace crashdump

M board/rt1051/crashdump-serial-number/include/crashdump-serial-number/crashdump_serial_number.hpp => board/rt1051/crashdump-serial-number/include/crashdump-serial-number/crashdump_serial_number.hpp +3 -2
@@ 8,10 8,11 @@
// getSerialNumber() is called by the crash dump writer during file creation.

#pragma once

#include <string>

namespace crashdump
{
    void setSerialNumber(const std::string &sn);
    std::string getSerialNumber();

    const std::string &getSerialNumber();
} // namespace crashdump

M harmony_changelog.md => harmony_changelog.md +1 -0
@@ 26,6 26,7 @@
* Added error message when files limit is exceeded in Relaxation app
* Added label informing about PC connection.
* Added serial number to About section
* Added possibility to detect device's case colour

### Changed / Improved


M image/system_a/data/lang/Deutsch.json => image/system_a/data/lang/Deutsch.json +1 -0
@@ 61,6 61,7 @@
    "app_bell_relaxation_timer_title": "Timer",
    "app_bell_settings_about": "Information",
    "app_bell_settings_about_info_text": "www.mudita.com",
    "app_bell_settings_about_serial_number": "Seriennummer",
    "app_bell_settings_about_info_title": "Handbuch & Zertifikat-Info",
    "app_bell_settings_about_product": "Mudita Harmony",
    "app_bell_settings_about_storage_text": "<text>Verbraucht <token>$USED_MEMORY</token>MB von <token>$TOTAL_MEMORY</token>MB</text>",

M image/system_a/data/lang/English.json => image/system_a/data/lang/English.json +1 -0
@@ 95,6 95,7 @@
    "app_bell_reset_message": "<text>Resetting Mudita<br />Harmony</text>",
    "app_bell_settings_about": "About",
    "app_bell_settings_about_info_text": "www.mudita.com",
    "app_bell_settings_about_serial_number": "Serial number",
    "app_bell_settings_about_info_title": "Manual & certification info",
    "app_bell_settings_about_product": "Mudita Harmony",
    "app_bell_settings_about_storage_text": "<text><token>$USED_MEMORY</token>MB of <token>$TOTAL_MEMORY</token>MB used</text>",

M image/system_a/data/lang/Espanol.json => image/system_a/data/lang/Espanol.json +1 -0
@@ 60,6 60,7 @@
    "app_bell_relaxation_timer_title": "Temporizador",
    "app_bell_settings_about": "Informaci\u00f3n",
    "app_bell_settings_about_info_text": "www.mudita.com",
    "app_bell_settings_about_serial_number": "Número de serie",
    "app_bell_settings_about_info_title": "Manual y certificaci\u00f3n",
    "app_bell_settings_about_product": "Mudita Harmony",
    "app_bell_settings_about_storage_text": "<text>Usados <token>$USED_MEMORY</token>MB de <token>$TOTAL_MEMORY</token>MB</text>",

M image/system_a/data/lang/Francais.json => image/system_a/data/lang/Francais.json +1 -0
@@ 62,6 62,7 @@
    "app_bell_relaxation_timer_title": "Minuterie",
    "app_bell_settings_about": "\u00c0 propos",
    "app_bell_settings_about_info_text": "www.mudita.com",
    "app_bell_settings_about_serial_number": "Numéro de série",
    "app_bell_settings_about_info_title": "Manuel et certification",
    "app_bell_settings_about_product": "Mudita Harmony",
    "app_bell_settings_about_storage_text": "<text><token>$USED_MEMORY</token> Mo sur <token>$TOTAL_MEMORY</token> Mo utilis\u00e9s</text>",

M image/system_a/data/lang/Polski.json => image/system_a/data/lang/Polski.json +1 -0
@@ 61,6 61,7 @@
    "app_bell_relaxation_timer_title": "Wy\u0142\u0105cznik czasowy",
    "app_bell_settings_about": "O produkcie",
    "app_bell_settings_about_info_text": "www.mudita.com",
    "app_bell_settings_about_serial_number": "Numer seryjny",
    "app_bell_settings_about_info_title": "Instrukcja i informacje dot. certyfikacji",
    "app_bell_settings_about_product": "Mudita Harmony",
    "app_bell_settings_about_storage_text": "<text>Zu\u017cyto <token>$USED_MEMORY</token>MB z <token>$TOTAL_MEMORY</token>MB</text>",

M module-services/service-db/CMakeLists.txt => module-services/service-db/CMakeLists.txt +0 -1
@@ 17,7 17,6 @@ set(SOURCES
    agents/settings/Settings.cpp
    agents/settings/SettingsProxy.cpp
    agents/settings/SettingsCache.cpp
    agents/settings/FactorySettings.cpp
    agents/quotes/QuotesAgent.cpp
    agents/quotes/RandomizedQuoteModel.cpp
    agents/quotes/QuotesSettingsSerializer.cpp

M module-services/service-db/agents/settings/FactorySettings.hpp => module-services/service-db/agents/settings/FactorySettings.hpp +7 -18
@@ 1,35 1,24 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <Database/Database.hpp>
#include <purefs/filesystem_paths.hpp>
#include <json11.hpp>
#include <fstream>
#include "Settings_queries.hpp"

namespace settings
{
    namespace factory
    {
        constexpr auto entry_key = "factory_data";
        static constexpr auto entry_key         = "factory_data";
        static constexpr auto serial_number_key = "serial";
        static constexpr auto case_colour_key   = "case_colour";
    }

    class FactorySettings
    {
      public:
        FactorySettings(std::string path) : filePath(path)
        {}

        [[nodiscard]] std::unique_ptr<QueryResult> getMfgEntries();
        void initDb(Database *database);

      private:
        json11::Json readMfgSettings(const std::string &path);
        std::string readFileContent(const std::string &filename) const noexcept;

        std::string filePath;
        virtual ~FactorySettings()                                                       = default;
        [[nodiscard]] virtual auto getMfgEntries() const -> std::unique_ptr<QueryResult> = 0;
        virtual auto initDb(Database *database) const -> void                            = 0;
    };

} // namespace settings

M module-services/service-db/agents/settings/SettingsAgent.cpp => module-services/service-db/agents/settings/SettingsAgent.cpp +8 -14
@@ 1,8 1,9 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "SettingsAgent.hpp"
#include "Settings_queries.hpp"
#include "FactorySettings.hpp"

#include <Database/Database.hpp>
#include <Service/Service.hpp>


@@ 10,18 11,11 @@
#include <service-db/SettingsCache.hpp>
#include <log/log.hpp>

namespace settings
{
    namespace factory
    {
        constexpr auto data_file         = "personalization.json";
        const std::filesystem::path path = purefs::dir::getMfgConfPath() / data_file;
    } // namespace factory

} // namespace settings

SettingsAgent::SettingsAgent(sys::Service *parentService, const std::string dbName, settings::SettingsCache *cache)
    : DatabaseAgent(parentService), cache(cache), factorySettings(settings::factory::path), dbName{dbName}
SettingsAgent::SettingsAgent(sys::Service *parentService,
                             const std::string &dbName,
                             settings::FactorySettings *factorySettings,
                             settings::SettingsCache *cache)
    : DatabaseAgent(parentService), cache(cache), dbName{dbName}
{
    if (nullptr == cache) {
        this->cache = settings::SettingsCache::getInstance();


@@ 29,7 23,7 @@ SettingsAgent::SettingsAgent(sys::Service *parentService, const std::string dbNa

    database = std::make_unique<Database>((purefs::dir::getDatabasesPath() / dbName).c_str());

    factorySettings.initDb(database.get());
    factorySettings->initDb(database.get());

    // first approach -> take care about big amount of variables
    auto allVars = database->query(settings::Statements::getAllValues);

M module-services/service-db/agents/settings/SettingsAgent.hpp => module-services/service-db/agents/settings/SettingsAgent.hpp +7 -4
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 18,6 18,7 @@ namespace settings
    struct EntryPath;
    class SettingsCache;
} // namespace settings

namespace sys
{
    class Service;


@@ 26,7 27,10 @@ namespace sys
class SettingsAgent : public DatabaseAgent
{
  public:
    SettingsAgent(sys::Service *parentService, std::string dbName, settings::SettingsCache *cache = nullptr);
    SettingsAgent(sys::Service *parentService,
                  const std::string &dbName,
                  settings::FactorySettings *factorySettings,
                  settings::SettingsCache *cache = nullptr);
    ~SettingsAgent() = default;

    void registerMessages() override;


@@ 34,8 38,7 @@ class SettingsAgent : public DatabaseAgent
    auto getAgentName() -> const std::string override;

  private:
    settings::SettingsCache *cache;
    settings::FactorySettings factorySettings;
    settings::SettingsCache *cache = nullptr;

    using MapOfRecipentsToBeNotified = std::map<std::string, std::set<settings::EntryPath>>;
    MapOfRecipentsToBeNotified variableChangeRecipients;

M module-services/service-db/test/CMakeLists.txt => module-services/service-db/test/CMakeLists.txt +3 -0
@@ 7,6 7,7 @@ add_catch2_executable(
            test-service-db-settings-messages.cpp
            test-service-db-quotes.cpp
            test-factory-settings.cpp
            ${CMAKE_SOURCE_DIR}/products/PurePhone/services/db/PureFactorySettings.cpp
        LIBS
            module-db::test::helpers
            module-audio


@@ 16,6 17,8 @@ add_catch2_executable(
            module-vfs
            service-audio
            service-cellular
        INCLUDE
            ${CMAKE_SOURCE_DIR}/products/PurePhone/services/db/include/
)

add_catch2_executable(

M module-services/service-db/test/test-factory-settings.cpp => module-services/service-db/test/test-factory-settings.cpp +8 -7
@@ 1,18 1,19 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <catch2/catch.hpp>
#include <Helpers.hpp>
#include <service-db/agents/settings/FactorySettings.hpp>
#include <service-db/EntryPath.hpp>
#include <db/PureFactorySettings.hpp>
#include <service-db/agents/settings/Settings_queries.hpp>

const std::string valid_json   = "{\"serial\" : \"00000000000000\", \"case_colour\" : \"nocase\"}";
const std::string invalid_json = "{\"serial\" : \"00000000000000\", \"case_colour\" : \"nocase\"}}";

constexpr auto schema = "CREATE TABLE IF NOT EXISTS settings_tab ( path TEXT NOT NULL UNIQUE PRIMARY KEY,value TEXT);";

const auto valid_path   = "valid.json";
const auto invalid_path = "invalid.json";
constexpr auto valid_path   = "valid.json";
constexpr auto invalid_path = "invalid.json";

namespace
{


@@ 35,7 36,7 @@ TEST_CASE("Factory Settings")
    {
        spawnAndFillFile(valid_path, valid_json);

        settings::FactorySettings factory{valid_path};
        settings::PureFactorySettings factory{valid_path};
        auto entries = factory.getMfgEntries();
        REQUIRE(entries->getRowCount() == 2);
        REQUIRE(entries->getFieldCount() == 2);


@@ 47,7 48,7 @@ TEST_CASE("Factory Settings")
    {
        spawnAndFillFile(invalid_path, invalid_json);

        settings::FactorySettings factory{invalid_path};
        settings::PureFactorySettings factory{invalid_path};
        auto entries = factory.getMfgEntries();
        REQUIRE(entries->getRowCount() == 0);
    }


@@ 62,7 63,7 @@ TEST_CASE("Factory Settings Init")
    {
        spawnAndFillFile(valid_path, valid_json);

        settings::FactorySettings factory{valid_path};
        settings::PureFactorySettings factory{valid_path};
        factory.initDb(&db.get());

        settings::EntryPath variablePath{

M module-services/service-desktop/DeviceColour.cpp => module-services/service-desktop/DeviceColour.cpp +5 -6
@@ 1,15 1,14 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <service-desktop/DeviceColour.hpp>
#include <map>
#include <cstdio>

namespace
{
    constexpr auto NONE = "none";
    constexpr auto UNKNOWN = "unknown";
    const std::map<std::string, std::uint16_t> colour_to_version_map{
        {NONE, 0x0111}, {"black", 0x0112}, {"gray", 0x0113}};

        {UNKNOWN, 0x0111}, {"black", 0x0112}, {"gray", 0x0113}};
} // namespace

namespace device_colour


@@ 18,7 17,7 @@ namespace device_colour
    {
        auto it = colour_to_version_map.find(colour);
        if (it == colour_to_version_map.end()) {
            return colour_to_version_map.at(NONE);
            return colour_to_version_map.at(UNKNOWN);
        }
        return colour_to_version_map.at(colour);
    }

M module-services/service-desktop/ServiceDesktop.cpp => module-services/service-desktop/ServiceDesktop.cpp +7 -8
@@ 109,7 109,7 @@ auto ServiceDesktop::requestLogsFlush() -> void
        if ((responseMsg != nullptr) && responseMsg->retCode) {
            response = responseMsg->data;

            LOG_DEBUG("Respone data: %d", response);
            LOG_DEBUG("Response data: %d", response);
        }
    }
    if (ret.first == sys::ReturnCodes::Failure || response < 0) {


@@ 172,10 172,10 @@ auto ServiceDesktop::usbWorkerInit() -> sys::ReturnCodes
    if (initialized) {
        return sys::ReturnCodes::Success;
    }

    auto serialNumber = getSerialNumber();
    auto caseColour   = getCaseColour();
    LOG_DEBUG("usbWorkerInit Serial Number: %s, Case Colour: %s", serialNumber.c_str(), caseColour.c_str());

    LOG_DEBUG("Initializing USB worker, serial number: %s, case colour: %s", serialNumber.c_str(), caseColour.c_str());

    desktopWorker = std::make_unique<WorkerDesktop>(this,
                                                    std::bind(&ServiceDesktop::restartConnectionActiveTimer, this),


@@ 191,13 191,12 @@ auto ServiceDesktop::usbWorkerInit() -> sys::ReturnCodes
         {sdesktop::SIGNALLING_QUEUE_BUFFER_NAME, sizeof(WorkerDesktop::Signal), sdesktop::signallingQueueLength}});

    if (!initialized) {
        LOG_ERROR("!!! service-desktop usbWorkerInit failed to initialize worker, service-desktop won't work");
        LOG_FATAL("Failed to initialize USB worker, ServiceDesktop won't work!");
        return sys::ReturnCodes::Failure;
    }
    else {
        desktopWorker->run();
        return sys::ReturnCodes::Success;
    }

    desktopWorker->run();
    return sys::ReturnCodes::Success;
}

auto ServiceDesktop::usbWorkerDeinit() -> sys::ReturnCodes

M module-services/service-desktop/WorkerDesktop.cpp => module-services/service-desktop/WorkerDesktop.cpp +0 -4
@@ 8,7 8,6 @@
#include <service-desktop/DesktopMessages.hpp>
#include <endpoints/message/Sender.hpp>
#include <MessageHandler.hpp>
#include "Timers/TimerFactory.hpp"

#include <bsp/usb/usb.hpp>
#include <log/log.hpp>


@@ 16,11 15,8 @@

#include <utility>
#include <vector>
#include <filesystem>
#include "system/messages/SentinelRegistrationMessage.hpp"

inline constexpr auto uploadFailedMessage = "file upload terminated before all data transferred";

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

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

#pragma once


@@ 8,5 8,4 @@
namespace device_colour
{
    std::uint16_t getColourVersion(const std::string &colour);

} // namespace device_colour

M module-vfs/src/purefs/fs/filesystem_syscalls.cpp => module-vfs/src/purefs/fs/filesystem_syscalls.cpp +2 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <purefs/fs/filesystem.hpp>
#include <errno.h>


@@ 153,7 153,7 @@ namespace purefs::fs
        const auto abspath     = absolute_path(path);
        auto [mountp, pathpos] = find_mount_point(abspath);
        if (!mountp) {
            LOG_ERROR("VFS: Unable to find specified mount point");
            LOG_ERROR("VFS: Unable to find specified mount point '%s'", abspath.c_str());
            return -ENOENT;
        }
        auto fsops = mountp->fs_ops();

M products/BellHybrid/CMakeLists.txt => products/BellHybrid/CMakeLists.txt +1 -1
@@ 170,7 170,7 @@ add_subdirectory(apps)
add_subdirectory(keymap)
add_subdirectory(services)
add_subdirectory(sys)
add_subdirectory(serial-number-reader)
add_subdirectory(serial-number-parser)
add_subdirectory(paths)

option(CONFIG_ENABLE_TEMP "Enable displaying temperature" OFF)

M products/BellHybrid/apps/application-bell-settings/ApplicationBellSettings.cpp => products/BellHybrid/apps/application-bell-settings/ApplicationBellSettings.cpp +1 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "ApplicationBellSettings.hpp"

M products/BellHybrid/apps/application-bell-settings/CMakeLists.txt => products/BellHybrid/apps/application-bell-settings/CMakeLists.txt +0 -1
@@ 127,7 127,6 @@ target_link_libraries(application-bell-settings
        bell::appmgr
        service-appmgr
        apps-common
        serial-number-reader
    PUBLIC
        module-gui
        bell::app-common

M products/BellHybrid/apps/application-bell-settings/models/AboutYourBellModel.cpp => products/BellHybrid/apps/application-bell-settings/models/AboutYourBellModel.cpp +19 -11
@@ 7,16 7,21 @@
#include <widgets/AboutYourBellListItem.hpp>
#include <ProductConfig.hpp>

#include <serial-number-reader/SerialNumberReader.hpp>
#include <ListView.hpp>
#include <product/version.hpp>
#include <purefs/filesystem_paths.hpp>
#include <sys/statvfs.h>

namespace
{
    constexpr auto factoryDataSerialPath = "factory_data/serial";
}

namespace app::bell_settings
{
    AboutYourBellModel::AboutYourBellModel(app::ApplicationCommon *app) : application(app)
    AboutYourBellModel::AboutYourBellModel(app::ApplicationCommon *app)
    {
        settings.init(service::ServiceProxy{app->weak_from_this()});
        createData();
    }



@@ 30,7 35,7 @@ namespace app::bell_settings
        return gui::bell_settings_style::about_your_bell_window::height;
    }

    void AboutYourBellModel::requestRecords(const uint32_t offset, const uint32_t limit)
    void AboutYourBellModel::requestRecords(std::uint32_t offset, std::uint32_t limit)
    {
        setupModel(offset, limit);
        list->onProviderDataUpdate();


@@ 48,24 53,27 @@ namespace app::bell_settings
                                           utils::translate("app_bell_settings_about_version"),
                                           gui::AboutYourBellListItem::TokenMap({{"$VERSION", std::string(VERSION)}})));

        internalData.push_back(new gui::AboutYourBellListItem(utils::translate("app_settings_tech_info_serial_number"),
                                                              serial_number_reader::readSerialNumber()));
        internalData.push_back(
            new gui::AboutYourBellListItem(utils::translate("app_bell_settings_about_serial_number"),
                                           settings.getValue(factoryDataSerialPath, settings::SettingsScope::Global)));

#if CONFIG_SHOW_MEMORY_INFO == 1
        struct statvfs stat;
        const auto result = statvfs(purefs::dir::getRootDiskPath().c_str(), &stat);
        struct statvfs stat
        {};
        const auto result = statvfs(purefs::dir::getUserDiskPath().c_str(), &stat);
        if (result < 0) {
            LOG_ERROR("Getting memory info failed! result = %d", result);
            LOG_ERROR("Getting memory info failed, error: %d!", result);
            return;
        }

        const auto totalMB = (stat.f_frsize * stat.f_blocks) / 1024LLU / 1024LLU;
        const auto usedMB  = totalMB - (stat.f_bfree * stat.f_bsize) / 1024LLU / 1024LLU;
        constexpr auto bytesInMebibyte = 1024LLU * 1024LLU;
        const auto totalMiB            = (stat.f_frsize * stat.f_blocks) / bytesInMebibyte;
        const auto usedMiB             = totalMiB - (stat.f_bfree * stat.f_bsize) / bytesInMebibyte;
        internalData.push_back(new gui::AboutYourBellListItem(
            utils::translate("app_bell_settings_about_storage_title"),
            utils::translate("app_bell_settings_about_storage_text"),
            gui::AboutYourBellListItem::TokenMap(
                {{"$USED_MEMORY", std::to_string(usedMB)}, {"$TOTAL_MEMORY", std::to_string(totalMB)}})));
                {{"$USED_MEMORY", std::to_string(usedMiB)}, {"$TOTAL_MEMORY", std::to_string(totalMiB)}})));
#endif

        internalData.push_back(new gui::AboutYourBellListItem(utils::translate("app_bell_settings_about_info_title"),

M products/BellHybrid/apps/application-bell-settings/models/AboutYourBellModel.hpp => products/BellHybrid/apps/application-bell-settings/models/AboutYourBellModel.hpp +3 -3
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 20,9 20,9 @@ namespace app::bell_settings
        [[nodiscard]] auto requestRecordsCount() -> unsigned int override;
        [[nodiscard]] auto getMinimalItemSpaceRequired() const -> unsigned int override;
        auto getItem(gui::Order order) -> gui::ListItem * override;
        void requestRecords(const uint32_t offset, const uint32_t limit) override;
        void requestRecords(std::uint32_t offset, std::uint32_t limit) override;

      private:
        app::ApplicationCommon *application{};
        settings::Settings settings;
    };
} // namespace app::bell_settings

R products/BellHybrid/serial-number-reader/CMakeLists.txt => products/BellHybrid/serial-number-parser/CMakeLists.txt +5 -5
@@ 1,17 1,17 @@
add_library(serial-number-reader STATIC)
add_library(serial-number-parser STATIC)


target_sources(serial-number-reader
target_sources(serial-number-parser
    PUBLIC
        SerialNumberReader.cpp
        SerialNumberParser.cpp
)

target_include_directories(serial-number-reader
target_include_directories(serial-number-parser
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
)

target_link_libraries(serial-number-reader
target_link_libraries(serial-number-parser
    PRIVATE
    module-vfs
)

A products/BellHybrid/serial-number-parser/SerialNumberParser.cpp => products/BellHybrid/serial-number-parser/SerialNumberParser.cpp +118 -0
@@ 0,0 1,118 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <serial-number-parser/SerialNumberParser.hpp>
#include <purefs/vfs_subsystem.hpp>
#include <Utils.hpp>
#include <cstring>

/*
 * Old SN is in MMYYWWNNNNNNN form, where:
 * MM - model code, 04 for Harmony;
 * YY - production year;
 * WW - production week;
 * NNNNNNN - unique device number, defined per batch.
 *
 * ID string is a substring consisting of first 6 SN digits.
 *
 *
 * New SN is in MMRRCYYWWNNNN form, where:
 * MM - model code, 04 for Harmony;
 * RR - hardware revision, P1, P2, P3...;
 * C - case colour; G = gray, B = black;
 * YY - production year;
 * WW - production week;
 * NNNN - unique device number, defined per batch.
 *
 */

namespace serial_number_parser
{
    namespace
    {
        /* Block device constants */
        constexpr auto blkdevName  = "emmc0sys1";
        constexpr auto blockSize   = 512;
        constexpr auto blockToRead = 2;
        constexpr auto blocksCount = 1;

        /* Common constants */
        constexpr auto serialNumberOffset  = 0;
        constexpr auto serialNumberLength  = 13;
        constexpr auto unknownSerialNumber = "0000000000000";
        constexpr auto unknownColour       = "unknown";

        /* Old serial number constants */
        constexpr auto idStringOffset = 0;
        constexpr auto idStringLength = 6;

        /* ID string to colour map for already released batches */
        const std::map<std::string, std::string> idStringToColourMap{
            {"042148", "gray"}, {"042213", "gray"}, {"042242", "black"}};

        /* New serial number constants */
        constexpr auto colourCodeOffset = 4;
        const std::map<char, std::string> colourCodeToColourMap{{'G', "gray"}, {'B', "black"}};

        bool isOldSerialNumberFormat(const std::string &serialNumber)
        {
            return (serialNumber.find_first_not_of("0123456789") == std::string::npos);
        }

        std::string readSerialNumber()
        {
            char block[blockSize];

            const auto diskManager = purefs::subsystem::disk_mgr();
            if (diskManager == nullptr) {
                return "";
            }

            const auto status = diskManager->read(blkdevName, block, blockToRead, blocksCount);
            if (status != 0) {
                return "";
            }

            return std::string(&block[serialNumberOffset], serialNumberLength);
        }

        std::string getDeviceColour(const std::string &serialNumber)
        {
            if (isOldSerialNumberFormat(serialNumber)) {
                LOG_INFO("Device has old serial number format");
                const auto idString = serialNumber.substr(idStringOffset, idStringLength);
                const auto item     = idStringToColourMap.find(idString);
                if (item == idStringToColourMap.end()) {
                    return "";
                }
                return item->second;
            }
            else {
                LOG_INFO("Device has new serial number format");
                const auto colourCode = serialNumber[colourCodeOffset];
                const auto item       = colourCodeToColourMap.find(colourCode);
                if (item == colourCodeToColourMap.end()) {
                    return "";
                }
                return item->second;
            }
        }
    } // namespace

    std::pair<std::string, std::string> getDeviceMetadata()
    {
        const auto serialNumber = readSerialNumber();
        if (serialNumber.empty()) {
            LOG_ERROR("Error reading serial number from eMMC!");
            return {unknownSerialNumber, unknownColour};
        }

        const auto deviceColour = getDeviceColour(serialNumber);
        if (deviceColour.empty()) {
            LOG_ERROR("Failed to read colour for device with serial number '%s'!", serialNumber.c_str());
            return {serialNumber, unknownColour};
        }

        return {serialNumber, deviceColour};
    }
} // namespace serial_number_parser

R products/BellHybrid/serial-number-reader/include/serial-number-reader/SerialNumberReader.hpp => products/BellHybrid/serial-number-parser/include/serial-number-parser/SerialNumberParser.hpp +3 -3
@@ 4,7 4,7 @@
#pragma once
#include <string>

namespace serial_number_reader
namespace serial_number_parser
{
    const std::string &readSerialNumber();
} // namespace serial_number_reader
    std::pair<std::string, std::string> getDeviceMetadata();
} // namespace serial_number_parser

D products/BellHybrid/serial-number-reader/SerialNumberReader.cpp => products/BellHybrid/serial-number-reader/SerialNumberReader.cpp +0 -33
@@ 1,33 0,0 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <purefs/vfs_subsystem.hpp>

#include <serial-number-reader/SerialNumberReader.hpp>
#include <log/log.hpp>

namespace
{
    constexpr auto DEVICE_NAME      = "emmc0sys1";
    constexpr auto EMMC_SN_LENGTH   = 13;
    constexpr auto EMMC_BUFFER_SIZE = 512;
    constexpr auto SECTOR_TO_READ   = 2;
    constexpr auto SECTOR_COUNT     = 1U;

    std::string readSerialNumberFromEmmc()
    {
        char buffer[EMMC_BUFFER_SIZE];
        purefs::subsystem::disk_mgr()->read(DEVICE_NAME, buffer, SECTOR_TO_READ, SECTOR_COUNT);
        buffer[EMMC_SN_LENGTH] = '\0';
        return std::string(buffer);
    }

} // namespace
namespace serial_number_reader
{
    const std::string &readSerialNumber()
    {
        const static std::string serialNumber = readSerialNumberFromEmmc();
        return serialNumber;
    }
} // namespace serial_number_reader

A products/BellHybrid/services/db/BellFactorySettings.cpp => products/BellHybrid/services/db/BellFactorySettings.cpp +47 -0
@@ 0,0 1,47 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <db/BellFactorySettings.hpp>
#include <log/log.hpp>
#include <service-db/SettingsMessages.hpp>
#include <service-db/agents/settings/Settings_queries.hpp>
#include <serial-number-parser/SerialNumberParser.hpp>

namespace settings
{
    auto BellFactorySettings::getMfgEntries() const -> std::unique_ptr<QueryResult>
    {
        const auto [serialNumber, colour] = serial_number_parser::getDeviceMetadata();
        auto factoryData                  = std::make_unique<QueryResult>();

        factoryData->addRow({Field(factory::serial_number_key), Field(serialNumber.c_str())});
        factoryData->addRow({Field(factory::case_colour_key), Field(colour.c_str())});

        return factoryData;
    }

    auto BellFactorySettings::initDb(Database *database) const -> void
    {
        const auto factoryData = getMfgEntries();

        if (factoryData->getRowCount() <= 0) {
            LOG_FATAL("No eMMC factory data available!");
            return;
        }

        do {
            const auto key        = (*factoryData)[0].getString();
            const auto value      = (*factoryData)[1].getCString();
            const auto path       = settings::factory::entry_key + std::string("/") + key;
            const auto pathString = settings::EntryPath{"", "", "", path, settings::SettingsScope::Global}.to_string();

            if (!database->execute(settings::Statements::insertValue, pathString.c_str(), value)) {
                LOG_ERROR("Failed to set entry '%s' = '%s'!", pathString.c_str(), value);
            }
            else {
                LOG_INFO("Set entry '%s' = '%s'", pathString.c_str(), value);
            }

        } while (factoryData->nextRow());
    }
} // namespace settings

M products/BellHybrid/services/db/CMakeLists.txt => products/BellHybrid/services/db/CMakeLists.txt +3 -1
@@ 6,10 6,12 @@ add_subdirectory(databases)
target_sources(databases
    PRIVATE
        ServiceDB.cpp
        BellFactorySettings.cpp
        agents/MeditationStatsAgent.cpp
    PUBLIC
        include/db/ServiceDB.hpp
        include/db/SystemSettings.hpp
        include/db/BellFactorySettings.hpp
)

target_include_directories(databases


@@ 21,7 23,7 @@ target_link_libraries(databases
   PRIVATE
        bell::db::meditation_stats
        service-db
        serial-number-reader
        serial-number-parser
        crashdump-serial-number
)


M products/BellHybrid/services/db/ServiceDB.cpp => products/BellHybrid/services/db/ServiceDB.cpp +11 -6
@@ 2,6 2,7 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <db/ServiceDB.hpp>
#include <db/BellFactorySettings.hpp>

#include "agents/MeditationStatsAgent.hpp"



@@ 13,11 14,11 @@

#include <service-db/DBServiceMessage.hpp>
#include <service-db/agents/settings/SettingsAgent.hpp>
#include <service-db/Settings.hpp>
#include <time/ScopedTime.hpp>

#include <purefs/filesystem_paths.hpp>

#include <serial-number-reader/SerialNumberReader.hpp>
#include <crashdump-serial-number/crashdump_serial_number.hpp>

ServiceDB::~ServiceDB()


@@ 58,17 59,21 @@ sys::ReturnCodes ServiceDB::InitHandler()
    multimediaFilesRecordInterface =
        std::make_unique<db::multimedia_files::MultimediaFilesRecordInterface>(multimediaFilesDB.get());

    databaseAgents.emplace(std::make_unique<SettingsAgent>(this, "settings_bell.db"));
    const auto factorySettings = std::make_unique<settings::BellFactorySettings>();
    databaseAgents.emplace(std::make_unique<SettingsAgent>(this, "settings_bell.db", factorySettings.get()));
    databaseAgents.emplace(std::make_unique<service::db::agents::MeditationStats>(this, "meditation_stats.db"));

    for (auto &dbAgent : databaseAgents) {
        dbAgent->registerMessages();
    }

    LOG_INFO("Serial number: %s", serial_number_reader::readSerialNumber().c_str());
    const auto settings = std::make_unique<settings::Settings>();
    settings->init(service::ServiceProxy(shared_from_this()));

    // Saving serial number for crashdump generation purpose.
    crashdump::setSerialNumber(serial_number_reader::readSerialNumber());
    // Save serial number for crashdump generation purpose
    const auto serialNumberPath =
        settings::factory::entry_key + std::string("/") + settings::factory::serial_number_key;
    crashdump::setSerialNumber(settings->getValue(serialNumberPath, settings::SettingsScope::Global));

    return sys::ReturnCodes::Success;
}
\ No newline at end of file
}

A products/BellHybrid/services/db/include/db/BellFactorySettings.hpp => products/BellHybrid/services/db/include/db/BellFactorySettings.hpp +20 -0
@@ 0,0 1,20 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <Database/Database.hpp>
#include <purefs/filesystem_paths.hpp>
#include <json11.hpp>
#include <fstream>
#include "service-db/agents/settings/FactorySettings.hpp"

namespace settings
{
    class BellFactorySettings : public FactorySettings
    {
      public:
        [[nodiscard]] auto getMfgEntries() const -> std::unique_ptr<QueryResult> override final;
        auto initDb(Database *database) const -> void override final;
    };
} // namespace settings

M products/BellHybrid/services/desktop/endpoints/CMakeLists.txt => products/BellHybrid/services/desktop/endpoints/CMakeLists.txt +1 -1
@@ 22,7 22,7 @@ target_link_libraries(
        desktop-endpoints-common
    PRIVATE
        version-header
        serial-number-reader
        serial-number-parser
)

target_compile_definitions(

M products/BellHybrid/services/desktop/endpoints/deviceInfo/DeviceInfoEndpoint.cpp => products/BellHybrid/services/desktop/endpoints/deviceInfo/DeviceInfoEndpoint.cpp +11 -7
@@ 12,16 12,19 @@
#include <cstdint>
#include <string>
#include <purefs/filesystem_paths.hpp>
#include <serial-number-reader/SerialNumberReader.hpp>

#include <ctime>

namespace sdesktop::endpoints
{
    auto DeviceInfoEndpoint::getSerialNumber() -> std::string
    {
        return static_cast<ServiceDesktop *>(ownerServicePtr)->getSerialNumber();
    }

    auto DeviceInfoEndpoint::getSerialNumber() -> const std::string &
    auto DeviceInfoEndpoint::getCaseColour() -> std::string
    {
        return serial_number_reader::readSerialNumber();
        return static_cast<ServiceDesktop *>(ownerServicePtr)->getCaseColour();
    }

    auto DeviceInfoEndpoint::getOnboardingState() -> OnboardingState


@@ 31,7 34,7 @@ namespace sdesktop::endpoints

    auto DeviceInfoEndpoint::getDeviceInfo(Context &context) -> http::Code
    {
        auto [totalDeviceSpaceMiB, reservedSystemSpaceMiB, usedUserSpaceMiB] = getStorageInfo();
        const auto [totalDeviceSpaceMiB, reservedSystemSpaceMiB, usedUserSpaceMiB] = getStorageInfo();

        context.setResponseBody(json11::Json::object(
            {{json::batteryLevel, std::to_string(Store::Battery::get().level)},


@@ 39,11 42,12 @@ namespace sdesktop::endpoints
             {json::deviceSpaceTotal, std::to_string(totalDeviceSpaceMiB)},
             {json::systemReservedSpace, std::to_string(reservedSystemSpaceMiB)},
             {json::usedUserSpace, std::to_string(usedUserSpaceMiB)},
             {json::gitRevision, (std::string)(GIT_REV)},
             {json::gitBranch, (std::string)GIT_BRANCH},
             {json::currentRTCTime, std::to_string(static_cast<uint32_t>(std::time(nullptr)))},
             {json::gitRevision, std::string(GIT_REV)},
             {json::gitBranch, std::string(GIT_BRANCH)},
             {json::currentRTCTime, std::to_string(static_cast<std::uint32_t>(std::time(nullptr)))},
             {json::version, std::string(VERSION)},
             {json::serialNumber, getSerialNumber()},
             {json::caseColour, getCaseColour()},
             {json::recoveryStatusFilePath,
              (purefs::dir::getTemporaryPath() / sdesktop::paths::recoveryStatusFilename).string()},
             {json::updateFilePath, (purefs::dir::getTemporaryPath() / sdesktop::paths::updateFilename).string()},

M products/BellHybrid/services/desktop/endpoints/include/endpoints/deviceInfo/DeviceInfoEndpoint.hpp => products/BellHybrid/services/desktop/endpoints/include/endpoints/deviceInfo/DeviceInfoEndpoint.hpp +2 -1
@@ 14,7 14,8 @@ namespace sdesktop::endpoints
        explicit DeviceInfoEndpoint(sys::Service *ownerServicePtr) : DeviceInfoEndpointCommon(ownerServicePtr)
        {}

        auto getSerialNumber() -> const std::string &;
        auto getSerialNumber() -> std::string;
        auto getCaseColour() -> std::string;
        auto getOnboardingState() -> OnboardingState;
        auto getDeviceInfo(Context &context) -> http::Code override;
    };

M products/PurePhone/services/db/CMakeLists.txt => products/PurePhone/services/db/CMakeLists.txt +2 -0
@@ 3,8 3,10 @@ add_library(db STATIC)
target_sources(db
    PRIVATE
        ServiceDB.cpp
        PureFactorySettings.cpp
    PUBLIC
        include/db/ServiceDB.hpp
        include/db/PureFactorySettings.hpp
)

target_include_directories(db

R module-services/service-db/agents/settings/FactorySettings.cpp => products/PurePhone/services/db/PureFactorySettings.cpp +22 -19
@@ 1,18 1,36 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "FactorySettings.hpp"
#include <db/PureFactorySettings.hpp>

#include <log/log.hpp>
#include <service-db/SettingsMessages.hpp>
#include <service-db/agents/settings/Settings_queries.hpp>

namespace settings
{
    PureFactorySettings::PureFactorySettings(const std::string &filePath) : filePath(filePath)
    {}

    std::unique_ptr<QueryResult> FactorySettings::getMfgEntries()
    auto PureFactorySettings::readMfgSettings() const -> json11::Json
    {
        std::ifstream file(filePath.c_str());
        const std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());

        std::string parserError;
        auto factoryObj = json11::Json::parse(content, parserError);

        if (!parserError.empty()) {
            LOG_FATAL("Factory data parse error: %s", parserError.c_str());
        }

        return factoryObj;
    }

    auto PureFactorySettings::getMfgEntries() const -> std::unique_ptr<QueryResult>
    {
        auto factoryData          = std::make_unique<QueryResult>();
        const auto factoryContent = readMfgSettings(filePath);
        const auto factoryContent = readMfgSettings();

        for (const auto &[path, value] : factoryContent.object_items()) {
            factoryData->addRow({Field(path.c_str()), Field(value.string_value().c_str())});


@@ 21,7 39,7 @@ namespace settings
        return factoryData;
    }

    void FactorySettings::initDb(Database *database)
    auto PureFactorySettings::initDb(Database *database) const -> void
    {
        const auto factoryData = getMfgEntries();



@@ 45,19 63,4 @@ namespace settings

        } while (factoryData->nextRow());
    }

    json11::Json FactorySettings::readMfgSettings(const std::string &path)
    {
        std::ifstream file(path.c_str());
        const std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());

        std::string parserError;
        auto factoryObj = json11::Json::parse(content, parserError);

        if (!parserError.empty()) {
            LOG_FATAL("Factory data parse error: %s", parserError.c_str());
        }

        return factoryObj;
    }
} // namespace settings

M products/PurePhone/services/db/ServiceDB.cpp => products/PurePhone/services/db/ServiceDB.cpp +10 -8
@@ 2,10 2,11 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <db/ServiceDB.hpp>
#include <db/PureFactorySettings.hpp>

#include <module-db/databases/EventsDB.hpp>
#include <module-db/databases/MultimediaFilesDB.hpp>
#include "module-db/databases/NotificationsDB.hpp"
#include <module-db/databases/NotificationsDB.hpp>
#include <module-db/Interface/AlarmEventRecord.hpp>
#include <module-db/Interface/CalllogRecord.hpp>
#include <module-db/Interface/MultimediaFilesRecord.hpp>


@@ 23,10 24,6 @@
#include <time/ScopedTime.hpp>
#include <crashdump-serial-number/crashdump_serial_number.hpp>

namespace
{
    constexpr auto serial_number_path = "factory_data/serial";
}
ServiceDB::~ServiceDB()
{
    eventsDB.reset();


@@ 266,7 263,10 @@ sys::ReturnCodes ServiceDB::InitHandler()
        std::make_unique<NotificationsRecordInterface>(notificationsDB.get(), contactRecordInterface.get());
    multimediaFilesRecordInterface =
        std::make_unique<db::multimedia_files::MultimediaFilesRecordInterface>(multimediaFilesDB.get());
    databaseAgents.emplace(std::make_unique<SettingsAgent>(this, "settings_v2.db"));

    const auto factorySettings =
        std::make_unique<settings::PureFactorySettings>(purefs::dir::getMfgConfPath() / "personalization.json");
    databaseAgents.emplace(std::make_unique<SettingsAgent>(this, "settings_v2.db", factorySettings.get()));

    for (auto &dbAgent : databaseAgents) {
        dbAgent->registerMessages();


@@ 275,8 275,10 @@ sys::ReturnCodes ServiceDB::InitHandler()
    auto settings = std::make_unique<settings::Settings>();
    settings->init(service::ServiceProxy(shared_from_this()));

    // Saving serial number for crashdump generation purpose.
    crashdump::setSerialNumber(settings->getValue(serial_number_path, settings::SettingsScope::Global));
    // Save serial number for crashdump generation purpose
    const auto serialNumberPath =
        settings::factory::entry_key + std::string("/") + settings::factory::serial_number_key;
    crashdump::setSerialNumber(settings->getValue(serialNumberPath, settings::SettingsScope::Global));

    quotesRecordInterface =
        std::make_unique<Quotes::QuotesAgent>(predefinedQuotesDB.get(), customQuotesDB.get(), std::move(settings));

A products/PurePhone/services/db/include/db/PureFactorySettings.hpp => products/PurePhone/services/db/include/db/PureFactorySettings.hpp +25 -0
@@ 0,0 1,25 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <Database/Database.hpp>
#include <purefs/filesystem_paths.hpp>
#include <json11.hpp>
#include <fstream>
#include <service-db/agents/settings/FactorySettings.hpp>

namespace settings
{
    class PureFactorySettings : public FactorySettings
    {
      public:
        explicit PureFactorySettings(const std::string &filePath);
        [[nodiscard]] auto getMfgEntries() const -> std::unique_ptr<QueryResult> override final;
        auto initDb(Database *database) const -> void override final;

      private:
        const std::string filePath;
        auto readMfgSettings() const -> json11::Json;
    };
} // namespace settings

M products/PurePhone/services/db/include/db/ServiceDB.hpp => products/PurePhone/services/db/include/db/ServiceDB.hpp +1 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 11,7 11,6 @@ class CalllogDB;
class CalllogRecordInterface;
class ContactRecordInterface;
class ContactsDB;
class CountryCodeRecordInterface;
class DatabaseAgent;
class EventsDB;
class NotesDB;

M products/PurePhone/services/desktop/endpoints/deviceInfo/DeviceInfoEndpoint.cpp => products/PurePhone/services/desktop/endpoints/deviceInfo/DeviceInfoEndpoint.cpp +1 -1
@@ 19,7 19,7 @@ namespace sdesktop::endpoints
{
    auto DeviceInfoEndpoint::getSerialNumber() -> std::string
    {
        return dynamic_cast<ServiceDesktop *>(ownerServicePtr)->getSerialNumber();
        return static_cast<ServiceDesktop *>(ownerServicePtr)->getSerialNumber();
    }

    auto DeviceInfoEndpoint::getCaseColour() -> std::string