GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 98.4% 122 / 0 / 124
Functions: 100.0% 13 / 0 / 13
Branches: 75.9% 41 / 0 / 54

libfprint/drivers/virtual-device-storage.c
Line Branch Exec Source
1 /*
2 * Virtual driver for "simple" device debugging with storage
3 *
4 * Copyright (C) 2020 Bastien Nocera <hadess@hadess.net>
5 * Copyright (C) 2020 Marco Trevisan <marco.trevisan@canonical.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /*
23 * This is a virtual driver to debug the non-image based drivers. A small
24 * python script is provided to connect to it via a socket, allowing
25 * prints to registered programmatically.
26 * Using this, it is possible to test libfprint and fprintd.
27 */
28
29 #define FP_COMPONENT "virtual_device_storage"
30
31 #include "virtual-device-private.h"
32 #include "fpi-log.h"
33
34
4/6
fpi_device_virtual_device_storage_class_intern_init:
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 125 times.
fpi_device_virtual_device_storage_get_type:
✓ Branch 2 → 3 taken 125 times.
✓ Branch 2 → 7 taken 24 times.
✓ Branch 4 → 5 taken 125 times.
✗ Branch 4 → 7 not taken.
399 G_DEFINE_TYPE (FpDeviceVirtualDeviceStorage, fpi_device_virtual_device_storage, fpi_device_virtual_device_get_type ())
35
36 static GPtrArray * get_stored_prints (FpDeviceVirtualDevice * self);
37
38 static void
39 25 dev_identify (FpDevice *dev)
40 {
41 25 g_autoptr(GError) error = NULL;
42 25 FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (dev);
43
2/4
✗ Branch 35 → 36 not taken.
✓ Branch 35 → 37 taken 14 times.
✗ Branch 39 → 40 not taken.
✓ Branch 39 → 41 taken 11 times.
25 g_autofree char *scan_id = NULL;
44
45
2/2
✓ Branch 3 → 4 taken 15 times.
✓ Branch 3 → 38 taken 10 times.
25 if (!start_scan_command (self, &scan_id, &error))
46 return;
47
48
2/2
✓ Branch 4 → 5 taken 9 times.
✓ Branch 4 → 26 taken 6 times.
15 if (scan_id)
49 {
50 18 g_autoptr(GPtrArray) stored = get_stored_prints (self);
51 9 GPtrArray *prints;
52 9 GVariant *data = NULL;
53 9 FpPrint *new_scan;
54 9 FpPrint *match = NULL;
55 9 guint idx;
56
57 9 new_scan = fp_print_new (dev);
58 9 fpi_print_set_type (new_scan, FPI_PRINT_RAW);
59 9 fpi_print_set_device_stored (new_scan, TRUE);
60 9 data = g_variant_new_string (scan_id);
61 9 g_object_set (new_scan, "fpi-data", data, NULL);
62
63 9 fpi_device_get_identify_data (dev, &prints);
64 9 g_debug ("Trying to identify print '%s' against a gallery of %u prints", scan_id, prints->len);
65
66
2/2
✓ Branch 14 → 15 taken 4 times.
✓ Branch 14 → 17 taken 5 times.
9 if (!g_ptr_array_find_with_equal_func (stored,
67 new_scan,
68 (GEqualFunc) fp_print_equal,
69 NULL))
70 {
71 4 match = FALSE;
72
1/2
✓ Branch 15 → 16 taken 4 times.
✗ Branch 15 → 21 not taken.
4 g_clear_object (&new_scan);
73 }
74
2/2
✓ Branch 18 → 19 taken 3 times.
✓ Branch 18 → 21 taken 2 times.
5 else if (g_ptr_array_find_with_equal_func (prints,
75 new_scan,
76 (GEqualFunc) fp_print_equal,
77 &idx))
78 {
79 3 match = g_ptr_array_index (prints, idx);
80 3 fp_print_set_finger (new_scan, fp_print_get_finger (match));
81 }
82
83
2/2
✓ Branch 21 → 22 taken 8 times.
✓ Branch 21 → 23 taken 1 time.
9 if (!self->match_reported)
84 {
85 8 self->match_reported = TRUE;
86 8 fpi_device_identify_report (dev,
87 match,
88 new_scan,
89 NULL);
90 }
91 }
92
3/4
✓ Branch 26 → 27 taken 6 times.
✗ Branch 26 → 30 not taken.
✓ Branch 28 → 29 taken 1 time.
✓ Branch 28 → 30 taken 5 times.
6 else if (error && error->domain == FP_DEVICE_RETRY)
93 {
94 1 fpi_device_identify_report (dev, NULL, NULL, g_steal_pointer (&error));
95 }
96
97 15 fpi_device_report_finger_status_changes (FP_DEVICE (self),
98 FP_FINGER_STATUS_NONE,
99 FP_FINGER_STATUS_PRESENT);
100
101
2/2
✓ Branch 32 → 33 taken 14 times.
✓ Branch 32 → 38 taken 1 time.
15 if (should_wait_to_sleep (self, scan_id, error))
102 return;
103
104 14 self->match_reported = FALSE;
105 14 fpi_device_identify_complete (dev, g_steal_pointer (&error));
106 }
107
108 struct ListData
109 {
110 FpDevice *dev;
111 GPtrArray *res;
112 };
113
114 static void
115 17 dev_list_insert_print (gpointer key,
116 gpointer value,
117 gpointer user_data)
118 {
119 17 struct ListData *data = user_data;
120 17 FpPrint *print = fp_print_new (data->dev);
121 17 GVariant *var = NULL;
122
123 17 fpi_print_fill_from_user_id (print, key);
124 17 fpi_print_set_type (print, FPI_PRINT_RAW);
125 17 var = g_variant_new_string (key);
126 17 g_object_set (print, "fpi-data", var, NULL);
127 17 g_object_ref_sink (print);
128
129 17 g_ptr_array_add (data->res, print);
130 17 }
131
132 static GPtrArray *
133 16 get_stored_prints (FpDeviceVirtualDevice *self)
134 {
135 16 GPtrArray * prints_list;
136 16 struct ListData data;
137
138 16 prints_list = g_ptr_array_new_full (g_hash_table_size (self->prints_storage),
139 g_object_unref);
140 16 data.dev = FP_DEVICE (self);
141 16 data.res = prints_list;
142
143 16 g_hash_table_foreach (self->prints_storage, dev_list_insert_print, &data);
144
145 16 return prints_list;
146 }
147
148 static void
149 16 dev_list (FpDevice *dev)
150 {
151 16 g_autoptr(GPtrArray) prints_list = NULL;
152 16 g_autoptr(GError) error = NULL;
153 16 FpDeviceVirtualDevice *vdev = FP_DEVICE_VIRTUAL_DEVICE (dev);
154
155
2/2
✓ Branch 3 → 4 taken 8 times.
✓ Branch 3 → 12 taken 8 times.
16 if (!process_cmds (vdev, FALSE, NULL, &error))
156 return;
157
158
2/2
✓ Branch 4 → 5 taken 1 time.
✓ Branch 4 → 6 taken 7 times.
8 if (error)
159 {
160 1 fpi_device_list_complete (dev, NULL, g_steal_pointer (&error));
161 1 return;
162 }
163
164
1/2
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 7 times.
7 fpi_device_list_complete (dev, get_stored_prints (vdev), NULL);
165 }
166
167 static void
168 40 dev_clear_storage (FpDevice *dev)
169 {
170 40 g_autoptr(GPtrArray) prints_list = NULL;
171 40 g_autoptr(GError) error = NULL;
172 40 FpDeviceVirtualDevice *vdev = FP_DEVICE_VIRTUAL_DEVICE (dev);
173
174
1/2
✓ Branch 3 → 4 taken 40 times.
✗ Branch 3 → 12 not taken.
40 if (!process_cmds (vdev, FALSE, NULL, &error))
175 return;
176
177
2/2
✓ Branch 4 → 5 taken 1 time.
✓ Branch 4 → 6 taken 39 times.
40 if (error)
178 {
179 1 fpi_device_clear_storage_complete (dev, g_steal_pointer (&error));
180 1 return;
181 }
182
183 39 g_hash_table_remove_all (vdev->prints_storage);
184
185
1/2
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 39 times.
39 fpi_device_clear_storage_complete (dev, NULL);
186 }
187
188 static void
189 10 dev_delete (FpDevice *dev)
190 {
191 10 g_autoptr(GVariant) data = NULL;
192
2/4
✓ Branch 22 → 23 taken 4 times.
✗ Branch 22 → 24 not taken.
✗ Branch 28 → 29 not taken.
✓ Branch 28 → 30 taken 6 times.
10 g_autoptr(GError) error = NULL;
193 10 FpDeviceVirtualDevice *vdev = FP_DEVICE_VIRTUAL_DEVICE (dev);
194 10 FpPrint *print = NULL;
195 10 const char *id = NULL;
196
197
2/2
✓ Branch 3 → 4 taken 5 times.
✓ Branch 3 → 26 taken 5 times.
10 if (!process_cmds (vdev, FALSE, NULL, &error))
198 return;
199
200
2/2
✓ Branch 4 → 5 taken 1 time.
✓ Branch 4 → 6 taken 4 times.
5 if (error)
201 {
202 1 fpi_device_delete_complete (dev, g_steal_pointer (&error));
203 1 return;
204 }
205
206 4 fpi_device_get_delete_data (dev, &print);
207
208 4 g_object_get (print, "fpi-data", &data, NULL);
209
1/2
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 12 taken 4 times.
4 if (data == NULL)
210 {
211 fpi_device_delete_complete (dev,
212 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
213 return;
214 }
215
216 4 id = g_variant_get_string (data, NULL);
217
218 4 fp_dbg ("Deleting print %s for user %s",
219 id,
220 fp_print_get_username (print));
221
222
2/2
✓ Branch 16 → 17 taken 2 times.
✓ Branch 16 → 18 taken 2 times.
4 if (g_hash_table_remove (vdev->prints_storage, id))
223 2 fpi_device_delete_complete (dev, NULL);
224 else
225 2 fpi_device_delete_complete (dev,
226 fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND));
227 }
228
229 static void
230 42 dev_probe (FpDevice *dev)
231 {
232 /* Disable features listed in driver_data */
233 42 fpi_device_update_features (dev, fpi_device_get_driver_data (dev), 0);
234
235 42 fpi_device_probe_complete (dev, NULL, NULL, NULL);
236 42 }
237
238 static void
239 42 fpi_device_virtual_device_storage_init (FpDeviceVirtualDeviceStorage *self)
240 {
241 42 FpDeviceVirtualDevice *vdev = FP_DEVICE_VIRTUAL_DEVICE (self);
242
243 42 vdev->prints_storage = g_hash_table_new_full (g_str_hash,
244 g_str_equal,
245 g_free,
246 NULL);
247 42 }
248
249 static void
250 38 fpi_device_virtual_device_storage_finalize (GObject *object)
251 {
252 38 FpDeviceVirtualDevice *vdev = FP_DEVICE_VIRTUAL_DEVICE (object);
253
254 38 G_DEBUG_HERE ();
255
1/2
✓ Branch 4 → 5 taken 38 times.
✗ Branch 4 → 6 not taken.
38 g_clear_pointer (&vdev->prints_storage, g_hash_table_destroy);
256 38 G_OBJECT_CLASS (fpi_device_virtual_device_storage_parent_class)->finalize (object);
257 38 }
258
259 static const FpIdEntry driver_ids[] = {
260 { .virtual_envvar = "FP_VIRTUAL_DEVICE_STORAGE", .driver_data = 0 },
261 { .virtual_envvar = "FP_VIRTUAL_DEVICE_STORAGE_NO_LIST", .driver_data = FP_DEVICE_FEATURE_STORAGE_LIST },
262 { .virtual_envvar = NULL }
263 };
264
265 static void
266 125 fpi_device_virtual_device_storage_class_init (FpDeviceVirtualDeviceStorageClass *klass)
267 {
268 125 FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
269 125 GObjectClass *object_class = G_OBJECT_CLASS (klass);
270
271 125 object_class->finalize = fpi_device_virtual_device_storage_finalize;
272
273 125 dev_class->id = FP_COMPONENT;
274 125 dev_class->full_name = "Virtual device with storage and identification for debugging";
275 125 dev_class->id_table = driver_ids;
276
277 125 dev_class->probe = dev_probe;
278 125 dev_class->identify = dev_identify;
279 125 dev_class->list = dev_list;
280 125 dev_class->delete = dev_delete;
281 125 dev_class->clear_storage = dev_clear_storage;
282
283 125 fpi_device_class_auto_initialize_features (dev_class);
284 125 dev_class->features |= FP_DEVICE_FEATURE_DUPLICATES_CHECK;
285 125 }
286