From 672a932784bd33f2b6397e80827dd1cdc3caabd7 Mon Sep 17 00:00:00 2001 From: Alexander Pyhalov Date: Thu, 20 Feb 2020 08:20:01 +0300 Subject: [PATCH] Revert "all: Remove HAL" This reverts commit ce78295bbf068f8da27706666e693cbd007855cb. --- configure.ac | 25 +++- doc/reference/Makefile.am | 1 + lib/libmediaplayerid/Makefile.am | 15 ++- lib/libmediaplayerid/mpid-device.c | 2 +- lib/libmediaplayerid/mpid-util.c | 4 +- plugins/mtpdevice/Makefile.am | 2 + plugins/mtpdevice/rb-mtp-plugin.c | 195 +++++++++++++++++++++++++++++ 7 files changed, 238 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 9e1ffa42d..8b50b8410 100644 --- a/configure.ac +++ b/configure.ac @@ -147,6 +147,25 @@ else fi AM_CONDITIONAL(USE_GUDEV, test x"$use_gudev" = xyes) +dnl hal remnants +AC_ARG_WITH(hal, + AC_HELP_STRING([--without-hal], + [Disable HAL support])) +if test "x$with_hal" != "xno"; then + PKG_CHECK_MODULES(HAL, hal >= 0.5 hal < 0.6 dbus-glib-1, enable_hal=yes, enable_hal=no) + if test "x$enable_hal" != "xyes" -a "x$with_hal" = "xyes"; then + AC_MSG_ERROR([HAL support explicitly requested but HAL couldn't be found]) + fi + + if test "x$enable_hal" = "xyes"; then + AC_DEFINE(HAVE_HAL, 1, [Define if you have HAL support]) + AC_SUBST(HAL_CFLAGS) + AC_SUBST(HAL_LIBS) + fi +fi +AM_CONDITIONAL(HAVE_HAL, test x"$enable_hal" = xyes) + + dnl iPod support AC_ARG_WITH(ipod, AC_HELP_STRING([--with-ipod], @@ -178,7 +197,7 @@ AC_ARG_WITH(mtp, with_mtp=auto) if test "x$with_mtp" != "xno"; then can_use_mtp=no - if test x"$use_gudev" = "xyes"; then + if test x"$use_gudev" = "xyes" -o x"$enable_hal" = "xyes"; then can_use_mtp=yes fi @@ -188,7 +207,7 @@ if test "x$with_mtp" != "xno"; then AC_MSG_ERROR([MTP explicitly requested but libmtp is not available]) fi if test x"$can_use_mtp" = "xno"; then - AC_MSG_ERROR([MTP explicitly requested but GUdev is not available]) + AC_MSG_ERROR([MTP explicitly requested but GUdev and HAL are not available]) fi fi if test "x$have_libmtp" = "xyes" -a "x$can_use_mtp" = "xyes"; then @@ -773,6 +792,8 @@ else fi if test x"$use_gudev" = xyes; then AC_MSG_NOTICE([** GUdev support enabled]) +elif test x"$enable_hal" = xyes; then + AC_MSG_NOTICE([** HAL support enabled]) else AC_MSG_NOTICE([ GUdev support disabled]) fi diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am index 5d3bb57c1..28678e5ca 100644 --- a/doc/reference/Makefile.am +++ b/doc/reference/Makefile.am @@ -186,6 +186,7 @@ GTKDOC_LIBS=\ $(top_builddir)/shell/librhythmbox-core.la \ $(BINDING_LIBS) \ $(TOTEM_PLPARSER_LIBS) \ + $(HAL_LIBS) \ $(DBUS_LIBS) \ $(RHYTHMBOX_LIBS) \ $(MORE_GTKDOC_LIBS) diff --git a/lib/libmediaplayerid/Makefile.am b/lib/libmediaplayerid/Makefile.am index 2ccc6f90a..cda6e5fc3 100644 --- a/lib/libmediaplayerid/Makefile.am +++ b/lib/libmediaplayerid/Makefile.am @@ -16,7 +16,8 @@ AM_CPPFLAGS = \ -I$(top_srcdir) \ $(RHYTHMBOX_CFLAGS) -# use the GUdev/media-player-id implementation if possible. +# use the GUdev/media-player-id implementation if possible, +# otherwise HAL. if USE_GUDEV @@ -28,8 +29,20 @@ libmediaplayerid_la_LIBADD = $(GUDEV_LIBS) else +if HAVE_HAL + +libmediaplayerid_la_SOURCES += mpid-hal.c +EXTRA_DIST = mpid-udev.c mpid-dummy.c + +AM_CPPFLAGS += $(HAL_CFLAGS) +libmediaplayerid_la_LIBADD = $(HAL_LIBS) + +else + libmediaplayerid_la_SOURCES += mpid-dummy.c EXTRA_DIST = mpid-udev.c mpid-hal.c +endif # HAVE_HAL + endif # HAVE_GUDEV diff --git a/lib/libmediaplayerid/mpid-device.c b/lib/libmediaplayerid/mpid-device.c index 7caf34d11..d0b8e2a59 100644 --- a/lib/libmediaplayerid/mpid-device.c +++ b/lib/libmediaplayerid/mpid-device.c @@ -30,7 +30,7 @@ * * MPID provides access to device information, such as device and vendor names, * supported formats, and audio folder locations, for USB mass storage media - * player devices. It queries the operating system (udev) and reads + * player devices. It queries the operating system (udev or HAL) and reads * override files from the device filesystem and provides a simple set of * properties. */ diff --git a/lib/libmediaplayerid/mpid-util.c b/lib/libmediaplayerid/mpid-util.c index b5bfd0dd9..5a821d5aa 100644 --- a/lib/libmediaplayerid/mpid-util.c +++ b/lib/libmediaplayerid/mpid-util.c @@ -31,7 +31,7 @@ static gboolean debug_enabled = FALSE; * MPIDError: * @MPID_ERROR_NONE: Indicates no error has occurred * @MPID_ERROR_NO_DEVICE_PATH: Unable to find the device path - * @MPID_ERROR_MECHANISM_FAILED: The device detection mechanism (e.g. udev) failed + * @MPID_ERROR_MECHANISM_FAILED: The device detection mechanism (e.g. udev or HAL) failed * @MPID_ERROR_NOT_MEDIA_PLAYER: The device is not a media player * @MPID_ERROR_DEVICE_INFO_MISSING: The device detection mechanism identified the device * but was unable to locate its device information @@ -61,7 +61,7 @@ mpid_error_get_type (void) /** * MPIDSource: * @MPID_SOURCE_NONE: No device information is available - * @MPID_SOURCE_SYSTEM: Device information provided by the operating system (e.g. udev) + * @MPID_SOURCE_SYSTEM: Device information provided by the operating system (e.g. udev or HAL) * @MPID_SOURCE_OVERRIDE: Device information provided by an override file on the device itself. */ diff --git a/plugins/mtpdevice/Makefile.am b/plugins/mtpdevice/Makefile.am index b860cb696..cac9402c6 100644 --- a/plugins/mtpdevice/Makefile.am +++ b/plugins/mtpdevice/Makefile.am @@ -20,6 +20,7 @@ libmtpdevice_la_LIBTOOLFLAGS = --tag=disable-static libmtpdevice_la_LIBADD = \ $(top_builddir)/shell/librhythmbox-core.la \ $(GUDEV_LIBS) \ + $(HAL_LIBS) \ $(MTP_LIBS) AM_CPPFLAGS = \ @@ -42,6 +43,7 @@ AM_CPPFLAGS = \ -DDATADIR=\""$(datadir)"\" \ $(RHYTHMBOX_CFLAGS) \ $(GUDEV_CFLAGS) \ + $(HAL_CFLAGS) \ $(MTP_CFLAGS) plugin_in_files = mtpdevice.plugin.in diff --git a/plugins/mtpdevice/rb-mtp-plugin.c b/plugins/mtpdevice/rb-mtp-plugin.c index 7e1d7fc82..52ecb083b 100644 --- a/plugins/mtpdevice/rb-mtp-plugin.c +++ b/plugins/mtpdevice/rb-mtp-plugin.c @@ -38,8 +38,15 @@ #include #include +#if defined(HAVE_GUDEV) #define G_UDEV_API_IS_SUBJECT_TO_CHANGE #include +#else +#include +#include +#include +#include +#endif #include "rb-plugin-macros.h" #include "rb-source.h" @@ -70,6 +77,11 @@ typedef struct guint create_device_source_id; GList *mtp_sources; + +#if !defined(HAVE_GUDEV) + LibHalContext *hal_context; + DBusConnection *dbus_connection; +#endif } RBMtpPlugin; typedef struct @@ -82,7 +94,14 @@ G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module); static void rb_mtp_plugin_init (RBMtpPlugin *plugin); +#if defined(HAVE_GUDEV) static RBSource* create_source_device_cb (RBRemovableMediaManager *rmm, GObject *device, RBMtpPlugin *plugin); +#else +static void rb_mtp_plugin_maybe_add_source (RBMtpPlugin *plugin, const char *udi, LIBMTP_raw_device_t *raw_devices, int num); +static void rb_mtp_plugin_device_added (LibHalContext *context, const char *udi); +static void rb_mtp_plugin_device_removed (LibHalContext *context, const char *udi); +static gboolean rb_mtp_plugin_setup_dbus_hal_connection (RBMtpPlugin *plugin); +#endif GType rb_mtp_src_get_type (void); GType rb_mtp_sink_get_type (void); @@ -102,13 +121,19 @@ impl_activate (PeasActivatable *bplugin) RBMtpPlugin *plugin = RB_MTP_PLUGIN (bplugin); RBRemovableMediaManager *rmm; RBShell *shell; +#if defined(HAVE_GUDEV) gboolean rmm_scanned = FALSE; +#else + int num_mtp_devices; + LIBMTP_raw_device_t *mtp_devices; +#endif g_object_get (plugin, "object", &shell, NULL); g_object_get (shell, "removable-media-manager", &rmm, NULL); g_object_unref (shell); /* device detection */ +#if defined(HAVE_GUDEV) plugin->create_device_source_id = g_signal_connect_object (rmm, "create-source-device", @@ -120,6 +145,34 @@ impl_activate (PeasActivatable *bplugin) g_object_get (rmm, "scanned", &rmm_scanned, NULL); if (rmm_scanned) rb_removable_media_manager_scan (rmm); +#else + if (rb_mtp_plugin_setup_dbus_hal_connection (plugin) == FALSE) { + rb_debug ("not scanning for MTP devices because we couldn't get a HAL context"); + g_object_unref (rmm); + return; + } + + rb_profile_start ("scanning for MTP devices"); + LIBMTP_Detect_Raw_Devices (&mtp_devices, &num_mtp_devices); + if (num_mtp_devices > 0) { + int num_hal_devices; + char **hal_devices; + int i; + + rb_debug ("%d MTP devices found", num_mtp_devices); + + hal_devices = libhal_get_all_devices (plugin->hal_context, &num_hal_devices, NULL); + for (i = 0; i < num_hal_devices; i++) { + /* should narrow this down a bit - usb only, for a start */ + rb_mtp_plugin_maybe_add_source (plugin, hal_devices[i], mtp_devices, num_mtp_devices); + } + libhal_free_string_array (hal_devices); + } + if (mtp_devices != NULL) { + free (mtp_devices); + } + rb_profile_end ("scanning for MTP devices"); +#endif g_object_unref (rmm); } @@ -140,13 +193,31 @@ impl_deactivate (PeasActivatable *bplugin) g_list_free (plugin->mtp_sources); plugin->mtp_sources = NULL; +#if defined(HAVE_GUDEV) g_signal_handler_disconnect (rmm, plugin->create_device_source_id); plugin->create_device_source_id = 0; +#else + if (plugin->hal_context != NULL) { + DBusError error; + dbus_error_init (&error); + libhal_ctx_shutdown (plugin->hal_context, &error); + libhal_ctx_free (plugin->hal_context); + dbus_error_free (&error); + + plugin->hal_context = NULL; + } + + if (plugin->dbus_connection != NULL) { + dbus_connection_unref (plugin->dbus_connection); + plugin->dbus_connection = NULL; + } +#endif g_object_unref (rmm); g_object_unref (shell); } +#if defined(HAVE_GUDEV) static void source_deleted_cb (RBMtpSource *source, RBMtpPlugin *plugin) { @@ -239,6 +310,130 @@ create_source_device_cb (RBRemovableMediaManager *rmm, GObject *device_obj, RBMt return NULL; } +#else + +static void +source_deleted_cb (RBMtpSource *source, RBMtpPlugin *plugin) +{ + plugin->mtp_sources = g_list_remove (plugin->mtp_sources, source); +} + +static void +rb_mtp_plugin_maybe_add_source (RBMtpPlugin *plugin, const char *udi, LIBMTP_raw_device_t *raw_devices, int num_raw_devices) +{ + int i; + int device_num = 0; + DBusError error; + + rb_debug ("checking if UDI %s matches an MTP device", udi); + + /* get device number */ + dbus_error_init (&error); + device_num = libhal_device_get_property_int (plugin->hal_context, udi, "usb.linux.device_number", &error); + if (dbus_error_is_set (&error)) { + rb_debug ("unable to get USB device number: %s", error.message); + dbus_error_free (&error); + return; + } + + rb_debug ("USB device number: %d", device_num); + + for (i = 0; i < num_raw_devices; i++) { + rb_debug ("detected MTP device: device number %d (bus location %u)", raw_devices[i].devnum, raw_devices[i].bus_location); + if (raw_devices[i].devnum == device_num) { + RBSource *source; + RBShell *shell; + + rb_debug ("device matched, creating a source"); + g_object_get (plugin, "object", &shell, NULL); + source = RB_SOURCE (rb_mtp_source_new (shell, G_OBJECT (plugin), udi, &raw_devices[i])); + + rb_shell_append_display_page (shell, RB_DISPLAY_PAGE (source), RB_DISPLAY_PAGE_GROUP_DEVICES); + plugin->mtp_sources = g_list_prepend (plugin->mtp_sources, source); + g_signal_connect_object (source, + "deleted", G_CALLBACK (source_deleted_cb), + plugin, 0); + g_object_unref (shell); + } + } +} + +static void +rb_mtp_plugin_device_added (LibHalContext *context, const char *udi) +{ + RBMtpPlugin *plugin = (RBMtpPlugin *) libhal_ctx_get_user_data (context); + LIBMTP_raw_device_t *mtp_devices; + int num_mtp_devices; + + LIBMTP_Detect_Raw_Devices (&mtp_devices, &num_mtp_devices); + if (mtp_devices != NULL) { + rb_mtp_plugin_maybe_add_source (plugin, udi, mtp_devices, num_mtp_devices); + free (mtp_devices); + } +} + +static void +rb_mtp_plugin_device_removed (LibHalContext *context, const char *udi) +{ + RBMtpPlugin *plugin = (RBMtpPlugin *) libhal_ctx_get_user_data (context); + GList *list = plugin->mtp_sources; + GList *tmp; + + for (tmp = list; tmp != NULL; tmp = tmp->next) { + RBSource *source = (RBSource *)tmp->data; + char *source_udi; + + g_object_get (source, "udi", &source_udi, NULL); + if (strcmp (udi, source_udi) == 0) { + rb_debug ("removing device %s, %p", udi, source); + plugin->mtp_sources = g_list_remove (plugin->mtp_sources, source); + rb_display_page_delete_thyself (RB_DISPLAY_PAGE (source)); + } + g_free (source_udi); + } +} + +static gboolean +rb_mtp_plugin_setup_dbus_hal_connection (RBMtpPlugin *plugin) +{ + DBusError error; + + dbus_error_init (&error); + plugin->dbus_connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); + if (plugin->dbus_connection == NULL) { + rb_debug ("error: dbus_bus_get: %s: %s\n", error.name, error.message); + dbus_error_free (&error); + return FALSE; + } + + dbus_connection_setup_with_g_main (plugin->dbus_connection, NULL); + + rb_debug ("connected to: %s", dbus_bus_get_unique_name (plugin->dbus_connection)); + + plugin->hal_context = libhal_ctx_new (); + if (plugin->hal_context == NULL) { + dbus_error_free (&error); + return FALSE; + } + libhal_ctx_set_dbus_connection (plugin->hal_context, plugin->dbus_connection); + + libhal_ctx_set_user_data (plugin->hal_context, (void *)plugin); + libhal_ctx_set_device_added (plugin->hal_context, rb_mtp_plugin_device_added); + libhal_ctx_set_device_removed (plugin->hal_context, rb_mtp_plugin_device_removed); + libhal_device_property_watch_all (plugin->hal_context, &error); + + if (!libhal_ctx_init (plugin->hal_context, &error)) { + rb_debug ("error: libhal_ctx_init: %s: %s\n", error.name, error.message); + dbus_error_free (&error); + return FALSE; + } + + dbus_error_free (&error); + return TRUE; +} + +#endif + G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module) { -- 2.25.0