GCC Code Coverage Report


Directory: ./
File: src/ppd-driver-fake.c
Date: 2025-03-30 20:28:01
Exec Total Coverage
Lines: 38 88 43.2%
Functions: 9 12 75.0%
Branches: 14 37 37.8%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2020 Bastien Nocera <hadess@hadess.net>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3 as published by
6 * the Free Software Foundation.
7 *
8 */
9
10 #include "ppd-driver-fake.h"
11
12 #include <unistd.h>
13 #include <stdio.h>
14 #include <termios.h>
15
16 #include "power-profiles-daemon.h"
17
18 extern void main_loop_quit (void);
19
20 struct _PpdDriverFake
21 {
22 PpdDriverPlatform parent_instance;
23
24 gboolean tio_set;
25 struct termios old_tio;
26 GIOChannel *channel;
27 guint watch_id;
28 gboolean degraded;
29 };
30
31
4/5
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 142 times.
✓ Branch 3 taken 142 times.
✗ Branch 4 not taken.
884 G_DEFINE_TYPE (PpdDriverFake, ppd_driver_fake, PPD_TYPE_DRIVER_PLATFORM)
32
33 static GObject*
34 158 ppd_driver_fake_constructor (GType type,
35 guint n_construct_params,
36 GObjectConstructParam *construct_params)
37 {
38 158 GObject *object;
39
40 158 object = G_OBJECT_CLASS (ppd_driver_fake_parent_class)->constructor (type,
41 n_construct_params,
42 construct_params);
43 158 g_object_set (object,
44 "driver-name", "fake",
45 "profiles", PPD_PROFILE_ALL,
46 NULL);
47
48 158 return object;
49 }
50
51 static void
52 toggle_degradation (PpdDriverFake *fake)
53 {
54 fake->degraded = !fake->degraded;
55
56 g_object_set (G_OBJECT (fake),
57 "performance-degraded", fake->degraded ? "lap-detected" : NULL,
58 NULL);
59 }
60
61 static void
62 keyboard_usage (void)
63 {
64 g_print ("Valid keys are: d (toggle degradation), r (restart drivers), q/x (quit)\n");
65 }
66
67 static gboolean
68 check_keyboard (GIOChannel *source,
69 GIOCondition condition,
70 PpdDriverFake *fake)
71 {
72 GIOStatus status;
73 char buf[1];
74
75 status = g_io_channel_read_chars (source, buf, 1, NULL, NULL);
76 if (status == G_IO_STATUS_ERROR ||
77 status == G_IO_STATUS_EOF) {
78 g_warning ("Error checking keyboard");
79 return FALSE;
80 }
81
82 if (status == G_IO_STATUS_AGAIN)
83 return TRUE;
84
85 switch (buf[0]) {
86 case 'd':
87 g_print ("Toggling degradation\n");
88 toggle_degradation (fake);
89 break;
90 case 'r':
91 g_print ("Restarting profile drivers\n");
92 restart_profile_drivers_for_default_app ();
93 break;
94 case 'q':
95 case 'x':
96 main_loop_quit ();
97 break;
98 default:
99 keyboard_usage ();
100 return TRUE;
101 }
102
103 return TRUE;
104 }
105
106 static gboolean
107 setup_keyboard (PpdDriverFake *fake)
108 {
109 struct termios new_tio;
110
111 tcgetattr (STDIN_FILENO, &fake->old_tio);
112 new_tio = fake->old_tio;
113 new_tio.c_lflag &=(~ICANON & ~ECHO);
114 tcsetattr (STDIN_FILENO, TCSANOW, &new_tio);
115
116 fake->channel = g_io_channel_unix_new (STDIN_FILENO);
117 if (!fake->channel) {
118 g_warning ("Failed to open stdin");
119 return FALSE;
120 }
121
122 if (g_io_channel_set_encoding (fake->channel, NULL, NULL) != G_IO_STATUS_NORMAL) {
123 g_warning ("Failed to set stdin encoding to NULL");
124 return FALSE;
125 }
126
127 fake->watch_id = g_io_add_watch (fake->channel, G_IO_IN, (GIOFunc) check_keyboard, fake);
128 fake->tio_set = TRUE;
129 return TRUE;
130 }
131
132 static gboolean
133 158 envvar_set (const char *key)
134 {
135 158 const char *value;
136
137 158 value = g_getenv (key);
138
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 156 times.
158 if (value == NULL ||
139
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 *value == '0' ||
140 *value == 'f')
141 156 return FALSE;
142
143 return TRUE;
144 }
145
146 static PpdProbeResult
147 158 ppd_driver_fake_probe (PpdDriver *driver)
148 {
149 158 PpdDriverFake *fake;
150
151
2/2
✓ Branch 1 taken 156 times.
✓ Branch 2 taken 2 times.
158 if (!envvar_set ("POWER_PROFILE_DAEMON_FAKE_DRIVER"))
152 return PPD_PROBE_RESULT_FAIL;
153
154 /* don't activate stdin unless interactive */
155
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 if (isatty (fileno (stdout)) == 0)
156 return PPD_PROBE_RESULT_SUCCESS;
157
158 fake = PPD_DRIVER_FAKE (driver);
159 if (!setup_keyboard (fake))
160 return PPD_PROBE_RESULT_FAIL;
161 keyboard_usage ();
162
163 return PPD_PROBE_RESULT_SUCCESS;
164 }
165
166 static gboolean
167 2 ppd_driver_fake_activate_profile (PpdDriver *driver,
168 PpdProfile profile,
169 PpdProfileActivationReason reason,
170 GError **error)
171 {
172 2 g_print ("Receive '%s' profile activation for reason '%s'\n",
173 ppd_profile_to_str (profile),
174 ppd_profile_activation_reason_to_str (reason));
175
176 2 return TRUE;
177 }
178
179 static void
180 158 ppd_driver_fake_finalize (GObject *object)
181 {
182 158 PpdDriverFake *fake;
183
184 158 fake = PPD_DRIVER_FAKE (object);
185
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 158 times.
158 g_clear_pointer (&fake->channel, g_io_channel_unref);
186
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 158 times.
158 g_clear_handle_id (&fake->watch_id, g_source_remove);
187
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 158 times.
158 if (fake->tio_set)
188 tcsetattr (STDIN_FILENO, TCSANOW, &fake->old_tio);
189 158 G_OBJECT_CLASS (ppd_driver_fake_parent_class)->finalize (object);
190 158 }
191
192 static void
193 142 ppd_driver_fake_class_init (PpdDriverFakeClass *klass)
194 {
195 142 GObjectClass *object_class;
196 142 PpdDriverClass *driver_class;
197
198 142 object_class = G_OBJECT_CLASS (klass);
199 142 object_class->constructor = ppd_driver_fake_constructor;
200 142 object_class->finalize = ppd_driver_fake_finalize;
201
202 142 driver_class = PPD_DRIVER_CLASS (klass);
203 142 driver_class->probe = ppd_driver_fake_probe;
204 142 driver_class->activate_profile = ppd_driver_fake_activate_profile;
205 }
206
207 static void
208 158 ppd_driver_fake_init (PpdDriverFake *self)
209 {
210 158 }
211