| 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 |