1
/* ide-device-manager.c
3
* Copyright (C) 2015 Christian Hergert <christian@hergert.me>
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, either version 3 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19
#include <glib/gi18n.h>
21
#include "ide-device.h"
22
#include "ide-device-manager.h"
23
#include "ide-device-provider.h"
25
#include "local/ide-local-device.h"
27
struct _IdeDeviceManager
29
IdeObject parent_instance;
35
static void list_model_init_interface (GListModelInterface *iface);
37
G_DEFINE_TYPE_WITH_CODE (IdeDeviceManager, ide_device_manager, IDE_TYPE_OBJECT,
38
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL,
39
list_model_init_interface))
53
static guint gSignals [LAST_SIGNAL];
54
static GParamSpec *gParamSpecs [LAST_PROP];
57
ide_device_manager_get_settled (IdeDeviceManager *self)
61
g_return_val_if_fail (IDE_IS_DEVICE_MANAGER (self), FALSE);
63
for (i = 0; i < self->providers->len; i++)
65
IdeDeviceProvider *provider;
67
provider = g_ptr_array_index (self->providers, i);
68
if (!ide_device_provider_get_settled (provider))
76
ide_device_manager_device_notify_settled (IdeDeviceManager *self,
78
IdeDeviceProvider *provider)
80
g_return_if_fail (IDE_IS_DEVICE_MANAGER (self));
81
g_return_if_fail (IDE_IS_DEVICE_PROVIDER (provider));
83
g_object_notify_by_pspec (G_OBJECT (self),
84
gParamSpecs [PROP_SETTLED]);
88
ide_device_manager_do_add_device (IdeDeviceManager *self,
93
g_assert (IDE_IS_DEVICE_MANAGER (self));
94
g_assert (IDE_IS_DEVICE (device));
96
position = self->devices->len;
97
g_ptr_array_add (self->devices, g_object_ref (device));
98
g_list_model_items_changed (G_LIST_MODEL (self), position, 0, 1);
102
ide_device_manager_device_added (IdeDeviceManager *self,
104
IdeDeviceProvider *provider)
106
g_return_if_fail (IDE_IS_DEVICE_MANAGER (self));
107
g_return_if_fail (IDE_IS_DEVICE (device));
108
g_return_if_fail (IDE_IS_DEVICE_PROVIDER (provider));
110
ide_device_manager_do_add_device (self, device);
111
g_signal_emit (self, gSignals [DEVICE_ADDED], 0, provider, device);
115
ide_device_manager_device_removed (IdeDeviceManager *self,
117
IdeDeviceProvider *provider)
121
g_return_if_fail (IDE_IS_DEVICE_MANAGER (self));
122
g_return_if_fail (IDE_IS_DEVICE (device));
123
g_return_if_fail (IDE_IS_DEVICE_PROVIDER (provider));
125
g_signal_handlers_disconnect_by_func (provider,
126
G_CALLBACK (ide_device_manager_device_notify_settled),
128
g_signal_handlers_disconnect_by_func (provider,
129
G_CALLBACK (ide_device_manager_device_added),
131
g_signal_handlers_disconnect_by_func (provider,
132
G_CALLBACK (ide_device_manager_device_removed),
135
for (i = 0; i < self->devices->len; i++)
139
iter = g_ptr_array_index (self->devices, i);
143
g_ptr_array_remove_index (self->devices, i);
144
g_list_model_items_changed (G_LIST_MODEL (self), i, 1, 0);
145
g_signal_emit (self, gSignals [DEVICE_REMOVED], 0, provider, device);
153
ide_device_manager_add_provider (IdeDeviceManager *self,
154
IdeDeviceProvider *provider)
159
g_return_if_fail (IDE_IS_DEVICE_MANAGER (self));
160
g_return_if_fail (IDE_IS_DEVICE_PROVIDER (provider));
162
for (i = 0; i < self->providers->len; i++)
164
if (provider == g_ptr_array_index (self->providers, i))
166
g_warning ("Cannot add provider, already registered.");
171
g_ptr_array_add (self->providers, g_object_ref (provider));
173
g_signal_connect_object (provider,
175
G_CALLBACK (ide_device_manager_device_notify_settled),
179
g_signal_connect_object (provider,
181
G_CALLBACK (ide_device_manager_device_added),
185
g_signal_connect_object (provider,
187
G_CALLBACK (ide_device_manager_device_removed),
191
devices = ide_device_provider_get_devices (provider);
193
for (i = 0; i < devices->len; i++)
197
device = g_ptr_array_index (devices, i);
198
ide_device_manager_device_added (self, device, provider);
203
ide_device_manager_add_providers (IdeDeviceManager *self)
205
GIOExtensionPoint *extension_point;
210
g_assert (IDE_IS_DEVICE_MANAGER (self));
212
context = ide_object_get_context (IDE_OBJECT (self));
214
extension_point = g_io_extension_point_lookup (IDE_DEVICE_PROVIDER_EXTENSION_POINT);
215
extensions = g_io_extension_point_get_extensions (extension_point);
217
for (iter = extensions; iter; iter = iter->next)
219
GIOExtension *extension = iter->data;
220
g_autoptr(IdeDeviceProvider) provider = NULL;
223
type = g_io_extension_get_type (extension);
225
if (!g_type_is_a (type, IDE_TYPE_DEVICE_PROVIDER))
227
g_warning (_("%s is not an IdeDeviceProvider."),
232
provider = g_object_new (type, "context", context, NULL);
233
ide_device_manager_add_provider (self, provider);
238
* ide_device_manager_get_devices:
240
* Retrieves all of the devices that are registered with the #IdeDeviceManager.
242
* Returns: (transfer container) (element-type IdeDevice*): An array of devices
243
* registered with the #IdeManager.
246
ide_device_manager_get_devices (IdeDeviceManager *self)
251
g_return_val_if_fail (IDE_IS_DEVICE_MANAGER (self), NULL);
253
ret = g_ptr_array_new_with_free_func (g_object_unref);
255
for (i = 0; i < self->devices->len; i++)
259
device = g_ptr_array_index (self->devices, i);
260
g_ptr_array_add (ret, g_object_ref (device));
267
ide_device_manager_add_local (IdeDeviceManager *self)
269
g_autoptr(IdeDevice) device = NULL;
272
g_return_if_fail (IDE_IS_DEVICE_MANAGER (self));
274
context = ide_object_get_context (IDE_OBJECT (self));
275
device = g_object_new (IDE_TYPE_LOCAL_DEVICE,
278
ide_device_manager_do_add_device (self, device);
282
ide_device_manager_get_item_type (GListModel *list_model)
284
return IDE_TYPE_DEVICE;
288
ide_device_manager_get_n_items (GListModel *list_model)
290
IdeDeviceManager *self = (IdeDeviceManager *)list_model;
292
g_assert (IDE_IS_DEVICE_MANAGER (self));
294
return self->devices->len;
298
ide_device_manager_get_item (GListModel *list_model,
301
IdeDeviceManager *self = (IdeDeviceManager *)list_model;
303
g_assert (IDE_IS_DEVICE_MANAGER (self));
304
g_assert (position < self->devices->len);
306
return g_object_ref (g_ptr_array_index (self->devices, position));
310
ide_device_manager_constructed (GObject *object)
312
IdeDeviceManager *self = (IdeDeviceManager *)object;
314
g_return_if_fail (IDE_IS_DEVICE_MANAGER (self));
316
G_OBJECT_CLASS (ide_device_manager_parent_class)->constructed (object);
318
ide_device_manager_add_local (self);
319
ide_device_manager_add_providers (self);
323
ide_device_manager_finalize (GObject *object)
325
IdeDeviceManager *self = (IdeDeviceManager *)object;
327
g_clear_pointer (&self->devices, g_ptr_array_unref);
328
g_clear_pointer (&self->providers, g_ptr_array_unref);
330
G_OBJECT_CLASS (ide_device_manager_parent_class)->finalize (object);
334
ide_device_manager_get_property (GObject *object,
339
IdeDeviceManager *self = IDE_DEVICE_MANAGER(object);
344
g_value_set_boolean (value, ide_device_manager_get_settled (self));
348
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
353
ide_device_manager_class_init (IdeDeviceManagerClass *klass)
355
GObjectClass *object_class = G_OBJECT_CLASS (klass);
357
object_class->constructed = ide_device_manager_constructed;
358
object_class->finalize = ide_device_manager_finalize;
359
object_class->get_property = ide_device_manager_get_property;
361
gParamSpecs [PROP_SETTLED] =
362
g_param_spec_boolean ("settled",
364
_("If the device providers have settled."),
366
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
368
g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
370
gSignals [DEVICE_ADDED] =
371
g_signal_new ("device-added",
372
G_TYPE_FROM_CLASS (klass),
378
IDE_TYPE_DEVICE_PROVIDER,
381
gSignals [DEVICE_REMOVED] =
382
g_signal_new ("device-removed",
383
G_TYPE_FROM_CLASS (klass),
389
IDE_TYPE_DEVICE_PROVIDER,
394
list_model_init_interface (GListModelInterface *iface)
396
iface->get_item_type = ide_device_manager_get_item_type;
397
iface->get_n_items = ide_device_manager_get_n_items;
398
iface->get_item = ide_device_manager_get_item;
402
ide_device_manager_init (IdeDeviceManager *self)
404
self->devices = g_ptr_array_new_with_free_func (g_object_unref);
405
self->providers = g_ptr_array_new_with_free_func (g_object_unref);
409
* ide_device_manager_get_device:
410
* @device_id: The device identifier string.
412
* Fetches the first device that matches the device identifier @device_id.
414
* Returns: (transfer none): An #IdeDevice or %NULL.
417
ide_device_manager_get_device (IdeDeviceManager *self,
418
const gchar *device_id)
422
g_return_val_if_fail (IDE_IS_DEVICE_MANAGER (self), NULL);
424
for (i = 0; i < self->devices->len; i++)
429
device = g_ptr_array_index (self->devices, i);
430
id = ide_device_get_id (device);
432
if (0 == g_strcmp0 (id, device_id))