Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-22 13:58:55 +01:00
parent 4af19165ec
commit 68073add76
12458 changed files with 12350765 additions and 2 deletions

View file

@ -0,0 +1,135 @@
#include "map/power_management/power_management_schemas.hpp"
#include "base/assert.hpp"
#include <unordered_map>
using namespace power_management;
namespace
{
std::unordered_map<Scheme, FacilitiesState> const kSchemeToState = {
{Scheme::Normal,
{{
/* Buildings3d */ true,
/* PerspectiveView */ true,
/* TrackRecording */ true,
/* TrafficJams */ true,
/* GpsTrackingForTraffic */ true,
/* OsmEditsUploading */ true,
/* UgcUploading */ true,
/* BookmarkCloudUploading */ true,
/* MapDownloader */ true,
}}},
{Scheme::EconomyMedium,
{{
/* Buildings3d */ true,
/* PerspectiveView */ false,
/* TrackRecording */ true,
/* TrafficJams */ true,
/* GpsTrackingForTraffic */ true,
/* OsmEditsUploading */ true,
/* UgcUploading */ true,
/* BookmarkCloudUploading */ false,
/* MapDownloader */ true,
}}},
{Scheme::EconomyMaximum,
{{
/* Buildings3d */ false,
/* PerspectiveView */ false,
/* TrackRecording */ false,
/* TrafficJams */ false,
/* GpsTrackingForTraffic */ false,
/* OsmEditsUploading */ false,
/* UgcUploading */ false,
/* BookmarkCloudUploading */ false,
/* MapDownloader */ true,
}}},
};
std::unordered_map<AutoScheme, FacilitiesState> const kAutoSchemeToState = {
{AutoScheme::Normal,
{{
/* Buildings3d */ true,
/* PerspectiveView */ true,
/* TrackRecording */ true,
/* TrafficJams */ true,
/* GpsTrackingForTraffic */ true,
/* OsmEditsUploading */ true,
/* UgcUploading */ true,
/* BookmarkCloudUploading */ true,
/* MapDownloader */ true,
}}},
{AutoScheme::EconomyMedium,
{{
/* Buildings3d */ true,
/* PerspectiveView */ false,
/* TrackRecording */ true,
/* TrafficJams */ true,
/* GpsTrackingForTraffic */ false,
/* OsmEditsUploading */ true,
/* UgcUploading */ true,
/* BookmarkCloudUploading */ false,
/* MapDownloader */ false,
}}},
{AutoScheme::EconomyMaximum,
{{
/* Buildings3d */ false,
/* PerspectiveView */ false,
/* TrackRecording */ false,
/* TrafficJams */ false,
/* GpsTrackingForTraffic */ false,
/* OsmEditsUploading */ false,
/* UgcUploading */ false,
/* BookmarkCloudUploading */ false,
/* MapDownloader */ false,
}}},
};
} // namespace
namespace power_management
{
FacilitiesState const & GetFacilitiesState(Scheme const scheme)
{
CHECK_NOT_EQUAL(scheme, Scheme::None, ());
CHECK_NOT_EQUAL(scheme, Scheme::Auto, ());
return kSchemeToState.at(scheme);
}
FacilitiesState const & GetFacilitiesState(AutoScheme const autoScheme)
{
return kAutoSchemeToState.at(autoScheme);
}
std::string DebugPrint(Facility const facility)
{
switch (facility)
{
case Facility::Buildings3d: return "Buildings3d";
case Facility::PerspectiveView: return "PerspectiveView";
case Facility::TrackRecording: return "TrackRecording";
case Facility::TrafficJams: return "TrafficJams";
case Facility::GpsTrackingForTraffic: return "GpsTrackingForTraffic";
case Facility::OsmEditsUploading: return "OsmEditsUploading";
case Facility::UgcUploading: return "UgcUploading";
case Facility::BookmarkCloudUploading: return "BookmarkCloudUploading";
case Facility::MapDownloader: return "MapDownloader";
case Facility::Count: return "Count";
}
UNREACHABLE();
}
std::string DebugPrint(Scheme const scheme)
{
switch (scheme)
{
case Scheme::None: return "None";
case Scheme::Normal: return "Normal";
case Scheme::EconomyMedium: return "EconomyMedium";
case Scheme::EconomyMaximum: return "EconomyMaximum";
case Scheme::Auto: return "Auto";
}
UNREACHABLE();
}
} // namespace power_management

