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 130 times.
✓ Branch 1 taken 26164 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 130 times.
✗ Branch 4 not taken.
|
68308 | G_DEFINE_TYPE_WITH_PRIVATE (PpdDriver, ppd_driver, G_TYPE_OBJECT) |
56 | |||
57 | static void | ||
58 | 2700 | ppd_driver_set_property (GObject *object, | |
59 | guint property_id, | ||
60 | const GValue *value, | ||
61 | GParamSpec *pspec) | ||
62 | { | ||
63 | 2700 | PpdDriver *driver = PPD_DRIVER (object); | |
64 | 2700 | PpdDriverPrivate *priv = PPD_DRIVER_GET_PRIVATE (driver); | |
65 | |||
66 |
1/2✓ Branch 1 taken 2700 times.
✗ Branch 2 not taken.
|
2700 | g_return_if_fail (PPD_IS_DRIVER (object)); |
67 | |||
68 |
3/4✓ Branch 0 taken 1340 times.
✓ Branch 1 taken 1340 times.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
|
2700 | switch (property_id) { |
69 | 1340 | case PROP_DRIVER_NAME: | |
70 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1340 times.
|
1340 | g_return_if_fail (priv->driver_name == NULL); |
71 | 1340 | priv->driver_name = g_value_dup_string (value); | |
72 | 1340 | break; | |
73 | 1340 | case PROP_PROFILES: | |
74 | 1340 | priv->profiles = g_value_get_flags (value); | |
75 | 1340 | 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 | 670 | ppd_driver_finalize (GObject *object) | |
117 | { | ||
118 | 670 | PpdDriverPrivate *priv; | |
119 | |||
120 | 670 | priv = PPD_DRIVER_GET_PRIVATE (PPD_DRIVER (object)); | |
121 |
1/2✓ Branch 0 taken 670 times.
✗ Branch 1 not taken.
|
670 | g_clear_pointer (&priv->driver_name, g_free); |
122 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 660 times.
|
670 | g_clear_pointer (&priv->performance_degraded, g_free); |
123 | |||
124 | 670 | G_OBJECT_CLASS (ppd_driver_parent_class)->finalize (object); | |
125 | 670 | } | |
126 | |||
127 | static void | ||
128 | 130 | ppd_driver_class_init (PpdDriverClass *klass) | |
129 | { | ||
130 | 130 | GObjectClass *object_class; | |
131 | |||
132 | 130 | object_class = G_OBJECT_CLASS (klass); | |
133 | 130 | object_class->finalize = ppd_driver_finalize; | |
134 | 130 | object_class->get_property = ppd_driver_get_property; | |
135 | 130 | 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 | 130 | 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 | 130 | 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 | 130 | 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 | 130 | 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 | 130 | 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 | 130 | } | |
209 | |||
210 | static void | ||
211 | 670 | ppd_driver_init (PpdDriver *self) | |
212 | { | ||
213 | 670 | } | |
214 | |||
215 | PpdProbeResult | ||
216 | 586 | ppd_driver_probe (PpdDriver *driver) | |
217 | { | ||
218 |
1/2✓ Branch 1 taken 586 times.
✗ Branch 2 not taken.
|
586 | g_return_val_if_fail (PPD_IS_DRIVER (driver), FALSE); |
219 | |||
220 |
2/2✓ Branch 0 taken 504 times.
✓ Branch 1 taken 82 times.
|
586 | if (!PPD_DRIVER_GET_CLASS (driver)->probe) |
221 | return PPD_PROBE_RESULT_SUCCESS; | ||
222 | |||
223 | 504 | return PPD_DRIVER_GET_CLASS (driver)->probe (driver); | |
224 | } | ||
225 | |||
226 | gboolean | ||
227 | 336 | ppd_driver_activate_profile (PpdDriver *driver, | |
228 | PpdProfile profile, | ||
229 | PpdProfileActivationReason reason, | ||
230 | GError **error) | ||
231 | { | ||
232 |
1/2✓ Branch 1 taken 336 times.
✗ Branch 2 not taken.
|
336 | g_return_val_if_fail (PPD_IS_DRIVER (driver), FALSE); |
233 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 336 times.
|
336 | g_return_val_if_fail (ppd_profile_has_single_flag (profile), FALSE); |
234 | |||
235 |
2/2✓ Branch 0 taken 230 times.
✓ Branch 1 taken 106 times.
|
336 | if (!PPD_DRIVER_GET_CLASS (driver)->activate_profile) |
236 | return TRUE; | ||
237 | |||
238 | 230 | return PPD_DRIVER_GET_CLASS (driver)->activate_profile (driver, profile, reason, error); | |
239 | } | ||
240 | |||
241 | gboolean | ||
242 | 76 | ppd_driver_power_changed (PpdDriver *driver, | |
243 | PpdPowerChangedReason reason, | ||
244 | GError **error) | ||
245 | { | ||
246 |
1/2✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
|
76 | g_return_val_if_fail (PPD_IS_DRIVER (driver), FALSE); |
247 | |||
248 |
2/2✓ Branch 0 taken 36 times.
✓ Branch 1 taken 40 times.
|
76 | 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 | 10 | gboolean ppd_driver_battery_changed (PpdDriver *driver, | |
255 | gdouble val, | ||
256 | GError **error) | ||
257 | { | ||
258 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
10 | g_return_val_if_fail (PPD_IS_DRIVER (driver), FALSE); |
259 | |||
260 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
|
10 | 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 | 5708 | ppd_driver_get_driver_name (PpdDriver *driver) | |
281 | { | ||
282 | 5708 | PpdDriverPrivate *priv; | |
283 | |||
284 |
1/2✓ Branch 1 taken 5708 times.
✗ Branch 2 not taken.
|
5708 | g_return_val_if_fail (PPD_IS_DRIVER (driver), NULL); |
285 | |||
286 | 5708 | priv = PPD_DRIVER_GET_PRIVATE (driver); | |
287 | 5708 | return priv->driver_name; | |
288 | } | ||
289 | |||
290 | PpdProfile | ||
291 | 6024 | ppd_driver_get_profiles (PpdDriver *driver) | |
292 | { | ||
293 | 6024 | PpdDriverPrivate *priv; | |
294 | |||
295 |
1/2✓ Branch 1 taken 6024 times.
✗ Branch 2 not taken.
|
6024 | g_return_val_if_fail (PPD_IS_DRIVER (driver), PPD_PROFILE_BALANCED); |
296 | |||
297 | 6024 | priv = PPD_DRIVER_GET_PRIVATE (driver); | |
298 | 6024 | 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 | 358 | ppd_driver_get_performance_degraded (PpdDriver *driver) | |
314 | { | ||
315 | 358 | PpdDriverPrivate *priv; | |
316 | |||
317 |
1/2✓ Branch 1 taken 358 times.
✗ Branch 2 not taken.
|
358 | g_return_val_if_fail (PPD_IS_DRIVER (driver), NULL); |
318 | |||
319 | 358 | priv = PPD_DRIVER_GET_PRIVATE (driver); | |
320 | 358 | 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 | 52 | ppd_driver_emit_profile_changed (PpdDriver *driver, | |
337 | PpdProfile profile) | ||
338 | { | ||
339 |
1/2✓ Branch 1 taken 52 times.
✗ Branch 2 not taken.
|
52 | g_return_if_fail (PPD_IS_DRIVER (driver)); |
340 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 52 times.
|
52 | g_return_if_fail (ppd_profile_has_single_flag (profile)); |
341 | |||
342 | 52 | g_signal_emit_by_name (G_OBJECT (driver), | |
343 | "profile-changed", | ||
344 | profile); | ||
345 | } | ||
346 | |||
347 | const char * | ||
348 | 280 | ppd_profile_activation_reason_to_str (PpdProfileActivationReason reason) | |
349 | { | ||
350 |
1/6✓ Branch 0 taken 280 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
280 | switch (reason) { |
351 | case PPD_PROFILE_ACTIVATION_REASON_INTERNAL: | ||
352 | return "internal"; | ||
353 | ✗ | case PPD_PROFILE_ACTIVATION_REASON_RESET: | |
354 | ✗ | return "reset"; | |
355 | ✗ | case PPD_PROFILE_ACTIVATION_REASON_USER: | |
356 | ✗ | return "user"; | |
357 | ✗ | case PPD_PROFILE_ACTIVATION_REASON_RESUME: | |
358 | ✗ | return "resume"; | |
359 | ✗ | case PPD_PROFILE_ACTIVATION_REASON_PROGRAM_HOLD: | |
360 | ✗ | return "program-hold"; | |
361 | ✗ | default: | |
362 | ✗ | g_return_val_if_reached (NULL); | |
363 | } | ||
364 | } | ||
365 |