Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-3.0-or-later
2 : : // SPDX-FileCopyrightText: Andy Holmes <andrew.g.r.holmes@gmail.com>
3 : :
4 : : #define G_LOG_DOMAIN "valent-media"
5 : :
6 : : #include "config.h"
7 : :
8 : : #include <gio/gio.h>
9 : : #include <libpeas.h>
10 : : #include <libvalent-core.h>
11 : :
12 : : #include "valent-media-adapter.h"
13 : : #include "valent-media-player.h"
14 : :
15 : : #include "valent-media.h"
16 : :
17 : : /**
18 : : * ValentMedia:
19 : : *
20 : : * A class for monitoring and controlling media players.
21 : : *
22 : : * `ValentMedia` is an aggregator of media players, intended for use by
23 : : * [class@Valent.DevicePlugin] implementations.
24 : : *
25 : : * Plugins can implement [class@Valent.MediaAdapter] to provide an
26 : : * interface to manage instances of [class@Valent.MediaPlayer].
27 : : *
28 : : * Since: 1.0
29 : : */
30 : : struct _ValentMedia
31 : : {
32 : : ValentComponent parent_instance;
33 : :
34 : : GPtrArray *exports;
35 : : };
36 : :
37 [ + + + - ]: 170 : G_DEFINE_FINAL_TYPE (ValentMedia, valent_media, VALENT_TYPE_COMPONENT)
38 : :
39 : : /*
40 : : * GObject
41 : : */
42 : : static void
43 : 14 : valent_media_finalize (GObject *object)
44 : : {
45 : 14 : ValentMedia *self = VALENT_MEDIA (object);
46 : :
47 [ + - ]: 14 : g_clear_pointer (&self->exports, g_ptr_array_unref);
48 : :
49 : 14 : G_OBJECT_CLASS (valent_media_parent_class)->finalize (object);
50 : 14 : }
51 : :
52 : : static void
53 : 6 : valent_media_class_init (ValentMediaClass *klass)
54 : : {
55 : 6 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
56 : :
57 : 6 : object_class->finalize = valent_media_finalize;
58 : : }
59 : :
60 : : static void
61 : 16 : valent_media_init (ValentMedia *self)
62 : : {
63 : 16 : self->exports = g_ptr_array_new_with_free_func (g_object_unref);
64 : 16 : }
65 : :
66 : : /**
67 : : * valent_media_get_default:
68 : : *
69 : : * Get the default [class@Valent.Media].
70 : : *
71 : : * Returns: (transfer none) (not nullable): a `ValentMedia`
72 : : *
73 : : * Since: 1.0
74 : : */
75 : : ValentMedia *
76 : 56 : valent_media_get_default (void)
77 : : {
78 : 56 : static ValentMedia *default_instance = NULL;
79 : :
80 [ + + ]: 56 : if (default_instance == NULL)
81 : : {
82 : 16 : default_instance = g_object_new (VALENT_TYPE_MEDIA,
83 : : "plugin-domain", "media",
84 : : "plugin-type", VALENT_TYPE_MEDIA_ADAPTER,
85 : : NULL);
86 : 16 : g_object_add_weak_pointer (G_OBJECT (default_instance),
87 : : (gpointer)&default_instance);
88 : : }
89 : :
90 : 56 : return default_instance;
91 : : }
92 : :
93 : : /**
94 : : * valent_media_export_player:
95 : : * @media: a `ValentMedia`
96 : : * @player: a `ValentMediaPlayer`
97 : : *
98 : : * Export @player on all adapters that support it.
99 : : *
100 : : * Since: 1.0
101 : : */
102 : : void
103 : 3 : valent_media_export_player (ValentMedia *media,
104 : : ValentMediaPlayer *player)
105 : : {
106 : 3 : ValentResource *source = NULL;
107 : 3 : unsigned int n_items;
108 : :
109 : 3 : VALENT_ENTRY;
110 : :
111 [ + - ]: 3 : g_return_if_fail (VALENT_IS_MEDIA (media));
112 [ - + ]: 3 : g_return_if_fail (VALENT_IS_MEDIA_PLAYER (player));
113 : :
114 [ - + ]: 3 : if (g_ptr_array_find (media->exports, player, NULL))
115 : : {
116 : 0 : g_warning ("Player \"%s\" (%s) already exported",
117 : : valent_media_player_get_name (player),
118 : : G_OBJECT_TYPE_NAME (player));
119 : 0 : VALENT_EXIT;
120 : : }
121 : :
122 : 3 : g_signal_connect_object (player,
123 : : "destroy",
124 : : G_CALLBACK (valent_media_unexport_player),
125 : : media,
126 : : G_CONNECT_SWAPPED);
127 : 3 : g_ptr_array_add (media->exports, g_object_ref (player));
128 : :
129 : 3 : source = valent_resource_get_source (VALENT_RESOURCE (player));
130 : 3 : n_items = g_list_model_get_n_items (G_LIST_MODEL (media));
131 [ + + ]: 7 : for (unsigned int i = 0; i < n_items; i++)
132 : : {
133 : 4 : g_autoptr (ValentMediaAdapter) adapter = NULL;
134 : :
135 : 4 : adapter = g_list_model_get_item (G_LIST_MODEL (media), i);
136 [ + - ]: 4 : if (VALENT_RESOURCE (adapter) != source)
137 : 4 : valent_media_adapter_export_player (adapter, player);
138 : : }
139 : :
140 : 3 : VALENT_EXIT;
141 : : }
142 : :
143 : : /**
144 : : * valent_media_unexport_player:
145 : : * @media: a `ValentMedia`
146 : : * @player: a `ValentMediaPlayer`
147 : : *
148 : : * Unexport @player from all adapters that support it.
149 : : *
150 : : * Since: 1.0
151 : : */
152 : : void
153 : 3 : valent_media_unexport_player (ValentMedia *media,
154 : : ValentMediaPlayer *player)
155 : : {
156 : 3 : ValentResource *source = NULL;
157 : 3 : unsigned int n_items;
158 : 6 : g_autoptr (ValentExtension) item = NULL;
159 : 3 : unsigned int position = 0;
160 : :
161 : 3 : VALENT_ENTRY;
162 : :
163 [ + - ]: 3 : g_return_if_fail (VALENT_IS_MEDIA (media));
164 [ - + ]: 3 : g_return_if_fail (VALENT_IS_MEDIA_PLAYER (player));
165 : :
166 [ - + ]: 3 : if (!g_ptr_array_find (media->exports, player, &position))
167 : : {
168 : 0 : g_critical ("%s(): unknown player %s (%s)",
169 : : G_STRFUNC,
170 : : G_OBJECT_TYPE_NAME (player),
171 : : valent_media_player_get_name (player));
172 : 3 : VALENT_EXIT;
173 : : }
174 : :
175 : 3 : g_signal_handlers_disconnect_by_func (player, valent_media_unexport_player, media);
176 : 3 : item = g_ptr_array_steal_index (media->exports, position);
177 : :
178 : 3 : source = valent_resource_get_source (VALENT_RESOURCE (player));
179 : 3 : n_items = g_list_model_get_n_items (G_LIST_MODEL (media));
180 [ + + ]: 7 : for (unsigned int i = 0; i < n_items; i++)
181 : : {
182 : 4 : g_autoptr (ValentMediaAdapter) adapter = NULL;
183 : :
184 : 4 : adapter = g_list_model_get_item (G_LIST_MODEL (media), i);
185 [ + - ]: 4 : if (VALENT_RESOURCE (adapter) != source)
186 : 4 : valent_media_adapter_unexport_player (adapter, player);
187 : : }
188 : :
189 [ + - ]: 3 : VALENT_EXIT;
190 : : }
191 : :
|