~ubuntu-branches/ubuntu/maverick/brasero/maverick

« back to all changes in this revision

Viewing changes to libbrasero-utils/brasero-pk.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Ancell
  • Date: 2009-11-26 16:20:01 UTC
  • mto: This revision was merged to the branch mainline in revision 58.
  • Revision ID: james.westby@ubuntu.com-20091126162001-5iw2jzxdx8l31okz
Tags: upstream-2.29.2
ImportĀ upstreamĀ versionĀ 2.29.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
 
2
/*
 
3
 * Libbrasero-burn
 
4
 * Copyright (C) Luis Medinas 2008 <lmedinas@gmail.com>
 
5
 * Copyright (C) Philippe Rouquier 2008 <bonfire-app@wanadoo.fr>
 
6
 *
 
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.
 
11
 *
 
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.
 
19
 * 
 
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.
 
24
 * 
 
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.
 
30
 */
 
31
 
 
32
#ifdef HAVE_CONFIG_H
 
33
#  include <config.h>
 
34
#endif
 
35
 
 
36
#include <sys/utsname.h>
 
37
#include <string.h>
 
38
 
 
39
#include <glib.h>
 
40
#include <gdk/gdk.h>
 
41
#include <dbus/dbus-glib.h>
 
42
 
 
43
#include <gst/gst.h>
 
44
#include <gst/pbutils/install-plugins.h>
 
45
#include <gst/pbutils/missing-plugins.h>
 
46
 
 
47
#include "brasero-misc.h"
 
48
#include "brasero-pk.h"
 
49
 
 
50
static GSList *already_tested = NULL;
 
51
 
 
52
typedef struct _BraseroPKPrivate BraseroPKPrivate;
 
53
struct _BraseroPKPrivate
 
54
{
 
55
        DBusGConnection *connection;
 
56
        DBusGProxy *proxy;
 
57
        DBusGProxyCall *call;
 
58
 
 
59
        GMainLoop *loop;
 
60
        gboolean res;
 
61
};
 
62
 
 
63
#define BRASERO_PK_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_PK, BraseroPKPrivate))
 
64
 
 
65
G_DEFINE_TYPE (BraseroPK, brasero_pk, G_TYPE_OBJECT);
 
66
 
 
67
static void
 
68
brasero_pk_install_missing_files_result (DBusGProxy *proxy,
 
69
                                         DBusGProxyCall *call,
 
70
                                         gpointer user_data)
 
71
{
 
72
        GError *error = NULL;
 
73
        BraseroPKPrivate *priv = BRASERO_PK_PRIVATE (user_data);
 
74
 
 
75
        priv->call = NULL;
 
76
        priv->res = dbus_g_proxy_end_call (proxy,
 
77
                                           call,
 
78
                                           &error,
 
79
                                           G_TYPE_INVALID);
 
80
        if (!priv->res) {
 
81
                BRASERO_UTILS_LOG ("%s", error->message);
 
82
                g_error_free (error);
 
83
        }
 
84
 
 
85
        g_main_loop_quit (priv->loop);
 
86
}
 
87
 
 
88
static void
 
89
brasero_pk_cancelled (GCancellable *cancel,
 
90
                      BraseroPK *package)
 
91
{
 
92
        BraseroPKPrivate *priv = BRASERO_PK_PRIVATE (package);
 
93
 
 
94
        priv->res = FALSE;
 
95
 
 
96
        if (priv->call)
 
97
                dbus_g_proxy_cancel_call (priv->proxy, priv->call);
 
98
 
 
99
        if (priv->loop)
 
100
                g_main_loop_quit (priv->loop);
 
101
}
 
102
 
 
103
static gboolean
 
104
brasero_pk_wait_for_call_end (BraseroPK *package,
 
105
                              GCancellable *cancel)
 
