diff --git a/src/power-profiles-daemon.c b/src/power-profiles-daemon.c index 8d0c4e2..c19c7fa 100644 --- a/src/power-profiles-daemon.c +++ b/src/power-profiles-daemon.c @@ -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"); } diff --git a/src/power-profiles-daemon.dbus.xml.in b/src/power-profiles-daemon.dbus.xml.in index 04cfa72..2ef9258 100644 --- a/src/power-profiles-daemon.dbus.xml.in +++ b/src/power-profiles-daemon.dbus.xml.in @@ -143,5 +143,13 @@ --> + + + diff --git a/src/powerprofilesctl b/src/powerprofilesctl index 078fbbf..63dc3bf 100755 --- a/src/powerprofilesctl +++ b/src/powerprofilesctl @@ -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",