GCC Code Coverage Report


Directory: ./
File: libfprint/drivers/virtual-device-storage.c
Date: 2024-05-04 14:54:39
Exec Total Coverage
Lines: 119 121 98.3%
Functions: 13 13 100.0%
Branches: 41 53 77.4%

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/5
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 117 times.
✓ Branch 3 taken 117 times.
✗ Branch 4 not taken.
750 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 0 not taken.
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
25 g_autofree char *scan_id = NULL;
44
45
2/2
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 10 times.
25 if (!start_scan_command (self, &scan_id, &error))
46 return;
47
48
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 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 1 taken 4 times.
✓ Branch 2 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 0 taken 4 times.
✗ Branch 1 not taken.
4 g_clear_object (&new_scan);
73 }
74
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 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 }
81
82
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
9 if (!self->match_reported)
83 {
84 8 self->match_reported = TRUE;
85 8 fpi_device_identify_report (dev,
86 match,
87 new_scan,
88 NULL);
89 }
90 }
91
3/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 5 times.
6 else if (error && error->domain == FP_DEVICE_RETRY)
92 {
93 1 fpi_device_identify_report (dev, NULL, NULL, g_steal_pointer (&error));
94 }
95
96 15 fpi_device_report_finger_status_changes (FP_DEVICE (self),
97 FP_FINGER_STATUS_NONE,
98 FP_FINGER_STATUS_PRESENT);
99
100
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 1 times.
15 if (should_wait_to_sleep (self, scan_id, error))
101 return;
102
103 14 self->match_reported = FALSE;
104 14 fpi_device_identify_complete (dev, g_steal_pointer (&error));
105 }
106
107 struct ListData
108 {
109 FpDevice *dev;
110 GPtrArray *res;
111 };
112
113 static void
114 17 dev_list_insert_print (gpointer key,
115 gpointer value,
116 gpointer user_data)
117 {
118 17 struct ListData *data = user_data;
119 17 FpPrint *print = fp_print_new (data->dev);
120 17 GVariant *var = NULL;
121
122 17 fpi_print_fill_from_user_id (print, key);
123 17 fpi_print_set_type (print, FPI_PRINT_RAW);
124 17 var = g_variant_new_string (key);
125 17 g_object_set (print, "fpi-data", var, NULL);
126 17 g_object_ref_sink (print);
127
128 17 g_ptr_array_add (data->res, print);
129 17 }
130
131 static GPtrArray *
132 16 get_stored_prints (FpDeviceVirtualDevice *self)
133 {
134 16 GPtrArray * prints_list;
135 16 struct ListData data;
136
137 16 prints_list = g_ptr_array_new_full (g_hash_table_size (self->prints_storage),
138 g_object_unref);
139 16 data.dev = FP_DEVICE (self);
140 16 data.res = prints_list;
141
142 16 g_hash_table_foreach (self->prints_storage, dev_list_insert_print, &data);
143
144 16 return prints_list;
145 }
146
147 static void
148 16 dev_list (FpDevice *dev)
149 {
150 16 g_autoptr(GPtrArray) prints_list = NULL;
151 16 g_autoptr(GError) error = NULL;
152 16 FpDeviceVirtualDevice *vdev = FP_DEVICE_VIRTUAL_DEVICE (dev);
153
154
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8 times.
16 if (!process_cmds (vdev, FALSE, NULL, &error))
155 return;
156
157
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
8 if (error)
158 {
159 1 fpi_device_list_complete (dev, NULL, g_steal_pointer (&error));
160 1 return;
161 }
162
163
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
7 fpi_device_list_complete (dev, get_stored_prints (vdev), NULL);
164 }
165
166 static void
167 40 dev_clear_storage (FpDevice *dev)
168 {
169 40 g_autoptr(GPtrArray) prints_list = NULL;
170 40 g_autoptr(GError) error = NULL;
171 40 FpDeviceVirtualDevice *vdev = FP_DEVICE_VIRTUAL_DEVICE (dev);
172
173
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 if (!process_cmds (vdev, FALSE, NULL, &error))
174 return;
175
176
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 39 times.
40 if (error)
177 {
178 1 fpi_device_clear_storage_complete (dev, g_steal_pointer (&error));
179 1 return;
180 }
181
182 39 g_hash_table_remove_all (vdev->prints_storage);
183
184
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
39 fpi_device_clear_storage_complete (dev, NULL);
185 }
186
187 static void
188 10 dev_delete (FpDevice *dev)
189 {
190 10 g_autoptr(GVariant) data = NULL;
191
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
10 g_autoptr(GError) error = NULL;
192 10 FpDeviceVirtualDevice *vdev = FP_DEVICE_VIRTUAL_DEVICE (dev);
193 10 FpPrint *print = NULL;
194 10 const char *id = NULL;
195
196
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 5 times.
10 if (!process_cmds (vdev, FALSE, NULL, &error))
197 return;
198
199
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
5 if (error)
200 {
201 1 fpi_device_delete_complete (dev, g_steal_pointer (&error));
202 1 return;
203 }
204
205 4 fpi_device_get_delete_data (dev, &print);
206
207 4 g_object_get (print, "fpi-data", &data, NULL);
208
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (data == NULL)
209 {
210 fpi_device_delete_complete (dev,
211 fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
212 return;
213 }
214
215 4 id = g_variant_get_string (data, NULL);
216
217 4 fp_dbg ("Deleting print %s for user %s",
218 id,
219 fp_print_get_username (print));
220
221
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
4 if (g_hash_table_remove (vdev->prints_storage, id))
222 2 fpi_device_delete_complete (dev, NULL);
223 else
224 2 fpi_device_delete_complete (dev,
225 fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND));
226 }
227
228 static void
229 42 dev_probe (FpDevice *dev)
230 {
231 /* Disable features listed in driver_data */
232 42 fpi_device_update_features (dev, fpi_device_get_driver_data (dev), 0);
233
234 42 fpi_device_probe_complete (dev, NULL, NULL, NULL);
235 42 }
236
237 static void
238 42 fpi_device_virtual_device_storage_init (FpDeviceVirtualDeviceStorage *self)
239 {
240 42 FpDeviceVirtualDevice *vdev = FP_DEVICE_VIRTUAL_DEVICE (self);
241
242 42 vdev->prints_storage = g_hash_table_new_full (g_str_hash,
243 g_str_equal,
244 g_free,
245 NULL);
246 42 }
247
248 static void
249 38 fpi_device_virtual_device_storage_finalize (GObject *object)
250 {
251 38 FpDeviceVirtualDevice *vdev = FP_DEVICE_VIRTUAL_DEVICE (object);
252
253 38 G_DEBUG_HERE ();
254
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 g_clear_pointer (&vdev->prints_storage, g_hash_table_destroy);
255 38 G_OBJECT_CLASS (fpi_device_virtual_device_storage_parent_class)->finalize (object);
256 38 }
257
258 static const FpIdEntry driver_ids[] = {
259 { .virtual_envvar = "FP_VIRTUAL_DEVICE_STORAGE", .driver_data = 0 },
260 { .virtual_envvar = "FP_VIRTUAL_DEVICE_STORAGE_NO_LIST", .driver_data = FP_DEVICE_FEATURE_STORAGE_LIST },
261 { .virtual_envvar = NULL }
262 };
263
264 static void
265 117 fpi_device_virtual_device_storage_class_init (FpDeviceVirtualDeviceStorageClass *klass)
266 {
267 117 FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
268 117 GObjectClass *object_class = G_OBJECT_CLASS (klass);
269
270 117 object_class->finalize = fpi_device_virtual_device_storage_finalize;
271
272 117 dev_class->id = FP_COMPONENT;
273 117 dev_class->full_name = "Virtual device with storage and identification for debugging";
274 117 dev_class->id_table = driver_ids;
275
276 117 dev_class->probe = dev_probe;
277 117 dev_class->identify = dev_identify;
278 117 dev_class->list = dev_list;
279 117 dev_class->delete = dev_delete;
280 117 dev_class->clear_storage = dev_clear_storage;
281
282 117 fpi_device_class_auto_initialize_features (dev_class);
283 117 dev_class->features |= FP_DEVICE_FEATURE_DUPLICATES_CHECK;
284 117 }
285