From 1121e867aea9f283b8e596c06a6889d252d8d31f Mon Sep 17 00:00:00 2001 From: tangjie02 Date: Fri, 7 Jul 2023 18:04:51 +0800 Subject: [PATCH] feature(power): Compatiable two power profile daemon which contains hadess and tuned. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 电源节能模式兼容hadess和tuned两个后端。 Signed-off-by: tangjie02 --- .../com.kylinsec.kiran.power.gschema.xml.in | 10 + include/power-i.h | 23 ++ ...com.kylinsec.Kiran.SessionDaemon.Power.xml | 16 ++ plugins/power/power-manager.cpp | 24 ++ plugins/power/power-manager.h | 6 + plugins/power/save/power-save.cpp | 4 +- plugins/power/save/power-save.h | 2 +- .../power/wrapper/power-profiles-hadess.cpp | 217 ++++++++++++++++++ plugins/power/wrapper/power-profiles-hadess.h | 42 ++++ .../power/wrapper/power-profiles-tuned.cpp | 194 ++++++++++++++++ plugins/power/wrapper/power-profiles-tuned.h | 45 ++++ plugins/power/wrapper/power-profiles.cpp | 137 ++--------- plugins/power/wrapper/power-profiles.h | 41 ++-- .../power/wrapper/power-wrapper-manager.cpp | 2 +- 14 files changed, 611 insertions(+), 152 deletions(-) create mode 100644 plugins/power/wrapper/power-profiles-hadess.cpp create mode 100644 plugins/power/wrapper/power-profiles-hadess.h create mode 100644 plugins/power/wrapper/power-profiles-tuned.cpp create mode 100644 plugins/power/wrapper/power-profiles-tuned.h diff --git a/data/schemas/com.kylinsec.kiran.power.gschema.xml.in b/data/schemas/com.kylinsec.kiran.power.gschema.xml.in index 094ea2f..2c4eef9 100644 --- a/data/schemas/com.kylinsec.kiran.power.gschema.xml.in +++ b/data/schemas/com.kylinsec.kiran.power.gschema.xml.in @@ -34,6 +34,11 @@ + + + + + @@ -136,5 +141,10 @@ 'auto' Set the policy for obtaining brightness values. + + + 'hadess' + The profiles daemon used by current power plugin. + diff --git a/include/power-i.h b/include/power-i.h index 8d33a91..895c93e 100644 --- a/include/power-i.h +++ b/include/power-i.h @@ -116,6 +116,27 @@ extern "C" POWER_MONITOR_BACKLIGHT_POLICY_X11 = 2, }; + /* 这里兼容两个后端的原因是power-profiles-daemon更好用,支持holdprofile接口,但支持的架构比较少。 + 如果要支持D2000等系统,要使用tuned作为后端。由于tuned不支持holdprofile,如果电源电量过低时自动切换到saver + 模式后,如果电量充足了,就没法再切回原来的模式了,因此两者各有优缺点。*/ + enum PowerProfilePolicy + { + // 使用power-profiles-daemon作为后端 + POWER_PROFILE_POLICY_HADESS = 1, + // 使用tuned作为后端 + POWER_PROFILE_POLICY_TUNED = 2, + }; + + enum PowerProfileMode + { + // 节能 + POWER_PROFILE_MODE_SAVER = 0, + // 平衡 + POWER_PROFILE_MODE_BALANCED = 1, + // 高性能 + POWER_PROFILE_MODE_PERFORMANCE = 2, + }; + #define POWER_DBUS_NAME "com.kylinsec.Kiran.SessionDaemon.Power" #define POWER_OBJECT_PATH "/com/kylinsec/Kiran/SessionDaemon/Power" @@ -157,6 +178,8 @@ extern "C" #define POWER_SCHEMA_TRAY_ICON_POLICY "tray-icon-policy" // 设置获取显示器亮度值的策略,'tool'是直接操作背光设备文件,'x11'是通过xrandr接口调节亮度 #define POWER_SCHEMA_MONITOR_BACKLIGHT_POLICY "monitor-backlight-policy" +// 选用的profiles后端 +#define POWER_SCHEMA_PROFILE_POLICY "profile-policy" #ifdef __cplusplus } diff --git a/plugins/power/com.kylinsec.Kiran.SessionDaemon.Power.xml b/plugins/power/com.kylinsec.Kiran.SessionDaemon.Power.xml index fe2f35e..afa5ebc 100644 --- a/plugins/power/com.kylinsec.Kiran.SessionDaemon.Power.xml +++ b/plugins/power/com.kylinsec.Kiran.SessionDaemon.Power.xml @@ -81,6 +81,13 @@ Enable cpu save energy when the ups or battery power is low. + + + The profile mode. Refer to PowerProfileMode in power-i.h + + Switch profile mode. + + Indicates whether the system is running on battery power. @@ -106,6 +113,11 @@ Whether does the cpu save energy when the ups or battery power is low. + + + The active profile mode. + + @@ -119,5 +131,9 @@ + + + + diff --git a/plugins/power/power-manager.cpp b/plugins/power/power-manager.cpp index 9282b85..cf5d8d5 100644 --- a/plugins/power/power-manager.cpp +++ b/plugins/power/power-manager.cpp @@ -27,6 +27,7 @@ PowerManager::PowerManager(PowerWrapperManager* wrapper_manager, PowerBacklight* { this->power_settings_ = Gio::Settings::create(POWER_SCHEMA_ID); this->upower_client_ = this->wrapper_manager_->get_default_upower(); + this->profiles_ = this->wrapper_manager_->get_default_profiles(); } PowerManager::~PowerManager() @@ -56,6 +57,8 @@ void PowerManager::init() sigc::mem_fun(this, &PowerManager::on_bus_acquired), sigc::mem_fun(this, &PowerManager::on_name_acquired), sigc::mem_fun(this, &PowerManager::on_name_lost)); + + this->profiles_->signal_active_profile_changed().connect(sigc::mem_fun(this, &PowerManager::on_active_profile_changed)); } void PowerManager::SetIdleAction(gint32 device, @@ -329,6 +332,12 @@ void PowerManager::EnableChargeLowSaver(bool enabled, MethodInvocation& invocati invocation.ret(); } +void PowerManager::SwitchProfile(gint32 mode, MethodInvocation& invocation) +{ + this->ActiveProfile_set(mode); + invocation.ret(); +} + bool PowerManager::DisplayIdleDimmedEnabled_setHandler(bool value) { this->power_settings_->set_boolean(POWER_SCHEMA_ENABLE_DISPLAY_IDLE_DIMMED, value); @@ -347,6 +356,11 @@ bool PowerManager::ChargeLowSaverEnabled_setHandler(bool value) return true; } +bool PowerManager::ActiveProfile_setHandler(gint32 value) +{ + return this->profiles_->switch_profile(value); +} + bool PowerManager::OnBattery_get() { return this->upower_client_->get_on_battery(); @@ -372,6 +386,11 @@ bool PowerManager::ChargeLowSaverEnabled_get() return this->power_settings_->get_boolean(POWER_SCHEMA_ENABLE_CHARGE_LOW_SAVER); } +gint32 PowerManager::ActiveProfile_get() +{ + return this->profiles_->get_active_profile(); +} + void PowerManager::on_battery_changed(bool on_battery) { this->OnBattery_set(on_battery); @@ -426,6 +445,11 @@ void PowerManager::on_brightness_changed(std::shared_ptrBrightnessChanged_signal.emit(backlight_device->get_type()); } +void PowerManager::on_active_profile_changed(int32_t profile_mode) +{ + this->ActiveProfileChanged_signal.emit(profile_mode); +} + void PowerManager::on_bus_acquired(const Glib::RefPtr& connect, Glib::ustring name) { KLOG_PROFILE("name: %s", name.c_str()); diff --git a/plugins/power/power-manager.h b/plugins/power/power-manager.h index 674de4d..97c8c7d 100644 --- a/plugins/power/power-manager.h +++ b/plugins/power/power-manager.h @@ -88,12 +88,15 @@ protected: virtual void EnableChargeLowDimmed(bool enabled, MethodInvocation &invocation); // 电量过低时是否进入节能模式 virtual void EnableChargeLowSaver(bool enabled, MethodInvocation &invocation); + // 切换电源模式 + virtual void SwitchProfile(gint32 mode, MethodInvocation &invocation); virtual bool OnBattery_setHandler(bool value) { return true; } virtual bool LidIsPresent_setHandler(bool value) { return true; } virtual bool DisplayIdleDimmedEnabled_setHandler(bool value); virtual bool ChargeLowDimmedEnabled_setHandler(bool value); virtual bool ChargeLowSaverEnabled_setHandler(bool value); + virtual bool ActiveProfile_setHandler(gint32 value); // 系统是否在使用电池供电 virtual bool OnBattery_get(); @@ -102,6 +105,7 @@ protected: virtual bool DisplayIdleDimmedEnabled_get(); virtual bool ChargeLowDimmedEnabled_get(); virtual bool ChargeLowSaverEnabled_get(); + virtual gint32 ActiveProfile_get(); private: void init(); @@ -111,6 +115,7 @@ private: void on_settings_changed(const Glib::ustring &key); void on_brightness_changed(std::shared_ptr backlight_device, int32_t brightness_value); + void on_active_profile_changed(int32_t profile_mode); void on_bus_acquired(const Glib::RefPtr &connect, Glib::ustring name); void on_name_acquired(const Glib::RefPtr &connect, Glib::ustring name); @@ -122,6 +127,7 @@ private: PowerWrapperManager *wrapper_manager_; PowerBacklight *backlight_; std::shared_ptr upower_client_; + std::shared_ptr profiles_; Glib::RefPtr power_settings_; diff --git a/plugins/power/save/power-save.cpp b/plugins/power/save/power-save.cpp index 3dfcfce..c5b6bf8 100644 --- a/plugins/power/save/power-save.cpp +++ b/plugins/power/save/power-save.cpp @@ -162,7 +162,7 @@ void PowerSave::do_cpu_saver() return; } - this->cpu_saver_cookie_ = this->profiles_->hold_profile(POWER_PROFILE_SAVER, "battery or ups power low.", "kiran-session-daemon"); + this->cpu_saver_cookie_ = this->profiles_->hold_profile(PowerProfileMode::POWER_PROFILE_MODE_SAVER, "battery or ups power low."); this->cpu_saver_timestamp_ = time(NULL); } @@ -207,7 +207,7 @@ void PowerSave::on_monitor_brightness_changed(int32_t brightness_percentage) } } -void PowerSave::on_active_profile_changed(const Glib::ustring& active_profile) +void PowerSave::on_active_profile_changed(int32_t profile_mode) { if (this->cpu_saver_timestamp_ > 0 && this->cpu_saver_timestamp_ + CPU_SAVER_INTERVAL < time(NULL)) diff --git a/plugins/power/save/power-save.h b/plugins/power/save/power-save.h index ca0f6fd..6f994f5 100644 --- a/plugins/power/save/power-save.h +++ b/plugins/power/save/power-save.h @@ -54,7 +54,7 @@ private: void on_kbd_brightness_changed(int32_t brightness_percentage); void on_monitor_brightness_changed(int32_t brightness_percentage); - void on_active_profile_changed(const Glib::ustring& active_profile); + void on_active_profile_changed(int32_t profile_mode); private: static PowerSave* instance_; diff --git a/plugins/power/wrapper/power-profiles-hadess.cpp b/plugins/power/wrapper/power-profiles-hadess.cpp new file mode 100644 index 0000000..d6e4247 --- /dev/null +++ b/plugins/power/wrapper/power-profiles-hadess.cpp @@ -0,0 +1,217 @@ +/** + * Copyright (c) 2023 ~ 2024 KylinSec Co., Ltd. + * kiran-cc-daemon is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * + * Author: tangjie02 + */ + +#include "plugins/power/wrapper/power-profiles-hadess.h" +#include "power-i.h" + +namespace Kiran +{ +#define PROFILES_HADESS_MODE_SAVER "power-saver" +#define PROFILES_HADESS_MODE_BALANCED "balanced" +#define PROFILES_HADESS_MODE_PERFORMANCE "performance" + +#define PROFILES_HADESS_DBUS_NAME "net.hadess.PowerProfiles" +#define PROFILES_HADESS_DBUS_OBJECT_PATH "/net/hadess/PowerProfiles" +#define PROFILES_HADESS_DBUS_INTERFACE "net.hadess.PowerProfiles" +#define PROFILES_HADESS_DBUS_PROP_ACTIVE_PROFILE "ActiveProfile" + +PowerProfilesHadess::PowerProfilesHadess() +{ + try + { + this->profiles_proxy_ = Gio::DBus::Proxy::create_for_bus_sync(Gio::DBus::BUS_TYPE_SYSTEM, + PROFILES_HADESS_DBUS_NAME, + PROFILES_HADESS_DBUS_OBJECT_PATH, + PROFILES_HADESS_DBUS_INTERFACE); + } + catch (const Glib::Error &e) + { + KLOG_WARNING("Failed to create bus sync: %s", e.what().c_str()); + return; + } +} + +void PowerProfilesHadess::init() +{ + this->profiles_proxy_->signal_properties_changed().connect(sigc::mem_fun(this, &PowerProfilesHadess::on_properties_changed)); +} + +bool PowerProfilesHadess::switch_profile(int32_t profile_mode) +{ + RETURN_VAL_IF_FALSE(this->profiles_proxy_, false); + + auto profile_mode_str = this->porfile_mode_enum2str(profile_mode); + KLOG_DEBUG("Switch power active profile to %s.", profile_mode_str.c_str()); + + try + { + std::vector params_base; + params_base.push_back(Glib::Variant::create(PROFILES_HADESS_DBUS_INTERFACE)); + params_base.push_back(Glib::Variant::create(PROFILES_HADESS_DBUS_PROP_ACTIVE_PROFILE)); + params_base.push_back(Glib::Variant::create(Glib::Variant::create((profile_mode_str)))); + Glib::VariantContainerBase params = Glib::VariantContainerBase::create_tuple(params_base); + this->profiles_proxy_->call_sync("org.freedesktop.DBus.Properties.Set", params); + } + catch (const Glib::Error &e) + { + KLOG_WARNING("Failed to set property %s to %s: %s", + PROFILES_HADESS_DBUS_PROP_ACTIVE_PROFILE, + profile_mode_str.c_str(), + e.what().c_str()); + return false; + } + catch (const std::exception &e) + { + KLOG_WARNING("Failed to set property %s to %s: %s", + PROFILES_HADESS_DBUS_PROP_ACTIVE_PROFILE, + profile_mode_str.c_str(), + e.what()); + return false; + } + return true; +} + +uint32_t PowerProfilesHadess::hold_profile(int32_t profile_mode, const std::string &reason) +{ + RETURN_VAL_IF_FALSE(this->profiles_proxy_, -1); + + auto profile_mode_str = this->porfile_mode_enum2str(profile_mode); + KLOG_DEBUG("Hold power active profile to %s.", profile_mode_str.c_str()); + + try + { + auto parameters = g_variant_new("(sss)", profile_mode_str.c_str(), reason.c_str(), "kiran-session-daemon"); + Glib::VariantContainerBase base(parameters, false); + auto retval = this->profiles_proxy_->call_sync("HoldProfile", base); + auto v1 = retval.get_child(0); + return Glib::VariantBase::cast_dynamic>(v1).get(); + } + catch (const Glib::Error &e) + { + KLOG_WARNING("Failed to call HoldProfile: %s", e.what().c_str()); + return -1; + } + catch (const std::exception &e) + { + KLOG_WARNING("Failed to call HoldProfile: %s", e.what()); + return -1; + } + return 0; +} + +void PowerProfilesHadess::release_profile(uint32_t cookie) +{ + Glib::VariantContainerBase retval; + + RETURN_IF_FALSE(this->profiles_proxy_); + + auto parameters = g_variant_new("(u)", cookie); + Glib::VariantContainerBase base(parameters, false); + + try + { + this->profiles_proxy_->call_sync("ReleaseProfile", base); + } + catch (const Glib::Error &e) + { + KLOG_WARNING("Failed to call ReleaseProfile: %s", e.what().c_str()); + } +} + +int32_t PowerProfilesHadess::get_active_profile() +{ + RETURN_VAL_IF_FALSE(this->profiles_proxy_, POWER_PROFILE_MODE_PERFORMANCE); + + try + { + Glib::VariantBase value; + this->profiles_proxy_->get_cached_property(value, PROFILES_HADESS_DBUS_PROP_ACTIVE_PROFILE); + auto profile_mode_str = Glib::VariantBase::cast_dynamic>(value).get(); + return this->porfile_mode_str2enum(profile_mode_str); + } + catch (const std::exception &e) + { + KLOG_WARNING("Failed to get property %s: %s", PROFILES_HADESS_DBUS_PROP_ACTIVE_PROFILE, e.what()); + } + // 默认返回高性能模式 + return POWER_PROFILE_MODE_PERFORMANCE; +} + +std::string PowerProfilesHadess::porfile_mode_enum2str(int32_t profile_mode) +{ + switch (profile_mode) + { + case PowerProfileMode::POWER_PROFILE_MODE_SAVER: + return PROFILES_HADESS_MODE_SAVER; + case PowerProfileMode::POWER_PROFILE_MODE_BALANCED: + return PROFILES_HADESS_MODE_BALANCED; + case PowerProfileMode::POWER_PROFILE_MODE_PERFORMANCE: + return PROFILES_HADESS_MODE_PERFORMANCE; + default: + { + KLOG_WARNING("Unknown profile mode %d, so return performance as current profile mode.", profile_mode); + return PROFILES_HADESS_MODE_PERFORMANCE; + } + } +} + +int32_t PowerProfilesHadess::porfile_mode_str2enum(const std::string &profile_mode_str) +{ + switch (shash(profile_mode_str.c_str())) + { + case CONNECT(PROFILES_HADESS_MODE_SAVER, _hash): + return PowerProfileMode::POWER_PROFILE_MODE_SAVER; + case CONNECT(PROFILES_HADESS_MODE_BALANCED, _hash): + return PowerProfileMode::POWER_PROFILE_MODE_BALANCED; + case CONNECT(PROFILES_HADESS_MODE_PERFORMANCE, _hash): + return PowerProfileMode::POWER_PROFILE_MODE_PERFORMANCE; + + default: + { + KLOG_WARNING("Unknown profile mode %s, so return performance as current profile mode.", profile_mode_str.c_str()); + return PowerProfileMode::POWER_PROFILE_MODE_PERFORMANCE; + } + } +} + +void PowerProfilesHadess::on_properties_changed(const Gio::DBus::Proxy::MapChangedProperties &changed_properties, + const std::vector &invalidated_properties) +{ + try + { + for (auto &iter : changed_properties) + { + switch (shash(iter.first.c_str())) + { + case CONNECT(PROFILES_HADESS_DBUS_PROP_ACTIVE_PROFILE, _hash): + { + auto profile_mode_str = Glib::VariantBase::cast_dynamic>(iter.second).get(); + auto profile_mode = this->porfile_mode_str2enum(profile_mode_str); + this->active_profile_changed_.emit(profile_mode); + break; + } + default: + break; + } + } + } + catch (const std::exception &e) + { + KLOG_WARNING("%s", e.what()); + } + + return; +} + +} // namespace Kiran diff --git a/plugins/power/wrapper/power-profiles-hadess.h b/plugins/power/wrapper/power-profiles-hadess.h new file mode 100644 index 0000000..40bb4f5 --- /dev/null +++ b/plugins/power/wrapper/power-profiles-hadess.h @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2023 ~ 2024 KylinSec Co., Ltd. + * kiran-cc-daemon is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * + * Author: tangjie02 + */ + +#pragma once + +#include "plugins/power/wrapper/power-profiles.h" + +namespace Kiran +{ +class PowerProfilesHadess : public PowerProfiles +{ +public: + PowerProfilesHadess(); + virtual ~PowerProfilesHadess(){}; + + virtual void init(); + virtual bool switch_profile(int32_t profile_mode); + virtual uint32_t hold_profile(int32_t profile_mode, const std::string &reason); + virtual void release_profile(uint32_t cookie); + virtual int32_t get_active_profile(); + +private: + std::string porfile_mode_enum2str(int32_t profile_mode); + int32_t porfile_mode_str2enum(const std::string &profile_mode_str); + void on_properties_changed(const Gio::DBus::Proxy::MapChangedProperties &changed_properties, + const std::vector &invalidated_properties); + +private: + Glib::RefPtr profiles_proxy_; +}; +} // namespace Kiran diff --git a/plugins/power/wrapper/power-profiles-tuned.cpp b/plugins/power/wrapper/power-profiles-tuned.cpp new file mode 100644 index 0000000..ee1fa7b --- /dev/null +++ b/plugins/power/wrapper/power-profiles-tuned.cpp @@ -0,0 +1,194 @@ +/** + * Copyright (c) 2023 ~ 2024 KylinSec Co., Ltd. + * kiran-cc-daemon is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * + * Author: tangjie02 + */ + +#include "plugins/power/wrapper/power-profiles-tuned.h" +#include "power-i.h" + +namespace Kiran +{ +#define PROFILES_TUNED_MODE_SAVER "powersave" +#define PROFILES_TUNED_MODE_BALANCED "balanced" +#define PROFILES_TUNED_MODE_PERFORMANCE "throughput-performance" + +#define PROFILES_TUNED_DBUS_NAME "com.redhat.tuned" +#define PROFILES_TUNED_DBUS_OBJECT_PATH "/Tuned" +#define PROFILES_TUNED_DBUS_INTERFACE "com.redhat.tuned.control" + +PowerProfilesTuned::PowerProfilesTuned() +{ + try + { + this->profiles_proxy_ = Gio::DBus::Proxy::create_for_bus_sync(Gio::DBus::BUS_TYPE_SYSTEM, + PROFILES_TUNED_DBUS_NAME, + PROFILES_TUNED_DBUS_OBJECT_PATH, + PROFILES_TUNED_DBUS_INTERFACE); + } + catch (const Glib::Error &e) + { + KLOG_WARNING("Failed to create bus sync: %s", e.what().c_str()); + return; + } +} + +void PowerProfilesTuned::init() +{ + this->profiles_proxy_->signal_signal().connect(sigc::mem_fun(this, &PowerProfilesTuned::on_profile_signal)); +} + +bool PowerProfilesTuned::switch_profile(int32_t profile_mode) +{ + auto retval = this->hold_profile(profile_mode, std::string()); + return (retval >= 0); +} + +uint32_t PowerProfilesTuned::hold_profile(int32_t profile_mode, const std::string &) +{ + RETURN_VAL_IF_FALSE(this->profiles_proxy_, 0); + + auto profile_mode_str = this->porfile_mode_enum2str(profile_mode); + KLOG_DEBUG("Hold power active profile to %s.", profile_mode_str.c_str()); + + try + { + auto parameters = g_variant_new("(s)", profile_mode_str.c_str()); + Glib::VariantContainerBase base(parameters, false); + auto retval = this->profiles_proxy_->call_sync("switch_profile", base); + + auto ret_parameters = retval.get_child(0); + auto ret_parameters_tuple = Glib::VariantBase::cast_dynamic>>(ret_parameters); + auto successed = ret_parameters_tuple.get_child(0); + auto reason = ret_parameters_tuple.get_child(1); + + if (!successed) + { + KLOG_WARNING("Failed to call switch_profile: %s.", reason.c_str()); + return -1; + } + } + catch (const Glib::Error &e) + { + KLOG_WARNING("Failed to call switch_profile: %s", e.what().c_str()); + return -1; + } + catch (const std::exception &e) + { + KLOG_WARNING("Failed to call switch_profile: %s", e.what()); + return -1; + } + + return 0; +} + +int32_t PowerProfilesTuned::get_active_profile() +{ + RETURN_VAL_IF_FALSE(this->profiles_proxy_, POWER_PROFILE_MODE_PERFORMANCE); + + std::string profile_mode_str; + try + { + auto retval = this->profiles_proxy_->call_sync("active_profile", Glib::VariantContainerBase()); + auto v1 = retval.get_child(0); + profile_mode_str = Glib::VariantBase::cast_dynamic>(v1).get(); + } + catch (const Glib::Error &e) + { + KLOG_WARNING("Failed to call active_profile: %s", e.what().c_str()); + } + catch (const std::exception &e) + { + KLOG_WARNING("Failed to call active_profile: %s", e.what()); + } + + return this->porfile_mode_str2enum(profile_mode_str); +} + +std::string PowerProfilesTuned::porfile_mode_enum2str(int32_t profile_mode) +{ + switch (profile_mode) + { + case PowerProfileMode::POWER_PROFILE_MODE_SAVER: + return PROFILES_TUNED_MODE_SAVER; + case PowerProfileMode::POWER_PROFILE_MODE_BALANCED: + return PROFILES_TUNED_MODE_BALANCED; + case PowerProfileMode::POWER_PROFILE_MODE_PERFORMANCE: + return PROFILES_TUNED_MODE_PERFORMANCE; + default: + { + KLOG_WARNING("Unknown profile mode %d, so return performance as current profile mode.", profile_mode); + return PROFILES_TUNED_MODE_PERFORMANCE; + } + } +} + +int32_t PowerProfilesTuned::porfile_mode_str2enum(const std::string &profile_mode_str) +{ + switch (shash(profile_mode_str.c_str())) + { + case CONNECT(PROFILES_TUNED_MODE_SAVER, _hash): + return PowerProfileMode::POWER_PROFILE_MODE_SAVER; + case CONNECT(PROFILES_TUNED_MODE_BALANCED, _hash): + return PowerProfileMode::POWER_PROFILE_MODE_BALANCED; + case CONNECT(PROFILES_TUNED_MODE_PERFORMANCE, _hash): + return PowerProfileMode::POWER_PROFILE_MODE_PERFORMANCE; + + default: + { + KLOG_WARNING("Unknown profile mode %s, so return performance as current profile mode.", profile_mode_str.c_str()); + return PowerProfileMode::POWER_PROFILE_MODE_PERFORMANCE; + } + } +} + +void PowerProfilesTuned::on_profile_signal(const Glib::ustring &sender_name, + const Glib::ustring &signal_name, + const Glib::VariantContainerBase ¶meters) +{ + switch (shash(signal_name.c_str())) + { + case "profile_changed"_hash: + { + try + { + Glib::VariantContainerBase v1; + Glib::VariantContainerBase v2; + Glib::VariantContainerBase v3; + parameters.get_child(v1, 0); + parameters.get_child(v2, 1); + parameters.get_child(v3, 2); + + auto profiled_mode_str = Glib::VariantBase::cast_dynamic>(v1).get(); + auto successed = Glib::VariantBase::cast_dynamic>(v2).get(); + auto reason = Glib::VariantBase::cast_dynamic>(v3).get(); + + if (!successed) + { + KLOG_WARNING("Failed to call switch_profile: %s.", reason.c_str()); + } + else + { + this->active_profile_changed_.emit(this->porfile_mode_str2enum(profiled_mode_str)); + } + } + catch (const std::exception &e) + { + KLOG_WARNING("%s.", e.what()); + } + break; + } + default: + break; + } +} + +} // namespace Kiran diff --git a/plugins/power/wrapper/power-profiles-tuned.h b/plugins/power/wrapper/power-profiles-tuned.h new file mode 100644 index 0000000..af1fcf5 --- /dev/null +++ b/plugins/power/wrapper/power-profiles-tuned.h @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2023 ~ 2024 KylinSec Co., Ltd. + * kiran-cc-daemon is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * + * Author: tangjie02 + */ + +#pragma once + +#include "plugins/power/wrapper/power-profiles.h" + +namespace Kiran +{ +class PowerProfilesTuned : public PowerProfiles +{ +public: + PowerProfilesTuned(); + virtual ~PowerProfilesTuned(){}; + + virtual void init(); + virtual bool switch_profile(int32_t profile_mode); + // 这里永远返回0,因为不支持hold操作 + virtual uint32_t hold_profile(int32_t profile_mode, const std::string& reason); + // 不支持该操作,什么都不执行 + virtual void release_profile(uint32_t cookie){}; + virtual int32_t get_active_profile(); + +private: + std::string porfile_mode_enum2str(int32_t profile_mode); + int32_t porfile_mode_str2enum(const std::string& profile_mode_str); + void on_profile_signal(const Glib::ustring& sender_name, + const Glib::ustring& signal_name, + const Glib::VariantContainerBase& parameters); + +private: + Glib::RefPtr profiles_proxy_; +}; +} // namespace Kiran diff --git a/plugins/power/wrapper/power-profiles.cpp b/plugins/power/wrapper/power-profiles.cpp index d7ba1b3..ac5f15c 100644 --- a/plugins/power/wrapper/power-profiles.cpp +++ b/plugins/power/wrapper/power-profiles.cpp @@ -13,135 +13,24 @@ */ #include "plugins/power/wrapper/power-profiles.h" +#include "plugins/power/wrapper/power-profiles-hadess.h" +#include "plugins/power/wrapper/power-profiles-tuned.h" +#include "power-i.h" namespace Kiran { -#define PROFILES_DBUS_NAME "net.hadess.PowerProfiles" -#define PROFILES_DBUS_OBJECT_PATH "/net/hadess/PowerProfiles" -#define PROFILES_DBUS_INTERFACE "net.hadess.PowerProfiles" -#define PROFILES_DBUS_PROP_ACTIVE_PROFILE "ActiveProfile" - -PowerProfiles::PowerProfiles() -{ - try - { - this->profiles_proxy_ = Gio::DBus::Proxy::create_for_bus_sync(Gio::DBus::BUS_TYPE_SYSTEM, - PROFILES_DBUS_NAME, - PROFILES_DBUS_OBJECT_PATH, - PROFILES_DBUS_INTERFACE); - } - catch (const Glib::Error &e) - { - KLOG_WARNING("Failed to create bus sync: %s", e.what().c_str()); - return; - } -} - -void PowerProfiles::init() -{ - this->profiles_proxy_->signal_properties_changed().connect(sigc::mem_fun(this, &PowerProfiles::on_properties_changed)); -} - -uint32_t PowerProfiles::hold_profile(const std::string &profile, - const std::string &reason, - const std::string &application_id) -{ - Glib::VariantContainerBase retval; - - RETURN_VAL_IF_FALSE(this->profiles_proxy_, false); - - auto parameters = g_variant_new("(sss)", profile.c_str(), reason.c_str(), application_id.c_str()); - Glib::VariantContainerBase base(parameters, false); - - KLOG_DEBUG("Set power active profile to %s.", profile.c_str()); - - try - { - retval = this->profiles_proxy_->call_sync("HoldProfile", base); - } - catch (const Glib::Error &e) - { - KLOG_WARNING("%s", e.what().c_str()); - return 0; - } - - try - { - auto v1 = retval.get_child(0); - auto cookie = Glib::VariantBase::cast_dynamic>(v1).get(); - return cookie; - } - catch (const std::exception &e) - { - KLOG_WARNING("%s", e.what()); - } - - return 0; -} - -void PowerProfiles::release_profile(uint32_t cookie) +std::shared_ptr PowerProfiles::create() { - Glib::VariantContainerBase retval; - - RETURN_IF_FALSE(this->profiles_proxy_); - - auto parameters = g_variant_new("(u)", cookie); - Glib::VariantContainerBase base(parameters, false); - - try + auto power_settings = Gio::Settings::create(POWER_SCHEMA_ID); + auto profiles_policy = power_settings->get_enum(POWER_SCHEMA_PROFILE_POLICY); + switch (profiles_policy) { - this->profiles_proxy_->call_sync("ReleaseProfile", base); - } - catch (const Glib::Error &e) - { - KLOG_WARNING("%s", e.what().c_str()); + case PowerProfilePolicy::POWER_PROFILE_POLICY_HADESS: + return std::make_shared(); + case PowerProfilePolicy::POWER_PROFILE_POLICY_TUNED: + return std::make_shared(); + default: + return std::make_shared(); } } - -std::string PowerProfiles::get_active_profile() -{ - RETURN_VAL_IF_FALSE(this->profiles_proxy_, POWER_PROFILE_BALANCED); - - try - { - Glib::VariantBase value; - this->profiles_proxy_->get_cached_property(value, PROFILES_DBUS_PROP_ACTIVE_PROFILE); - return Glib::VariantBase::cast_dynamic>(value).get(); - } - catch (const std::exception &e) - { - KLOG_WARNING("%s", e.what()); - } - // 默认返回平衡模式 - return POWER_PROFILE_BALANCED; -} - -void PowerProfiles::on_properties_changed(const Gio::DBus::Proxy::MapChangedProperties &changed_properties, - const std::vector &invalidated_properties) -{ - try - { - for (auto &iter : changed_properties) - { - switch (shash(iter.first.c_str())) - { - case CONNECT(PROFILES_DBUS_PROP_ACTIVE_PROFILE, _hash): - { - auto active_profile = Glib::VariantBase::cast_dynamic>(iter.second).get(); - this->active_profile_changed_.emit(active_profile); - break; - } - default: - break; - } - } - } - catch (const std::exception &e) - { - KLOG_WARNING("%s", e.what()); - } - - return; -} - } // namespace Kiran diff --git a/plugins/power/wrapper/power-profiles.h b/plugins/power/wrapper/power-profiles.h index cf5b943..8f9f6f7 100644 --- a/plugins/power/wrapper/power-profiles.h +++ b/plugins/power/wrapper/power-profiles.h @@ -12,41 +12,34 @@ * Author: tangjie02 */ +#pragma once + #include "lib/base/base.h" namespace Kiran { -#define POWER_PROFILE_SAVER "power-saver" -#define POWER_PROFILE_BALANCED "balanced" -#define POWER_PROFILE_PERFORMANCE "performance" - class PowerProfiles { public: - PowerProfiles(); - virtual ~PowerProfiles(){}; - - void init(); + // 根据gsettings的设置创建不同的子类 + static std::shared_ptr create(); - // 设置模式,如果调用了ReleaseProfile,则进行恢复。如果有其他用户进行了手动设置(直接修改ActiveProfile属性),则不再hold当前模式 - uint32_t hold_profile(const std::string &profile, - const std::string &reason, - const std::string &application_id); + virtual void init() = 0; + // 设置模式 + virtual bool switch_profile(int32_t profile_mode) = 0; + /* 临时设置模式,如果调用了ReleaseProfile,则进行恢复。如果调用了switch_profile,则不再hold当前模式 + 如果返回值大于0,则表示一个cookie;如果返回值等于0;则表示无法hold,只能永久生效,功能同switch_profile; + 如果小于0则表示调用失败。*/ + virtual uint32_t hold_profile(int32_t profile_mode, const std::string &reason) = 0; // 释放hold_profile操作。恢复到之前的模式 - void release_profile(uint32_t cookie); - - std::string get_active_profile(); - - sigc::signal &signal_active_profile_changed() { return this->active_profile_changed_; }; - -private: - void on_properties_changed(const Gio::DBus::Proxy::MapChangedProperties &changed_properties, - const std::vector &invalidated_properties); + virtual void release_profile(uint32_t cookie) = 0; + // 获取当前模式 + virtual int32_t get_active_profile() = 0; -private: - Glib::RefPtr profiles_proxy_; + sigc::signal &signal_active_profile_changed() { return this->active_profile_changed_; }; - sigc::signal active_profile_changed_; +protected: + sigc::signal active_profile_changed_; }; } // namespace Kiran diff --git a/plugins/power/wrapper/power-wrapper-manager.cpp b/plugins/power/wrapper/power-wrapper-manager.cpp index 685000d..c60f46b 100644 --- a/plugins/power/wrapper/power-wrapper-manager.cpp +++ b/plugins/power/wrapper/power-wrapper-manager.cpp @@ -22,7 +22,7 @@ PowerWrapperManager::PowerWrapperManager() this->screensaver_ = std::make_shared(); this->session_ = std::make_shared(); this->upower_ = std::make_shared(); - this->profiles_ = std::make_shared(); + this->profiles_ = PowerProfiles::create(); } PowerWrapperManager::~PowerWrapperManager() -- 2.36.1