M module-apps/application-settings/windows/system/SystemMainWindow.cpp => module-apps/application-settings/windows/system/SystemMainWindow.cpp +1 -3
@@ 41,9 41,7 @@ namespace gui
utils::translate("app_settings_display_factory_reset_confirmation"),
"",
[this]() {
- auto msg = std::make_shared<sdesktop::FactoryMessage>();
- application->bus.sendUnicast(msg, service::name::service_desktop);
- application->returnToPreviousWindow(2);
+ sys::SystemManagerCommon::FactoryReset(application);
return true;
}});
LOG_INFO("switching to %s page", window.c_str());
M module-services/service-appmgr/model/ApplicationManagerCommon.cpp => module-services/service-appmgr/model/ApplicationManagerCommon.cpp +2 -0
@@ 163,6 163,8 @@ namespace app::manager
case sys::CloseReason::RegularPowerDown:
[[fallthrough]];
case sys::CloseReason::Reboot:
+ [[fallthrough]];
+ case sys::CloseReason::FactoryReset:
break;
}
handleActionRequest(&act);
M module-services/service-db/ServiceDBCommon.cpp => module-services/service-db/ServiceDBCommon.cpp +24 -0
@@ 6,6 6,8 @@
#include <service-db/ServiceDBCommon.hpp>
#include <service-db/agents/quotes/QuotesAgent.cpp>
+#include <purefs/filesystem_paths.hpp>
+
static const auto service_db_stack = 1024 * 24;
ServiceDBCommon::ServiceDBCommon() : sys::Service(service::name::db, "", service_db_stack, sys::ServicePriority::Idle)
@@ 63,9 65,31 @@ sys::ReturnCodes ServiceDBCommon::DeinitHandler()
void ServiceDBCommon::ProcessCloseReason(sys::CloseReason closeReason)
{
+ if (closeReason == sys::CloseReason::FactoryReset) {
+ factoryReset();
+ }
sendCloseReadyMessage(this);
}
+void ServiceDBCommon::factoryReset() const
+{
+ constexpr std::array fileExtensions = {".db", ".db-journal", ".db-wal"};
+
+ LOG_INFO("Performing DB factory reset...");
+ const auto userOSPath = purefs::dir::getUserDiskPath();
+ for (const auto &f : std::filesystem::directory_iterator(userOSPath)) {
+ if (const auto it = std::find(fileExtensions.begin(), fileExtensions.end(), f.path().extension());
+ it != fileExtensions.end()) {
+ if (const auto removeStatus = std::filesystem::remove(f.path()); !removeStatus) {
+ LOG_ERROR("Unable to delete file: %s", f.path().c_str());
+ }
+ else {
+ LOG_INFO("File deleted: %s", f.path().c_str());
+ }
+ }
+ }
+}
+
sys::ReturnCodes ServiceDBCommon::SwitchPowerModeHandler(const sys::ServicePowerMode mode)
{
LOG_FATAL("[%s] PowerModeHandler: %s", this->GetName().c_str(), c_str(mode));
M module-services/service-db/include/service-db/ServiceDBCommon.hpp => module-services/service-db/include/service-db/ServiceDBCommon.hpp +3 -0
@@ 11,6 11,9 @@
class ServiceDBCommon : public sys::Service
{
+ private:
+ void factoryReset() const;
+
protected:
virtual db::Interface *getInterface(db::Interface::Name interface);
std::set<std::unique_ptr<DatabaseAgent>> databaseAgents;
M module-services/service-desktop/CMakeLists.txt => module-services/service-desktop/CMakeLists.txt +0 -1
@@ 22,7 22,6 @@ set(SOURCES
endpoints/developerMode/event/DomRequest.cpp
endpoints/developerMode/event/ATRequest.cpp
endpoints/deviceInfo/DeviceInfoEndpoint.cpp
- endpoints/factoryReset/FactoryReset.cpp
endpoints/factoryReset/FactoryResetEndpoint.cpp
endpoints/messages/MessageHelper.cpp
endpoints/messages/MessagesEndpoint.cpp
M module-services/service-desktop/ServiceDesktop.cpp => module-services/service-desktop/ServiceDesktop.cpp +1 -2
@@ 6,7 6,6 @@
#include "service-desktop/ServiceDesktop.hpp"
#include "service-desktop/WorkerDesktop.hpp"
#include "service-cellular/CellularMessage.hpp"
-#include "endpoints/factoryReset/FactoryReset.hpp"
#include "endpoints/backup/BackupRestore.hpp"
#include <Common/Query.hpp>
@@ 143,7 142,7 @@ sys::ReturnCodes ServiceDesktop::InitHandler()
auto *factoryMessage = dynamic_cast<sdesktop::FactoryMessage *>(msg);
if (factoryMessage != nullptr) {
LOG_DEBUG("ServiceDesktop: FactoryMessage received");
- FactoryReset::Run(this);
+ sys::SystemManagerCommon::FactoryReset(this);
}
return sys::MessageNone{};
});
D module-services/service-desktop/endpoints/factoryReset/FactoryReset.cpp => module-services/service-desktop/endpoints/factoryReset/FactoryReset.cpp +0 -238
@@ 1,238 0,0 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#include "FactoryReset.hpp"
-#include <SystemManager/SystemManagerCommon.hpp>
-#include <log.hpp>
-#include <service-db/DBServiceName.hpp>
-#include <Utils.hpp>
-
-#include <cstdint>
-#include <filesystem>
-#include <memory>
-#include <vector>
-#include <purefs/filesystem_paths.hpp>
-#include <purefs/fs/filesystem.hpp>
-#include <limits.h>
-
-namespace sys
-{
- class Service;
-} // namespace sys
-
-namespace FactoryReset
-{
- namespace
- {
- inline constexpr auto copy_buf = 8192 * 4;
- } // namespace
-
- static bool CopyFile(const std::string &sourcefile, const std::string &targetfile);
-
- static int recurseDepth = 0;
- static const int max_recurse_depth = 120; /* 120 is just an arbitrary value of max number of recursive calls.
- * If more then error is assumed, not the real depth of directories."
- */
- static const int max_filepath_length = PATH_MAX;
-
- bool Run(sys::Service *ownerService)
- {
- LOG_INFO("Restoring factory state started...");
-
- recurseDepth = 0;
- const auto userOSPath = purefs::dir::getUserDiskPath();
-
- if (std::filesystem::is_directory(userOSPath.c_str()) && std::filesystem::is_empty(userOSPath.c_str())) {
- LOG_ERROR("Restoring factory state aborted");
- LOG_ERROR("Directory %s seems empty.", userOSPath.c_str());
- return false;
- }
-
- if (ownerService != nullptr) {
- LOG_INFO("Closing ServiceDB...");
- std::string dbServiceName = service::name::db;
- sys::SystemManagerCommon::DestroySystemService(dbServiceName, ownerService);
- }
-
- DeleteSelectedUserFiles(userOSPath);
-
- LOG_INFO("Rebooting...");
- sys::SystemManagerCommon::Reboot(ownerService);
- return true;
- }
-
- bool DeleteSelectedUserFiles(const std::filesystem::path &userOSPath)
- {
- bool returnStatus = true;
- std::vector<std::string> selectedFileExt = {".db", ".db-journal", ".db-wal"};
-
- LOG_INFO("Delete DB files which will be recreated with factory content after reboot:");
- for (const auto &f : std::filesystem::directory_iterator(userOSPath.c_str())) {
- for (const auto &ext : selectedFileExt) {
- if (f.path().extension() == ext) {
- auto removeStatus = std::filesystem::remove(f.path());
- if (!removeStatus) {
- LOG_ERROR("Error deleting file %s, aborting...", f.path().c_str());
- returnStatus = false;
- }
- else {
- LOG_INFO("%s deleted.", f.path().c_str());
- }
- break;
- }
- }
- }
- return returnStatus;
- }
-
- bool DeleteDirContent(const std::string &dir)
- {
- for (auto &direntry : std::filesystem::directory_iterator(dir.c_str())) {
- if (!((direntry.path().string() != ".") && (direntry.path().string() != "..") &&
- (direntry.path().string() != "..."))) {
- continue;
- }
- std::string delpath = dir;
- delpath += "/";
- delpath += direntry.path().string();
-
- if (std::filesystem::is_directory(direntry)) {
- if (direntry.path().string() != purefs::dir::getFactoryOSPath()) {
- LOG_INFO("FactoryReset: recursively deleting dir...");
- try {
- std::filesystem::remove_all(delpath.c_str());
- }
- catch (const std::filesystem::filesystem_error &e) {
- LOG_ERROR("FactoryReset: error deleting dir, aborting...");
- return false;
- }
- }
- }
- else {
- LOG_INFO("FactoryReset: deleting file...");
- if (std::filesystem::remove(delpath.c_str())) {
- LOG_ERROR("FactoryReset: error deleting file, aborting...");
- return false;
- }
- }
- }
-
- return true;
- }
-
- bool CopyDirContent(const std::string &sourcedir, const std::string &targetdir)
- {
- if (recurseDepth >= max_recurse_depth) {
- LOG_ERROR("FactoryReset: recurse level %d (too high), error assumed, skipping restore of dir",
- recurseDepth);
- return false;
- }
-
- const auto factoryOSPath = purefs::dir::getFactoryOSPath();
-
- for (auto &direntry : std::filesystem::directory_iterator(sourcedir.c_str())) {
- if ((direntry.path().string() == ".") || (direntry.path().string() == "..") ||
- (direntry.path().string() == "...")) {
- continue;
- }
-
- std::string sourcepath = sourcedir;
- sourcepath += "/";
- sourcepath += direntry.path().string();
-
- std::string targetpath = targetdir;
- targetpath += "/";
- targetpath += direntry.path().string();
-
- if ((sourcepath.size() >= max_filepath_length) || (targetpath.size() >= max_filepath_length)) {
- LOG_ERROR("FactoryReset: path length (source or target) exceeds system limit of %d",
- max_filepath_length);
- LOG_ERROR("FactoryReset: skipping restore of directory");
- return false;
- }
-
- if (std::filesystem::is_directory(direntry)) {
- if (targetpath == factoryOSPath) {
- continue;
- }
-
- LOG_INFO("FactoryReset: restoring directory");
-
- try {
- if (std::filesystem::create_directory(targetpath.c_str())) {
- LOG_ERROR("FactoryReset: create dir failed");
- return false;
- }
- }
- catch (const std::filesystem::filesystem_error &err) {
- LOG_FATAL("Exception while creating dir");
- return false;
- }
-
- recurseDepth++;
-
- if (!CopyDirContent(sourcepath, targetpath)) {
- recurseDepth--;
- return false;
- }
-
- recurseDepth--;
- }
- else {
- LOG_INFO("FactoryReset: restoring file");
-
- if (!CopyFile(sourcepath, targetpath)) {
- return false;
- }
- }
- }
-
- return true;
- }
-
- static bool CopyFile(const std::string &sourcefile, const std::string &targetfile)
- {
- bool ret = true;
- auto lamb = [](std::FILE *stream) { std::fclose(stream); };
-
- std::unique_ptr<std::FILE, decltype(lamb)> sf(std::fopen(sourcefile.c_str(), "r"), lamb);
- std::unique_ptr<std::FILE, decltype(lamb)> tf(std::fopen(targetfile.c_str(), "w"), lamb);
-
- if (sf && tf) {
- std::unique_ptr<unsigned char[]> buffer(new unsigned char[copy_buf]);
-
- if (buffer) {
- uint32_t loopcount = (std::filesystem::file_size(sourcefile) / copy_buf) + 1u;
- uint32_t readsize = copy_buf;
-
- for (uint32_t i = 0u; i < loopcount; i++) {
- if (i + 1u == loopcount) {
- readsize = std::filesystem::file_size(sourcefile) % copy_buf;
- }
-
- if (std::fread(buffer.get(), 1, readsize, sf.get()) != readsize) {
- LOG_ERROR("FactoryReset: read from sourcefile failed");
- ret = false;
- break;
- }
-
- if (std::fwrite(buffer.get(), 1, readsize, tf.get()) != readsize) {
- LOG_ERROR("FactoryReset: write to targetfile failed");
- ret = false;
- break;
- }
- }
- }
- else {
- LOG_ERROR("FactoryReset: unable to open copy buffer");
- ret = false;
- }
- }
- else {
- LOG_ERROR("FactoryReset: unable to open source or target file");
- ret = false;
- }
-
- return ret;
- }
-} // namespace FactoryReset
D module-services/service-desktop/endpoints/factoryReset/FactoryReset.hpp => module-services/service-desktop/endpoints/factoryReset/FactoryReset.hpp +0 -20
@@ 1,20 0,0 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#pragma once
-#include <purefs/filesystem_paths.hpp>
-#include <Service/Service.hpp>
-#include <string>
-
-namespace sys
-{
- class Service;
-} // namespace sys
-
-namespace FactoryReset
-{
- bool Run(sys::Service *ownerService);
- bool DeleteSelectedUserFiles(const std::filesystem::path &userOSPath);
- bool DeleteDirContent(const std::string &dir);
- bool CopyDirContent(const std::string &sourcedir, const std::string &targetdir);
-} // namespace FactoryReset
M module-services/service-desktop/tests/unittest.cpp => module-services/service-desktop/tests/unittest.cpp +0 -1
@@ 5,7 5,6 @@
#include <endpoints/EndpointFactory.hpp>
#include <endpoints/contacts/ContactHelper.hpp>
#include <endpoints/contacts/ContactsEndpoint.hpp>
-#include <endpoints/factoryReset/FactoryReset.hpp>
#include <endpoints/messages/MessageHelper.hpp>
#include <endpoints/filesystem/FileContext.hpp>
#include <endpoints/filesystem/FileOperations.hpp>
M module-sys/Service/Common.hpp => module-sys/Service/Common.hpp +1 -0
@@ 49,6 49,7 @@ namespace sys
{
RegularPowerDown,
Reboot,
+ FactoryReset,
SystemBrownout,
LowBattery
};
M module-sys/SystemManager/SystemManagerCommon.cpp => module-sys/SystemManager/SystemManagerCommon.cpp +11 -1
@@ 232,9 232,16 @@ namespace sys
return true;
}
+ bool SystemManagerCommon::FactoryReset(Service *s)
+ {
+ return s->bus.sendUnicast(std::make_shared<SystemManagerCmd>(Code::FactoryReset, CloseReason::FactoryReset),
+ service::name::system_manager);
+ }
+
bool SystemManagerCommon::Reboot(Service *s)
{
- s->bus.sendUnicast(std::make_shared<SystemManagerCmd>(Code::Reboot), service::name::system_manager);
+ s->bus.sendUnicast(std::make_shared<SystemManagerCmd>(Code::Reboot, CloseReason::Reboot),
+ service::name::system_manager);
return true;
}
@@ 474,6 481,9 @@ namespace sys
case Code::RebootToUpdate:
RebootHandler(State::RebootToUpdate, data->updateReason);
break;
+ case Code::FactoryReset:
+ CloseSystemHandler(CloseReason::FactoryReset);
+ break;
case Code::None:
break;
}
M module-sys/SystemManager/SystemManagerCommon.hpp => module-sys/SystemManager/SystemManagerCommon.hpp +3 -0
@@ 39,6 39,7 @@ namespace sys
Restore,
Reboot,
RebootToUpdate,
+ FactoryReset,
None,
};
@@ 92,6 93,8 @@ namespace sys
static bool Restore(Service *s);
+ static bool FactoryReset(Service *s);
+
static bool Reboot(Service *s);
static bool RebootToUpdate(Service *s, UpdateReason updateReason);