View file

@ -0,0 +1,51 @@
#pragma once
#include <array>
#include <cstdint>
#include <string>
namespace power_management
{
// Note: the order is important.
// Note: new facilities must be added before Facility::Count.
// Note: do not use Facility::Count in external code, this value for internal use only.
enum class Facility : uint8_t
{
Buildings3d,
PerspectiveView,
TrackRecording,
TrafficJams,
GpsTrackingForTraffic,
OsmEditsUploading,
UgcUploading,
BookmarkCloudUploading,
MapDownloader,
Count
};
// Note: the order is important.
enum class Scheme : uint8_t
{
None,
Normal,
EconomyMedium,
EconomyMaximum,
Auto,
};
enum class AutoScheme : uint8_t
{
Normal,
EconomyMedium,
EconomyMaximum,
};
using FacilitiesState = std::array<bool, static_cast<size_t>(Facility::Count)>;
FacilitiesState const & GetFacilitiesState(Scheme const scheme);
FacilitiesState const & GetFacilitiesState(AutoScheme const autoScheme);
std::string DebugPrint(Facility const facility);
std::string DebugPrint(Scheme const scheme);
} // namespace power_management

View file

@ -0,0 +1,222 @@
#include "map/power_management/power_manager.hpp"
#include "platform/platform.hpp"
#include "coding/file_reader.hpp"
#include "coding/file_writer.hpp"
#include "coding/internal/file_data.hpp"
#include "coding/serdes_json.hpp"
#include "base/assert.hpp"
#include "base/file_name_utils.hpp"
#include "base/logging.hpp"
using namespace power_management;
namespace
{
using Subscribers = std::vector<PowerManager::Subscriber *>;
void NotifySubscribers(Subscribers & subscribers, Scheme const scheme)
{
for (auto & subscriber : subscribers)
subscriber->OnPowerSchemeChanged(scheme);
}
void NotifySubscribers(Subscribers & subscribers, Facility const facility, bool enabled)
{
for (auto & subscriber : subscribers)
subscriber->OnPowerFacilityChanged(facility, enabled);
}
} // namespace
namespace power_management
{
// static
std::string PowerManager::GetConfigPath()
{
return base::JoinPath(GetPlatform().SettingsDir(), "power_manager_config");
}
void PowerManager::Load()
{
try
{
FileReader reader(GetConfigPath());
NonOwningReaderSource source(reader);
coding::DeserializerJson des(source);
Config result;
des(result);
m_config = result;
if (m_config.m_scheme == Scheme::Auto)
GetPlatform().GetBatteryTracker().Subscribe(this);
for (size_t i = 0; i < m_config.m_facilities.size(); ++i)
NotifySubscribers(m_subscribers, static_cast<Facility>(i), m_config.m_facilities[i]);
NotifySubscribers(m_subscribers, m_config.m_scheme);
return;
}
catch (base::Json::Exception & ex)
{
LOG(LERROR, ("Cannot deserialize power manager data from file. Exception:", ex.Msg()));
}
catch (FileReader::Exception const & ex)
{
LOG(LWARNING, ("Cannot read power manager config file. Exception:", ex.Msg()));
}
// Reset to default state.
m_config = {};
}
void PowerManager::SetFacility(Facility const facility, bool enabled)
{
CHECK_NOT_EQUAL(facility, Facility::Count, ());
if (m_config.m_facilities[static_cast<size_t>(facility)] == enabled)
return;
m_config.m_facilities[static_cast<size_t>(facility)] = enabled;
auto const isSchemeChanged = m_config.m_scheme != Scheme::None;
if (m_config.m_scheme == Scheme::Auto)
GetPlatform().GetBatteryTracker().Unsubscribe(this);
m_config.m_scheme = Scheme::None;
if (!Save())
return;
NotifySubscribers(m_subscribers, facility, enabled);
if (isSchemeChanged)
NotifySubscribers(m_subscribers, m_config.m_scheme);
}
void PowerManager::SetScheme(Scheme const scheme)
{
if (m_config.m_scheme == scheme)
return;
m_config.m_scheme = scheme;
if (m_config.m_scheme == Scheme::Auto)
GetPlatform().GetBatteryTracker().Subscribe(this);
else
GetPlatform().GetBatteryTracker().Unsubscribe(this);
if (m_config.m_scheme == Scheme::None || m_config.m_scheme == Scheme::Auto)
{
if (!Save())
return;
NotifySubscribers(m_subscribers, m_config.m_scheme);
return;
}
auto actualState = GetFacilitiesState(scheme);
std::swap(m_config.m_facilities, actualState);
if (!Save())
return;
NotifySubscribers(m_subscribers, m_config.m_scheme);
for (size_t i = 0; i < actualState.size(); ++i)
if (m_config.m_facilities[i] != actualState[i])
NotifySubscribers(m_subscribers, static_cast<Facility>(i), m_config.m_facilities[i]);
}
bool PowerManager::IsFacilityEnabled(Facility const facility) const
{
CHECK_NOT_EQUAL(facility, Facility::Count, ());
return m_config.m_facilities[static_cast<size_t>(facility)];
}
FacilitiesState const & PowerManager::GetFacilities() const
{
return m_config.m_facilities;
}
Scheme const & PowerManager::GetScheme() const
{
return m_config.m_scheme;
}
void PowerManager::OnBatteryLevelReceived(uint8_t level)
{
CHECK_LESS_OR_EQUAL(level, 100, ());
if (m_config.m_scheme != Scheme::Auto)
return;
AutoScheme actualScheme = AutoScheme::Normal;
if (level < 20)
actualScheme = AutoScheme::EconomyMaximum;
else if (level < 30)
actualScheme = AutoScheme::EconomyMedium;
auto actualState = GetFacilitiesState(actualScheme);
if (m_config.m_facilities == actualState)
return;
std::swap(m_config.m_facilities, actualState);
if (!Save())
return;
for (size_t i = 0; i < actualState.size(); ++i)
if (m_config.m_facilities[i] != actualState[i])
NotifySubscribers(m_subscribers, static_cast<Facility>(i), m_config.m_facilities[i]);
}
void PowerManager::Subscribe(Subscriber * subscriber)
{
ASSERT(subscriber, ());
m_subscribers.push_back(subscriber);
}
void PowerManager::UnsubscribeAll()
{
m_subscribers.clear();
}
bool PowerManager::Save()
{
auto const result = base::WriteToTempAndRenameToFile(GetConfigPath(), [this](std::string const & fileName)
{
try
{
FileWriter writer(fileName);
coding::SerializerJson<FileWriter> ser(writer);
ser(m_config);
return true;
}
catch (base::Json::Exception & ex)
{
LOG(LERROR, ("Cannot serialize power manager data into file. Exception:", ex.Msg()));
}
catch (FileWriter::Exception const & ex)
{
LOG(LERROR, ("Cannot write power manager file. Exception:", ex.Msg()));
}
return false;
});
if (result)
return true;
// Try to load last correct state and notify subscribers.
Load();
return false;
}
} // namespace power_management