106
{
 
107
        BraseroPKPrivate *priv;
 
108
        GMainLoop *loop;
 
109
        gulong sig_int;
 
110
 
 
111
        priv = BRASERO_PK_PRIVATE (package);
 
112
 
 
113
        loop = g_main_loop_new (NULL, FALSE);
 
114
        priv->loop = loop;
 
115
 
 
116
        sig_int = g_signal_connect (cancel,
 
117
                                    "cancelled",
 
118
                                    G_CALLBACK (brasero_pk_cancelled),
 
119
                                    package);
 
120
 
 
121
        GDK_THREADS_LEAVE ();
 
122
        g_main_loop_run (loop);
 
123
        GDK_THREADS_ENTER ();
 
124
 
 
125
        g_signal_handler_disconnect (cancel, sig_int);
 
126
 
 
127
        g_main_loop_unref (loop);
 
128
        priv->loop = NULL;
 
129
 
 
130
        return priv->res;
 
131
}
 
132
 
 
133
static gboolean
 
134
brasero_pk_connect (BraseroPK *package)
 
135
{
 
136
        BraseroPKPrivate *priv;
 
137
        GError *error = NULL;
 
138
 
 
139
        priv = BRASERO_PK_PRIVATE (package);
 
140
 
 
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);
 
145
                return FALSE;
 
146
        }
 
147
 
 
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");
 
155
                return FALSE;
 
156
        }
 
157
 
 
158
        /* don't timeout, as dbus-glib sets the timeout ~25 seconds */
 
159
        dbus_g_proxy_set_default_timeout (priv->proxy, INT_MAX);
 
160
 
 
161
        return TRUE;
 
162
}
 
163
 
 
164
#if 0
 
165
 
 
166
/**
 
167
 * This would be the proper way to do it except
 
168
 * it has two faults:
 
169
 * - it cannot be cancelled
 
170
 * - it does not work for elements
 
171
 **/
 
172
 
 
173
static void
 
174
brasero_pk_install_gst_plugin_result (GstInstallPluginsReturn res,
 
175
                                      gpointer user_data)
 
176
{
 
177
        BraseroPKPrivate *priv = BRASERO_PK_PRIVATE (user_data);
 
178
 
 
179
        switch (res) {
 
180
        case GST_INSTALL_PLUGINS_SUCCESS:
 
181
                priv->res = TRUE;
 
182
                break;
 
183
 
 
184
        case GST_INSTALL_PLUGINS_PARTIAL_SUCCESS:
 
185
        case GST_INSTALL_PLUGINS_USER_ABORT:
 
186
 
 
187
        case GST_INSTALL_PLUGINS_NOT_FOUND:
 
188
        case GST_INSTALL_PLUGINS_ERROR:
 
189
        case GST_INSTALL_PLUGINS_CRASHED:
 
190
        default:
 
191
                priv->res = FALSE;
 
192
                break;
 
193
        }
 
194
 
 
195
        g_main_loop_quit (priv->loop);
 
196
}
 
197
 
 
198
gboolean
 
199
brasero_pk_install_gstreamer_plugin (BraseroPK *package,
 
200
                                     const gchar *element_name,
 
201
                                     int xid,
 
202
                                    GCancellable *cancel)
 
203
{
 
204
        GstInstallPluginsContext *context;
 
205
        GPtrArray *gst_plugins = NULL;
 
206
        GstInstallPluginsReturn status;
 
207
        gboolean res = FALSE;
 
208
        gchar *detail;
 
209
 
 
210
        /* The problem with this is that we can't 
 
211
         * cancel a search */
 
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);
 
216
 
 
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,
 
220
                                            context,
 
221
                                            brasero_pk_install_gst_plugin_result,
 
222
                                            package);
 
223
 
 
224
        if (status == GST_INSTALL_PLUGINS_STARTED_OK)
 
225
                res = brasero_pk_wait_for_call_end (package, cancel);
 
226
 
 
227
        gst_install_plugins_context_free (context);
 
228
        g_strfreev ((gchar **) gst_plugins->pdata);
 
229
        g_ptr_array_free (gst_plugins, FALSE);
 
230
 
 
231
        return res;
 
232
}
 
233
 
 
234
#endif
 
235
 
 
236
static gboolean
 
237
brasero_pk_install_file_requirement (BraseroPK *package,
 
238
                                     GPtrArray *missing_files,
 
239
                                     int xid,
 
240
                                    GCancellable *cancel)
 
