Add support for adaptive profiles property

The AdaptiveProfiles property will apply tuned profiles when the system switches
to and from battery.
This commit is contained in:
Mario Limonciello 2024-04-25 22:54:15 -05:00
parent d8120fe3e0
commit 6825145599
3 changed files with 98 additions and 20 deletions

View file

@ -127,6 +127,7 @@ static PpdApp *ppd_app = NULL;
static void stop_profile_drivers (PpdApp *data);
static void start_profile_drivers (PpdApp *data);
static void upower_battery_set_power_changed_reason (PpdApp *, PpdPowerChangedReason);
static gboolean set_adaptive (PpdApp *data, gboolean enable, GError **error);
/* profile drivers and actions */
#include "ppd-action-trickle-charge.h"
@ -162,6 +163,7 @@ typedef enum {
PROP_DEGRADED = 1 << 4,
PROP_ACTIVE_PROFILE_HOLDS = 1 << 5,
PROP_VERSION = 1 << 6,
PROP_ADAPTIVE_PROFILES = 1 << 7,
} PropertiesMask;
#define PROP_ALL (PROP_ACTIVE_PROFILE | \
@ -219,6 +221,12 @@ get_performance_degraded (PpdApp *data)
return g_strjoin (",", cpu_degraded, platform_degraded, NULL);
}
static GVariant *
get_adaptive_profiles (PpdApp *data)
{
return g_variant_new_boolean (data->upower_proxy != NULL);
}
static GVariant *
get_profiles_variant (PpdApp *data)
{
@ -360,6 +368,10 @@ send_dbus_event_iface (PpdApp *data,
g_variant_builder_add (&props_builder, "{sv}", "Version",
g_variant_new_string (VERSION));
}
if (mask & PROP_ADAPTIVE_PROFILES) {
g_variant_builder_add (&props_builder, "{sb}", "AdaptiveProfiles",
get_adaptive_profiles (data));
}
props_changed = g_variant_new ("(s@a{sv}@as)", iface,
g_variant_builder_end (&props_builder),
@ -872,6 +884,8 @@ handle_get_property (GDBusConnection *connection,
return get_profile_holds_variant (data);
if (g_strcmp0 (property_name, "Version") == 0)
return g_variant_new_string (VERSION);
if (g_strcmp0 (property_name, "AdaptiveProfiles") == 0)
return get_adaptive_profiles (data);
return NULL;
}
@ -886,22 +900,34 @@ handle_set_property (GDBusConnection *connection,
gpointer user_data)
{
PpdApp *data = user_data;
const char *profile;
g_return_val_if_fail (data->connection, FALSE);
if (g_strcmp0 (property_name, "ActiveProfile") != 0) {
g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
"No such property: %s", property_name);
return FALSE;
}
if (!check_action_permission (data, sender,
POWER_PROFILES_POLICY_NAMESPACE ".switch-profile",
error))
return FALSE;
g_variant_get (value, "&s", &profile);
return set_active_profile (data, profile, error);
if (g_strcmp0 (property_name, "ActiveProfile") == 0) {
const char *profile;
g_variant_get (value, "&s", &profile);
return set_active_profile (data, profile, error);
}
if (g_strcmp0 (property_name, "AdaptiveProfiles") == 0) {
gboolean enable;
g_variant_get (value, "b", &enable);
return set_adaptive (data, enable, error);
}
g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
"No such property: %s", property_name);
return FALSE;
}
static void
@ -1257,6 +1283,43 @@ maybe_disconnect_object_by_data (void *object,
g_signal_handlers_disconnect_by_data (object, data);
}
static gboolean
set_adaptive (PpdApp *data,
gboolean enable,
GError **error)
{
g_debug ("setting adaptive profiles to %d", enable);
if (enable) {
if (data->upower_proxy) {
g_debug ("adaptive profiles already enabled");
return TRUE;
}
g_dbus_proxy_new (data->connection,
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
NULL,
UPOWER_DBUS_NAME,
UPOWER_DBUS_PATH,
UPOWER_DBUS_INTERFACE,
data->cancellable,
on_upower_proxy_cb,
data);
} else {
if (!data->upower_proxy) {
g_debug ("adaptive profiles already disabled");
return TRUE;
}
g_clear_signal_handler (&data->upower_watch_id, data->upower_proxy);
g_clear_signal_handler (&data->upower_properties_id, data->upower_proxy);
maybe_disconnect_object_by_data (data->upower_proxy, data);
g_clear_object (&data->upower_proxy);
upower_battery_set_power_changed_reason (data, PPD_POWER_CHANGED_REASON_UNKNOWN);
}
return TRUE;
}
static void
stop_profile_drivers (PpdApp *data)
{
@ -1272,11 +1335,8 @@ stop_profile_drivers (PpdApp *data)
g_ptr_array_set_size (data->probed_drivers, 0);
disconnect_array_objects_signals_by_data (data->actions, data);
g_ptr_array_set_size (data->actions, 0);
g_clear_signal_handler (&data->upower_watch_id, data->upower_proxy);
g_clear_signal_handler (&data->upower_properties_id, data->upower_proxy);
g_clear_object (&data->cancellable);
maybe_disconnect_object_by_data (data->upower_proxy, data);
g_clear_object (&data->upower_proxy);
set_adaptive (data, FALSE, NULL);
maybe_disconnect_object_by_data (data->cpu_driver, data);
g_clear_object (&data->cpu_driver);
maybe_disconnect_object_by_data (data->platform_driver, data);
@ -1443,16 +1503,7 @@ start_profile_drivers (PpdApp *data)
} else if (needs_battery_monitor) {
/* start watching for power changes */
g_debug ("Battery state monitor required, connecting to upower...");
g_dbus_proxy_new (data->connection,
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
NULL,
UPOWER_DBUS_NAME,
UPOWER_DBUS_PATH,
UPOWER_DBUS_INTERFACE,
data->cancellable,
on_upower_proxy_cb,
data);
set_adaptive (data, TRUE, NULL);
} else {
g_debug ("No battery state monitor required by any driver, let's skip it");
}

View file

@ -143,5 +143,13 @@
-->
<property name="Version" type="s" access="read"/>
<!--
AdaptiveProfiles:
AdaptiveProfiles will have separate values for battery and AC. These
profiles will be adjusted when connecting or disconnecting AC.
-->
<property name="AdaptiveProfiles" type="b" access="readwrite"/>
</interface>
</node>

View file

@ -67,6 +67,18 @@ def get_profiles_property(prop):
return proxy.Get("(ss)", PP_IFACE, prop)
@command
def _adaptive(args):
if args.enable is None:
adaptive = get_profiles_property("AdaptiveProfiles")
print(adaptive)
else:
proxy = get_proxy()
proxy.Set(
"(ssv)", PP_IFACE, "AdaptiveProfiles", GLib.Variant.new_boolean(args.enable)
)
@command
def _list(_args):
profiles = get_profiles_property("Profiles")
@ -183,6 +195,13 @@ def get_parser():
help="Profile to use for set command",
)
parser_set.set_defaults(func=_set)
parser_adaptive = subparsers.add_parser(
"adaptive",
help="Manage adaptive profiles",
description="Adaptive profiles will react to exterior factors such as a charger.",
)
parser_adaptive.set_defaults(func=_adaptive)
parser_adaptive.add_argument("--enable", action=argparse.BooleanOptionalAction)
parser_launch = subparsers.add_parser(
"launch",
help="Launch a command while holding a power profile",