GCC Code Coverage Report


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