| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * Copyright (c) 2014-2016, 2020-2021 Bastien Nocera <hadess@hadess.net> | ||
| 3 | * Copyright (c) 2021 David Redondo <kde@david-redondo.de> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 3 as published by | ||
| 7 | * the Free Software Foundation. | ||
| 8 | * | ||
| 9 | */ | ||
| 10 | |||
| 11 | #define G_LOG_DOMAIN "Core" | ||
| 12 | |||
| 13 | #include "config.h" | ||
| 14 | |||
| 15 | #include <glib-unix.h> | ||
| 16 | #include <locale.h> | ||
| 17 | #include <polkit/polkit.h> | ||
| 18 | #include <stdlib.h> | ||
| 19 | #include <stdio.h> | ||
| 20 | |||
| 21 | #include "power-profiles-daemon-resources.h" | ||
| 22 | #include "power-profiles-daemon.h" | ||
| 23 | #include "ppd-driver-cpu.h" | ||
| 24 | #include "ppd-driver-platform.h" | ||
| 25 | #include "ppd-action.h" | ||
| 26 | #include "ppd-enums.h" | ||
| 27 | |||
| 28 | #define POWER_PROFILES_DBUS_NAME "org.freedesktop.UPower.PowerProfiles" | ||
| 29 | #define POWER_PROFILES_DBUS_PATH "/org/freedesktop/UPower/PowerProfiles" | ||
| 30 | #define POWER_PROFILES_IFACE_NAME POWER_PROFILES_DBUS_NAME | ||
| 31 | |||
| 32 | #define POWER_PROFILES_LEGACY_DBUS_NAME "net.hadess.PowerProfiles" | ||
| 33 | #define POWER_PROFILES_LEGACY_DBUS_PATH "/net/hadess/PowerProfiles" | ||
| 34 | #define POWER_PROFILES_LEGACY_IFACE_NAME POWER_PROFILES_LEGACY_DBUS_NAME | ||
| 35 | |||
| 36 | #define POWER_PROFILES_POLICY_NAMESPACE "org.freedesktop.UPower.PowerProfiles" | ||
| 37 | |||
| 38 | #define POWER_PROFILES_RESOURCES_PATH "/org/freedesktop/UPower/PowerProfiles" | ||
| 39 | |||
| 40 | #define UPOWER_DBUS_NAME "org.freedesktop.UPower" | ||
| 41 | #define UPOWER_DBUS_PATH "/org/freedesktop/UPower" | ||
| 42 | #define UPOWER_DBUS_INTERFACE "org.freedesktop.UPower" | ||
| 43 | |||
| 44 | #define UPOWER_DBUS_DISPLAY_DEVICE_PATH "/org/freedesktop/UPower/devices/DisplayDevice" | ||
| 45 | #define UPOWER_DBUS_DEVICE_INTERFACE "org.freedesktop.UPower.Device" | ||
| 46 | |||
| 47 | #define LOGIND_DBUS_NAME "org.freedesktop.login1" | ||
| 48 | #define LOGIND_DBUS_PATH "/org/freedesktop/login1" | ||
| 49 | #define LOGIND_DBUS_INTERFACE "org.freedesktop.login1.Manager" | ||
| 50 | |||
| 51 | #ifndef POLKIT_HAS_AUTOPOINTERS | ||
| 52 | /* FIXME: Remove this once we're fine to depend on polkit 0.114 */ | ||
| 53 | G_DEFINE_AUTOPTR_CLEANUP_FUNC (PolkitAuthorizationResult, g_object_unref) | ||
| 54 | G_DEFINE_AUTOPTR_CLEANUP_FUNC (PolkitSubject, g_object_unref) | ||
| 55 | #endif | ||
| 56 | |||
| 57 | typedef struct { | ||
| 58 | GOptionGroup *group; | ||
| 59 | GLogLevelFlags log_level; | ||
| 60 | gboolean replace; | ||
| 61 | gboolean disable_upower; | ||
| 62 | gboolean disable_logind; | ||
| 63 | GStrv blocked_drivers; | ||
| 64 | GStrv blocked_actions; | ||
| 65 | } DebugOptions; | ||
| 66 | |||
| 67 | typedef struct { | ||
| 68 | GMainLoop *main_loop; | ||
| 69 | GDBusConnection *connection; | ||
| 70 | GCancellable *cancellable; | ||
| 71 | guint name_id; | ||
| 72 | guint legacy_name_id; | ||
| 73 | gboolean was_started; | ||
| 74 | int ret; | ||
| 75 | |||
| 76 | GKeyFile *config; | ||
| 77 | char *config_path; | ||
| 78 | |||
| 79 | PolkitAuthority *auth; | ||
| 80 | |||
| 81 | PpdProfile active_profile; | ||
| 82 | PpdProfile selected_profile; | ||
| 83 | GPtrArray *probed_drivers; | ||
| 84 | PpdDriverCpu *cpu_driver; | ||
| 85 | PpdDriverPlatform *platform_driver; | ||
| 86 | GPtrArray *actions; | ||
| 87 | GHashTable *profile_holds; | ||
| 88 | |||
| 89 | gboolean battery_support; | ||
| 90 | GDBusProxy *upower_proxy; | ||
| 91 | GDBusProxy *upower_display_proxy; | ||
| 92 | gulong upower_watch_id; | ||
| 93 | gulong upower_display_watch_id; | ||
| 94 | gulong upower_properties_id; | ||
| 95 | gulong upower_display_properties_id; | ||
| 96 | PpdPowerChangedReason power_changed_reason; | ||
| 97 | |||
| 98 | guint logind_sleep_signal_id; | ||
| 99 | |||
| 100 | DebugOptions *debug_options; | ||
| 101 | } PpdApp; | ||
| 102 | |||
| 103 | typedef struct { | ||
| 104 | PpdProfile profile; | ||
| 105 | char *reason; | ||
| 106 | char *application_id; | ||
| 107 | char *requester; | ||
| 108 | char *requester_iface; | ||
| 109 | } ProfileHold; | ||
| 110 | |||
| 111 | static void | ||
| 112 | 144 | debug_options_free(DebugOptions *options) | |
| 113 | { | ||
| 114 | 144 | g_strfreev (options->blocked_drivers); | |
| 115 | 144 | g_strfreev (options->blocked_actions); | |
| 116 | 144 | g_free (options); | |
| 117 | 144 | } | |
| 118 | ✗ | G_DEFINE_AUTOPTR_CLEANUP_FUNC (DebugOptions, debug_options_free) | |
| 119 | |||
| 120 | static void | ||
| 121 | 39 | profile_hold_free (ProfileHold *hold) | |
| 122 | { | ||
| 123 |
1/2✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
|
39 | if (hold == NULL) |
| 124 | return; | ||
| 125 | 39 | g_free (hold->reason); | |
| 126 | 39 | g_free (hold->application_id); | |
| 127 | 39 | g_free (hold->requester); | |
| 128 | 39 | g_free (hold->requester_iface); | |
| 129 | 39 | g_free (hold); | |
| 130 | } | ||
| 131 | |||
| 132 | static PpdApp *ppd_app = NULL; | ||
| 133 | |||
| 134 | static void stop_profile_drivers (PpdApp *data); | ||
| 135 | static void start_profile_drivers (PpdApp *data); | ||
| 136 | static void upower_battery_set_power_changed_reason (PpdApp *, PpdPowerChangedReason); | ||
| 137 | |||
| 138 | /* profile drivers and actions */ | ||
| 139 | #include "ppd-action-trickle-charge.h" | ||
| 140 | #include "ppd-action-amdgpu-panel-power.h" | ||
| 141 | #include "ppd-action-amdgpu-dpm.h" | ||
| 142 | #include "ppd-driver-placeholder.h" | ||
| 143 | #include "ppd-driver-platform-profile.h" | ||
| 144 | #include "ppd-driver-intel-pstate.h" | ||
| 145 | #include "ppd-driver-amd-pstate.h" | ||
| 146 | #include "ppd-driver-fake.h" | ||
| 147 | |||
| 148 | typedef GType (*GTypeGetFunc) (void); | ||
| 149 | |||
| 150 | static GTypeGetFunc objects[] = { | ||
| 151 | /* Hardware specific profile drivers */ | ||
| 152 | ppd_driver_fake_get_type, | ||
| 153 | ppd_driver_platform_profile_get_type, | ||
| 154 | ppd_driver_intel_pstate_get_type, | ||
| 155 | ppd_driver_amd_pstate_get_type, | ||
| 156 | |||
| 157 | /* Generic profile driver */ | ||
| 158 | ppd_driver_placeholder_get_type, | ||
| 159 | |||
| 160 | /* Actions */ | ||
| 161 | ppd_action_trickle_charge_get_type, | ||
| 162 | ppd_action_amdgpu_panel_power_get_type, | ||
| 163 | ppd_action_amdgpu_dpm_get_type, | ||
| 164 | }; | ||
| 165 | |||
| 166 | typedef enum { | ||
| 167 | PROP_ACTIVE_PROFILE = 1 << 0, | ||
| 168 | PROP_INHIBITED = 1 << 1, | ||
| 169 | PROP_PROFILES = 1 << 2, | ||
| 170 | PROP_ACTIONS = 1 << 3, | ||
| 171 | PROP_DEGRADED = 1 << 4, | ||
| 172 | PROP_ACTIVE_PROFILE_HOLDS = 1 << 5, | ||
| 173 | PROP_VERSION = 1 << 6, | ||
| 174 | PROP_UPOWER = 1 << 7, | ||
| 175 | } PropertiesMask; | ||
| 176 | |||
| 177 | #define PROP_ALL (PROP_ACTIVE_PROFILE | \ | ||
| 178 | PROP_INHIBITED | \ | ||
| 179 | PROP_PROFILES | \ | ||
| 180 | PROP_ACTIONS | \ | ||
| 181 | PROP_DEGRADED | \ | ||
| 182 | PROP_ACTIVE_PROFILE_HOLDS | \ | ||
| 183 | PROP_VERSION | \ | ||
| 184 | PROP_UPOWER) | ||
| 185 | |||
| 186 | static gboolean | ||
| 187 | 11038 | driver_profile_support (PpdDriver *driver, | |
| 188 | PpdProfile profile) | ||
| 189 | { | ||
| 190 |
2/2✓ Branch 1 taken 6563 times.
✓ Branch 2 taken 4475 times.
|
11038 | if (!PPD_IS_DRIVER (driver)) |
| 191 | return FALSE; | ||
| 192 | 6563 | return (ppd_driver_get_profiles (driver) & profile) != 0; | |
| 193 | } | ||
| 194 | |||
| 195 | static gboolean | ||
| 196 | 2871 | get_profile_available (PpdApp *data, | |
| 197 | PpdProfile profile) | ||
| 198 | { | ||
| 199 |
4/4✓ Branch 1 taken 2281 times.
✓ Branch 2 taken 590 times.
✓ Branch 3 taken 1786 times.
✓ Branch 4 taken 495 times.
|
5152 | return driver_profile_support (PPD_DRIVER (data->cpu_driver), profile) || |
| 200 | 2281 | driver_profile_support (PPD_DRIVER (data->platform_driver), profile); | |
| 201 | } | ||
| 202 | |||
| 203 | static const char * | ||
| 204 | 1722 | get_active_profile (PpdApp *data) | |
| 205 | { | ||
| 206 | 1722 | return ppd_profile_to_str (data->active_profile); | |
| 207 | } | ||
| 208 | |||
| 209 | static char * | ||
| 210 | 544 | get_performance_degraded (PpdApp *data) | |
| 211 | { | ||
| 212 | 544 | const gchar *cpu_degraded = NULL; | |
| 213 | 544 | const gchar *platform_degraded = NULL; | |
| 214 | |||
| 215 |
2/2✓ Branch 1 taken 210 times.
✓ Branch 2 taken 334 times.
|
544 | if (driver_profile_support (PPD_DRIVER (data->platform_driver), PPD_PROFILE_PERFORMANCE)) |
| 216 | 210 | platform_degraded = ppd_driver_get_performance_degraded (PPD_DRIVER (data->platform_driver)); | |
| 217 | |||
| 218 |
2/2✓ Branch 1 taken 162 times.
✓ Branch 2 taken 382 times.
|
544 | if (driver_profile_support (PPD_DRIVER (data->cpu_driver), PPD_PROFILE_PERFORMANCE)) |
| 219 | 162 | cpu_degraded = ppd_driver_get_performance_degraded (PPD_DRIVER (data->cpu_driver)); | |
| 220 | |||
| 221 |
2/2✓ Branch 0 taken 506 times.
✓ Branch 1 taken 38 times.
|
544 | if (!cpu_degraded && !platform_degraded) |
| 222 | 506 | return g_strdup (""); | |
| 223 | |||
| 224 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 26 times.
|
38 | if (!cpu_degraded) |
| 225 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
24 | return g_strdup (platform_degraded); |
| 226 | |||
| 227 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 6 times.
|
26 | if (!platform_degraded) |
| 228 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
|
40 | return g_strdup (cpu_degraded); |
| 229 | |||
| 230 | 6 | return g_strjoin (",", cpu_degraded, platform_degraded, NULL); | |
| 231 | } | ||
| 232 | |||
| 233 | static GVariant * | ||
| 234 | 860 | get_profiles_variant (PpdApp *data) | |
| 235 | { | ||
| 236 | 860 | GVariantBuilder builder; | |
| 237 | 860 | guint i; | |
| 238 | |||
| 239 | 860 | g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}")); | |
| 240 | |||
| 241 |
2/2✓ Branch 1 taken 2580 times.
✓ Branch 2 taken 860 times.
|
4300 | for (i = 0; i < NUM_PROFILES; i++) { |
| 242 | 2580 | PpdDriver *platform_driver = PPD_DRIVER (data->platform_driver); | |
| 243 | 2580 | PpdDriver *cpu_driver = PPD_DRIVER (data->cpu_driver); | |
| 244 | 2580 | PpdProfile profile = 1 << i; | |
| 245 | 2580 | GVariantBuilder asv_builder; | |
| 246 | 2580 | gboolean cpu, platform; | |
| 247 | 2580 | const gchar *driver = NULL; | |
| 248 | |||
| 249 | /* check if any of the drivers support */ | ||
| 250 |
2/2✓ Branch 1 taken 489 times.
✓ Branch 2 taken 2091 times.
|
2580 | if (!get_profile_available (data, profile)) |
| 251 | 489 | continue; | |
| 252 | |||
| 253 | 2091 | g_variant_builder_init (&asv_builder, G_VARIANT_TYPE ("a{sv}")); | |
| 254 | 2091 | g_variant_builder_add (&asv_builder, "{sv}", "Profile", | |
| 255 | 2091 | g_variant_new_string (ppd_profile_to_str (profile))); | |
| 256 | 2091 | cpu = driver_profile_support (cpu_driver, profile); | |
| 257 | 2091 | platform = driver_profile_support (platform_driver, profile); | |
| 258 |
2/2✓ Branch 0 taken 510 times.
✓ Branch 1 taken 1581 times.
|
2091 | if (cpu) |
| 259 | 510 | g_variant_builder_add (&asv_builder, "{sv}", "CpuDriver", | |
| 260 | 510 | g_variant_new_string (ppd_driver_get_driver_name (cpu_driver))); | |
| 261 |
2/2✓ Branch 0 taken 1945 times.
✓ Branch 1 taken 146 times.
|
2091 | if (platform) |
| 262 | 1945 | g_variant_builder_add (&asv_builder, "{sv}", "PlatformDriver", | |
| 263 | 1945 | g_variant_new_string (ppd_driver_get_driver_name (platform_driver))); | |
| 264 | |||
| 265 | /* compatibility with older API */ | ||
| 266 |
2/2✓ Branch 0 taken 1727 times.
✓ Branch 1 taken 364 times.
|
2091 | if (cpu && platform) |
| 267 | driver = "multiple"; | ||
| 268 |
2/2✓ Branch 0 taken 146 times.
✓ Branch 1 taken 1581 times.
|
1727 | else if (cpu) |
| 269 | 146 | driver = ppd_driver_get_driver_name (cpu_driver); | |
| 270 |
1/2✓ Branch 0 taken 1581 times.
✗ Branch 1 not taken.
|
1581 | else if (platform) |
| 271 | 1581 | driver = ppd_driver_get_driver_name (platform_driver); | |
| 272 | |||
| 273 |
1/2✓ Branch 0 taken 1727 times.
✗ Branch 1 not taken.
|
1727 | if (driver) |
| 274 | 2091 | g_variant_builder_add (&asv_builder, "{sv}", "Driver", | |
| 275 | g_variant_new_string (driver)); | ||
| 276 | |||
| 277 | 2091 | g_variant_builder_add (&builder, "a{sv}", &asv_builder); | |
| 278 | } | ||
| 279 | |||
| 280 | 860 | return g_variant_builder_end (&builder); | |
| 281 | } | ||
| 282 | |||
| 283 | static GVariant * | ||
| 284 | 344 | get_legacy_actions_variant (PpdApp *data) | |
| 285 | { | ||
| 286 | 344 | GVariantBuilder builder; | |
| 287 | 344 | guint i; | |
| 288 | |||
| 289 | 344 | g_variant_builder_init (&builder, G_VARIANT_TYPE ("as")); | |
| 290 | |||
| 291 |
2/2✓ Branch 1 taken 1032 times.
✓ Branch 2 taken 344 times.
|
1720 | for (i = 0; i < data->actions->len; i++) { |
| 292 | 1032 | PpdAction *action = g_ptr_array_index (data->actions, i); | |
| 293 | |||
| 294 |
2/2✓ Branch 1 taken 693 times.
✓ Branch 2 taken 339 times.
|
1032 | if (!ppd_action_get_active (action)) |
| 295 | 693 | continue; | |
| 296 | |||
| 297 | 339 | g_variant_builder_add (&builder, "s", ppd_action_get_action_name (action)); | |
| 298 | } | ||
| 299 | |||
| 300 | 344 | return g_variant_builder_end (&builder); | |
| 301 | } | ||
| 302 | |||
| 303 | static GVariant * | ||
| 304 | 270 | get_modern_actions_variant (PpdApp *data) | |
| 305 | { | ||
| 306 | 270 | GVariantBuilder builder; | |
| 307 | 270 | guint i; | |
| 308 | |||
| 309 | 270 | g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}")); | |
| 310 | |||
| 311 |
2/2✓ Branch 1 taken 810 times.
✓ Branch 2 taken 270 times.
|
1350 | for (i = 0; i < data->actions->len; i++) { |
| 312 | 810 | PpdAction *action = g_ptr_array_index (data->actions, i); | |
| 313 | 810 | GVariantBuilder asv_builder; | |
| 314 | |||
| 315 | 810 | g_variant_builder_init (&asv_builder, G_VARIANT_TYPE ("a{sv}")); | |
| 316 | 810 | g_variant_builder_add (&asv_builder, "{sv}", "Name", | |
| 317 | 810 | g_variant_new_string (ppd_action_get_action_name (action))); | |
| 318 | 810 | g_variant_builder_add (&asv_builder, "{sv}", "Description", | |
| 319 | 810 | g_variant_new_string (ppd_action_get_action_description (action))); | |
| 320 | 810 | g_variant_builder_add (&asv_builder, "{sv}", "Enabled", | |
| 321 | g_variant_new_boolean (ppd_action_get_active (action))); | ||
| 322 | 810 | g_variant_builder_add (&builder, "a{sv}", &asv_builder); | |
| 323 | } | ||
| 324 | |||
| 325 | 270 | return g_variant_builder_end (&builder); | |
| 326 | } | ||
| 327 | |||
| 328 | |||
| 329 | static GVariant * | ||
| 330 | 660 | get_profile_holds_variant (PpdApp *data) | |
| 331 | { | ||
| 332 | 660 | GVariantBuilder builder; | |
| 333 | 660 | GHashTableIter iter; | |
| 334 | 660 | gpointer value; | |
| 335 | |||
| 336 | 660 | g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}")); | |
| 337 | 660 | g_hash_table_iter_init (&iter, data->profile_holds); | |
| 338 | |||
| 339 |
2/2✓ Branch 2 taken 115 times.
✓ Branch 3 taken 660 times.
|
775 | while (g_hash_table_iter_next (&iter, NULL, &value)) { |
| 340 | 115 | GVariantBuilder asv_builder; | |
| 341 | 115 | ProfileHold *hold = value; | |
| 342 | |||
| 343 | 115 | g_variant_builder_init (&asv_builder, G_VARIANT_TYPE ("a{sv}")); | |
| 344 | 115 | g_variant_builder_add (&asv_builder, "{sv}", "ApplicationId", | |
| 345 | 115 | g_variant_new_string (hold->application_id)); | |
| 346 | 115 | g_variant_builder_add (&asv_builder, "{sv}", "Profile", | |
| 347 | 115 | g_variant_new_string (ppd_profile_to_str (hold->profile))); | |
| 348 | 115 | g_variant_builder_add (&asv_builder, "{sv}", "Reason", g_variant_new_string (hold->reason)); | |
| 349 | |||
| 350 | 115 | g_variant_builder_add (&builder, "a{sv}", &asv_builder); | |
| 351 | } | ||
| 352 | |||
| 353 | 660 | return g_variant_builder_end (&builder); | |
| 354 | } | ||
| 355 | |||
| 356 | static void | ||
| 357 | 650 | send_dbus_event_iface (PpdApp *data, | |
| 358 | PropertiesMask mask, | ||
| 359 | const gchar *iface, | ||
| 360 | const gchar *path) | ||
| 361 | { | ||
| 362 | 650 | GVariantBuilder props_builder; | |
| 363 | 650 | GVariant *props_changed = NULL; | |
| 364 | |||
| 365 |
1/2✓ Branch 0 taken 650 times.
✗ Branch 1 not taken.
|
650 | g_return_if_fail (data->connection); |
| 366 | |||
| 367 |
1/2✓ Branch 0 taken 650 times.
✗ Branch 1 not taken.
|
650 | if (mask == 0) |
| 368 | return; | ||
| 369 | |||
| 370 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 650 times.
|
650 | g_return_if_fail ((mask & PROP_ALL) != 0); |
| 371 | |||
| 372 | 650 | g_variant_builder_init (&props_builder, G_VARIANT_TYPE ("a{sv}")); | |
| 373 | |||
| 374 |
2/2✓ Branch 0 taken 610 times.
✓ Branch 1 taken 40 times.
|
650 | if (mask & PROP_ACTIVE_PROFILE) { |
| 375 | 1220 | g_variant_builder_add (&props_builder, "{sv}", "ActiveProfile", | |
| 376 | 610 | g_variant_new_string (get_active_profile (data))); | |
| 377 | } | ||
| 378 |
2/2✓ Branch 0 taken 316 times.
✓ Branch 1 taken 334 times.
|
650 | if (mask & PROP_INHIBITED) { |
| 379 | 316 | g_variant_builder_add (&props_builder, "{sv}", "PerformanceInhibited", | |
| 380 | g_variant_new_string ("")); | ||
| 381 | } | ||
| 382 |
2/2✓ Branch 0 taken 340 times.
✓ Branch 1 taken 310 times.
|
650 | if (mask & PROP_DEGRADED) { |
| 383 | 340 | gchar *degraded = get_performance_degraded (data); | |
| 384 | 340 | g_variant_builder_add (&props_builder, "{sv}", "PerformanceDegraded", | |
| 385 | 340 | g_variant_new_take_string (g_steal_pointer (°raded))); | |
| 386 | } | ||
| 387 |
2/2✓ Branch 0 taken 316 times.
✓ Branch 1 taken 334 times.
|
650 | if (mask & PROP_PROFILES) { |
| 388 | 316 | g_variant_builder_add (&props_builder, "{sv}", "Profiles", | |
| 389 | get_profiles_variant (data)); | ||
| 390 | } | ||
| 391 |
2/2✓ Branch 0 taken 316 times.
✓ Branch 1 taken 334 times.
|
650 | if (mask & PROP_ACTIONS) { |
| 392 |
2/2✓ Branch 0 taken 158 times.
✓ Branch 1 taken 158 times.
|
316 | if (g_str_equal (iface, POWER_PROFILES_IFACE_NAME)) |
| 393 | 158 | g_variant_builder_add (&props_builder, "{sv}", "Actions", | |
| 394 | get_modern_actions_variant (data)); | ||
| 395 | else | ||
| 396 | 158 | g_variant_builder_add (&props_builder, "{sv}", "Actions", | |
| 397 | get_legacy_actions_variant (data)); | ||
| 398 | } | ||
| 399 |
2/2✓ Branch 0 taken 468 times.
✓ Branch 1 taken 182 times.
|
650 | if (mask & PROP_ACTIVE_PROFILE_HOLDS) { |
| 400 | 468 | g_variant_builder_add (&props_builder, "{sv}", "ActiveProfileHolds", | |
| 401 | get_profile_holds_variant (data)); | ||
| 402 | } | ||
| 403 |
2/2✓ Branch 0 taken 316 times.
✓ Branch 1 taken 334 times.
|
650 | if (mask & PROP_VERSION) { |
| 404 | 316 | g_variant_builder_add (&props_builder, "{sv}", "Version", | |
| 405 | g_variant_new_string (VERSION)); | ||
| 406 | } | ||
| 407 |
2/2✓ Branch 0 taken 316 times.
✓ Branch 1 taken 334 times.
|
650 | if (mask & PROP_UPOWER) { |
| 408 | 316 | g_variant_builder_add (&props_builder, "{sv}", "BatteryAware", | |
| 409 | g_variant_new_boolean (data->battery_support)); | ||
| 410 | } | ||
| 411 | |||
| 412 | 650 | props_changed = g_variant_new ("(s@a{sv}@as)", iface, | |
| 413 | g_variant_builder_end (&props_builder), | ||
| 414 | g_variant_new_strv (NULL, 0)); | ||
| 415 | |||
| 416 | 650 | g_dbus_connection_emit_signal (data->connection, | |
| 417 | NULL, | ||
| 418 | path, | ||
| 419 | "org.freedesktop.DBus.Properties", | ||
| 420 | "PropertiesChanged", | ||
| 421 | props_changed, NULL); | ||
| 422 | } | ||
| 423 | |||
| 424 | static void | ||
| 425 | 325 | send_dbus_event (PpdApp *data, | |
| 426 | PropertiesMask mask) | ||
| 427 | { | ||
| 428 | 325 | send_dbus_event_iface (data, mask, | |
| 429 | POWER_PROFILES_IFACE_NAME, | ||
| 430 | POWER_PROFILES_DBUS_PATH); | ||
| 431 | 325 | send_dbus_event_iface (data, mask, | |
| 432 | POWER_PROFILES_LEGACY_IFACE_NAME, | ||
| 433 | POWER_PROFILES_LEGACY_DBUS_PATH); | ||
| 434 | 325 | } | |
| 435 | |||
| 436 | static void | ||
| 437 | 81 | save_configuration (PpdApp *data) | |
| 438 | { | ||
| 439 | 162 | g_autoptr(GError) error = NULL; | |
| 440 | |||
| 441 |
2/2✓ Branch 1 taken 30 times.
✓ Branch 2 taken 51 times.
|
81 | if (PPD_IS_DRIVER_CPU (data->cpu_driver)) { |
| 442 | 30 | g_key_file_set_string (data->config, "State", "CpuDriver", | |
| 443 | 30 | ppd_driver_get_driver_name (PPD_DRIVER (data->cpu_driver))); | |
| 444 | } | ||
| 445 | |||
| 446 |
1/2✓ Branch 1 taken 81 times.
✗ Branch 2 not taken.
|
81 | if (PPD_IS_DRIVER_PLATFORM (data->platform_driver)) { |
| 447 | 81 | g_key_file_set_string (data->config, "State", "PlatformDriver", | |
| 448 | 81 | ppd_driver_get_driver_name (PPD_DRIVER (data->platform_driver))); | |
| 449 | } | ||
| 450 | |||
| 451 | 162 | g_key_file_set_string (data->config, "State", "Profile", | |
| 452 | 81 | ppd_profile_to_str (data->active_profile)); | |
| 453 | |||
| 454 |
2/2✓ Branch 1 taken 243 times.
✓ Branch 2 taken 81 times.
|
324 | for (guint i = 0; i < data->actions->len; i++) { |
| 455 | 243 | PpdAction *action = g_ptr_array_index (data->actions, i); | |
| 456 | 486 | g_key_file_set_boolean (data->config, "Actions", | |
| 457 | 243 | ppd_action_get_action_name (action), | |
| 458 | ppd_action_get_active (action)); | ||
| 459 | } | ||
| 460 | |||
| 461 | 81 | g_key_file_set_boolean (data->config, "State", "battery_aware", data->battery_support); | |
| 462 | |||
| 463 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 81 times.
|
81 | if (!g_key_file_save_to_file (data->config, data->config_path, &error)) |
| 464 | ✗ | g_warning ("Could not save configuration file '%s': %s", data->config_path, error->message); | |
| 465 | 81 | } | |
| 466 | |||
| 467 | static gboolean | ||
| 468 | 158 | apply_configuration (PpdApp *data) | |
| 469 | { | ||
| 470 | 316 | g_autofree char *platform_driver = NULL; | |
| 471 | 158 | g_autofree char *profile_str = NULL; | |
| 472 | 158 | g_autofree char *cpu_driver = NULL; | |
| 473 | 158 | g_autoptr(GError) error = NULL; | |
| 474 | 158 | PpdProfile profile; | |
| 475 | |||
| 476 | 158 | data->battery_support = g_key_file_get_boolean (data->config, "State", "battery_aware", &error); | |
| 477 |
2/2✓ Branch 0 taken 134 times.
✓ Branch 1 taken 24 times.
|
158 | if (error != NULL) { |
| 478 | 134 | g_debug("battery_aware key not found: %s, defaulting to TRUE", error->message); | |
| 479 | 134 | data->battery_support = TRUE; | |
| 480 | 134 | g_key_file_set_boolean (data->config, "State", "battery_aware", TRUE); | |
| 481 | 134 | g_clear_error (&error); | |
| 482 | } | ||
| 483 | |||
| 484 | 158 | cpu_driver = g_key_file_get_string (data->config, "State", "CpuDriver", NULL); | |
| 485 |
4/4✓ Branch 1 taken 44 times.
✓ Branch 2 taken 114 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 42 times.
|
202 | if (PPD_IS_DRIVER_CPU (data->cpu_driver) && |
| 486 | 44 | g_strcmp0 (ppd_driver_get_driver_name (PPD_DRIVER (data->cpu_driver)), cpu_driver) != 0) | |
| 487 | return FALSE; | ||
| 488 | |||
| 489 | 116 | platform_driver = g_key_file_get_string (data->config, "State", "PlatformDriver", NULL); | |
| 490 | |||
| 491 |
3/4✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 110 times.
✓ Branch 4 taken 6 times.
|
232 | if (PPD_IS_DRIVER_PLATFORM (data->platform_driver) && |
| 492 | 116 | g_strcmp0 (ppd_driver_get_driver_name (PPD_DRIVER (data->platform_driver)), platform_driver) != 0) | |
| 493 | return FALSE; | ||
| 494 | |||
| 495 | 6 | profile_str = g_key_file_get_string (data->config, "State", "Profile", NULL); | |
| 496 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
6 | if (profile_str == NULL) |
| 497 | return FALSE; | ||
| 498 | |||
| 499 | 6 | profile = ppd_profile_from_str (profile_str); | |
| 500 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
6 | if (profile == PPD_PROFILE_UNSET) { |
| 501 | ✗ | g_debug ("Resetting invalid configuration profile '%s'", profile_str); | |
| 502 | ✗ | g_key_file_remove_key (data->config, "State", "Profile", NULL); | |
| 503 | ✗ | return FALSE; | |
| 504 | } | ||
| 505 | |||
| 506 | 6 | g_debug ("Applying profile '%s' from configuration file", profile_str); | |
| 507 | 6 | data->active_profile = profile; | |
| 508 | 6 | return TRUE; | |
| 509 | } | ||
| 510 | |||
| 511 | static void | ||
| 512 | 144 | load_configuration (PpdApp *data) | |
| 513 | { | ||
| 514 | 288 | g_autoptr(GError) error = NULL; | |
| 515 | |||
| 516 |
2/2✓ Branch 1 taken 142 times.
✓ Branch 2 taken 2 times.
|
144 | if (g_getenv ("UMOCKDEV_DIR") != NULL) |
| 517 | 142 | data->config_path = g_build_filename (g_getenv ("UMOCKDEV_DIR"), "ppd_test_conf.ini", NULL); | |
| 518 | else | ||
| 519 | 2 | data->config_path = g_strdup ("/var/lib/power-profiles-daemon/state.ini"); | |
| 520 | 144 | data->config = g_key_file_new (); | |
| 521 |
2/2✓ Branch 1 taken 136 times.
✓ Branch 2 taken 8 times.
|
144 | if (!g_key_file_load_from_file (data->config, data->config_path, G_KEY_FILE_KEEP_COMMENTS, &error)) |
| 522 | 136 | g_debug ("Could not load configuration file '%s': %s", data->config_path, error->message); | |
| 523 | else | ||
| 524 | 8 | g_debug ("Loaded configuration file '%s'", data->config_path); | |
| 525 | 144 | } | |
| 526 | |||
| 527 | static void | ||
| 528 | 303 | actions_activate_profile (GPtrArray *actions, | |
| 529 | PpdProfile profile) | ||
| 530 | { | ||
| 531 | 303 | guint i; | |
| 532 | |||
| 533 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 303 times.
|
303 | g_return_if_fail (actions != NULL); |
| 534 | |||
| 535 |
2/2✓ Branch 0 taken 909 times.
✓ Branch 1 taken 303 times.
|
1212 | for (i = 0; i < actions->len; i++) { |
| 536 | 909 | g_autoptr(GError) error = NULL; | |
| 537 | 909 | PpdAction *action; | |
| 538 | |||
| 539 | 909 | action = g_ptr_array_index (actions, i); | |
| 540 | |||
| 541 |
2/2✓ Branch 1 taken 603 times.
✓ Branch 2 taken 306 times.
|
909 | if (!ppd_action_get_active (action)) |
| 542 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 603 times.
|
603 | continue; |
| 543 | |||
| 544 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 306 times.
|
306 | if (!ppd_action_activate_profile (action, profile, &error)) |
| 545 | ✗ | g_warning ("Failed to activate action '%s' to profile %s: %s", | |
| 546 | ppd_profile_to_str (profile), | ||
| 547 | ppd_action_get_action_name (action), | ||
| 548 | error->message); | ||
| 549 | } | ||
| 550 | } | ||
| 551 | |||
| 552 | static gboolean | ||
| 553 | 311 | activate_target_profile (PpdApp *data, | |
| 554 | PpdProfile target_profile, | ||
| 555 | PpdProfileActivationReason reason, | ||
| 556 | GError **error) | ||
| 557 | { | ||
| 558 | 311 | PpdProfile current_profile = data->active_profile; | |
| 559 | |||
| 560 | 311 | g_info ("Setting active profile '%s' for reason '%s' (current: '%s')", | |
| 561 | ppd_profile_to_str (target_profile), | ||
| 562 | ppd_profile_activation_reason_to_str (reason), | ||
| 563 | ppd_profile_to_str (current_profile)); | ||
| 564 | |||
| 565 | /* Try CPU first */ | ||
| 566 |
4/4✓ Branch 1 taken 80 times.
✓ Branch 2 taken 231 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 74 times.
|
391 | if (driver_profile_support (PPD_DRIVER (data->cpu_driver), target_profile) && |
| 567 | 80 | !ppd_driver_activate_profile (PPD_DRIVER (data->cpu_driver), | |
| 568 | target_profile, reason, error)) { | ||
| 569 | 12 | g_prefix_error (error, "Failed to activate CPU driver '%s': ", | |
| 570 | 6 | ppd_driver_get_driver_name (PPD_DRIVER (data->cpu_driver))); | |
| 571 | 6 | return FALSE; | |
| 572 | } | ||
| 573 | |||
| 574 | /* Then try platform */ | ||
| 575 |
4/4✓ Branch 1 taken 291 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 289 times.
|
596 | if (driver_profile_support (PPD_DRIVER (data->platform_driver), target_profile) && |
| 576 | 291 | !ppd_driver_activate_profile (PPD_DRIVER (data->platform_driver), | |
| 577 | target_profile, reason, error)) { | ||
| 578 | 2 | g_autoptr(GError) recovery_error = NULL; | |
| 579 | |||
| 580 | 2 | g_prefix_error (error, "Failed to activate platform driver '%s': ", | |
| 581 | 2 | ppd_driver_get_driver_name (PPD_DRIVER (data->platform_driver))); | |
| 582 | |||
| 583 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | if (!PPD_IS_DRIVER (data->cpu_driver)) |
| 584 | return FALSE; | ||
| 585 | |||
| 586 | 2 | g_debug ("Reverting CPU driver '%s' to profile '%s'", | |
| 587 | ppd_driver_get_driver_name (PPD_DRIVER (data->cpu_driver)), | ||
| 588 | ppd_profile_to_str (current_profile)); | ||
| 589 | |||
| 590 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (!ppd_driver_activate_profile (PPD_DRIVER (data->cpu_driver), |
| 591 | current_profile, PPD_PROFILE_ACTIVATION_REASON_INTERNAL, | ||
| 592 | &recovery_error)) { | ||
| 593 | ✗ | g_warning ("Failed to revert CPU driver '%s': %s", | |
| 594 | ppd_driver_get_driver_name (PPD_DRIVER (data->cpu_driver)), | ||
| 595 | recovery_error->message); | ||
| 596 | } | ||
| 597 | |||
| 598 | 2 | return FALSE; | |
| 599 | } | ||
| 600 | |||
| 601 | 303 | actions_activate_profile (data->actions, target_profile); | |
| 602 | |||
| 603 | 303 | data->active_profile = target_profile; | |
| 604 | |||
| 605 | 303 | if (reason == PPD_PROFILE_ACTIVATION_REASON_USER || | |
| 606 |
2/2✓ Branch 0 taken 81 times.
✓ Branch 1 taken 222 times.
|
303 | reason == PPD_PROFILE_ACTIVATION_REASON_INTERNAL) |
| 607 | 81 | save_configuration (data); | |
| 608 | |||
| 609 | return TRUE; | ||
| 610 | } | ||
| 611 | |||
| 612 | static void | ||
| 613 | 39 | release_hold_notify (PpdApp *data, | |
| 614 | ProfileHold *hold, | ||
| 615 | guint cookie) | ||
| 616 | { | ||
| 617 | 39 | const char *req_path = POWER_PROFILES_DBUS_PATH; | |
| 618 | |||
| 619 |
2/2✓ Branch 1 taken 12 times.
✓ Branch 2 taken 27 times.
|
39 | if (g_strcmp0 (hold->requester_iface, POWER_PROFILES_LEGACY_IFACE_NAME) == 0) |
| 620 | 12 | req_path = POWER_PROFILES_LEGACY_DBUS_PATH; | |
| 621 | |||
| 622 | 39 | g_dbus_connection_emit_signal (data->connection, hold->requester, req_path, | |
| 623 | 39 | hold->requester_iface, "ProfileReleased", | |
| 624 | g_variant_new ("(u)", cookie), NULL); | ||
| 625 | 39 | } | |
| 626 | |||
| 627 | static void | ||
| 628 | 162 | release_all_profile_holds (PpdApp *data) | |
| 629 | { | ||
| 630 | 162 | GHashTableIter iter; | |
| 631 | 162 | gpointer key, value; | |
| 632 | |||
| 633 | 162 | g_hash_table_iter_init (&iter, data->profile_holds); | |
| 634 |
2/2✓ Branch 2 taken 4 times.
✓ Branch 3 taken 162 times.
|
166 | while (g_hash_table_iter_next (&iter, &key, &value)) { |
| 635 | 4 | ProfileHold *hold = value; | |
| 636 | 4 | guint cookie = GPOINTER_TO_UINT (key); | |
| 637 | |||
| 638 | 4 | release_hold_notify (data, hold, cookie); | |
| 639 | 4 | g_bus_unwatch_name (cookie); | |
| 640 | } | ||
| 641 | 162 | g_hash_table_remove_all (data->profile_holds); | |
| 642 | 162 | } | |
| 643 | |||
| 644 | static gboolean | ||
| 645 | 6 | set_battery_support (PpdApp *data, gboolean battery_support, GError **error) | |
| 646 | { | ||
| 647 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
|
6 | if (data->battery_support == battery_support) { |
| 648 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, |
| 649 | "battery_aware is already set to %s", battery_support ? "TRUE" : "FALSE"); | ||
| 650 | 2 | return FALSE; | |
| 651 | } | ||
| 652 | |||
| 653 | 4 | data->battery_support = battery_support; | |
| 654 | 4 | g_key_file_set_boolean (data->config, "State", "battery_aware", data->battery_support); | |
| 655 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
6 | g_debug("battery_aware set to %s", data->battery_support ? "TRUE" : "FALSE"); |
| 656 | |||
| 657 | 4 | restart_profile_drivers_for_default_app (); | |
| 658 | |||
| 659 | 4 | return TRUE; | |
| 660 | } | ||
| 661 | |||
| 662 | static gboolean | ||
| 663 | 92 | set_active_profile (PpdApp *data, | |
| 664 | const char *profile, | ||
| 665 | GError **error) | ||
| 666 | { | ||
| 667 | 92 | PpdProfile target_profile; | |
| 668 | 92 | guint mask = PROP_ACTIVE_PROFILE; | |
| 669 | |||
| 670 | 92 | target_profile = ppd_profile_from_str (profile); | |
| 671 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
|
92 | if (target_profile == PPD_PROFILE_UNSET) { |
| 672 | ✗ | g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, | |
| 673 | "Invalid profile name '%s'", profile); | ||
| 674 | ✗ | return FALSE; | |
| 675 | } | ||
| 676 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 88 times.
|
92 | if (!get_profile_available (data, target_profile)) { |
| 677 | 4 | g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, | |
| 678 | "Cannot switch to unavailable profile '%s'", profile); | ||
| 679 | 4 | return FALSE; | |
| 680 | } | ||
| 681 | |||
| 682 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 85 times.
|
88 | if (target_profile == data->active_profile) |
| 683 | return TRUE; | ||
| 684 | |||
| 685 | 85 | g_debug ("Transitioning active profile from '%s' to '%s' by user request", | |
| 686 | ppd_profile_to_str (data->active_profile), profile); | ||
| 687 | |||
| 688 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 83 times.
|
85 | if (g_hash_table_size (data->profile_holds) != 0 ) { |
| 689 | 2 | g_debug ("Releasing active profile holds"); | |
| 690 | 2 | release_all_profile_holds (data); | |
| 691 | 2 | mask |= PROP_ACTIVE_PROFILE_HOLDS; | |
| 692 | } | ||
| 693 | |||
| 694 |
2/2✓ Branch 1 taken 6 times.
✓ Branch 2 taken 79 times.
|
85 | if (!activate_target_profile (data, target_profile, PPD_PROFILE_ACTIVATION_REASON_USER, error)) |
| 695 | return FALSE; | ||
| 696 | 79 | data->selected_profile = target_profile; | |
| 697 | 79 | send_dbus_event (data, mask); | |
| 698 | |||
| 699 | 79 | return TRUE; | |
| 700 | } | ||
| 701 | |||
| 702 | static PpdProfile | ||
| 703 | 43 | effective_hold_profile (PpdApp *data) | |
| 704 | { | ||
| 705 | 43 | GHashTableIter iter; | |
| 706 | 43 | gpointer value; | |
| 707 | 43 | PpdProfile profile = PPD_PROFILE_UNSET; | |
| 708 | |||
| 709 | 43 | g_hash_table_iter_init (&iter, data->profile_holds); | |
| 710 |
2/2✓ Branch 2 taken 47 times.
✓ Branch 3 taken 30 times.
|
77 | while (g_hash_table_iter_next (&iter, NULL, &value)) { |
| 711 | 47 | ProfileHold *hold = value; | |
| 712 | |||
| 713 |
2/2✓ Branch 0 taken 34 times.
✓ Branch 1 taken 13 times.
|
47 | if (hold->profile == PPD_PROFILE_POWER_SAVER) { |
| 714 | profile = PPD_PROFILE_POWER_SAVER; | ||
| 715 | break; | ||
| 716 | } | ||
| 717 | profile = hold->profile; | ||
| 718 | } | ||
| 719 | 43 | return profile; | |
| 720 | } | ||
| 721 | |||
| 722 | static void | ||
| 723 | 12 | driver_performance_degraded_changed_cb (GObject *gobject, | |
| 724 | GParamSpec *pspec, | ||
| 725 | gpointer user_data) | ||
| 726 | { | ||
| 727 | 12 | PpdApp *data = user_data; | |
| 728 | 12 | PpdDriver *driver = PPD_DRIVER (gobject); | |
| 729 | 12 | const char *prop_str = pspec->name; | |
| 730 | |||
| 731 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
|
12 | if (g_strcmp0 (prop_str, "performance-degraded") != 0) { |
| 732 | ✗ | g_warning ("Ignoring '%s' property change on profile driver '%s'", | |
| 733 | prop_str, ppd_driver_get_driver_name (driver)); | ||
| 734 | ✗ | return; | |
| 735 | } | ||
| 736 | |||
| 737 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
|
12 | if (!(ppd_driver_get_profiles (driver) & PPD_PROFILE_PERFORMANCE)) { |
| 738 | ✗ | g_warning ("Ignored 'performance-degraded' change on non-performance driver '%s'", | |
| 739 | ppd_driver_get_driver_name (driver)); | ||
| 740 | ✗ | return; | |
| 741 | } | ||
| 742 | |||
| 743 | 12 | send_dbus_event (data, PROP_DEGRADED); | |
| 744 | } | ||
| 745 | |||
| 746 | static void | ||
| 747 | 2 | driver_profile_changed_cb (PpdDriver *driver, | |
| 748 | PpdProfile new_profile, | ||
| 749 | gpointer user_data) | ||
| 750 | { | ||
| 751 | 2 | PpdApp *data = user_data; | |
| 752 | |||
| 753 | 2 | g_debug ("Driver '%s' switched internally to profile '%s' (current: '%s')", | |
| 754 | ppd_driver_get_driver_name (driver), | ||
| 755 | ppd_profile_to_str (new_profile), | ||
| 756 | ppd_profile_to_str (data->active_profile)); | ||
| 757 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (new_profile == data->active_profile) |
| 758 | return; | ||
| 759 | |||
| 760 | 2 | activate_target_profile (data, new_profile, PPD_PROFILE_ACTIVATION_REASON_INTERNAL, NULL); | |
| 761 | 2 | send_dbus_event (data, PROP_ACTIVE_PROFILE); | |
| 762 | } | ||
| 763 | |||
| 764 | static void | ||
| 765 | 35 | release_profile_hold (PpdApp *data, | |
| 766 | guint cookie) | ||
| 767 | { | ||
| 768 | 35 | guint mask = PROP_ACTIVE_PROFILE_HOLDS; | |
| 769 | 35 | ProfileHold *hold; | |
| 770 | 35 | PpdProfile hold_profile, next_profile; | |
| 771 | |||
| 772 | 35 | hold = g_hash_table_lookup (data->profile_holds, GUINT_TO_POINTER (cookie)); | |
| 773 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 35 times.
|
35 | if (!hold) { |
| 774 | ✗ | g_debug ("No hold with cookie %d", cookie); | |
| 775 | ✗ | return; | |
| 776 | } | ||
| 777 | |||
| 778 | 35 | g_bus_unwatch_name (cookie); | |
| 779 | 35 | hold_profile = hold->profile; | |
| 780 | 35 | release_hold_notify (data, hold, cookie); | |
| 781 | 35 | g_hash_table_remove (data->profile_holds, GUINT_TO_POINTER (cookie)); | |
| 782 | |||
| 783 |
2/2✓ Branch 1 taken 27 times.
✓ Branch 2 taken 8 times.
|
35 | if (g_hash_table_size (data->profile_holds) == 0 && |
| 784 |
1/2✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
|
27 | hold_profile != data->selected_profile) { |
| 785 | 27 | g_debug ("No profile holds anymore going back to last manually activated profile"); | |
| 786 | 27 | activate_target_profile (data, data->selected_profile, PPD_PROFILE_ACTIVATION_REASON_PROGRAM_HOLD, NULL); | |
| 787 | 27 | mask |= PROP_ACTIVE_PROFILE; | |
| 788 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
|
8 | } else if (hold_profile == data->active_profile) { |
| 789 | 4 | next_profile = effective_hold_profile (data); | |
| 790 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (next_profile != PPD_PROFILE_UNSET && |
| 791 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | next_profile != data->active_profile) { |
| 792 | 4 | g_debug ("Next profile is %s", ppd_profile_to_str (next_profile)); | |
| 793 | 4 | activate_target_profile (data, next_profile, PPD_PROFILE_ACTIVATION_REASON_PROGRAM_HOLD, NULL); | |
| 794 | 4 | mask |= PROP_ACTIVE_PROFILE; | |
| 795 | } | ||
| 796 | } | ||
| 797 | |||
| 798 | 35 | send_dbus_event (data, mask); | |
| 799 | } | ||
| 800 | |||
| 801 | static void | ||
| 802 | ✗ | holder_disappeared (GDBusConnection *connection, | |
| 803 | const gchar *name, | ||
| 804 | gpointer user_data) | ||
| 805 | { | ||
| 806 | ✗ | PpdApp *data = user_data; | |
| 807 | ✗ | GHashTableIter iter; | |
| 808 | ✗ | gpointer key, value; | |
| 809 | ✗ | GPtrArray *cookies; | |
| 810 | ✗ | guint i; | |
| 811 | |||
| 812 | ✗ | cookies = g_ptr_array_new (); | |
| 813 | ✗ | g_hash_table_iter_init (&iter, data->profile_holds); | |
| 814 | ✗ | while (g_hash_table_iter_next (&iter, &key, (gpointer *) &value)) { | |
| 815 | ✗ | guint cookie = GPOINTER_TO_UINT (key); | |
| 816 | ✗ | ProfileHold *hold = value; | |
| 817 | |||
| 818 | ✗ | if (g_strcmp0 (hold->requester, name) != 0) | |
| 819 | ✗ | continue; | |
| 820 | |||
| 821 | ✗ | g_debug ("Holder %s with cookie %u disappeared, adding to list", name, cookie); | |
| 822 | ✗ | g_ptr_array_add (cookies, GUINT_TO_POINTER (cookie)); | |
| 823 | } | ||
| 824 | |||
| 825 | ✗ | for (i = 0; i < cookies->len; i++) { | |
| 826 | ✗ | guint cookie = GPOINTER_TO_UINT (cookies->pdata[i]); | |
| 827 | ✗ | g_debug ("Removing profile hold for cookie %u", cookie); | |
| 828 | ✗ | release_profile_hold (data, cookie); | |
| 829 | } | ||
| 830 | ✗ | g_ptr_array_free (cookies, TRUE); | |
| 831 | ✗ | } | |
| 832 | |||
| 833 | static void | ||
| 834 | 41 | hold_profile (PpdApp *data, | |
| 835 | GVariant *parameters, | ||
| 836 | GDBusMethodInvocation *invocation) | ||
| 837 | { | ||
| 838 | 41 | const char *profile_name; | |
| 839 | 41 | const char *reason; | |
| 840 | 41 | const char *application_id; | |
| 841 | 41 | PpdProfile profile; | |
| 842 | 41 | ProfileHold *hold; | |
| 843 | 41 | guint watch_id; | |
| 844 | 41 | guint mask; | |
| 845 | |||
| 846 | 41 | g_variant_get (parameters, "(&s&s&s)", &profile_name, &reason, &application_id); | |
| 847 | 41 | profile = ppd_profile_from_str (profile_name); | |
| 848 | 41 | if (profile != PPD_PROFILE_PERFORMANCE && | |
| 849 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
|
41 | profile != PPD_PROFILE_POWER_SAVER) { |
| 850 | ✗ | g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, | |
| 851 | "Only profiles 'performance' and 'power-saver' can be a hold profile"); | ||
| 852 | 2 | return; | |
| 853 | } | ||
| 854 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 39 times.
|
41 | if (!get_profile_available (data, profile)) { |
| 855 | 2 | g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, | |
| 856 | "Cannot hold profile '%s' as it is not available", | ||
| 857 | profile_name); | ||
| 858 | 2 | return; | |
| 859 | } | ||
| 860 | |||
| 861 | 39 | hold = g_new0 (ProfileHold, 1); | |
| 862 | 39 | hold->profile = profile; | |
| 863 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
|
39 | hold->reason = g_strdup (reason); |
| 864 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
|
39 | hold->application_id = g_strdup (application_id); |
| 865 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
|
39 | hold->requester = g_strdup (g_dbus_method_invocation_get_sender (invocation)); |
| 866 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
|
39 | hold->requester_iface = g_strdup (g_dbus_method_invocation_get_interface_name (invocation)); |
| 867 | |||
| 868 | 39 | g_debug ("%s (%s) requesting to hold profile '%s', reason: '%s'", application_id, | |
| 869 | hold->requester, profile_name, reason); | ||
| 870 | 39 | watch_id = g_bus_watch_name_on_connection (data->connection, hold->requester, | |
| 871 | G_BUS_NAME_WATCHER_FLAGS_NONE, NULL, | ||
| 872 | holder_disappeared, data, NULL); | ||
| 873 | 39 | g_hash_table_insert (data->profile_holds, GUINT_TO_POINTER (watch_id), hold); | |
| 874 | 39 | g_dbus_method_invocation_return_value (invocation, g_variant_new ("(u)", watch_id)); | |
| 875 | 39 | mask = PROP_ACTIVE_PROFILE_HOLDS; | |
| 876 | |||
| 877 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
|
39 | if (profile != data->active_profile) { |
| 878 | 39 | PpdProfile target_profile = effective_hold_profile (data); | |
| 879 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
|
39 | if (target_profile != PPD_PROFILE_UNSET && |
| 880 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 35 times.
|
39 | target_profile != data->active_profile) { |
| 881 | 35 | activate_target_profile (data, target_profile, PPD_PROFILE_ACTIVATION_REASON_PROGRAM_HOLD, NULL); | |
| 882 | 35 | mask |= PROP_ACTIVE_PROFILE; | |
| 883 | } | ||
| 884 | } | ||
| 885 | |||
| 886 | 39 | send_dbus_event (data, mask); | |
| 887 | } | ||
| 888 | |||
| 889 | static void | ||
| 890 | 35 | release_profile (PpdApp *data, | |
| 891 | GVariant *parameters, | ||
| 892 | GDBusMethodInvocation *invocation) | ||
| 893 | { | ||
| 894 | 35 | guint cookie; | |
| 895 | 35 | g_variant_get (parameters, "(u)", &cookie); | |
| 896 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 35 times.
|
35 | if (!g_hash_table_contains (data->profile_holds, GUINT_TO_POINTER (cookie))) { |
| 897 | ✗ | g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, | |
| 898 | "No hold with cookie %d", cookie); | ||
| 899 | ✗ | return; | |
| 900 | } | ||
| 901 | 35 | release_profile_hold (data, cookie); | |
| 902 | 35 | g_dbus_method_invocation_return_value (invocation, NULL); | |
| 903 | } | ||
| 904 | |||
| 905 | static gboolean | ||
| 906 | 151 | check_action_permission (PpdApp *data, | |
| 907 | const char *sender, | ||
| 908 | const char *action, | ||
| 909 | GError **error) | ||
| 910 | { | ||
| 911 | 302 | g_autoptr(GError) local_error = NULL; | |
| 912 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 151 times.
|
151 | g_autoptr(PolkitAuthorizationResult) result = NULL; |
| 913 |
1/2✓ Branch 0 taken 151 times.
✗ Branch 1 not taken.
|
151 | g_autoptr(PolkitSubject) subject = NULL; |
| 914 | |||
| 915 | 151 | subject = polkit_system_bus_name_new (sender); | |
| 916 | 151 | result = polkit_authority_check_authorization_sync (data->auth, | |
| 917 | subject, | ||
| 918 | action, | ||
| 919 | NULL, | ||
| 920 | POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE, | ||
| 921 | NULL, &local_error); | ||
| 922 |
3/4✓ Branch 0 taken 151 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 147 times.
|
302 | if (result == NULL || |
| 923 | 151 | !polkit_authorization_result_get_is_authorized (result)) | |
| 924 | { | ||
| 925 | 4 | g_set_error (error, G_DBUS_ERROR, | |
| 926 | G_DBUS_ERROR_ACCESS_DENIED, | ||
| 927 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | "Not Authorized: %s", local_error ? local_error->message : action); |
| 928 | 4 | return FALSE; | |
| 929 | } | ||
| 930 | |||
| 931 | return TRUE; | ||
| 932 | |||
| 933 | } | ||
| 934 | |||
| 935 | static GVariant * | ||
| 936 | 2821 | handle_get_property (GDBusConnection *connection, | |
| 937 | const gchar *sender, | ||
| 938 | const gchar *object_path, | ||
| 939 | const gchar *interface_name, | ||
| 940 | const gchar *property_name, | ||
| 941 | GError **error, | ||
| 942 | gpointer user_data) | ||
| 943 | { | ||
| 944 | 2821 | PpdApp *data = user_data; | |
| 945 | |||
| 946 |
1/2✓ Branch 0 taken 2821 times.
✗ Branch 1 not taken.
|
2821 | g_return_val_if_fail (data->connection, NULL); |
| 947 | |||
| 948 |
2/2✓ Branch 1 taken 1112 times.
✓ Branch 2 taken 1709 times.
|
2821 | if (g_strcmp0 (property_name, "ActiveProfile") == 0) |
| 949 | 1112 | return g_variant_new_string (get_active_profile (data)); | |
| 950 |
2/2✓ Branch 1 taken 182 times.
✓ Branch 2 taken 1527 times.
|
1709 | if (g_strcmp0 (property_name, "PerformanceInhibited") == 0) |
| 951 | 182 | return g_variant_new_string (""); | |
| 952 |
2/2✓ Branch 1 taken 544 times.
✓ Branch 2 taken 983 times.
|
1527 | if (g_strcmp0 (property_name, "Profiles") == 0) |
| 953 | 544 | return get_profiles_variant (data); | |
| 954 |
2/2✓ Branch 0 taken 112 times.
✓ Branch 1 taken 871 times.
|
983 | if (g_str_equal (property_name, "ActionsInfo") && |
| 955 |
1/2✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
|
112 | g_str_equal (interface_name, POWER_PROFILES_IFACE_NAME)) |
| 956 | 112 | return get_modern_actions_variant (data); | |
| 957 |
2/2✓ Branch 0 taken 186 times.
✓ Branch 1 taken 685 times.
|
871 | if (g_str_equal (property_name, "Actions")) |
| 958 | 186 | return get_legacy_actions_variant (data); | |
| 959 |
2/2✓ Branch 0 taken 105 times.
✓ Branch 1 taken 580 times.
|
685 | if (g_str_equal (property_name, "BatteryAware")) |
| 960 | 105 | return g_variant_new_boolean (data->battery_support); | |
| 961 |
2/2✓ Branch 1 taken 204 times.
✓ Branch 2 taken 376 times.
|
580 | if (g_strcmp0 (property_name, "PerformanceDegraded") == 0) { |
| 962 | 204 | gchar *degraded = get_performance_degraded (data); | |
| 963 | 204 | return g_variant_new_take_string (g_steal_pointer (°raded)); | |
| 964 | } | ||
| 965 |
2/2✓ Branch 1 taken 192 times.
✓ Branch 2 taken 184 times.
|
376 | if (g_strcmp0 (property_name, "ActiveProfileHolds") == 0) |
| 966 | 192 | return get_profile_holds_variant (data); | |
| 967 |
1/2✓ Branch 1 taken 184 times.
✗ Branch 2 not taken.
|
184 | if (g_strcmp0 (property_name, "Version") == 0) |
| 968 | 184 | return g_variant_new_string (VERSION); | |
| 969 | ✗ | g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, | |
| 970 | "Invalid property'%s'", property_name); | ||
| 971 | ✗ | return NULL; | |
| 972 | } | ||
| 973 | |||
| 974 | static gboolean | ||
| 975 | 100 | handle_set_property (GDBusConnection *connection, | |
| 976 | const gchar *sender, | ||
| 977 | const gchar *object_path, | ||
| 978 | const gchar *interface_name, | ||
| 979 | const gchar *property_name, | ||
| 980 | GVariant *value, | ||
| 981 | GError **error, | ||
| 982 | gpointer user_data) | ||
| 983 | { | ||
| 984 | 100 | PpdApp *data = user_data; | |
| 985 | |||
| 986 |
1/2✓ Branch 0 taken 100 times.
✗ Branch 1 not taken.
|
100 | g_return_val_if_fail (data->connection, FALSE); |
| 987 | |||
| 988 |
2/2✓ Branch 0 taken 94 times.
✓ Branch 1 taken 6 times.
|
100 | if (g_str_equal (property_name, "ActiveProfile")) { |
| 989 | 94 | const char *profile; | |
| 990 | |||
| 991 |
2/2✓ Branch 1 taken 92 times.
✓ Branch 2 taken 2 times.
|
94 | if (!check_action_permission (data, sender, |
| 992 | POWER_PROFILES_POLICY_NAMESPACE ".switch-profile", | ||
| 993 | error)) | ||
| 994 | return FALSE; | ||
| 995 | |||
| 996 | 92 | g_variant_get (value, "&s", &profile); | |
| 997 | 92 | return set_active_profile (data, profile, error); | |
| 998 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | } else if (g_str_equal (property_name, "BatteryAware")) { |
| 999 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
|
6 | if (!check_action_permission (data, |
| 1000 | sender, | ||
| 1001 | POWER_PROFILES_POLICY_NAMESPACE ".configure-battery-aware", | ||
| 1002 | error)) { | ||
| 1003 | return FALSE; | ||
| 1004 | } | ||
| 1005 | |||
| 1006 | 6 | return set_battery_support (data, g_variant_get_boolean (value), error); | |
| 1007 | } | ||
| 1008 | |||
| 1009 | ✗ | g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, | |
| 1010 | "No such property: %s", property_name); | ||
| 1011 | ✗ | return FALSE; | |
| 1012 | } | ||
| 1013 | |||
| 1014 | 8 | static gboolean set_action_enabled (PpdApp *data, | |
| 1015 | GVariant *parameters, | ||
| 1016 | GError **error) | ||
| 1017 | { | ||
| 1018 | 8 | const char *action_name; | |
| 1019 | 8 | gboolean active; | |
| 1020 | |||
| 1021 | 8 | g_variant_get (parameters, "(&sb)", &action_name, &active); | |
| 1022 | |||
| 1023 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | for (guint i = 0; i < data->actions->len; i++) { |
| 1024 | 14 | PpdAction *action = g_ptr_array_index (data->actions, i); | |
| 1025 | |||
| 1026 |
2/2✓ Branch 2 taken 8 times.
✓ Branch 3 taken 6 times.
|
14 | if (g_strcmp0 (ppd_action_get_action_name (action), action_name) == 0) { |
| 1027 | 8 | g_key_file_set_boolean (data->config, "Actions", action_name, active); | |
| 1028 | 8 | restart_profile_drivers_for_default_app (); | |
| 1029 | 8 | return TRUE; | |
| 1030 | } | ||
| 1031 | } | ||
| 1032 | ✗ | g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, | |
| 1033 | "No such action '%s'", action_name); | ||
| 1034 | ✗ | return FALSE; | |
| 1035 | } | ||
| 1036 | |||
| 1037 | static void | ||
| 1038 | 86 | handle_method_call (GDBusConnection *connection, | |
| 1039 | const gchar *sender, | ||
| 1040 | const gchar *object_path, | ||
| 1041 | const gchar *interface_name, | ||
| 1042 | const gchar *method_name, | ||
| 1043 | GVariant *parameters, | ||
| 1044 | GDBusMethodInvocation *invocation, | ||
| 1045 | gpointer user_data) | ||
| 1046 | { | ||
| 1047 | 86 | PpdApp *data = user_data; | |
| 1048 |
1/2✓ Branch 0 taken 86 times.
✗ Branch 1 not taken.
|
86 | g_return_if_fail (data->connection); |
| 1049 | |||
| 1050 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 62 times.
|
86 | if (!g_str_equal (interface_name, POWER_PROFILES_IFACE_NAME) && |
| 1051 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 | !g_str_equal (interface_name, POWER_PROFILES_LEGACY_IFACE_NAME)) { |
| 1052 | ✗ | g_dbus_method_invocation_return_error (invocation,G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_INTERFACE, | |
| 1053 | "Unknown interface %s", interface_name); | ||
| 1054 | ✗ | return; | |
| 1055 | } | ||
| 1056 | |||
| 1057 |
2/2✓ Branch 1 taken 43 times.
✓ Branch 2 taken 43 times.
|
86 | if (g_strcmp0 (method_name, "HoldProfile") == 0) { |
| 1058 | 43 | g_autoptr(GError) local_error = NULL; | |
| 1059 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 41 times.
|
43 | if (!check_action_permission (data, |
| 1060 | 43 | g_dbus_method_invocation_get_sender (invocation), | |
| 1061 | POWER_PROFILES_POLICY_NAMESPACE ".hold-profile", | ||
| 1062 | &local_error)) { | ||
| 1063 | 2 | g_dbus_method_invocation_return_gerror (invocation, local_error); | |
| 1064 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | return; |
| 1065 | } | ||
| 1066 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
|
41 | hold_profile (data, parameters, invocation); |
| 1067 |
2/2✓ Branch 1 taken 35 times.
✓ Branch 2 taken 8 times.
|
43 | } else if (g_strcmp0 (method_name, "ReleaseProfile") == 0) { |
| 1068 | 35 | release_profile (data, parameters, invocation); | |
| 1069 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | } else if (g_strcmp0 (method_name, "SetActionEnabled") == 0) { |
| 1070 | 8 | g_autoptr(GError) local_error = NULL; | |
| 1071 | |||
| 1072 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (g_str_equal (interface_name, POWER_PROFILES_LEGACY_IFACE_NAME)) { |
| 1073 | ✗ | g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, | |
| 1074 | "Method %s is not available in interface %s", method_name, | ||
| 1075 | interface_name); | ||
| 1076 | ✗ | return; | |
| 1077 | } | ||
| 1078 | |||
| 1079 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | if (!check_action_permission (data, |
| 1080 | 8 | g_dbus_method_invocation_get_sender (invocation), | |
| 1081 | POWER_PROFILES_POLICY_NAMESPACE ".configure-action", | ||
| 1082 | &local_error)) { | ||
| 1083 | ✗ | g_dbus_method_invocation_return_gerror (invocation, local_error); | |
| 1084 | ✗ | return; | |
| 1085 | } | ||
| 1086 | |||
| 1087 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | if (!set_action_enabled (data, parameters, &local_error)) { |
| 1088 | ✗ | g_dbus_method_invocation_return_gerror (invocation, local_error); | |
| 1089 | ✗ | return; | |
| 1090 | } | ||
| 1091 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | g_dbus_method_invocation_return_value (invocation, NULL); |
| 1092 | } else { | ||
| 1093 | ✗ | g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, | |
| 1094 | "No such method %s in interface %s", interface_name, | ||
| 1095 | method_name); | ||
| 1096 | } | ||
| 1097 | } | ||
| 1098 | |||
| 1099 | |||
| 1100 | static const GDBusInterfaceVTable interface_vtable = | ||
| 1101 | { | ||
| 1102 | handle_method_call, | ||
| 1103 | handle_get_property, | ||
| 1104 | handle_set_property | ||
| 1105 | }; | ||
| 1106 | |||
| 1107 | typedef struct { | ||
| 1108 | PpdApp *app; | ||
| 1109 | GBusNameOwnerFlags flags; | ||
| 1110 | GDBusInterfaceInfo *interface; | ||
| 1111 | GDBusInterfaceInfo *legacy_interface; | ||
| 1112 | } PpdBusOwnData; | ||
| 1113 | |||
| 1114 | static void | ||
| 1115 | 2 | ppd_bus_own_data_free (PpdBusOwnData *data) | |
| 1116 | { | ||
| 1117 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | g_clear_pointer (&data->interface, g_dbus_interface_info_unref); |
| 1118 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | g_clear_pointer (&data->legacy_interface, g_dbus_interface_info_unref); |
| 1119 | 2 | g_free (data); | |
| 1120 | 2 | } | |
| 1121 | |||
| 1122 | static void | ||
| 1123 | 2 | name_lost_handler (GDBusConnection *connection, | |
| 1124 | const gchar *name, | ||
| 1125 | gpointer user_data) | ||
| 1126 | { | ||
| 1127 | 2 | PpdBusOwnData *data = user_data; | |
| 1128 | 2 | PpdApp *app = data->app; | |
| 1129 | |||
| 1130 | 2 | g_warning ("power-profiles-daemon is already running, or it cannot own its D-Bus name. Verify installation."); | |
| 1131 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (!app->was_started) |
| 1132 | 2 | app->ret = EXIT_FAILURE; | |
| 1133 | |||
| 1134 | 2 | g_main_loop_quit (app->main_loop); | |
| 1135 | 2 | } | |
| 1136 | |||
| 1137 | static void | ||
| 1138 | 142 | legacy_name_acquired_handler (GDBusConnection *connection, | |
| 1139 | const gchar *name, | ||
| 1140 | gpointer user_data) | ||
| 1141 | { | ||
| 1142 | 142 | g_debug ("Name '%s' acquired", name); | |
| 1143 | 142 | } | |
| 1144 | |||
| 1145 | static void | ||
| 1146 | 142 | bus_acquired_handler (GDBusConnection *connection, | |
| 1147 | const gchar *name, | ||
| 1148 | gpointer user_data) | ||
| 1149 | { | ||
| 1150 | 142 | PpdBusOwnData *data = user_data; | |
| 1151 | |||
| 1152 | 142 | g_dbus_connection_register_object (connection, | |
| 1153 | POWER_PROFILES_DBUS_PATH, | ||
| 1154 | data->interface, | ||
| 1155 | &interface_vtable, | ||
| 1156 | 142 | data->app, | |
| 1157 | NULL, | ||
| 1158 | NULL); | ||
| 1159 | |||
| 1160 | 142 | g_dbus_connection_register_object (connection, | |
| 1161 | POWER_PROFILES_LEGACY_DBUS_PATH, | ||
| 1162 | data->legacy_interface, | ||
| 1163 | &interface_vtable, | ||
| 1164 | 142 | data->app, | |
| 1165 | NULL, | ||
| 1166 | NULL); | ||
| 1167 | |||
| 1168 | 142 | data->app->legacy_name_id = g_bus_own_name_on_connection (connection, | |
| 1169 | POWER_PROFILES_LEGACY_DBUS_NAME, | ||
| 1170 | data->flags, | ||
| 1171 | legacy_name_acquired_handler, | ||
| 1172 | name_lost_handler, | ||
| 1173 | data, | ||
| 1174 | NULL); | ||
| 1175 | |||
| 1176 | 142 | data->app->connection = g_object_ref (connection); | |
| 1177 | 142 | } | |
| 1178 | |||
| 1179 | static void | ||
| 1180 | 174 | upower_source_update_from_value (PpdApp *data, | |
| 1181 | GVariant *battery_val) | ||
| 1182 | { | ||
| 1183 | 174 | PpdPowerChangedReason reason; | |
| 1184 | |||
| 1185 |
2/2✓ Branch 0 taken 26 times.
✓ Branch 1 taken 148 times.
|
174 | if (!battery_val) |
| 1186 | reason = PPD_POWER_CHANGED_REASON_UNKNOWN; | ||
| 1187 |
2/2✓ Branch 1 taken 12 times.
✓ Branch 2 taken 14 times.
|
26 | else if (g_variant_get_boolean (battery_val)) |
| 1188 | reason = PPD_POWER_CHANGED_REASON_BATTERY; | ||
| 1189 | else | ||
| 1190 | 12 | reason = PPD_POWER_CHANGED_REASON_AC; | |
| 1191 | |||
| 1192 | 174 | upower_battery_set_power_changed_reason (data, reason); | |
| 1193 | 174 | } | |
| 1194 | |||
| 1195 | static void | ||
| 1196 | 162 | upower_source_update (PpdApp *data) | |
| 1197 | { | ||
| 1198 | 324 | g_autoptr(GVariant) battery_val = NULL; | |
| 1199 | |||
| 1200 | 162 | battery_val = g_dbus_proxy_get_cached_property (data->upower_proxy, "OnBattery"); | |
| 1201 |
2/2✓ Branch 1 taken 14 times.
✓ Branch 2 taken 148 times.
|
162 | upower_source_update_from_value (data, battery_val); |
| 1202 | 162 | } | |
| 1203 | |||
| 1204 | static void | ||
| 1205 | 18 | upower_battery_changed (PpdApp *data, gdouble level) | |
| 1206 | { | ||
| 1207 | 18 | g_info ("Battery level changed to %f", level); | |
| 1208 | |||
| 1209 |
2/2✓ Branch 1 taken 54 times.
✓ Branch 2 taken 18 times.
|
72 | for (guint i = 0; i < data->actions->len; i++) { |
| 1210 | 54 | g_autoptr(GError) error = NULL; | |
| 1211 | 54 | PpdAction *action; | |
| 1212 | |||
| 1213 | 54 | action = g_ptr_array_index (data->actions, i); | |
| 1214 | |||
| 1215 |
2/2✓ Branch 1 taken 31 times.
✓ Branch 2 taken 23 times.
|
54 | if (!ppd_action_get_active (action)) |
| 1216 | 31 | continue; | |
| 1217 | |||
| 1218 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 23 times.
|
23 | if (!ppd_action_battery_changed (action, level, &error)) { |
| 1219 | ✗ | g_warning ("failed to update action %s: %s", | |
| 1220 | ppd_action_get_action_name (action), | ||
| 1221 | error->message); | ||
| 1222 | ✗ | g_clear_error (&error); | |
| 1223 | ✗ | continue; | |
| 1224 | } | ||
| 1225 | } | ||
| 1226 | |||
| 1227 |
2/2✓ Branch 1 taken 8 times.
✓ Branch 2 taken 10 times.
|
18 | if (PPD_IS_DRIVER_CPU (data->cpu_driver)) { |
| 1228 | 8 | g_autoptr(GError) error = NULL; | |
| 1229 | |||
| 1230 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | if (!ppd_driver_battery_changed (PPD_DRIVER (data->cpu_driver), level, &error)) { |
| 1231 | ✗ | g_warning ("failed to update driver %s: %s", | |
| 1232 | ppd_driver_get_driver_name (PPD_DRIVER (data->cpu_driver)), | ||
| 1233 | error->message); | ||
| 1234 | } | ||
| 1235 | } | ||
| 1236 | |||
| 1237 |
1/2✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
|
18 | if (PPD_IS_DRIVER_PLATFORM (data->platform_driver)) { |
| 1238 | 18 | g_autoptr(GError) error = NULL; | |
| 1239 | |||
| 1240 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
|
18 | if (!ppd_driver_battery_changed (PPD_DRIVER (data->platform_driver), level, &error)) { |
| 1241 | ✗ | g_warning ("failed to update driver %s: %s", | |
| 1242 | ppd_driver_get_driver_name (PPD_DRIVER (data->platform_driver)), | ||
| 1243 | error->message); | ||
| 1244 | } | ||
| 1245 | } | ||
| 1246 | 18 | } | |
| 1247 | |||
| 1248 | static void | ||
| 1249 | 154 | upower_battery_update (PpdApp *data) | |
| 1250 | { | ||
| 1251 | 308 | g_autoptr(GVariant) val = NULL; | |
| 1252 | |||
| 1253 | 154 | val = g_dbus_proxy_get_cached_property (data->upower_display_proxy, "Percentage"); | |
| 1254 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 140 times.
|
154 | if (val) |
| 1255 | 14 | upower_battery_changed(data, g_variant_get_double (val)); | |
| 1256 | 154 | } | |
| 1257 | |||
| 1258 | static void | ||
| 1259 | 30 | upower_properties_changed (GDBusProxy *proxy, | |
| 1260 | GVariant *changed_properties, | ||
| 1261 | GStrv invalidated_properties, | ||
| 1262 | PpdApp *data) | ||
| 1263 | { | ||
| 1264 | 60 | g_auto(GVariantDict) props_dict = G_VARIANT_DICT_INIT (changed_properties); | |
| 1265 | 30 | g_autoptr(GVariant) battery_val = NULL; | |
| 1266 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 18 times.
|
30 | g_autoptr(GVariant) percent_val = NULL; |
| 1267 | |||
| 1268 | 30 | battery_val = g_variant_dict_lookup_value (&props_dict, "OnBattery", | |
| 1269 | G_VARIANT_TYPE_BOOLEAN); | ||
| 1270 | |||
| 1271 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 18 times.
|
30 | if (battery_val) |
| 1272 | 12 | upower_source_update_from_value (data, battery_val); | |
| 1273 | |||
| 1274 | 30 | percent_val = g_variant_dict_lookup_value (&props_dict, "Percentage", | |
| 1275 | G_VARIANT_TYPE_DOUBLE); | ||
| 1276 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 26 times.
|
30 | if (percent_val) |
| 1277 | 4 | upower_battery_changed (data, g_variant_get_double (percent_val)); | |
| 1278 | 30 | } | |
| 1279 | |||
| 1280 | static void | ||
| 1281 | 342 | upower_battery_set_power_changed_reason (PpdApp *data, | |
| 1282 | PpdPowerChangedReason reason) | ||
| 1283 | { | ||
| 1284 |
2/2✓ Branch 0 taken 48 times.
✓ Branch 1 taken 294 times.
|
342 | if (data->power_changed_reason == reason) |
| 1285 | return; | ||
| 1286 | |||
| 1287 | 48 | data->power_changed_reason = reason; | |
| 1288 | 48 | g_info ("Power Changed because of reason %s", | |
| 1289 | ppd_power_changed_reason_to_str (reason)); | ||
| 1290 | |||
| 1291 |
2/2✓ Branch 1 taken 144 times.
✓ Branch 2 taken 48 times.
|
192 | for (guint i = 0; i < data->actions->len; i++) { |
| 1292 | 144 | g_autoptr(GError) error = NULL; | |
| 1293 | 144 | PpdAction *action; | |
| 1294 | |||
| 1295 | 144 | action = g_ptr_array_index (data->actions, i); | |
| 1296 | |||
| 1297 |
2/2✓ Branch 1 taken 94 times.
✓ Branch 2 taken 50 times.
|
144 | if (!ppd_action_get_active (action)) |
| 1298 | 94 | continue; | |
| 1299 | |||
| 1300 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 50 times.
|
50 | if (!ppd_action_power_changed (action, reason, &error)) { |
| 1301 | ✗ | g_warning ("failed to update action %s: %s", | |
| 1302 | ppd_action_get_action_name (action), | ||
| 1303 | error->message); | ||
| 1304 | ✗ | g_clear_error (&error); | |
| 1305 | ✗ | continue; | |
| 1306 | } | ||
| 1307 | } | ||
| 1308 | |||
| 1309 |
2/2✓ Branch 1 taken 36 times.
✓ Branch 2 taken 12 times.
|
48 | if (PPD_IS_DRIVER_CPU (data->cpu_driver)) { |
| 1310 | 36 | g_autoptr(GError) error = NULL; | |
| 1311 | |||
| 1312 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 36 times.
|
36 | if (!ppd_driver_power_changed (PPD_DRIVER (data->cpu_driver), reason, &error)) { |
| 1313 | ✗ | g_warning ("failed to update driver %s: %s", | |
| 1314 | ppd_driver_get_driver_name (PPD_DRIVER (data->cpu_driver)), | ||
| 1315 | error->message); | ||
| 1316 | } | ||
| 1317 | } | ||
| 1318 | |||
| 1319 |
1/2✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
|
48 | if (PPD_IS_DRIVER_PLATFORM (data->platform_driver)) { |
| 1320 | 48 | g_autoptr(GError) error = NULL; | |
| 1321 | |||
| 1322 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
|
48 | if (!ppd_driver_power_changed (PPD_DRIVER (data->platform_driver), reason, &error)) { |
| 1323 | ✗ | g_warning ("failed to update driver %s: %s", | |
| 1324 | ppd_driver_get_driver_name (PPD_DRIVER (data->platform_driver)), | ||
| 1325 | error->message); | ||
| 1326 | } | ||
| 1327 | } | ||
| 1328 | } | ||
| 1329 | |||
| 1330 | static void | ||
| 1331 | 16 | upower_name_owner_changed (GObject *object, | |
| 1332 | GParamSpec *pspec, | ||
| 1333 | gpointer user_data) | ||
| 1334 | { | ||
| 1335 | 16 | PpdApp *data = user_data; | |
| 1336 | 16 | GDBusProxy *upower_proxy = G_DBUS_PROXY (object); | |
| 1337 | 16 | g_autofree char *name_owner = NULL; | |
| 1338 | |||
| 1339 | 16 | name_owner = g_dbus_proxy_get_name_owner (upower_proxy); | |
| 1340 | |||
| 1341 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | if (name_owner != NULL) { |
| 1342 | 8 | g_debug ("%s appeared", UPOWER_DBUS_NAME); | |
| 1343 | 8 | upower_source_update (data); | |
| 1344 | 8 | return; | |
| 1345 | } | ||
| 1346 | |||
| 1347 | 8 | g_debug ("%s vanished", UPOWER_DBUS_NAME); | |
| 1348 | 8 | upower_battery_set_power_changed_reason (data, PPD_POWER_CHANGED_REASON_UNKNOWN); | |
| 1349 | } | ||
| 1350 | |||
| 1351 | static void | ||
| 1352 | 154 | on_upower_proxy_cb (GObject *source_object, | |
| 1353 | GAsyncResult *res, | ||
| 1354 | gpointer user_data) | ||
| 1355 | { | ||
| 1356 | 154 | PpdApp *data = user_data; | |
| 1357 | 154 | g_autoptr(GDBusProxy) upower_proxy = NULL; | |
| 1358 |
0/2✗ Branch 0 not taken.
✗ Branch 1 not taken.
|
154 | g_autoptr(GError) error = NULL; |
| 1359 | |||
| 1360 | 154 | upower_proxy = g_dbus_proxy_new_finish (res, &error); | |
| 1361 | |||
| 1362 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 154 times.
|
154 | if (upower_proxy == NULL) { |
| 1363 | ✗ | if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) | |
| 1364 | return; | ||
| 1365 | |||
| 1366 | ✗ | g_warning ("failed to connect to upower: %s", error->message); | |
| 1367 | ✗ | return; | |
| 1368 | } | ||
| 1369 | |||
| 1370 |
1/2✓ Branch 0 taken 154 times.
✗ Branch 1 not taken.
|
154 | g_return_if_fail (data->upower_proxy == NULL); |
| 1371 | 154 | data->upower_proxy = g_steal_pointer (&upower_proxy); | |
| 1372 | |||
| 1373 | 154 | data->upower_properties_id = g_signal_connect (data->upower_proxy, | |
| 1374 | "g-properties-changed", | ||
| 1375 | G_CALLBACK (upower_properties_changed), | ||
| 1376 | data); | ||
| 1377 | |||
| 1378 |
1/2✓ Branch 0 taken 154 times.
✗ Branch 1 not taken.
|
154 | if (!data->upower_display_watch_id) { |
| 1379 | 154 | data->upower_watch_id = g_signal_connect (data->upower_proxy, | |
| 1380 | "notify::g-name-owner", | ||
| 1381 | G_CALLBACK (upower_name_owner_changed), | ||
| 1382 | data); | ||
| 1383 | } | ||
| 1384 | |||
| 1385 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 154 times.
|
154 | upower_source_update (data); |
| 1386 | } | ||
| 1387 | |||
| 1388 | static void | ||
| 1389 | 154 | on_upower_display_proxy_cb (GObject *source_object, | |
| 1390 | GAsyncResult *res, | ||
| 1391 | gpointer user_data) | ||
| 1392 | { | ||
| 1393 | 154 | PpdApp *data = user_data; | |
| 1394 | 154 | g_autoptr(GDBusProxy) proxy = NULL; | |
| 1395 |
0/2✗ Branch 0 not taken.
✗ Branch 1 not taken.
|
154 | g_autoptr(GError) error = NULL; |
| 1396 | |||
| 1397 | 154 | proxy = g_dbus_proxy_new_finish (res, &error); | |
| 1398 | |||
| 1399 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 154 times.
|
154 | if (proxy == NULL) { |
| 1400 | ✗ | if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) | |
| 1401 | return; | ||
| 1402 | |||
| 1403 | ✗ | g_warning ("failed to connect to upower: %s", error->message); | |
| 1404 | ✗ | return; | |
| 1405 | } | ||
| 1406 | |||
| 1407 |
1/2✓ Branch 0 taken 154 times.
✗ Branch 1 not taken.
|
154 | g_return_if_fail (data->upower_display_proxy == NULL); |
| 1408 | 154 | data->upower_display_proxy = g_steal_pointer (&proxy); | |
| 1409 | |||
| 1410 | 154 | data->upower_display_properties_id = g_signal_connect (data->upower_display_proxy, | |
| 1411 | "g-properties-changed", | ||
| 1412 | G_CALLBACK (upower_properties_changed), | ||
| 1413 | data); | ||
| 1414 | |||
| 1415 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 154 times.
|
154 | if (!data->upower_watch_id) { |
| 1416 | ✗ | data->upower_display_watch_id = g_signal_connect (data->upower_display_proxy, | |
| 1417 | "notify::g-name-owner", | ||
| 1418 | G_CALLBACK (upower_name_owner_changed), | ||
| 1419 | data); | ||
| 1420 | } | ||
| 1421 | |||
| 1422 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 154 times.
|
154 | upower_battery_update (data); |
| 1423 | } | ||
| 1424 | |||
| 1425 | static void | ||
| 1426 | 4 | on_logind_prepare_for_sleep_cb (GDBusConnection *connection, | |
| 1427 | const gchar *sender_name, | ||
| 1428 | const gchar *object_path, | ||
| 1429 | const gchar *interface_name, | ||
| 1430 | const gchar *signal_name, | ||
| 1431 | GVariant *parameters, | ||
| 1432 | gpointer user_data) | ||
| 1433 | { | ||
| 1434 | 4 | PpdApp *data = user_data; | |
| 1435 | 4 | gboolean start; | |
| 1436 | |||
| 1437 | 4 | g_variant_get (parameters, "(b)", &start); | |
| 1438 | |||
| 1439 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | if (start) |
| 1440 | 2 | g_debug ("System preparing for suspend"); | |
| 1441 | else | ||
| 1442 | 2 | g_debug ("System woke up from suspend"); | |
| 1443 | |||
| 1444 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | if (PPD_IS_DRIVER_CPU (data->cpu_driver)) { |
| 1445 | 4 | g_autoptr(GError) error = NULL; | |
| 1446 | |||
| 1447 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (!ppd_driver_prepare_to_sleep (PPD_DRIVER (data->cpu_driver), start, &error)) { |
| 1448 | ✗ | g_warning ("failed to notify driver %s: %s", | |
| 1449 | ppd_driver_get_driver_name (PPD_DRIVER (data->cpu_driver)), | ||
| 1450 | error->message); | ||
| 1451 | } | ||
| 1452 | } | ||
| 1453 | |||
| 1454 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | if (PPD_IS_DRIVER_PLATFORM (data->platform_driver)) { |
| 1455 | 4 | g_autoptr(GError) error = NULL; | |
| 1456 | |||
| 1457 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (!ppd_driver_prepare_to_sleep (PPD_DRIVER (data->platform_driver), start, &error)) { |
| 1458 | ✗ | g_warning ("failed to notify driver %s: %s", | |
| 1459 | ppd_driver_get_driver_name (PPD_DRIVER (data->platform_driver)), | ||
| 1460 | error->message); | ||
| 1461 | } | ||
| 1462 | } | ||
| 1463 | 4 | } | |
| 1464 | |||
| 1465 | static gboolean | ||
| 1466 | 158 | has_required_drivers (PpdApp *data) | |
| 1467 | { | ||
| 1468 |
3/4✓ Branch 1 taken 114 times.
✓ Branch 2 taken 44 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 114 times.
|
272 | if (!PPD_IS_DRIVER_CPU (data->cpu_driver) && |
| 1469 | 114 | !PPD_IS_DRIVER_PLATFORM (data->platform_driver)) | |
| 1470 | return FALSE; | ||
| 1471 | |||
| 1472 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 158 times.
|
158 | if (!get_profile_available (data, PPD_PROFILE_BALANCED | PPD_PROFILE_POWER_SAVER)) |
| 1473 | return FALSE; | ||
| 1474 | |||
| 1475 | return TRUE; | ||
| 1476 | } | ||
| 1477 | |||
| 1478 | static void | ||
| 1479 | 16 | restart_profile_drivers (PpdApp *data) | |
| 1480 | { | ||
| 1481 | 16 | stop_profile_drivers (data); | |
| 1482 | 16 | start_profile_drivers (data); | |
| 1483 | } | ||
| 1484 | |||
| 1485 | static void | ||
| 1486 | 4 | driver_probe_request_cb (PpdDriver *driver, | |
| 1487 | gpointer user_data) | ||
| 1488 | { | ||
| 1489 | 4 | PpdApp *data = user_data; | |
| 1490 | |||
| 1491 | 4 | restart_profile_drivers (data); | |
| 1492 | 4 | } | |
| 1493 | |||
| 1494 | static void | ||
| 1495 | 320 | disconnect_array_objects_signals_by_data (GPtrArray *array, | |
| 1496 | void *data) | ||
| 1497 | { | ||
| 1498 |
2/2✓ Branch 0 taken 478 times.
✓ Branch 1 taken 320 times.
|
798 | for (guint i = 0; i < array->len; ++i) { |
| 1499 | 478 | GObject *object = g_ptr_array_index (array, i); | |
| 1500 | |||
| 1501 | 478 | g_signal_handlers_disconnect_by_data (object, data); | |
| 1502 | } | ||
| 1503 | 320 | } | |
| 1504 | |||
| 1505 | static void | ||
| 1506 | 640 | maybe_disconnect_object_by_data (void *object, | |
| 1507 | void *data) | ||
| 1508 | { | ||
| 1509 |
2/2✓ Branch 0 taken 510 times.
✓ Branch 1 taken 130 times.
|
640 | if (!G_IS_OBJECT (object)) |
| 1510 | return; | ||
| 1511 | |||
| 1512 | 510 | g_signal_handlers_disconnect_by_data (object, data); | |
| 1513 | } | ||
| 1514 | |||
| 1515 | static void | ||
| 1516 | 160 | stop_profile_drivers (PpdApp *data) | |
| 1517 | { | ||
| 1518 |
2/2✓ Branch 0 taken 22 times.
✓ Branch 1 taken 138 times.
|
160 | if (data->logind_sleep_signal_id) { |
| 1519 | 22 | g_dbus_connection_signal_unsubscribe (data->connection, data->logind_sleep_signal_id); | |
| 1520 | 22 | data->logind_sleep_signal_id = 0; | |
| 1521 | } | ||
| 1522 | |||
| 1523 | 160 | upower_battery_set_power_changed_reason (data, PPD_POWER_CHANGED_REASON_UNKNOWN); | |
| 1524 | 160 | release_all_profile_holds (data); | |
| 1525 | 160 | g_cancellable_cancel (data->cancellable); | |
| 1526 | 160 | disconnect_array_objects_signals_by_data (data->probed_drivers, data); | |
| 1527 | 160 | g_ptr_array_set_size (data->probed_drivers, 0); | |
| 1528 | 160 | disconnect_array_objects_signals_by_data (data->actions, data); | |
| 1529 | 160 | g_ptr_array_set_size (data->actions, 0); | |
| 1530 |
2/2✓ Branch 0 taken 154 times.
✓ Branch 1 taken 6 times.
|
160 | g_clear_signal_handler (&data->upower_watch_id, data->upower_proxy); |
| 1531 |
2/2✓ Branch 0 taken 154 times.
✓ Branch 1 taken 6 times.
|
160 | g_clear_signal_handler (&data->upower_properties_id, data->upower_proxy); |
| 1532 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 160 times.
|
160 | g_clear_signal_handler (&data->upower_display_watch_id, data->upower_display_proxy); |
| 1533 |
2/2✓ Branch 0 taken 154 times.
✓ Branch 1 taken 6 times.
|
160 | g_clear_signal_handler (&data->upower_display_properties_id, data->upower_display_proxy); |
| 1534 |
2/2✓ Branch 0 taken 158 times.
✓ Branch 1 taken 2 times.
|
160 | g_clear_object (&data->cancellable); |
| 1535 | 160 | maybe_disconnect_object_by_data (data->upower_proxy, data); | |
| 1536 |
2/2✓ Branch 0 taken 154 times.
✓ Branch 1 taken 6 times.
|
160 | g_clear_object (&data->upower_proxy); |
| 1537 | 160 | maybe_disconnect_object_by_data (data->upower_display_proxy, data); | |
| 1538 |
2/2✓ Branch 0 taken 154 times.
✓ Branch 1 taken 6 times.
|
160 | g_clear_object (&data->upower_display_proxy); |
| 1539 | 160 | maybe_disconnect_object_by_data (data->cpu_driver, data); | |
| 1540 |
2/2✓ Branch 0 taken 44 times.
✓ Branch 1 taken 116 times.
|
160 | g_clear_object (&data->cpu_driver); |
| 1541 | 160 | maybe_disconnect_object_by_data (data->platform_driver, data); | |
| 1542 |
2/2✓ Branch 0 taken 158 times.
✓ Branch 1 taken 2 times.
|
160 | g_clear_object (&data->platform_driver); |
| 1543 | 160 | } | |
| 1544 | |||
| 1545 | static gboolean | ||
| 1546 | 474 | action_blocked (PpdApp *app, PpdAction *action) | |
| 1547 | { | ||
| 1548 | 474 | const gchar *action_name = ppd_action_get_action_name (action); | |
| 1549 | 948 | g_autoptr(GError) error = NULL; | |
| 1550 | 474 | gboolean blocked; | |
| 1551 | |||
| 1552 |
3/4✓ Branch 0 taken 6 times.
✓ Branch 1 taken 468 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
|
480 | if (app->debug_options->blocked_actions != NULL && |
| 1553 | 6 | g_strv_length (app->debug_options->blocked_actions) != 0) { | |
| 1554 | |||
| 1555 | 6 | blocked = g_strv_contains ((const gchar *const *) app->debug_options->blocked_actions, action_name); | |
| 1556 | |||
| 1557 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
|
6 | if (blocked) { |
| 1558 | 2 | g_debug ("Action '%s' is blocked by command line", action_name); | |
| 1559 | 2 | return TRUE; | |
| 1560 | } | ||
| 1561 | } | ||
| 1562 | |||
| 1563 | 472 | blocked = !g_key_file_get_boolean (app->config, "Actions", action_name, &error); | |
| 1564 | |||
| 1565 | /* if not in conffile, fallback to action opt-in */ | ||
| 1566 |
2/2✓ Branch 0 taken 434 times.
✓ Branch 1 taken 38 times.
|
472 | if (error != NULL) { |
| 1567 | 434 | blocked = ppd_action_get_optin (action); | |
| 1568 |
2/2✓ Branch 0 taken 142 times.
✓ Branch 1 taken 292 times.
|
434 | g_debug ("Action '%s' is set %s by default", action_name, blocked ? "disabled" : "enabled"); |
| 1569 | 434 | return blocked; | |
| 1570 | } | ||
| 1571 | |||
| 1572 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 22 times.
|
38 | g_debug ("Action '%s' is %s by configuration", action_name, blocked ? "disabled" : "enabled"); |
| 1573 | 38 | return blocked; | |
| 1574 | } | ||
| 1575 | |||
| 1576 | static gboolean | ||
| 1577 | 790 | driver_blocked (PpdApp *app, PpdDriver *driver) | |
| 1578 | { | ||
| 1579 | 790 | const gchar *driver_name = ppd_driver_get_driver_name (driver); | |
| 1580 | 790 | gboolean blocked; | |
| 1581 | |||
| 1582 |
3/4✓ Branch 0 taken 20 times.
✓ Branch 1 taken 770 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20 times.
|
790 | if (app->debug_options->blocked_drivers == NULL || g_strv_length (app->debug_options->blocked_drivers) == 0) |
| 1583 | 770 | return FALSE; | |
| 1584 | |||
| 1585 | 20 | blocked = g_strv_contains ((const gchar *const *) app->debug_options->blocked_drivers, driver_name); | |
| 1586 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 14 times.
|
20 | if (blocked) |
| 1587 | 6 | g_debug ("Driver '%s' is blocked", driver_name); | |
| 1588 | return blocked; | ||
| 1589 | } | ||
| 1590 | |||
| 1591 | static void | ||
| 1592 | 158 | start_profile_drivers (PpdApp *data) | |
| 1593 | { | ||
| 1594 | 158 | guint i; | |
| 1595 | 158 | g_autoptr(GError) initial_error = NULL; | |
| 1596 | 158 | gboolean needs_battery_state_monitor = FALSE; | |
| 1597 | 158 | gboolean needs_battery_change_monitor = FALSE; | |
| 1598 | 158 | gboolean needs_suspend_monitor = FALSE; | |
| 1599 | |||
| 1600 | 158 | data->cancellable = g_cancellable_new (); | |
| 1601 | |||
| 1602 |
2/2✓ Branch 0 taken 1264 times.
✓ Branch 1 taken 158 times.
|
1422 | for (i = 0; i < G_N_ELEMENTS (objects); i++) { |
| 1603 |
0/2✗ Branch 0 not taken.
✗ Branch 1 not taken.
|
1264 | g_autoptr(GObject) object = NULL; |
| 1604 | |||
| 1605 | 1264 | object = g_object_new (objects[i] (), NULL); | |
| 1606 | |||
| 1607 |
2/2✓ Branch 1 taken 790 times.
✓ Branch 2 taken 474 times.
|
1264 | if (PPD_IS_DRIVER (object)) { |
| 1608 |
0/2✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
790 | g_autoptr(PpdDriver) driver = PPD_DRIVER (g_steal_pointer (&object)); |
| 1609 | 790 | PpdProfile profiles; | |
| 1610 | 790 | PpdProbeResult result; | |
| 1611 | |||
| 1612 | 790 | g_debug ("Handling driver '%s'", ppd_driver_get_driver_name (driver)); | |
| 1613 |
2/2✓ Branch 1 taken 6 times.
✓ Branch 2 taken 784 times.
|
790 | if (driver_blocked (data, driver)) { |
| 1614 | 6 | g_debug ("Driver '%s' is blocked, skipping", ppd_driver_get_driver_name (driver)); | |
| 1615 | 6 | continue; | |
| 1616 | } | ||
| 1617 | |||
| 1618 |
4/4✓ Branch 1 taken 68 times.
✓ Branch 2 taken 716 times.
✓ Branch 4 taken 24 times.
✓ Branch 5 taken 44 times.
|
784 | if (PPD_IS_DRIVER_CPU (data->cpu_driver) && PPD_IS_DRIVER_CPU (driver)) { |
| 1619 | 24 | g_debug ("CPU driver '%s' already probed, skipping driver '%s'", | |
| 1620 | ppd_driver_get_driver_name (PPD_DRIVER (data->cpu_driver)), | ||
| 1621 | ppd_driver_get_driver_name (driver)); | ||
| 1622 | 24 | continue; | |
| 1623 | } | ||
| 1624 | |||
| 1625 |
4/4✓ Branch 1 taken 157 times.
✓ Branch 2 taken 603 times.
✓ Branch 4 taken 55 times.
✓ Branch 5 taken 102 times.
|
760 | if (PPD_IS_DRIVER_PLATFORM (data->platform_driver) && PPD_IS_DRIVER_PLATFORM (driver)) { |
| 1626 | 55 | g_debug ("Platform driver '%s' already probed, skipping driver '%s'", | |
| 1627 | ppd_driver_get_driver_name (PPD_DRIVER (data->platform_driver)), | ||
| 1628 | ppd_driver_get_driver_name (driver)); | ||
| 1629 | 55 | continue; | |
| 1630 | } | ||
| 1631 | |||
| 1632 | 705 | profiles = ppd_driver_get_profiles (driver); | |
| 1633 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 705 times.
|
705 | if (!(profiles & PPD_PROFILE_ALL)) { |
| 1634 | ✗ | g_warning ("Profile Driver '%s' implements invalid profiles '0x%X'", | |
| 1635 | ppd_driver_get_driver_name (driver), | ||
| 1636 | profiles); | ||
| 1637 | ✗ | continue; | |
| 1638 | } | ||
| 1639 | |||
| 1640 | 705 | result = ppd_driver_probe (driver); | |
| 1641 |
2/2✓ Branch 0 taken 499 times.
✓ Branch 1 taken 206 times.
|
705 | if (result == PPD_PROBE_RESULT_FAIL) { |
| 1642 | 499 | g_debug ("probe () failed for driver %s, skipping", | |
| 1643 | ppd_driver_get_driver_name (driver)); | ||
| 1644 | 499 | continue; | |
| 1645 | } | ||
| 1646 | |||
| 1647 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 202 times.
|
206 | if (result == PPD_PROBE_RESULT_DEFER) { |
| 1648 | 4 | g_signal_connect (G_OBJECT (driver), "probe-request", | |
| 1649 | G_CALLBACK (driver_probe_request_cb), data); | ||
| 1650 | 4 | g_ptr_array_add (data->probed_drivers, g_steal_pointer (&driver)); | |
| 1651 | 4 | continue; | |
| 1652 | } | ||
| 1653 | |||
| 1654 |
2/2✓ Branch 1 taken 44 times.
✓ Branch 2 taken 158 times.
|
202 | if (PPD_IS_DRIVER_CPU (driver)) |
| 1655 | 44 | g_set_object (&data->cpu_driver, PPD_DRIVER_CPU (driver)); | |
| 1656 |
1/2✓ Branch 1 taken 158 times.
✗ Branch 2 not taken.
|
158 | else if (PPD_IS_DRIVER_PLATFORM (driver)) |
| 1657 | 158 | g_set_object (&data->platform_driver, PPD_DRIVER_PLATFORM (driver)); | |
| 1658 | else | ||
| 1659 | ✗ | g_return_if_reached (); | |
| 1660 | |||
| 1661 |
2/2✓ Branch 0 taken 44 times.
✓ Branch 1 taken 158 times.
|
202 | if (PPD_DRIVER_GET_CLASS (driver)->power_changed != NULL) |
| 1662 | 44 | needs_battery_state_monitor = TRUE; | |
| 1663 | |||
| 1664 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 202 times.
|
202 | if (PPD_DRIVER_GET_CLASS (driver)->battery_changed != NULL) |
| 1665 | ✗ | needs_battery_change_monitor = TRUE; | |
| 1666 | |||
| 1667 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 178 times.
|
202 | if (PPD_DRIVER_GET_CLASS (driver)->prepare_to_sleep != NULL) |
| 1668 | 24 | needs_suspend_monitor = TRUE; | |
| 1669 | |||
| 1670 | 202 | g_info ("Driver '%s' loaded", ppd_driver_get_driver_name (driver)); | |
| 1671 | |||
| 1672 | 202 | g_signal_connect (G_OBJECT (driver), "notify::performance-degraded", | |
| 1673 | G_CALLBACK (driver_performance_degraded_changed_cb), data); | ||
| 1674 | 202 | g_signal_connect (G_OBJECT (driver), "profile-changed", | |
| 1675 | G_CALLBACK (driver_profile_changed_cb), data); | ||
| 1676 | 202 | continue; | |
| 1677 | } | ||
| 1678 | |||
| 1679 |
1/2✓ Branch 1 taken 474 times.
✗ Branch 2 not taken.
|
474 | if (PPD_IS_ACTION (object)) { |
| 1680 | 948 | g_autoptr(PpdAction) action = PPD_ACTION (g_steal_pointer (&object)); | |
| 1681 | |||
| 1682 | 474 | g_debug ("Handling action '%s'", ppd_action_get_action_name (action)); | |
| 1683 | |||
| 1684 |
2/2✓ Branch 1 taken 316 times.
✓ Branch 2 taken 158 times.
|
474 | if (action_blocked (data, action)) { |
| 1685 | 316 | ppd_action_set_active (action, FALSE); | |
| 1686 | } else { | ||
| 1687 |
1/2✓ Branch 1 taken 158 times.
✗ Branch 2 not taken.
|
158 | switch (ppd_action_probe(action)) { |
| 1688 | 158 | case PPD_PROBE_RESULT_SUCCESS: | |
| 1689 | 158 | ppd_action_set_active (action, TRUE); | |
| 1690 | 158 | break; | |
| 1691 | ✗ | default: | |
| 1692 | ✗ | ppd_action_set_active (action, FALSE); | |
| 1693 | ✗ | break; | |
| 1694 | } | ||
| 1695 | } | ||
| 1696 | |||
| 1697 |
2/2✓ Branch 0 taken 158 times.
✓ Branch 1 taken 316 times.
|
474 | if (PPD_ACTION_GET_CLASS (action)->power_changed != NULL) |
| 1698 | 158 | needs_battery_state_monitor = TRUE; | |
| 1699 | |||
| 1700 |
2/2✓ Branch 0 taken 158 times.
✓ Branch 1 taken 316 times.
|
474 | if (PPD_ACTION_GET_CLASS (action)->battery_changed != NULL) |
| 1701 | 158 | needs_battery_change_monitor = TRUE; | |
| 1702 | |||
| 1703 | 474 | g_info ("Action '%s' active %d", | |
| 1704 | ppd_action_get_action_name (action), | ||
| 1705 | ppd_action_get_active (action)); | ||
| 1706 | 474 | g_ptr_array_add (data->actions, g_steal_pointer (&action)); | |
| 1707 | 474 | continue; | |
| 1708 | } | ||
| 1709 | |||
| 1710 |
0/2✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
1264 | g_return_if_reached (); |
| 1711 | } | ||
| 1712 | |||
| 1713 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 158 times.
|
158 | if (!has_required_drivers (data)) { |
| 1714 | ✗ | data->ret = EXIT_FAILURE; | |
| 1715 | ✗ | g_warning ("Some non-optional profile drivers are missing, programmer error"); | |
| 1716 | ✗ | g_main_loop_quit (data->main_loop); | |
| 1717 | } | ||
| 1718 | |||
| 1719 | /* Set initial state either from configuration, or using the currently selected profile */ | ||
| 1720 | 158 | apply_configuration (data); | |
| 1721 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 156 times.
|
158 | if (!activate_target_profile (data, data->active_profile, PPD_PROFILE_ACTIVATION_REASON_RESET, &initial_error)) |
| 1722 | 2 | g_warning ("Failed to activate initial profile: %s", initial_error->message); | |
| 1723 | |||
| 1724 | 158 | send_dbus_event (data, PROP_ALL); | |
| 1725 | 158 | data->was_started = TRUE; | |
| 1726 | |||
| 1727 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 156 times.
|
158 | if (data->debug_options->disable_upower) |
| 1728 | 2 | data->battery_support = FALSE; | |
| 1729 | |||
| 1730 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 154 times.
|
158 | if (!data->battery_support) { |
| 1731 | 4 | g_debug ("upower is disabled, let's skip it"); | |
| 1732 |
1/2✓ Branch 0 taken 154 times.
✗ Branch 1 not taken.
|
154 | } else if (needs_battery_state_monitor || needs_battery_change_monitor) { |
| 1733 | /* start watching for power changes */ | ||
| 1734 |
1/2✓ Branch 0 taken 154 times.
✗ Branch 1 not taken.
|
154 | if (needs_battery_state_monitor) { |
| 1735 | 154 | g_debug ("Battery state monitor required, connecting to upower..."); | |
| 1736 | 154 | g_dbus_proxy_new (data->connection, | |
| 1737 | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START | | ||
| 1738 | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, | ||
| 1739 | NULL, | ||
| 1740 | UPOWER_DBUS_NAME, | ||
| 1741 | UPOWER_DBUS_PATH, | ||
| 1742 | UPOWER_DBUS_INTERFACE, | ||
| 1743 | data->cancellable, | ||
| 1744 | on_upower_proxy_cb, | ||
| 1745 | data); | ||
| 1746 | } | ||
| 1747 | |||
| 1748 |
1/2✓ Branch 0 taken 154 times.
✗ Branch 1 not taken.
|
154 | if (needs_battery_change_monitor) { |
| 1749 | 154 | g_debug ("Battery change monitor required, connecting to upower..."); | |
| 1750 | 154 | g_dbus_proxy_new (data->connection, | |
| 1751 | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START | | ||
| 1752 | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, | ||
| 1753 | NULL, | ||
| 1754 | UPOWER_DBUS_NAME, | ||
| 1755 | UPOWER_DBUS_DISPLAY_DEVICE_PATH, | ||
| 1756 | UPOWER_DBUS_DEVICE_INTERFACE, | ||
| 1757 | data->cancellable, | ||
| 1758 | on_upower_display_proxy_cb, | ||
| 1759 | data); | ||
| 1760 | } | ||
| 1761 | } else { | ||
| 1762 | ✗ | g_debug ("No battery state monitor required by any driver, let's skip it"); | |
| 1763 | } | ||
| 1764 | |||
| 1765 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 156 times.
|
158 | if (data->debug_options->disable_logind) { |
| 1766 | 2 | g_debug ("logind is disabled, let's skip it"); | |
| 1767 |
2/2✓ Branch 0 taken 22 times.
✓ Branch 1 taken 134 times.
|
156 | } else if (needs_suspend_monitor) { |
| 1768 | 22 | g_debug ("Suspension state monitor required, monitoring logind..."); | |
| 1769 | 22 | data->logind_sleep_signal_id = | |
| 1770 | 22 | g_dbus_connection_signal_subscribe (data->connection, | |
| 1771 | LOGIND_DBUS_NAME, | ||
| 1772 | LOGIND_DBUS_INTERFACE, | ||
| 1773 | "PrepareForSleep", | ||
| 1774 | LOGIND_DBUS_PATH, | ||
| 1775 | NULL, | ||
| 1776 | G_DBUS_SIGNAL_FLAGS_NONE, | ||
| 1777 | on_logind_prepare_for_sleep_cb, | ||
| 1778 | data, | ||
| 1779 | NULL); | ||
| 1780 | } else { | ||
| 1781 | 134 | g_debug ("No suspension monitor required by any driver, let's skip it"); | |
| 1782 | } | ||
| 1783 | } | ||
| 1784 | |||
| 1785 | void | ||
| 1786 | 12 | restart_profile_drivers_for_default_app (void) | |
| 1787 | { | ||
| 1788 | 12 | restart_profile_drivers (ppd_app); | |
| 1789 | 12 | } | |
| 1790 | |||
| 1791 | |||
| 1792 | static void | ||
| 1793 | 142 | name_acquired_handler (GDBusConnection *connection, | |
| 1794 | const gchar *name, | ||
| 1795 | gpointer user_data) | ||
| 1796 | { | ||
| 1797 | 142 | PpdBusOwnData *data = user_data; | |
| 1798 | |||
| 1799 | 142 | g_debug ("Name '%s' acquired", name); | |
| 1800 | |||
| 1801 | 142 | start_profile_drivers (data->app); | |
| 1802 | 142 | } | |
| 1803 | |||
| 1804 | static gboolean | ||
| 1805 | 144 | setup_dbus (PpdApp *data, | |
| 1806 | GError **error) | ||
| 1807 | { | ||
| 1808 | 288 | g_autoptr(GBytes) iface_data = NULL; | |
| 1809 |
1/2✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
|
144 | g_autoptr(GBytes) legacy_iface_data = NULL; |
| 1810 |
1/2✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
|
144 | g_autoptr(GDBusNodeInfo) introspection_data = NULL; |
| 1811 |
1/2✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
|
144 | g_autoptr(GDBusNodeInfo) legacy_introspection_data = NULL; |
| 1812 | 144 | PpdBusOwnData *own_data; | |
| 1813 | |||
| 1814 | 144 | iface_data = g_resources_lookup_data (POWER_PROFILES_RESOURCES_PATH "/" | |
| 1815 | POWER_PROFILES_DBUS_NAME ".xml", | ||
| 1816 | G_RESOURCE_LOOKUP_FLAGS_NONE, | ||
| 1817 | error); | ||
| 1818 |
1/2✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
|
144 | if (!iface_data) |
| 1819 | return FALSE; | ||
| 1820 | |||
| 1821 | 144 | legacy_iface_data = g_resources_lookup_data (POWER_PROFILES_RESOURCES_PATH "/" | |
| 1822 | POWER_PROFILES_LEGACY_DBUS_NAME ".xml", | ||
| 1823 | G_RESOURCE_LOOKUP_FLAGS_NONE, | ||
| 1824 | error); | ||
| 1825 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
|
144 | if (!legacy_iface_data) |
| 1826 | return FALSE; | ||
| 1827 | |||
| 1828 | 144 | introspection_data = g_dbus_node_info_new_for_xml (g_bytes_get_data (iface_data, NULL), | |
| 1829 | error); | ||
| 1830 |
1/2✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
|
144 | if (!introspection_data) |
| 1831 | return FALSE; | ||
| 1832 | |||
| 1833 | 144 | legacy_introspection_data = g_dbus_node_info_new_for_xml (g_bytes_get_data (legacy_iface_data, NULL), | |
| 1834 | error); | ||
| 1835 |
1/2✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
|
144 | if (!legacy_introspection_data) |
| 1836 | return FALSE; | ||
| 1837 | |||
| 1838 | 144 | own_data = g_new0 (PpdBusOwnData, 1); | |
| 1839 | 144 | own_data->app = data; | |
| 1840 | 144 | own_data->interface = g_dbus_interface_info_ref (introspection_data->interfaces[0]); | |
| 1841 | 144 | own_data->legacy_interface = g_dbus_interface_info_ref (legacy_introspection_data->interfaces[0]); | |
| 1842 | |||
| 1843 | 144 | own_data->flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT; | |
| 1844 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
|
144 | if (data->debug_options->replace) |
| 1845 | ✗ | own_data->flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE; | |
| 1846 | |||
| 1847 | 144 | data->name_id = g_bus_own_name (G_BUS_TYPE_SYSTEM, | |
| 1848 | POWER_PROFILES_DBUS_NAME, | ||
| 1849 | own_data->flags, | ||
| 1850 | bus_acquired_handler, | ||
| 1851 | name_acquired_handler, | ||
| 1852 | name_lost_handler, | ||
| 1853 | own_data, | ||
| 1854 | (GDestroyNotify) ppd_bus_own_data_free); | ||
| 1855 | |||
| 1856 | 144 | return TRUE; | |
| 1857 | } | ||
| 1858 | |||
| 1859 | static void | ||
| 1860 | 144 | free_app_data (PpdApp *data) | |
| 1861 | { | ||
| 1862 |
1/2✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
|
144 | if (data == NULL) |
| 1863 | return; | ||
| 1864 | |||
| 1865 | 144 | stop_profile_drivers (data); | |
| 1866 | |||
| 1867 |
1/2✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
|
144 | g_clear_handle_id (&data->name_id, g_bus_unown_name); |
| 1868 |
2/2✓ Branch 0 taken 142 times.
✓ Branch 1 taken 2 times.
|
144 | g_clear_handle_id (&data->legacy_name_id, g_bus_unown_name); |
| 1869 | |||
| 1870 |
1/2✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
|
144 | g_clear_pointer (&data->debug_options, debug_options_free); |
| 1871 |
1/2✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
|
144 | g_clear_pointer (&data->config_path, g_free); |
| 1872 |
1/2✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
|
144 | g_clear_pointer (&data->config, g_key_file_unref); |
| 1873 |
1/2✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
|
144 | g_clear_pointer (&data->probed_drivers, g_ptr_array_unref); |
| 1874 |
1/2✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
|
144 | g_clear_pointer (&data->actions, g_ptr_array_unref); |
| 1875 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
|
144 | g_clear_object (&data->cpu_driver); |
| 1876 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
|
144 | g_clear_object (&data->platform_driver); |
| 1877 | 144 | g_hash_table_destroy (data->profile_holds); | |
| 1878 | |||
| 1879 |
2/2✓ Branch 0 taken 142 times.
✓ Branch 1 taken 2 times.
|
144 | g_clear_object (&data->auth); |
| 1880 | |||
| 1881 |
1/2✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
|
144 | g_clear_pointer (&data->main_loop, g_main_loop_unref); |
| 1882 |
2/2✓ Branch 0 taken 142 times.
✓ Branch 1 taken 2 times.
|
144 | g_clear_object (&data->connection); |
| 1883 | 144 | g_free (data); | |
| 1884 | 144 | ppd_app = NULL; | |
| 1885 | } | ||
| 1886 | |||
| 1887 | 144 | G_DEFINE_AUTOPTR_CLEANUP_FUNC (PpdApp, free_app_data) | |
| 1888 | |||
| 1889 | void | ||
| 1890 | ✗ | main_loop_quit (void) | |
| 1891 | { | ||
| 1892 | ✗ | g_main_loop_quit (ppd_app->main_loop); | |
| 1893 | ✗ | } | |
| 1894 | |||
| 1895 | static inline gboolean | ||
| 1896 | 6995 | use_colored_ouput (void) | |
| 1897 | { | ||
| 1898 |
1/2✓ Branch 1 taken 6995 times.
✗ Branch 2 not taken.
|
6995 | if (g_getenv ("NO_COLOR")) |
| 1899 | return FALSE; | ||
| 1900 | 6995 | return isatty (fileno (stdout)); | |
| 1901 | } | ||
| 1902 | |||
| 1903 | static void | ||
| 1904 | 6999 | debug_handler_cb (const gchar *log_domain, | |
| 1905 | GLogLevelFlags log_level, | ||
| 1906 | const gchar *message, | ||
| 1907 | gpointer user_data) | ||
| 1908 | { | ||
| 1909 | 6999 | DebugOptions *data = user_data; | |
| 1910 | 6995 | g_autoptr(GString) domain = NULL; | |
| 1911 | 6999 | gboolean use_color; | |
| 1912 | 6999 | gint color; | |
| 1913 | |||
| 1914 | /* not in verbose mode */ | ||
| 1915 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6995 times.
|
6999 | if (log_level > data->log_level) |
| 1916 | 4 | return; | |
| 1917 | |||
| 1918 | 6995 | domain = g_string_new (log_domain); | |
| 1919 | 6995 | use_color = use_colored_ouput (); | |
| 1920 | |||
| 1921 |
2/2✓ Branch 0 taken 63222 times.
✓ Branch 1 taken 6995 times.
|
70217 | for (gsize i = domain->len; i < 15; i++) |
| 1922 |
1/2✓ Branch 0 taken 63222 times.
✗ Branch 1 not taken.
|
126444 | g_string_append_c (domain, ' '); |
| 1923 | 6995 | g_print ("%s", domain->str); | |
| 1924 | |||
| 1925 |
2/2✓ Branch 0 taken 6983 times.
✓ Branch 1 taken 12 times.
|
6995 | switch (log_level) { |
| 1926 | case G_LOG_LEVEL_ERROR: | ||
| 1927 | case G_LOG_LEVEL_CRITICAL: | ||
| 1928 | case G_LOG_LEVEL_WARNING: | ||
| 1929 | color = 31; /* red */ | ||
| 1930 | break; | ||
| 1931 | 6983 | default: | |
| 1932 | 6983 | color = 34; /* blue */ | |
| 1933 | 6983 | break; | |
| 1934 | } | ||
| 1935 | |||
| 1936 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6995 times.
|
6995 | if (use_color) |
| 1937 | ✗ | g_print ("%c[%dm%s\n%c[%dm", 0x1B, color, message, 0x1B, 0); | |
| 1938 | else | ||
| 1939 | 6995 | g_print ("%s\n", message); | |
| 1940 | } | ||
| 1941 | |||
| 1942 | static gboolean | ||
| 1943 | 142 | quit_signal_callback (gpointer user_data) | |
| 1944 | { | ||
| 1945 | 142 | PpdApp *data = user_data; | |
| 1946 | |||
| 1947 | 142 | g_main_loop_quit (data->main_loop); | |
| 1948 | 142 | return FALSE; | |
| 1949 | } | ||
| 1950 | |||
| 1951 | static gboolean | ||
| 1952 | 284 | verbose_arg_cb (const gchar *option_name, | |
| 1953 | const gchar *value, | ||
| 1954 | gpointer user_data, | ||
| 1955 | GError **error) | ||
| 1956 | { | ||
| 1957 | 284 | DebugOptions *data = user_data; | |
| 1958 | |||
| 1959 |
2/2✓ Branch 0 taken 142 times.
✓ Branch 1 taken 142 times.
|
284 | if (data->log_level == G_LOG_LEVEL_MESSAGE) { |
| 1960 | 142 | data->log_level = G_LOG_LEVEL_INFO; | |
| 1961 | 142 | return TRUE; | |
| 1962 | } | ||
| 1963 |
1/2✓ Branch 0 taken 142 times.
✗ Branch 1 not taken.
|
142 | if (data->log_level == G_LOG_LEVEL_INFO) { |
| 1964 | 142 | data->log_level = G_LOG_LEVEL_DEBUG; | |
| 1965 | 142 | return TRUE; | |
| 1966 | } | ||
| 1967 | ✗ | g_set_error_literal (error, | |
| 1968 | G_OPTION_ERROR, | ||
| 1969 | G_OPTION_ERROR_FAILED, | ||
| 1970 | "No further debug level supported"); | ||
| 1971 | ✗ | return FALSE; | |
| 1972 | } | ||
| 1973 | |||
| 1974 | static gboolean | ||
| 1975 | 144 | debug_pre_parse_hook (GOptionContext *context, | |
| 1976 | GOptionGroup *group, | ||
| 1977 | gpointer user_data, | ||
| 1978 | GError **error) | ||
| 1979 | { | ||
| 1980 | 144 | DebugOptions *data = user_data; | |
| 1981 | |||
| 1982 | 144 | const GOptionEntry options[] = { | |
| 1983 | { | ||
| 1984 | "verbose", | ||
| 1985 | 'v', | ||
| 1986 | G_OPTION_FLAG_NO_ARG, | ||
| 1987 | G_OPTION_ARG_CALLBACK, | ||
| 1988 | (GOptionArgFunc)verbose_arg_cb, | ||
| 1989 | "Show extra debugging information", | ||
| 1990 | NULL, | ||
| 1991 | }, | ||
| 1992 | { | ||
| 1993 | "replace", | ||
| 1994 | 'r', | ||
| 1995 | G_OPTION_FLAG_NONE, | ||
| 1996 | G_OPTION_ARG_NONE, | ||
| 1997 | 144 | &data->replace, | |
| 1998 | "Replace the running instance of power-profiles-daemon", | ||
| 1999 | NULL, | ||
| 2000 | }, | ||
| 2001 | { | ||
| 2002 | "block-driver", | ||
| 2003 | 0, | ||
| 2004 | G_OPTION_FLAG_NONE, | ||
| 2005 | G_OPTION_ARG_STRING_ARRAY, | ||
| 2006 | 144 | &data->blocked_drivers, | |
| 2007 | "Block driver(s) from loading", | ||
| 2008 | NULL, | ||
| 2009 | }, | ||
| 2010 | { | ||
| 2011 | "block-action", | ||
| 2012 | 0, | ||
| 2013 | G_OPTION_FLAG_NONE, | ||
| 2014 | G_OPTION_ARG_STRING_ARRAY, | ||
| 2015 | 144 | &data->blocked_actions, | |
| 2016 | "Block action(s) from loading", | ||
| 2017 | NULL, | ||
| 2018 | }, | ||
| 2019 | { | ||
| 2020 | "disable-upower", | ||
| 2021 | 0, | ||
| 2022 | G_OPTION_FLAG_NONE, | ||
| 2023 | G_OPTION_ARG_NONE, | ||
| 2024 | 144 | &data->disable_upower, | |
| 2025 | "Disable upower integration", | ||
| 2026 | NULL, | ||
| 2027 | }, | ||
| 2028 | { | ||
| 2029 | "disable-logind", | ||
| 2030 | 0, | ||
| 2031 | G_OPTION_FLAG_NONE, | ||
| 2032 | G_OPTION_ARG_NONE, | ||
| 2033 | 144 | &data->disable_logind, | |
| 2034 | "Disable logind integration", | ||
| 2035 | NULL, | ||
| 2036 | }, | ||
| 2037 | { NULL } | ||
| 2038 | }; | ||
| 2039 | 144 | g_option_group_add_entries (group, options); | |
| 2040 | |||
| 2041 | 144 | return TRUE; | |
| 2042 | } | ||
| 2043 | |||
| 2044 | static gboolean | ||
| 2045 | 144 | debug_post_parse_hook (GOptionContext *context, | |
| 2046 | GOptionGroup *group, | ||
| 2047 | gpointer user_data, | ||
| 2048 | GError **error) | ||
| 2049 | { | ||
| 2050 | 144 | DebugOptions *debug = (DebugOptions *)user_data; | |
| 2051 | |||
| 2052 | 144 | g_log_set_default_handler (debug_handler_cb, debug); | |
| 2053 | |||
| 2054 | 144 | return TRUE; | |
| 2055 | } | ||
| 2056 | |||
| 2057 | 144 | int main (int argc, char **argv) | |
| 2058 | { | ||
| 2059 | 144 | g_autoptr(DebugOptions) debug_options = g_new0 (DebugOptions, 1); | |
| 2060 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
|
144 | g_autoptr(PpdApp) data = NULL; |
| 2061 |
1/2✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
|
144 | g_autoptr(GOptionContext) option_context = NULL; |
| 2062 |
1/2✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
|
144 | g_autoptr(GError) error = NULL; |
| 2063 | |||
| 2064 | 144 | debug_options->log_level = G_LOG_LEVEL_MESSAGE; | |
| 2065 | 144 | debug_options->group = g_option_group_new ("debug", | |
| 2066 | "Debugging Options", | ||
| 2067 | "Show debugging options", | ||
| 2068 | debug_options, | ||
| 2069 | NULL); | ||
| 2070 | 144 | g_option_group_set_parse_hooks (debug_options->group, | |
| 2071 | debug_pre_parse_hook, | ||
| 2072 | debug_post_parse_hook); | ||
| 2073 | |||
| 2074 | 144 | setlocale (LC_ALL, ""); | |
| 2075 | 144 | option_context = g_option_context_new (""); | |
| 2076 | 144 | g_option_context_add_group (option_context, debug_options->group); | |
| 2077 | |||
| 2078 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 144 times.
|
144 | if (!g_option_context_parse (option_context, &argc, &argv, &error)) { |
| 2079 | ✗ | g_print ("Failed to parse arguments: %s\n", error->message); | |
| 2080 | ✗ | return EXIT_FAILURE; | |
| 2081 | } | ||
| 2082 | |||
| 2083 | 144 | data = g_new0 (PpdApp, 1); | |
| 2084 | 144 | data->main_loop = g_main_loop_new (NULL, TRUE); | |
| 2085 | 144 | data->auth = polkit_authority_get_sync (NULL, NULL); | |
| 2086 | 144 | data->probed_drivers = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); | |
| 2087 | 144 | data->actions = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); | |
| 2088 | 144 | data->profile_holds = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) profile_hold_free); | |
| 2089 | 144 | data->active_profile = PPD_PROFILE_BALANCED; | |
| 2090 | 144 | data->selected_profile = PPD_PROFILE_BALANCED; | |
| 2091 | 144 | data->debug_options = g_steal_pointer(&debug_options); | |
| 2092 | |||
| 2093 | 144 | g_unix_signal_add (SIGTERM, quit_signal_callback, data); | |
| 2094 | 144 | g_unix_signal_add (SIGINT, quit_signal_callback, data); | |
| 2095 | |||
| 2096 | 144 | g_info ("Starting power-profiles-daemon version "VERSION); | |
| 2097 | |||
| 2098 | 144 | load_configuration (data); | |
| 2099 | 144 | ppd_app = data; | |
| 2100 | |||
| 2101 | /* Set up D-Bus */ | ||
| 2102 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 144 times.
|
144 | if (!setup_dbus (data, &error)) { |
| 2103 | ✗ | g_error ("Failed to start dbus: %s", error->message); | |
| 2104 | return EXIT_FAILURE; | ||
| 2105 | } | ||
| 2106 | |||
| 2107 | 144 | g_main_loop_run (data->main_loop); | |
| 2108 | |||
| 2109 | 144 | return data->ret; | |
| 2110 | } | ||
| 2111 |