Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
135
libs/map/power_management/power_management_schemas.cpp
Normal file
135
libs/map/power_management/power_management_schemas.cpp
Normal 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
|
||||
51
libs/map/power_management/power_management_schemas.hpp
Normal file
51
libs/map/power_management/power_management_schemas.hpp
Normal 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
|
||||
222
libs/map/power_management/power_manager.cpp
Normal file
222
libs/map/power_management/power_manager.cpp
Normal 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
|
||||
62
libs/map/power_management/power_manager.hpp
Normal file
62
libs/map/power_management/power_manager.hpp
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue