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.h" | ||
11 | #include "ppd-enums.h" | ||
12 | |||
13 | /** | ||
14 | * SECTION:ppd-driver | ||
15 | * @Short_description: Profile Drivers | ||
16 | * @Title: Profile Drivers | ||
17 | * | ||
18 | * Profile drivers are the implementation of the different profiles for | ||
19 | * the whole system. A driver will need to implement support `power-saver` | ||
20 | * and `balanced` at a minimum. | ||
21 | * | ||
22 | * All drivers should be derived from either #PpdDriverCpu or #PpdDriverPlatform | ||
23 | * | ||
24 | * When a driver implements the `performance` profile, it might set the | ||
25 | * #PpdDriver:performance-degraded property if the profile isn't running to | ||
26 | * its fullest performance for any reason, such as thermal limits being | ||
27 | * reached, or because a part of the user's body is too close for safety, | ||
28 | * for example. | ||
29 | */ | ||
30 | |||
31 | typedef struct | ||
32 | { | ||
33 | char *driver_name; | ||
34 | PpdProfile profiles; | ||
35 | gboolean selected; | ||
36 | char *performance_degraded; | ||
37 | } PpdDriverPrivate; | ||
38 | |||
39 | enum { | ||
40 | PROP_0, | ||
41 | PROP_DRIVER_NAME, | ||
42 | PROP_PROFILES, | ||
43 | PROP_PERFORMANCE_DEGRADED | ||
44 | }; | ||
45 | |||
46 | enum { | ||
47 | PROFILE_CHANGED, | ||
48 | PROBE_REQUEST, | ||
49 | LAST_SIGNAL | ||
50 | }; | ||
51 | |||
52 | static guint signals[LAST_SIGNAL] = { 0 }; | ||
53 | |||
54 | #define PPD_DRIVER_GET_PRIVATE(o) (ppd_driver_get_instance_private (o)) | ||
55 |
3/5✓ Branch 0 taken 142 times.
✓ Branch 1 taken 31577 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 142 times.
✗ Branch 4 not taken.
|
82254 | G_DEFINE_TYPE_WITH_PRIVATE (PpdDriver, ppd_driver, G_TYPE_OBJECT) |
56 | |||
57 | static void | ||
58 | 3180 | ppd_driver_set_property (GObject *object, | |
59 | guint property_id, | ||
60 | const GValue *value, | ||
61 | GParamSpec *pspec) | ||
62 | { | ||
63 | 3180 | PpdDriver *driver = PPD_DRIVER (object); | |
64 | 3180 | PpdDriverPrivate *priv = PPD_DRIVER_GET_PRIVATE (driver); | |
65 | |||
66 |
1/2✓ Branch 1 taken 3180 times.
✗ Branch 2 not taken.
|
3180 | g_return_if_fail (PPD_IS_DRIVER (object)); |
67 | |||
68 |
3/4✓ Branch 0 taken 1580 times.
✓ Branch 1 taken 1580 times.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
|
3180 | switch (property_id) { |
69 | 1580 | case PROP_DRIVER_NAME: | |
70 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1580 times.
|
1580 | g_return_if_fail (priv->driver_name == NULL); |
71 | 1580 | priv->driver_name = g_value_dup_string (value); | |
72 | 1580 | break; | |
73 | 1580 | case PROP_PROFILES: | |
74 | 1580 | priv->profiles = g_value_get_flags (value); | |
75 | 1580 | break; | |
76 | 20 | case PROP_PERFORMANCE_DEGRADED: | |
77 | { | ||
78 | 20 | const char *degraded = g_value_get_string (value); | |
79 | |||
80 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 18 times.
|
20 | g_clear_pointer (&priv->performance_degraded, g_free); |
81 | |||
82 |
3/4✓ Branch 0 taken 12 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
20 | if (degraded != NULL && *degraded != '\0') |
83 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
24 | priv->performance_degraded = g_strdup (degraded); |
84 | } | ||
85 | break; | ||
86 | ✗ | default: | |
87 | ✗ | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); | |
88 | } | ||
89 | } | ||
90 | |||
91 | static void | ||
92 | ✗ | ppd_driver_get_property (GObject *object, | |
93 | guint property_id, | ||
94 | GValue *value, | ||
95 | GParamSpec *pspec) | ||
96 | { | ||
97 | ✗ | PpdDriver *driver = PPD_DRIVER (object); | |
98 | ✗ | PpdDriverPrivate *priv = PPD_DRIVER_GET_PRIVATE (driver); | |
99 | |||
100 | ✗ | switch (property_id) { | |
101 | ✗ | case PROP_DRIVER_NAME: | |
102 | ✗ | g_value_set_string (value, priv->driver_name); | |
103 | ✗ | break; | |
104 | ✗ | case PROP_PROFILES: | |
105 | ✗ | g_value_set_flags (value, priv->profiles); | |
106 | ✗ | break; | |
107 | ✗ | case PROP_PERFORMANCE_DEGRADED: | |
108 | ✗ | g_value_set_string (value, priv->performance_degraded); | |
109 | ✗ | break; | |
110 | ✗ | default: | |
111 | ✗ | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); | |
112 | } | ||
113 | ✗ | } | |
114 | |||
115 | static void | ||
116 | 790 | ppd_driver_finalize (GObject *object) | |
117 | { | ||
118 | 790 | PpdDriverPrivate *priv; | |
119 | |||
120 | 790 | priv = PPD_DRIVER_GET_PRIVATE (PPD_DRIVER (object)); | |
121 |
1/2✓ Branch 0 taken 790 times.
✗ Branch 1 not taken.
|
790 | g_clear_pointer (&priv->driver_name, g_free); |
122 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 780 times.
|
790 | g_clear_pointer (&priv->performance_degraded, g_free); |
123 | |||
124 | 790 | G_OBJECT_CLASS (ppd_driver_parent_class)->finalize (object); | |
125 | 790 | } | |
126 | |||
127 | static void | ||
128 | 142 | ppd_driver_class_init (PpdDriverClass *klass) | |
129 | { | ||
130 | 142 | GObjectClass *object_class; | |
131 | |||
132 | 142 | object_class = G_OBJECT_CLASS (klass); | |
133 | 142 | object_class->finalize = ppd_driver_finalize; | |
134 | 142 | object_class->get_property = ppd_driver_get_property; | |
135 | 142 | object_class->set_property = ppd_driver_set_property; | |
136 | |||
137 | /** | ||
138 | * PpdDriver::profile-changed: | ||
139 | * @profile: the updated #PpdProfile | ||
140 | * | ||
141 | * Emitted when the profile was changed from the outside, usually | ||
142 | * by key combinations implemented in firmware. | ||
143 | */ | ||
144 | 142 | signals[PROFILE_CHANGED] = g_signal_new ("profile-changed", | |
145 | G_TYPE_FROM_CLASS (klass), | ||
146 | G_SIGNAL_RUN_LAST, | ||
147 | 0, | ||
148 | NULL, | ||
149 | NULL, | ||
150 | g_cclosure_marshal_generic, | ||
151 | G_TYPE_NONE, | ||
152 | 1, | ||
153 | PPD_TYPE_PROFILE); | ||
154 | |||
155 | |||
156 | /** | ||
157 | * PpdDriver::probe-request | ||
158 | * | ||
159 | * The driver requested to be reprobed, because it became available. | ||
160 | */ | ||
161 | 142 | signals[PROBE_REQUEST] = g_signal_new ("probe-request", | |
162 | G_TYPE_FROM_CLASS (klass), | ||
163 | G_SIGNAL_RUN_LAST, | ||
164 | 0, | ||
165 | NULL, | ||
166 | NULL, | ||
167 | g_cclosure_marshal_generic, | ||
168 | G_TYPE_NONE, | ||
169 | 0, | ||
170 | G_TYPE_NONE); | ||
171 | |||
172 | /** | ||
173 | * PpdDriver::driver-name: | ||
174 | * | ||
175 | * A unique driver name, only used for debugging. | ||
176 | */ | ||
177 | 142 | g_object_class_install_property (object_class, PROP_DRIVER_NAME, | |
178 | g_param_spec_string ("driver-name", | ||
179 | "Driver name", | ||
180 | "Profile driver name", | ||
181 | NULL, | ||
182 | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); | ||
183 | |||
184 | /** | ||
185 | * PpdDriver::profiles: | ||
186 | * | ||
187 | * The bitmask of #PpdProfile<!-- -->s implemented by this driver. | ||
188 | */ | ||
189 | 142 | g_object_class_install_property (object_class, PROP_PROFILES, | |
190 | g_param_spec_flags ("profiles", | ||
191 | "Profiles", | ||
192 | "Profiles implemented by this driver", | ||
193 | PPD_TYPE_PROFILE, | ||
194 | 0, | ||
195 | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); | ||
196 | /** | ||
197 | * PpdPlatformDriver:performance-degraded: | ||
198 | * | ||
199 | * If set to a non-%NULL value, the reason why the performance profile is unavailable. | ||
200 | * The value must be one of the options listed in the D-Bus API reference. | ||
201 | */ | ||
202 | 142 | g_object_class_install_property (object_class, PROP_PERFORMANCE_DEGRADED, | |
203 | g_param_spec_string ("performance-degraded", | ||
204 | "Performance Degraded", | ||
205 | "Why the performance profile is degraded, if set", | ||
206 | NULL, | ||
207 | G_PARAM_READWRITE)); | ||
208 | 142 | } | |
209 | |||
210 | static void | ||
211 | 790 | ppd_driver_init (PpdDriver *self) | |
212 | { | ||
213 | 790 | } | |
214 | |||
215 | PpdProbeResult | ||
216 | 705 | ppd_driver_probe (PpdDriver *driver) | |
217 | { | ||
218 |
1/2✓ Branch 1 taken 705 times.
✗ Branch 2 not taken.
|
705 | g_return_val_if_fail (PPD_IS_DRIVER (driver), FALSE); |
219 | |||
220 |
2/2✓ Branch 0 taken 600 times.
✓ Branch 1 taken 105 times.
|
705 | if (!PPD_DRIVER_GET_CLASS (driver)->probe) |
221 | return PPD_PROBE_RESULT_SUCCESS; | ||
222 | |||
223 | 600 | return PPD_DRIVER_GET_CLASS (driver)->probe (driver); | |
224 | } | ||
225 | |||
226 | gboolean | ||
227 | 373 | ppd_driver_activate_profile (PpdDriver *driver, | |
228 | PpdProfile profile, | ||
229 | PpdProfileActivationReason reason, | ||
230 | GError **error) | ||
231 | { | ||
232 |
1/2✓ Branch 1 taken 373 times.
✗ Branch 2 not taken.
|
373 | g_return_val_if_fail (PPD_IS_DRIVER (driver), FALSE); |
233 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 373 times.
|
373 | g_return_val_if_fail (ppd_profile_has_single_flag (profile), FALSE); |
234 | |||
235 |
2/2✓ Branch 0 taken 237 times.
✓ Branch 1 taken 136 times.
|
373 | if (!PPD_DRIVER_GET_CLASS (driver)->activate_profile) |
236 | return TRUE; | ||
237 | |||
238 | 237 | return PPD_DRIVER_GET_CLASS (driver)->activate_profile (driver, profile, reason, error); | |
239 | } | ||
240 | |||
241 | gboolean | ||
242 | 84 | ppd_driver_power_changed (PpdDriver *driver, | |
243 | PpdPowerChangedReason reason, | ||
244 | GError **error) | ||
245 | { | ||
246 |
1/2✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
|
84 | g_return_val_if_fail (PPD_IS_DRIVER (driver), FALSE); |
247 | |||
248 |
2/2✓ Branch 0 taken 36 times.
✓ Branch 1 taken 48 times.
|
84 | if (!PPD_DRIVER_GET_CLASS (driver)->power_changed) |
249 | return TRUE; | ||
250 | |||
251 | 36 | return PPD_DRIVER_GET_CLASS (driver)->power_changed (driver, reason, error); | |
252 | } | ||
253 | |||
254 | 26 | gboolean ppd_driver_battery_changed (PpdDriver *driver, | |
255 | gdouble val, | ||
256 | GError **error) | ||
257 | { | ||
258 |
1/2✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
|
26 | g_return_val_if_fail (PPD_IS_DRIVER (driver), FALSE); |
259 | |||
260 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
|
26 | if (!PPD_DRIVER_GET_CLASS (driver)->battery_changed) |
261 | return TRUE; | ||
262 | |||
263 | ✗ | return PPD_DRIVER_GET_CLASS (driver)->battery_changed (driver, val, error); | |
264 | } | ||
265 | |||
266 | gboolean | ||
267 | 8 | ppd_driver_prepare_to_sleep (PpdDriver *driver, | |
268 | gboolean start, | ||
269 | GError **error) | ||
270 | { | ||
271 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | g_return_val_if_fail (PPD_IS_DRIVER (driver), FALSE); |
272 | |||
273 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
|
8 | if (!PPD_DRIVER_GET_CLASS (driver)->prepare_to_sleep) |
274 | return TRUE; | ||
275 | |||
276 | 4 | return PPD_DRIVER_GET_CLASS (driver)->prepare_to_sleep (driver, start, error); | |
277 | } | ||
278 | |||
279 | const char * | ||
280 | 6910 | ppd_driver_get_driver_name (PpdDriver *driver) | |
281 | { | ||
282 | 6910 | PpdDriverPrivate *priv; | |
283 | |||
284 |
1/2✓ Branch 1 taken 6910 times.
✗ Branch 2 not taken.
|
6910 | g_return_val_if_fail (PPD_IS_DRIVER (driver), NULL); |
285 | |||
286 | 6910 | priv = PPD_DRIVER_GET_PRIVATE (driver); | |
287 | 6910 | return priv->driver_name; | |
288 | } | ||
289 | |||
290 | PpdProfile | ||
291 | 7280 | ppd_driver_get_profiles (PpdDriver *driver) | |
292 | { | ||
293 | 7280 | PpdDriverPrivate *priv; | |
294 | |||
295 |
1/2✓ Branch 1 taken 7280 times.
✗ Branch 2 not taken.
|
7280 | g_return_val_if_fail (PPD_IS_DRIVER (driver), PPD_PROFILE_BALANCED); |
296 | |||
297 | 7280 | priv = PPD_DRIVER_GET_PRIVATE (driver); | |
298 | 7280 | return priv->profiles; | |
299 | } | ||
300 | |||
301 | gboolean | ||
302 | ✗ | ppd_driver_get_selected (PpdDriver *driver) | |
303 | { | ||
304 | ✗ | PpdDriverPrivate *priv; | |
305 | |||
306 | ✗ | g_return_val_if_fail (PPD_IS_DRIVER (driver), FALSE); | |
307 | |||
308 | ✗ | priv = PPD_DRIVER_GET_PRIVATE (driver); | |
309 | ✗ | return priv->selected; | |
310 | } | ||
311 | |||
312 | const char * | ||
313 | 372 | ppd_driver_get_performance_degraded (PpdDriver *driver) | |
314 | { | ||
315 | 372 | PpdDriverPrivate *priv; | |
316 | |||
317 |
1/2✓ Branch 1 taken 372 times.
✗ Branch 2 not taken.
|
372 | g_return_val_if_fail (PPD_IS_DRIVER (driver), NULL); |
318 | |||
319 | 372 | priv = PPD_DRIVER_GET_PRIVATE (driver); | |
320 | 372 | return priv->performance_degraded; | |
321 | } | ||
322 | |||
323 | gboolean | ||
324 | ✗ | ppd_driver_is_performance_degraded (PpdDriver *driver) | |
325 | { | ||
326 | ✗ | PpdDriverPrivate *priv; | |
327 | |||
328 | ✗ | g_return_val_if_fail (PPD_IS_DRIVER (driver), FALSE); | |
329 | |||
330 | ✗ | priv = PPD_DRIVER_GET_PRIVATE (driver); | |
331 | |||
332 | ✗ | return (priv->performance_degraded != NULL); | |
333 | } | ||
334 | |||
335 | void | ||
336 | 51 | ppd_driver_emit_profile_changed (PpdDriver *driver, | |
337 | PpdProfile profile) | ||
338 | { | ||
339 |
1/2✓ Branch 1 taken 51 times.
✗ Branch 2 not taken.
|
51 | g_return_if_fail (PPD_IS_DRIVER (driver)); |
340 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 51 times.
|
51 | g_return_if_fail (ppd_profile_has_single_flag (profile)); |
341 | |||
342 | 51 | g_signal_emit_by_name (G_OBJECT (driver), | |
343 | "profile-changed", | ||
344 | profile); | ||
345 | } | ||
346 | |||
347 | const char * | ||
348 | 313 | ppd_profile_activation_reason_to_str (PpdProfileActivationReason reason) | |
349 | { | ||
350 |
4/6✓ Branch 0 taken 160 times.
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 66 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
313 | switch (reason) { |
351 | case PPD_PROFILE_ACTIVATION_REASON_INTERNAL: | ||
352 | return "internal"; | ||
353 | 160 | case PPD_PROFILE_ACTIVATION_REASON_RESET: | |
354 | 160 | return "reset"; | |
355 | 85 | case PPD_PROFILE_ACTIVATION_REASON_USER: | |
356 | 85 | return "user"; | |
357 | ✗ | case PPD_PROFILE_ACTIVATION_REASON_RESUME: | |
358 | ✗ | return "resume"; | |
359 | 66 | case PPD_PROFILE_ACTIVATION_REASON_PROGRAM_HOLD: | |
360 | 66 | return "program-hold"; | |
361 | ✗ | default: | |
362 | ✗ | g_return_val_if_reached (NULL); | |
363 | } | ||
364 | } | ||
365 |