241
{
 
242
        BraseroPKPrivate *priv;
 
243
 
 
244
        priv = BRASERO_PK_PRIVATE (package);
 
245
 
 
246
        if (!brasero_pk_connect (package))
 
247
                return FALSE;
 
248
 
 
249
        priv->call = dbus_g_proxy_begin_call_with_timeout (priv->proxy, "InstallProvideFiles",
 
250
                                                           brasero_pk_install_missing_files_result,
 
251
                                                           package,
 
252
                                                           NULL,
 
253
                                                           INT_MAX,
 
254
                                                           G_TYPE_UINT, xid,
 
255
                                                           G_TYPE_STRV, missing_files->pdata,
 
256
                                                           G_TYPE_STRING, "hide-finished,hide-warnings",
 
257
                                                           G_TYPE_INVALID);
 
258
 
 
259
        return brasero_pk_wait_for_call_end (package, cancel);
 
260
}
 
261
 
 
262
gboolean
 
263
brasero_pk_install_missing_app (BraseroPK *package,
 
264
                                const gchar *file_name,
 
265
                                int xid,
 
266
                                GCancellable *cancel)
 
267
{
 
268
        gchar *path;
 
269
        gboolean res;
 
270
        GPtrArray *missing_files;
 
271
 
 
272
        path = g_build_path (G_DIR_SEPARATOR_S,
 
273
                             "/usr/bin/",
 
274
                             file_name,
 
275
                             NULL);
 
276
 
 
277
        if (g_slist_find_custom (already_tested, path, (GCompareFunc) g_strcmp0)) {
 
278
                g_free (path);
 
279
                return FALSE;
 
280
        }
 
281
        already_tested = g_slist_prepend (already_tested, g_strdup (path));
 
282
 
 
283
        missing_files = g_ptr_array_new ();
 
284
        g_ptr_array_add (missing_files, path);
 
285
        g_ptr_array_add (missing_files, NULL);
 
286
 
 
287
        res = brasero_pk_install_file_requirement (package, missing_files, xid, cancel);
 
288
 
 
289
        g_strfreev ((gchar **) missing_files->pdata);
 
290
        g_ptr_array_free (missing_files, FALSE);
 
291
 
 
292
        return res;
 
293
}
 
294
 
 
295
/**
 
296
 * pk_gst_get_arch_suffix:
 
297
 *
 
298
 * Return value: something other than blank if we are running on 64 bit.
 
299
 **/
 
300
static gboolean
 
301
pk_gst_is_x64_arch (void)
 
302
{
 
303
        gint retval;
 
304
        struct utsname buf;
 
305
 
 
306
        retval = uname (&buf);
 
307
 
 
308
        /* did we get valid value? */
 
309
        if (retval != 0 || buf.machine == NULL) {
 
310
                g_warning ("PackageKit: cannot get machine type");
 
311
                return FALSE;
 
312
        }
 
313
 
 
314
        /* 64 bit machines */
 
315
        if (g_strcmp0 (buf.machine, "x86_64") == 0)
 
316
                return TRUE;
 
317
 
 
318
        /* 32 bit machines and unrecognized arch */
 
319
        return FALSE;
 
320
}
 
321
 
 
322
gboolean
 
323
brasero_pk_install_missing_library (BraseroPK *package,
 
324
                                    const gchar *library_name,
 
325
                                    int xid,
 
326
                                    GCancellable *cancel)
 
327
{
 
328
        gchar *path;
 
329
        gboolean res;
 
330
        GPtrArray *missing_files;
 
331
 
 
332
        if (pk_gst_is_x64_arch ())
 
333
                path = g_strdup_printf ("/usr/lib64/%s", library_name);
 
334
        else
 
335
                path = g_strdup_printf ("/usr/lib/%s", library_name);
 
336
 
 
337
        if (g_slist_find_custom (already_tested, path, (GCompareFunc) g_strcmp0)) {
 
338
                g_free (path);
 
339
                return FALSE;
 
340
        }
 
341
        already_tested = g_slist_prepend (already_tested, g_strdup (path));
 
342
 
 
343
        missing_files = g_ptr_array_new ();
 
344
        g_ptr_array_add (missing_files, path);
 
345
        g_ptr_array_add (missing_files, NULL);
 
346
 
 
347
        res = brasero_pk_install_file_requirement (package, missing_files, xid, cancel);
 
348
 
 
349
        g_strfreev ((gchar **) missing_files->pdata);
 
350
        g_ptr_array_free (missing_files, FALSE);
 
351
 
 
352
        return res;
 
353
}
 