View file

@ -0,0 +1,62 @@
#pragma once
#include "map/power_management/power_management_schemas.hpp"
#include "platform/battery_tracker.hpp"
#include "base/visitor.hpp"
#include <cstdint>
#include <string>
#include <vector>
namespace power_management
{
// Note: this class is NOT thread-safe.
class PowerManager : public platform::BatteryLevelTracker::Subscriber
{
public:
class Subscriber
{
public:
virtual void OnPowerFacilityChanged(Facility const facility, bool enabled) = 0;
virtual void OnPowerSchemeChanged(Scheme const actualScheme) = 0;
protected:
virtual ~Subscriber() = default;
};
static std::string GetConfigPath();
void Load();
// Set some facility state manually, it turns current scheme to Scheme::None.
void SetFacility(Facility const facility, bool enabled);
void SetScheme(Scheme const scheme);
bool IsFacilityEnabled(Facility const facility) const;
FacilitiesState const & GetFacilities() const;
Scheme const & GetScheme() const;
// BatteryLevelTracker::Subscriber overrides:
void OnBatteryLevelReceived(uint8_t level) override;
void Subscribe(Subscriber * subscriber);
void UnsubscribeAll();
private:
struct Config
{
DECLARE_VISITOR(visitor(m_facilities, "current_state"), visitor(m_scheme, "scheme"))
Config() { m_facilities.fill(true); }
FacilitiesState m_facilities;
Scheme m_scheme = Scheme::Normal;
};
bool Save();
std::vector<Subscriber *> m_subscribers;
Config m_config;
};
} // namespace power_management