GCC Code Coverage Report


Directory: ./
File: src/power-profiles-daemon.c
Date: 2025-03-30 20:28:01
Exec Total Coverage
Lines: 850 944 90.0%
Functions: 64 66 97.0%
Branches: 387 528 73.3%

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 1578 get_active_profile (PpdApp *data)
205 {
206 1578 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 (&degraded)));
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 2677 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 2677 PpdApp *data = user_data;
945
946
1/2
✓ Branch 0 taken 2677 times.
✗ Branch 1 not taken.
2677 g_return_val_if_fail (data->connection, NULL);
947
948
2/2
✓ Branch 1 taken 968 times.
✓ Branch 2 taken 1709 times.
2677 if (g_strcmp0 (property_name, "ActiveProfile") == 0)
949 968 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 (&degraded));
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 7007 use_colored_ouput (void)
1897 {
1898
1/2
✓ Branch 1 taken 7007 times.
✗ Branch 2 not taken.
7007 if (g_getenv ("NO_COLOR"))
1899 return FALSE;
1900 7007 return isatty (fileno (stdout));
1901 }
1902
1903 static void
1904 7011 debug_handler_cb (const gchar *log_domain,
1905 GLogLevelFlags log_level,
1906 const gchar *message,
1907 gpointer user_data)
1908 {
1909 7011 DebugOptions *data = user_data;
1910 7007 g_autoptr(GString) domain = NULL;
1911 7011 gboolean use_color;
1912 7011 gint color;
1913
1914 /* not in verbose mode */
1915
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 7007 times.
7011 if (log_level > data->log_level)
1916 4 return;
1917
1918 7007 domain = g_string_new (log_domain);
1919 7007 use_color = use_colored_ouput ();
1920
1921
2/2
✓ Branch 0 taken 63239 times.
✓ Branch 1 taken 7007 times.
70246 for (gsize i = domain->len; i < 15; i++)
1922
1/2
✓ Branch 0 taken 63239 times.
✗ Branch 1 not taken.
126478 g_string_append_c (domain, ' ');
1923 7007 g_print ("%s", domain->str);
1924
1925
2/2
✓ Branch 0 taken 6995 times.
✓ Branch 1 taken 12 times.
7007 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 6995 default:
1932 6995 color = 34; /* blue */
1933 6995 break;
1934 }
1935
1936
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7007 times.
7007 if (use_color)
1937 g_print ("%c[%dm%s\n%c[%dm", 0x1B, color, message, 0x1B, 0);
1938 else
1939 7007 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