1
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
4
* Copyright (C) Luis Medinas 2008 <lmedinas@gmail.com>
5
* Copyright (C) Philippe Rouquier 2008 <bonfire-app@wanadoo.fr>
7
* Libbrasero-burn is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* The Libbrasero-burn authors hereby grant permission for non-GPL compatible
13
* GStreamer plugins to be used and distributed together with GStreamer
14
* and Libbrasero-burn. This permission is above and beyond the permissions granted
15
* by the GPL license by which Libbrasero-burn is covered. If you modify this code
16
* you may extend this exception to your version of the code, but you are not
17
* obligated to do so. If you do not wish to do so, delete this exception
18
* statement from your version.
20
* Libbrasero-burn is distributed in the hope that it will be useful,
21
* but WITHOUT ANY WARRANTY; without even the implied warranty of
22
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
* GNU Library General Public License for more details.
25
* You should have received a copy of the GNU General Public License
26
* along with this program; if not, write to:
27
* The Free Software Foundation, Inc.,
28
* 51 Franklin Street, Fifth Floor
29
* Boston, MA 02110-1301, USA.
36
#include <sys/utsname.h>
41
#include <dbus/dbus-glib.h>
44
#include <gst/pbutils/install-plugins.h>
45
#include <gst/pbutils/missing-plugins.h>
47
#include "brasero-misc.h"
48
#include "brasero-pk.h"
50
static GSList *already_tested = NULL;
52
typedef struct _BraseroPKPrivate BraseroPKPrivate;
53
struct _BraseroPKPrivate
55
DBusGConnection *connection;
63
#define BRASERO_PK_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_PK, BraseroPKPrivate))
65
G_DEFINE_TYPE (BraseroPK, brasero_pk, G_TYPE_OBJECT);
68
brasero_pk_install_missing_files_result (DBusGProxy *proxy,
73
BraseroPKPrivate *priv = BRASERO_PK_PRIVATE (user_data);
76
priv->res = dbus_g_proxy_end_call (proxy,
81
BRASERO_UTILS_LOG ("%s", error->message);
85
g_main_loop_quit (priv->loop);
89
brasero_pk_cancelled (GCancellable *cancel,
92
BraseroPKPrivate *priv = BRASERO_PK_PRIVATE (package);
97
dbus_g_proxy_cancel_call (priv->proxy, priv->call);
100
g_main_loop_quit (priv->loop);
104
brasero_pk_wait_for_call_end (BraseroPK *package,
105
GCancellable *cancel)
107
BraseroPKPrivate *priv;
111
priv = BRASERO_PK_PRIVATE (package);
113
loop = g_main_loop_new (NULL, FALSE);
116
sig_int = g_signal_connect (cancel,
118
G_CALLBACK (brasero_pk_cancelled),
121
GDK_THREADS_LEAVE ();
122
g_main_loop_run (loop);
123
GDK_THREADS_ENTER ();
125
g_signal_handler_disconnect (cancel, sig_int);
127
g_main_loop_unref (loop);
134
brasero_pk_connect (BraseroPK *package)
136
BraseroPKPrivate *priv;
137
GError *error = NULL;
139
priv = BRASERO_PK_PRIVATE (package);
141
/* check dbus connections, exit if not valid */
142
priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
143
if (priv->connection == NULL) {
144
BRASERO_UTILS_LOG ("%s", error->message);
148
/* get a connection */
149
priv->proxy = dbus_g_proxy_new_for_name (priv->connection,
150
"org.freedesktop.PackageKit",
151
"/org/freedesktop/PackageKit",
152
"org.freedesktop.PackageKit.Modify");
153
if (priv->proxy == NULL) {
154
BRASERO_UTILS_LOG ("Cannot connect to session service");
158
/* don't timeout, as dbus-glib sets the timeout ~25 seconds */
159
dbus_g_proxy_set_default_timeout (priv->proxy, INT_MAX);
167
* This would be the proper way to do it except
169
* - it cannot be cancelled
170
* - it does not work for elements
174
brasero_pk_install_gst_plugin_result (GstInstallPluginsReturn res,
177
BraseroPKPrivate *priv = BRASERO_PK_PRIVATE (user_data);
180
case GST_INSTALL_PLUGINS_SUCCESS:
184
case GST_INSTALL_PLUGINS_PARTIAL_SUCCESS:
185
case GST_INSTALL_PLUGINS_USER_ABORT:
187
case GST_INSTALL_PLUGINS_NOT_FOUND:
188
case GST_INSTALL_PLUGINS_ERROR:
189
case GST_INSTALL_PLUGINS_CRASHED:
195
g_main_loop_quit (priv->loop);
199
brasero_pk_install_gstreamer_plugin (BraseroPK *package,
200
const gchar *element_name,
202
GCancellable *cancel)
204
GstInstallPluginsContext *context;
205
GPtrArray *gst_plugins = NULL;
206
GstInstallPluginsReturn status;
207
gboolean res = FALSE;
210
/* The problem with this is that we can't
212
gst_plugins = g_ptr_array_new ();
213
detail = gst_missing_element_installer_detail_new (element_name);
214
g_ptr_array_add (gst_plugins, detail);
215
g_ptr_array_add (gst_plugins, NULL);
217
context = gst_install_plugins_context_new ();
218
gst_install_plugins_context_set_xid (context, xid);
219
status = gst_install_plugins_async ((gchar **) gst_plugins->pdata,
221
brasero_pk_install_gst_plugin_result,
224
if (status == GST_INSTALL_PLUGINS_STARTED_OK)
225
res = brasero_pk_wait_for_call_end (package, cancel);
227
gst_install_plugins_context_free (context);
228
g_strfreev ((gchar **) gst_plugins->pdata);
229
g_ptr_array_free (gst_plugins, FALSE);
237
brasero_pk_install_file_requirement (BraseroPK *package,
238
GPtrArray *missing_files,
240
GCancellable *cancel)
242
BraseroPKPrivate *priv;
244
priv = BRASERO_PK_PRIVATE (package);
246
if (!brasero_pk_connect (package))
249
priv->call = dbus_g_proxy_begin_call_with_timeout (priv->proxy, "InstallProvideFiles",
250
brasero_pk_install_missing_files_result,
255
G_TYPE_STRV, missing_files->pdata,
256
G_TYPE_STRING, "hide-finished,hide-warnings",
259
return brasero_pk_wait_for_call_end (package, cancel);
263
brasero_pk_install_missing_app (BraseroPK *package,
264
const gchar *file_name,
266
GCancellable *cancel)
270
GPtrArray *missing_files;
272
path = g_build_path (G_DIR_SEPARATOR_S,
277
if (g_slist_find_custom (already_tested, path, (GCompareFunc) g_strcmp0)) {
281
already_tested = g_slist_prepend (already_tested, g_strdup (path));
283
missing_files = g_ptr_array_new ();
284
g_ptr_array_add (missing_files, path);
285
g_ptr_array_add (missing_files, NULL);
287
res = brasero_pk_install_file_requirement (package, missing_files, xid, cancel);
289
g_strfreev ((gchar **) missing_files->pdata);
290
g_ptr_array_free (missing_files, FALSE);
296
* pk_gst_get_arch_suffix:
298
* Return value: something other than blank if we are running on 64 bit.
301
pk_gst_is_x64_arch (void)
306
retval = uname (&buf);
308
/* did we get valid value? */
309
if (retval != 0 || buf.machine == NULL) {
310
g_warning ("PackageKit: cannot get machine type");
314
/* 64 bit machines */
315
if (g_strcmp0 (buf.machine, "x86_64") == 0)
318
/* 32 bit machines and unrecognized arch */
323
brasero_pk_install_missing_library (BraseroPK *package,
324
const gchar *library_name,
326
GCancellable *cancel)
330
GPtrArray *missing_files;
332
if (pk_gst_is_x64_arch ())
333
path = g_strdup_printf ("/usr/lib64/%s", library_name);
335
path = g_strdup_printf ("/usr/lib/%s", library_name);
337
if (g_slist_find_custom (already_tested, path, (GCompareFunc) g_strcmp0)) {
341
already_tested = g_slist_prepend (already_tested, g_strdup (path));
343
missing_files = g_ptr_array_new ();
344
g_ptr_array_add (missing_files, path);
345
g_ptr_array_add (missing_files, NULL);
347
res = brasero_pk_install_file_requirement (package, missing_files, xid, cancel);
349
g_strfreev ((gchar **) missing_files->pdata);
350
g_ptr_array_free (missing_files, FALSE);
356
brasero_pk_install_gstreamer_plugin (BraseroPK *package,
357
const gchar *element_name,
359
GCancellable *cancel)
364
BraseroPKPrivate *priv;
365
GPtrArray *missing_files;
367
priv = BRASERO_PK_PRIVATE (package);
369
/* The whole function is gross but it works:
372
/* This is a special case for ffmpeg plugin. It
373
* comes as a single library for all elements
374
* so we have to workaround this */
375
if (!strncmp (element_name, "ff", 2))
380
if (pk_gst_is_x64_arch ())
381
resource = g_strdup_printf ("/usr/lib64/gstreamer-0.10/libgst%s.so", name);
383
resource = g_strdup_printf ("/usr/lib/gstreamer-0.10/libgst%s.so", name);
385
if (g_slist_find_custom (already_tested, resource, (GCompareFunc) g_strcmp0)) {
389
already_tested = g_slist_prepend (already_tested, g_strdup (resource));
391
missing_files = g_ptr_array_new ();
392
g_ptr_array_add (missing_files, resource);
393
g_ptr_array_add (missing_files, NULL);
395
res = brasero_pk_install_file_requirement (package, missing_files, xid, cancel);
398
res = gst_update_registry ();
400
g_strfreev ((gchar **) missing_files->pdata);
401
g_ptr_array_free (missing_files, FALSE);
407
brasero_pk_init (BraseroPK *object)
411
brasero_pk_finalize (GObject *object)
413
BraseroPKPrivate *priv;
415
priv = BRASERO_PK_PRIVATE (object);
418
dbus_g_proxy_cancel_call (priv->proxy, priv->call);
421
g_main_loop_quit (priv->loop);
424
g_object_unref (priv->proxy);
428
if (priv->connection) {
429
dbus_g_connection_unref (priv->connection);
430
priv->connection = NULL;
433
G_OBJECT_CLASS (brasero_pk_parent_class)->finalize (object);
437
brasero_pk_class_init (BraseroPKClass *klass)
439
GObjectClass* object_class = G_OBJECT_CLASS (klass);
441
g_type_class_add_private (klass, sizeof (BraseroPKPrivate));
443
object_class->finalize = brasero_pk_finalize;
447
brasero_pk_new (void)
449
return g_object_new (BRASERO_TYPE_PK, NULL);