kiran-cc-daemon/0001-feature-power-Compatiable-two-power-profile-daemon-w.patch

1045 lines
38 KiB
Diff
Raw Normal View History

From 1121e867aea9f283b8e596c06a6889d252d8d31f Mon Sep 17 00:00:00 2001
From: tangjie02 <tangjie02@kylinsec.com.cn>
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 <tangjie02@kylinsec.com.cn>
---
.../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 @@
<value nick="x11" value="2"/>
</enum>
+ <enum id="com.kylinsec.kiran.power.profile-policy">
+ <value nick="hadess" value="1"/>
+ <value nick="tuned" value="2"/>
+ </enum>
+
<schema id="com.kylinsec.kiran.power" path="/com/kylinsec/kiran/power/">
<key name="computer-battery-idle-time" type="i">
@@ -136,5 +141,10 @@
<default>'auto'</default>
<description>Set the policy for obtaining brightness values.</description>
</key>
+
+ <key name="profile-policy" enum="com.kylinsec.kiran.power.profile-policy">
+ <default>'hadess'</default>
+ <description>The profiles daemon used by current power plugin.</description>
+ </key>
</schema>
</schemalist>
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 @@
<description>Enable cpu save energy when the ups or battery power is low.</description>
</method>
+ <method name="SwitchProfile">
+ <arg type="i" name="mode" direction="in">
+ <description>The profile mode. Refer to PowerProfileMode in power-i.h</description>
+ </arg>
+ <description>Switch profile mode.</description>
+ </method>
+
<property name="OnBattery" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="true"/>
<description>Indicates whether the system is running on battery power.</description>
@@ -106,6 +113,11 @@
<description>Whether does the cpu save energy when the ups or battery power is low.</description>
</property>
+ <property name="ActiveProfile" type="i" access="read">
+ <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="true"/>
+ <description>The active profile mode.</description>
+ </property>
+
<signal name="IdleActionChanged">
<arg name="device" type="i" />
<arg name="supply" type="i" />
@@ -119,5 +131,9 @@
<arg name="device" type="i" />
</signal>
+ <signal name="ActiveProfileChanged">
+ <arg name="active_profile" type="i" />
+ </signal>
+
</interface>
</node>
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_ptr<PowerBacklightPercentag
this->BrightnessChanged_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<Gio::DBus::Connection>& 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<PowerBacklightPercentage> backlight_device, int32_t brightness_value);
+ void on_active_profile_changed(int32_t profile_mode);
void on_bus_acquired(const Glib::RefPtr<Gio::DBus::Connection> &connect, Glib::ustring name);
void on_name_acquired(const Glib::RefPtr<Gio::DBus::Connection> &connect, Glib::ustring name);
@@ -122,6 +127,7 @@ private:
PowerWrapperManager *wrapper_manager_;
PowerBacklight *backlight_;
std::shared_ptr<PowerUPower> upower_client_;
+ std::shared_ptr<PowerProfiles> profiles_;
Glib::RefPtr<Gio::Settings> 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 <tangjie02@kylinos.com.cn>
+ */
+
+#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<Glib::VariantBase> params_base;
+ params_base.push_back(Glib::Variant<Glib::ustring>::create(PROFILES_HADESS_DBUS_INTERFACE));
+ params_base.push_back(Glib::Variant<Glib::ustring>::create(PROFILES_HADESS_DBUS_PROP_ACTIVE_PROFILE));
+ params_base.push_back(Glib::Variant<Glib::VariantBase>::create(Glib::Variant<Glib::ustring>::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<Glib::Variant<uint32_t>>(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<Glib::Variant<Glib::ustring>>(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<Glib::ustring> &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<Glib::Variant<Glib::ustring>>(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 <tangjie02@kylinos.com.cn>
+ */
+
+#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<Glib::ustring> &invalidated_properties);
+
+private:
+ Glib::RefPtr<Gio::DBus::Proxy> 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 <tangjie02@kylinos.com.cn>
+ */
+
+#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<Glib::Variant<std::tuple<bool, Glib::ustring>>>(ret_parameters);
+ auto successed = ret_parameters_tuple.get_child<bool>(0);
+ auto reason = ret_parameters_tuple.get_child<Glib::ustring>(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<Glib::Variant<Glib::ustring>>(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 &parameters)
+{
+ 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<Glib::Variant<Glib::ustring>>(v1).get();
+ auto successed = Glib::VariantBase::cast_dynamic<Glib::Variant<bool>>(v2).get();
+ auto reason = Glib::VariantBase::cast_dynamic<Glib::Variant<Glib::ustring>>(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 <tangjie02@kylinos.com.cn>
+ */
+
+#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<Gio::DBus::Proxy> 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<Glib::Variant<uint32_t>>(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> 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<PowerProfilesHadess>();
+ case PowerProfilePolicy::POWER_PROFILE_POLICY_TUNED:
+ return std::make_shared<PowerProfilesTuned>();
+ default:
+ return std::make_shared<PowerProfilesTuned>();
}
}
-
-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<Glib::Variant<Glib::ustring>>(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<Glib::ustring> &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<Glib::Variant<Glib::ustring>>(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 <tangjie02@kylinos.com.cn>
*/
+#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<PowerProfiles> 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<void, const Glib::ustring &> &signal_active_profile_changed() { return this->active_profile_changed_; };
-
-private:
- void on_properties_changed(const Gio::DBus::Proxy::MapChangedProperties &changed_properties,
- const std::vector<Glib::ustring> &invalidated_properties);
+ virtual void release_profile(uint32_t cookie) = 0;
+ // 获取当前模式
+ virtual int32_t get_active_profile() = 0;
-private:
- Glib::RefPtr<Gio::DBus::Proxy> profiles_proxy_;
+ sigc::signal<void, int32_t> &signal_active_profile_changed() { return this->active_profile_changed_; };
- sigc::signal<void, const Glib::ustring &> active_profile_changed_;
+protected:
+ sigc::signal<void, int32_t> 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<PowerScreenSaver>();
this->session_ = std::make_shared<PowerSession>();
this->upower_ = std::make_shared<PowerUPower>();
- this->profiles_ = std::make_shared<PowerProfiles>();
+ this->profiles_ = PowerProfiles::create();
}
PowerWrapperManager::~PowerWrapperManager()
--
2.36.1