354
 
 
355
gboolean
 
356
brasero_pk_install_gstreamer_plugin (BraseroPK *package,
 
357
                                     const gchar *element_name,
 
358
                                     int xid,
 
359
                                     GCancellable *cancel)
 
360
{
 
361
        gboolean res;
 
362
        gchar *resource;
 
363
        const gchar *name;
 
364
        BraseroPKPrivate *priv;
 
365
        GPtrArray *missing_files;
 
366
 
 
367
        priv = BRASERO_PK_PRIVATE (package);
 
368
 
 
369
        /* The whole function is gross but it works:
 
370
         * - on fedora */
 
371
 
 
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))
 
376
                name = "ffmpeg";
 
377
        else
 
378
                name = element_name;
 
379
 
 
380
        if (pk_gst_is_x64_arch ())
 
381
                resource = g_strdup_printf ("/usr/lib64/gstreamer-0.10/libgst%s.so", name);
 
382
        else
 
383
                resource = g_strdup_printf ("/usr/lib/gstreamer-0.10/libgst%s.so", name);
 
384
 
 
385
        if (g_slist_find_custom (already_tested, resource, (GCompareFunc) g_strcmp0)) {
 
386
                g_free (resource);
 
387
                return FALSE;
 
388
        }
 
389
        already_tested = g_slist_prepend (already_tested, g_strdup (resource));
 
390
 
 
391
        missing_files = g_ptr_array_new ();
 
392
        g_ptr_array_add (missing_files, resource);
 
393
        g_ptr_array_add (missing_files, NULL);
 
394
 
 
395
        res = brasero_pk_install_file_requirement (package, missing_files, xid, cancel);
 
396
 
 
397
        if (res)
 
398
                 res = gst_update_registry ();
 
399
 
 
400
        g_strfreev ((gchar **) missing_files->pdata);
 
401
        g_ptr_array_free (missing_files, FALSE);
 
402
 
 
403
        return res;
 
404
}
 
405
 
 
406
static void
 
407
brasero_pk_init (BraseroPK *object)
 
408
{}
 
409
 
 
410
static void
 
411
brasero_pk_finalize (GObject *object)
 
412
{
 
413
        BraseroPKPrivate *priv;
 
414
 
 
415
        priv = BRASERO_PK_PRIVATE (object);
 
416
 
 
417
        if (priv->call)
 
418
                dbus_g_proxy_cancel_call (priv->proxy, priv->call);
 
419
 
 
420
        if (priv->loop)
 
421
                g_main_loop_quit (priv->loop);
 
422
 
 
423
        if (priv->proxy) {
 
424
                g_object_unref (priv->proxy);
 
425
                priv->proxy = NULL;
 
426
        }
 
427
 
 
428
        if (priv->connection) {
 
429
                dbus_g_connection_unref (priv->connection);
 
430
                priv->connection = NULL;
 
431
        }
 
432
 
 
433
        G_OBJECT_CLASS (brasero_pk_parent_class)->finalize (object);
 
434
}
 
435
 
 
436
static void
 
437
brasero_pk_class_init (BraseroPKClass *klass)
 
438
{
 
439
        GObjectClass* object_class = G_OBJECT_CLASS (klass);
 
440
 
 
441
        g_type_class_add_private (klass, sizeof (BraseroPKPrivate));
 
442
 
 
443
        object_class->finalize = brasero_pk_finalize;
 
444
}
 
445
 
 
446
BraseroPK *
 
447
brasero_pk_new (void)
 
448
{
 
449
        return g_object_new (BRASERO_TYPE_PK, NULL);
 
450
}