diff options
22 files changed, 1166 insertions, 1022 deletions
diff --git a/po/POTFILES.in b/po/POTFILES.in index 92030f063..1820be8e8 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -12,6 +12,7 @@ src/libtracker-miner/tracker-data-provider.c src/libtracker-miner/tracker-miner-fs.c src/libtracker-miner/tracker-miner-object.c src/libtracker-miner/tracker-miner-online.c +src/libtracker-miner/tracker-miner-proxy.c src/miners/apps/org.freedesktop.Tracker1.Miner.Applications.service.in.in src/miners/apps/tracker-main.c src/miners/apps/tracker-miner-apps.desktop.in.in diff --git a/src/libtracker-common/tracker-dbus.c b/src/libtracker-common/tracker-dbus.c index e8c43d202..5907d29fa 100644 --- a/src/libtracker-common/tracker-dbus.c +++ b/src/libtracker-common/tracker-dbus.c @@ -497,3 +497,45 @@ tracker_g_dbus_request_begin (GDBusMethodInvocation *invocation, return request; } + +gboolean +tracker_dbus_request_name (GDBusConnection *connection, + const gchar *name, + GError **error) +{ + GError *inner_error = NULL; + GVariant *reply; + gint rval; + + reply = g_dbus_connection_call_sync (connection, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "RequestName", + g_variant_new ("(su)", + name, + 0x4 /* DBUS_NAME_FLAG_DO_NOT_QUEUE */), + G_VARIANT_TYPE ("(u)"), + 0, -1, NULL, &inner_error); + if (inner_error) { + g_propagate_prefixed_error (error, inner_error, + "Could not acquire name:'%s'. ", + name); + return FALSE; + } + + g_variant_get (reply, "(u)", &rval); + g_variant_unref (reply); + + if (rval != 1 /* DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER */) { + g_set_error (error, + G_DBUS_ERROR, + G_DBUS_ERROR_ADDRESS_IN_USE, + "D-Bus service name:'%s' is already taken, " + "perhaps the application is already running?", + name); + return FALSE; + } + + return TRUE; +} diff --git a/src/libtracker-common/tracker-dbus.h b/src/libtracker-common/tracker-dbus.h index 6ea5bb888..bfbff9bb3 100644 --- a/src/libtracker-common/tracker-dbus.h +++ b/src/libtracker-common/tracker-dbus.h @@ -92,6 +92,10 @@ void tracker_dbus_request_debug (TrackerDBusRequest void tracker_dbus_enable_client_lookup (gboolean enable); +gboolean tracker_dbus_request_name (GDBusConnection *connection, + const gchar *name, + GError **error); + /* GDBus convenience API */ TrackerDBusRequest *tracker_g_dbus_request_begin (GDBusMethodInvocation *invocation, const gchar *format, diff --git a/src/libtracker-miner/Makefile.am b/src/libtracker-miner/Makefile.am index 590bc095c..913fdb0d0 100644 --- a/src/libtracker-miner/Makefile.am +++ b/src/libtracker-miner/Makefile.am @@ -70,6 +70,8 @@ miner_sources = \ tracker-miner-object.h \ tracker-miner-online.c \ tracker-miner-online.h \ + tracker-miner-proxy.c \ + tracker-miner-proxy.h \ tracker-miner-fs.c \ tracker-miner-fs.h @@ -90,6 +92,7 @@ libtracker_minerinclude_HEADERS = \ tracker-miner-enum-types.h \ tracker-miner-object.h \ tracker-miner-online.h \ + tracker-miner-proxy.h \ tracker-miner-fs.h libtracker_miner_@TRACKER_API_VERSION@_la_LDFLAGS = \ diff --git a/src/libtracker-miner/meson.build b/src/libtracker-miner/meson.build index 545867771..d178f74bb 100644 --- a/src/libtracker-miner/meson.build +++ b/src/libtracker-miner/meson.build @@ -27,6 +27,7 @@ miner_headers = [ 'tracker-decorator-fs.h', 'tracker-miner-fs.h', 'tracker-miner-object.h', + 'tracker-miner-proxy.h', 'tracker-decorator.h', 'tracker-miner-enums.h', 'tracker-miner.h', @@ -43,6 +44,7 @@ miner_sources = ( 'tracker-indexing-tree.c', 'tracker-miner-object.c', 'tracker-miner-online.c', + 'tracker-miner-proxy.c', 'tracker-miner-fs.c']) libtracker_miner_private = static_library( diff --git a/src/libtracker-miner/tracker-miner-object.c b/src/libtracker-miner/tracker-miner-object.c index b58c83d01..487a331d7 100644 --- a/src/libtracker-miner/tracker-miner-object.c +++ b/src/libtracker-miner/tracker-miner-object.c @@ -37,8 +37,6 @@ */ #define PROGRESS_ROUNDED(x) ((x) < 0.01 ? 0.00 : (ceil (((x) * 100) - 0.49) / 100)) -#define TRACKER_SERVICE "org.freedesktop.Tracker1" - #ifdef MINER_STATUS_ENABLE_TRACE #warning Miner status traces are enabled #define trace(message, ...) g_debug (message, ##__VA_ARGS__) @@ -64,88 +62,22 @@ #define TRACKER_MINER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_MINER, TrackerMinerPrivate)) -/* Introspection data for the service we are exporting */ -static const gchar miner_introspection_xml[] = - "<node>" - " <interface name='org.freedesktop.Tracker1.Miner'>" - " <method name='Start'>" - " </method>" - " <method name='GetStatus'>" - " <arg type='s' name='status' direction='out' />" - " </method>" - " <method name='GetProgress'>" - " <arg type='d' name='progress' direction='out' />" - " </method>" - " <method name='GetRemainingTime'>" - " <arg type='i' name='remaining_time' direction='out' />" - " </method>" - " <method name='GetPauseDetails'>" - " <arg type='as' name='pause_applications' direction='out' />" - " <arg type='as' name='pause_reasons' direction='out' />" - " </method>" - " <method name='Pause'>" - " <arg type='s' name='application' direction='in' />" - " <arg type='s' name='reason' direction='in' />" - " <arg type='i' name='cookie' direction='out' />" - " </method>" - " <method name='PauseForProcess'>" - " <arg type='s' name='application' direction='in' />" - " <arg type='s' name='reason' direction='in' />" - " <arg type='i' name='cookie' direction='out' />" - " </method>" - " <method name='Resume'>" - " <arg type='i' name='cookie' direction='in' />" - " </method>" - " <signal name='Started' />" - " <signal name='Stopped' />" - " <signal name='Paused' />" - " <signal name='Resumed' />" - " <signal name='Progress'>" - " <arg type='s' name='status' />" - " <arg type='d' name='progress' />" - " <arg type='i' name='remaining_time' />" - " </signal>" - " <!-- Additional introspection data given by other miners -->" - " %s" - " </interface>" - "</node>"; - struct _TrackerMinerPrivate { TrackerSparqlConnection *connection; - GHashTable *pauses; gboolean started; - gchar *name; + gint n_pauses; gchar *status; gdouble progress; - gchar *introspection_xml; - GDBusInterfaceVTable *introspection_handler; gint remaining_time; gint availability_cookie; - GDBusConnection *d_connection; - GDBusNodeInfo *introspection_data; - guint watch_name_id; - guint registration_id; - gchar *full_name; - gchar *full_path; guint update_id; }; -typedef struct { - gint cookie; - gchar *application; - gchar *reason; - gchar *watch_name; - guint watch_name_id; -} PauseData; - enum { PROP_0, - PROP_NAME, PROP_STATUS, PROP_PROGRESS, PROP_REMAINING_TIME, - PROP_INTROSPECTION_XML, - PROP_INTROSPECTION_HANDLER }; enum { @@ -172,41 +104,6 @@ static void miner_initable_iface_init (GInitableIface *iface); static gboolean miner_initable_init (GInitable *initable, GCancellable *cancellable, GError **error); -static void pause_data_destroy (gpointer data); -static PauseData *pause_data_new (const gchar *application, - const gchar *reason, - const gchar *watch_name, - guint watch_name_id); -static void handle_method_call (GDBusConnection *connection, - const gchar *sender, - const gchar *object_path, - const gchar *interface_name, - const gchar *method_name, - GVariant *parameters, - GDBusMethodInvocation *invocation, - gpointer user_data); -static GVariant *handle_get_property (GDBusConnection *connection, - const gchar *sender, - const gchar *object_path, - const gchar *interface_name, - const gchar *property_name, - GError **error, - gpointer user_data); -static gboolean handle_set_property (GDBusConnection *connection, - const gchar *sender, - const gchar *object_path, - const gchar *interface_name, - const gchar *property_name, - GVariant *value, - GError **error, - gpointer user_data); -static void on_tracker_store_appeared (GDBusConnection *connection, - const gchar *name, - const gchar *name_owner, - gpointer user_data); -static void on_tracker_store_disappeared (GDBusConnection *connection, - const gchar *name, - gpointer user_data); /** * tracker_miner_error_quark: @@ -336,13 +233,6 @@ tracker_miner_class_init (TrackerMinerClass *klass) G_TYPE_INT); g_object_class_install_property (object_class, - PROP_NAME, - g_param_spec_string ("name", - "Miner name", - "Miner name", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, PROP_STATUS, g_param_spec_string ("status", "Status", @@ -368,19 +258,6 @@ tracker_miner_class_init (TrackerMinerClass *klass) G_MAXINT, -1, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - g_object_class_install_property (object_class, - PROP_INTROSPECTION_XML, - g_param_spec_string ("introspection-xml", - "Introspection XML", - "Introspection XML to *append* to the standard miner interface provided", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - g_object_class_install_property (object_class, - PROP_INTROSPECTION_HANDLER, - g_param_spec_pointer ("introspection-handler", - "Introspection Handler", - "Introspection Method Handler function, expected to be a pointer to GDBusInterfaceVTable", - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); g_type_class_add_private (object_class, sizeof (TrackerMinerPrivate)); } @@ -398,14 +275,6 @@ miner_initable_init (GInitable *initable, { TrackerMiner *miner = TRACKER_MINER (initable); GError *inner_error = NULL; - GVariant *reply; - guint32 rval; - gchar *extra_xml, *full_xml; - GDBusInterfaceVTable interface_vtable = { - handle_method_call, - handle_get_property, - handle_set_property - }; /* Try to get SPARQL connection... */ miner->priv->connection = tracker_sparql_connection_get (NULL, &inner_error); @@ -414,122 +283,13 @@ miner_initable_init (GInitable *initable, return FALSE; } - /* Try to get DBus connection... */ - miner->priv->d_connection = g_bus_get_sync (TRACKER_IPC_BUS, NULL, &inner_error); - if (!miner->priv->d_connection) { - g_propagate_error (error, inner_error); - return FALSE; - } - - /* Setup introspection data */ - g_object_get (initable, "introspection-xml", &extra_xml, NULL); - - full_xml = g_strdup_printf (miner_introspection_xml, extra_xml ? extra_xml : ""); - g_free (extra_xml); - - g_message ("Trying to use introspection XML:\n%s\n", full_xml); - miner->priv->introspection_data = g_dbus_node_info_new_for_xml (full_xml, &inner_error); - g_free (full_xml); - - if (!miner->priv->introspection_data) { - g_propagate_error (error, inner_error); - return FALSE; - } - - /* Check miner has a proper name */ - if (!miner->priv->name) { - g_set_error (error, - tracker_miner_error_quark (), - TRACKER_MINER_ERROR_NAME_MISSING, - "Miner '%s' should have been given a name, bailing out", - G_OBJECT_TYPE_NAME (miner)); - return FALSE; - } - - /* Setup full name */ - miner->priv->full_name = g_strconcat (TRACKER_MINER_DBUS_NAME_PREFIX, - miner->priv->name, - NULL); - - /* Register the D-Bus object */ - miner->priv->full_path = g_strconcat (TRACKER_MINER_DBUS_PATH_PREFIX, - miner->priv->name, - NULL); - - g_message ("Registering D-Bus object..."); - g_message (" Path:'%s'", miner->priv->full_path); - g_message (" Object Type:'%s'", G_OBJECT_TYPE_NAME (miner)); - - miner->priv->registration_id = - g_dbus_connection_register_object (miner->priv->d_connection, - miner->priv->full_path, - miner->priv->introspection_data->interfaces[0], - &interface_vtable, - miner, - NULL, - &inner_error); - if (inner_error) { - g_propagate_error (error, inner_error); - g_prefix_error (error, - "Could not register the D-Bus object '%s'. ", - miner->priv->full_path); - return FALSE; - } - - /* Request the D-Bus name */ - reply = g_dbus_connection_call_sync (miner->priv->d_connection, - "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus", - "RequestName", - g_variant_new ("(su)", - miner->priv->full_name, - 0x4 /* DBUS_NAME_FLAG_DO_NOT_QUEUE */), - G_VARIANT_TYPE ("(u)"), - 0, -1, NULL, &inner_error); - if (inner_error) { - g_propagate_error (error, inner_error); - g_prefix_error (error, - "Could not acquire name:'%s'. ", - miner->priv->full_name); - return FALSE; - } - - g_variant_get (reply, "(u)", &rval); - g_variant_unref (reply); - - if (rval != 1 /* DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER */) { - g_set_error (error, - tracker_miner_error_quark (), - TRACKER_MINER_ERROR_NAME_UNAVAILABLE, - "D-Bus service name:'%s' is already taken, " - "perhaps the application is already running?", - miner->priv->full_name); - return FALSE; - } - - miner->priv->watch_name_id = g_bus_watch_name (TRACKER_IPC_BUS, - TRACKER_SERVICE, - G_BUS_NAME_WATCHER_FLAGS_NONE, - on_tracker_store_appeared, - on_tracker_store_disappeared, - miner, - NULL); - return TRUE; } static void tracker_miner_init (TrackerMiner *miner) { - TrackerMinerPrivate *priv; - - miner->priv = priv = TRACKER_MINER_GET_PRIVATE (miner); - - priv->pauses = g_hash_table_new_full (g_direct_hash, - g_direct_equal, - NULL, - pause_data_destroy); + miner->priv = TRACKER_MINER_GET_PRIVATE (miner); } static gboolean @@ -537,26 +297,13 @@ miner_update_progress_cb (gpointer data) { TrackerMiner *miner = data; - trace ("(Miner:'%s') UPDATE PROGRESS SIGNAL", miner->priv->name); + trace ("(Miner:'%s') UPDATE PROGRESS SIGNAL", G_OBJECT_TYPE_NAME (miner)); g_signal_emit (miner, signals[PROGRESS], 0, miner->priv->status, miner->priv->progress, miner->priv->remaining_time); - if (miner->priv->d_connection) { - g_dbus_connection_emit_signal (miner->priv->d_connection, - NULL, - miner->priv->full_path, - TRACKER_MINER_DBUS_INTERFACE, - "Progress", - g_variant_new ("(sdi)", - miner->priv->status, - miner->priv->progress, - miner->priv->remaining_time), - NULL); - } - miner->priv->update_id = 0; return FALSE; @@ -580,17 +327,13 @@ miner_set_property (GObject *object, */ switch (prop_id) { - case PROP_NAME: - g_free (miner->priv->name); - miner->priv->name = g_value_dup_string (value); - break; case PROP_STATUS: { const gchar *new_status; new_status = g_value_get_string (value); trace ("(Miner:'%s') Set property:'status' to '%s'", - miner->priv->name, + G_OBJECT_TYPE_NAME (miner), new_status); if (miner->priv->status && new_status && @@ -607,12 +350,12 @@ miner_set_property (GObject *object, if (g_ascii_strcasecmp (new_status, "Initializing") == 0 && miner->priv->progress != 0.0) { trace ("(Miner:'%s') Set progress to 0.0 from status:'Initializing'", - miner->priv->name); + G_OBJECT_TYPE_NAME (miner)); miner->priv->progress = 0.0; } else if (g_ascii_strcasecmp (new_status, "Idle") == 0 && miner->priv->progress != 1.0) { trace ("(Miner:'%s') Set progress to 1.0 from status:'Idle'", - miner->priv->name); + G_OBJECT_TYPE_NAME (miner)); miner->priv->progress = 1.0; } } @@ -631,7 +374,7 @@ miner_set_property (GObject *object, new_progress = PROGRESS_ROUNDED (g_value_get_double (value)); trace ("(Miner:'%s') Set property:'progress' to '%2.2f' (%2.2f before rounded)", - miner->priv->name, + G_OBJECT_TYPE_NAME (miner), new_progress, g_value_get_double (value)); @@ -653,7 +396,7 @@ miner_set_property (GObject *object, if (miner->priv->status == NULL || g_ascii_strcasecmp (miner->priv->status, "Initializing") != 0) { trace ("(Miner:'%s') Set status:'Initializing' from progress:0.0", - miner->priv->name); + G_OBJECT_TYPE_NAME (miner)); g_free (miner->priv->status); miner->priv->status = g_strdup ("Initializing"); } @@ -661,7 +404,7 @@ miner_set_property (GObject *object, if (miner->priv->status == NULL || g_ascii_strcasecmp (miner->priv->status, "Idle") != 0) { trace ("(Miner:'%s') Set status:'Idle' from progress:1.0", - miner->priv->name); + G_OBJECT_TYPE_NAME (miner)); g_free (miner->priv->status); miner->priv->status = g_strdup ("Idle"); } @@ -686,16 +429,6 @@ miner_set_property (GObject *object, } break; } - case PROP_INTROSPECTION_XML: { - /* Only set on constructor */ - miner->priv->introspection_xml = g_value_dup_string (value); - break; - } - case PROP_INTROSPECTION_HANDLER: { - /* Only set on constructor */ - miner->priv->introspection_handler = g_value_get_pointer (value); - break; - } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -711,9 +444,6 @@ miner_get_property (GObject *object, TrackerMiner *miner = TRACKER_MINER (object); switch (prop_id) { - case PROP_NAME: - g_value_set_string (value, miner->priv->name); - break; case PROP_STATUS: g_value_set_string (value, miner->priv->status); break; @@ -723,57 +453,12 @@ miner_get_property (GObject *object, case PROP_REMAINING_TIME: g_value_set_int (value, miner->priv->remaining_time); break; - case PROP_INTROSPECTION_XML: - g_value_set_string (value, miner->priv->introspection_xml); - break; - case PROP_INTROSPECTION_HANDLER: - g_value_set_pointer (value, miner->priv->introspection_handler); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } -static PauseData * -pause_data_new (const gchar *application, - const gchar *reason, - const gchar *watch_name, - guint watch_name_id) -{ - PauseData *data; - static gint cookie = 1; - - data = g_slice_new0 (PauseData); - - data->cookie = cookie++; - data->application = g_strdup (application); - data->reason = g_strdup (reason); - data->watch_name = g_strdup (watch_name); - data->watch_name_id = watch_name_id; - - return data; -} - -static void -pause_data_destroy (gpointer data) -{ - PauseData *pd; - - pd = data; - - if (pd->watch_name_id) { - g_bus_unwatch_name (pd->watch_name_id); - } - - g_free (pd->watch_name); - - g_free (pd->reason); - g_free (pd->application); - - g_slice_free (PauseData, pd); -} - /** * tracker_miner_start: * @miner: a #TrackerMiner @@ -789,18 +474,7 @@ tracker_miner_start (TrackerMiner *miner) g_return_if_fail (miner->priv->started == FALSE); miner->priv->started = TRUE; - g_signal_emit (miner, signals[STARTED], 0); - - if (miner->priv->d_connection) { - g_dbus_connection_emit_signal (miner->priv->d_connection, - NULL, - miner->priv->full_path, - TRACKER_MINER_DBUS_INTERFACE, - "Started", - NULL, - NULL); - } } /** @@ -818,18 +492,7 @@ tracker_miner_stop (TrackerMiner *miner) g_return_if_fail (miner->priv->started == TRUE); miner->priv->started = FALSE; - g_signal_emit (miner, signals[STOPPED], 0); - - if (miner->priv->d_connection) { - g_dbus_connection_emit_signal (miner->priv->d_connection, - NULL, - miner->priv->full_path, - TRACKER_MINER_DBUS_INTERFACE, - "Stopped", - NULL, - NULL); - } } /** @@ -865,212 +528,54 @@ tracker_miner_is_paused (TrackerMiner *miner) { g_return_val_if_fail (TRACKER_IS_MINER (miner), TRUE); - return g_hash_table_size (miner->priv->pauses) > 0 ? TRUE : FALSE; -} - -/** - * tracker_miner_get_n_pause_reasons: - * @miner: a #TrackerMiner - * - * Returns the number of pause reasons holding @miner from - * indexing contents. - * - * Returns: The number of current pause reasons - * - * Since: 0.10.5 - **/ -guint -tracker_miner_get_n_pause_reasons (TrackerMiner *miner) -{ - g_return_val_if_fail (TRACKER_IS_MINER (miner), 0); - - return g_hash_table_size (miner->priv->pauses); -} - -static void -pause_process_disappeared_cb (GDBusConnection *connection, - const gchar *name, - gpointer user_data) -{ - TrackerMiner *miner; - PauseData *pd = NULL; - GError *error = NULL; - GHashTableIter iter; - gpointer key, value; - - miner = user_data; - - g_message ("Process with name:'%s' has disappeared", name); - - g_hash_table_iter_init (&iter, miner->priv->pauses); - while (g_hash_table_iter_next (&iter, &key, &value)) { - PauseData *pd_iter = value; - - if (g_strcmp0 (name, pd_iter->watch_name) == 0) { - pd = pd_iter; - break; - } - } - - if (!pd) { - g_critical ("Could not find PauseData for process with name:'%s'", name); - return; - } - - /* Resume */ - g_message ("Resuming pause associated with process"); - - tracker_miner_resume (miner, pd->cookie, &error); - - if (error) { - g_warning ("Could not resume miner, %s", error->message); - g_error_free (error); - } -} - -static gint -miner_pause_internal (TrackerMiner *miner, - const gchar *application, - const gchar *reason, - const gchar *calling_name, - GError **error) -{ - PauseData *pd; - GHashTableIter iter; - gpointer key, value; - guint watch_name_id = 0; - - /* Check this is not a duplicate pause */ - g_hash_table_iter_init (&iter, miner->priv->pauses); - while (g_hash_table_iter_next (&iter, &key, &value)) { - PauseData *pd = value; - - if (g_strcmp0 (application, pd->application) == 0 && - g_strcmp0 (reason, pd->reason) == 0) { - /* Can't use duplicate pauses */ - g_set_error_literal (error, - tracker_miner_error_quark (), - TRACKER_MINER_ERROR_PAUSED_ALREADY, - _("Pause application and reason match an already existing pause request")); - return -1; - } - } - - if (calling_name) { - g_message ("Watching process with name:'%s'", calling_name); - watch_name_id = g_bus_watch_name (TRACKER_IPC_BUS, - calling_name, - G_BUS_NAME_WATCHER_FLAGS_NONE, - NULL, - pause_process_disappeared_cb, - miner, - NULL); - } - - pd = pause_data_new (application, reason, calling_name, watch_name_id); - - g_hash_table_insert (miner->priv->pauses, - GINT_TO_POINTER (pd->cookie), - pd); - - if (g_hash_table_size (miner->priv->pauses) == 1) { - /* Pause */ - g_message ("Miner:'%s' is pausing", miner->priv->name); - g_signal_emit (miner, signals[PAUSED], 0); - - if (miner->priv->d_connection) { - g_dbus_connection_emit_signal (miner->priv->d_connection, - NULL, - miner->priv->full_path, - TRACKER_MINER_DBUS_INTERFACE, - "Paused", - NULL, - NULL); - } - } - - return pd->cookie; + return miner->priv->n_pauses > 0; } /** * tracker_miner_pause: * @miner: a #TrackerMiner - * @reason: reason to pause - * @error: (out callee-allocates) (transfer full) (allow-none): return location for errors - * - * Asks @miner to pause. On success the cookie ID is returned, - * this is what must be used in tracker_miner_resume() to resume - * operations. On failure @error will be set and -1 will be returned. * - * Returns: The pause cookie ID. - * - * Since: 0.8 + * Asks @miner to pause. This call may be called multiple times, + * but #TrackerMiner::paused will only be emitted the first time. + * The same number of tracker_miner_resume() calls are expected + * in order to resume operations. **/ -gint -tracker_miner_pause (TrackerMiner *miner, - const gchar *reason, - GError **error) +void +tracker_miner_pause (TrackerMiner *miner) { - const gchar *application; + gint previous; - g_return_val_if_fail (TRACKER_IS_MINER (miner), -1); - g_return_val_if_fail (reason != NULL, -1); - - application = g_get_application_name (); + g_return_if_fail (TRACKER_IS_MINER (miner)); - if (!application) { - application = miner->priv->name; - } + previous = g_atomic_int_add (&miner->priv->n_pauses, 1); - return miner_pause_internal (miner, application, reason, NULL, error); + if (previous == 0) + g_signal_emit (miner, signals[PAUSED], 0); } /** * tracker_miner_resume: * @miner: a #TrackerMiner - * @cookie: pause cookie - * @error: (out) (transfer full) (allow-none): return location for errors * - * Asks the miner to resume processing. The cookie must be something - * returned by tracker_miner_pause(). The miner won't actually resume - * operations until all pause requests have been resumed. + * Asks the miner to resume processing. This needs to be called + * as many times as tracker_miner_pause() calls were done + * previously. This function will return #TRUE when the miner + * is actually resumed. * - * Returns: #TRUE if the cookie was valid. - * - * Since: 0.8 + * Returns: #TRUE if the miner resumed its operations. **/ gboolean -tracker_miner_resume (TrackerMiner *miner, - gint cookie, - GError **error) +tracker_miner_resume (TrackerMiner *miner) { g_return_val_if_fail (TRACKER_IS_MINER (miner), FALSE); + g_return_val_if_fail (miner->priv->n_pauses > 0, FALSE); - if (!g_hash_table_remove (miner->priv->pauses, GINT_TO_POINTER (cookie))) { - g_set_error_literal (error, - tracker_miner_error_quark (), - TRACKER_MINER_ERROR_INVALID_COOKIE, - _("Cookie not recognized to resume paused miner")); - return FALSE; - } - - if (g_hash_table_size (miner->priv->pauses) == 0) { - /* Resume */ - g_message ("Miner:'%s' is resuming", miner->priv->name); + if (g_atomic_int_dec_and_test (&miner->priv->n_pauses)) { g_signal_emit (miner, signals[RESUMED], 0); - - if (miner->priv->d_connection) { - g_dbus_connection_emit_signal (miner->priv->d_connection, - NULL, - miner->priv->full_path, - TRACKER_MINER_DBUS_INTERFACE, - "Resumed", - NULL, - NULL); - } + return TRUE; } - return TRUE; + return FALSE; } /** @@ -1089,54 +594,6 @@ tracker_miner_get_connection (TrackerMiner *miner) return miner->priv->connection; } -/** - * tracker_miner_get_dbus_connection: - * @miner: a #TrackerMiner - * - * Gets the #GDBusConnection initialized by @miner - * - * Returns: (transfer none): a #GDBusConnection. - * - * Since: 0.10 - **/ -GDBusConnection * -tracker_miner_get_dbus_connection (TrackerMiner *miner) -{ - return miner->priv->d_connection; -} - -/** - * tracker_miner_get_dbus_full_name: - * @miner: a #TrackerMiner - * - * Gets the DBus name registered by @miner - * - * Returns: a constant string which should not be modified by the caller. - * - * Since: 0.10 - **/ -const gchar * -tracker_miner_get_dbus_full_name (TrackerMiner *miner) -{ - return miner->priv->full_name; -} - -/** - * tracker_miner_get_dbus_full_path: - * @miner: a #TrackerMiner - * - * Gets the DBus path registered by @miner - * - * Returns: a constant string which should not be modified by the caller. - * - * Since: 0.10 - **/ -const gchar * -tracker_miner_get_dbus_full_path (TrackerMiner *miner) -{ - return miner->priv->full_path; -} - static void miner_finalize (GObject *object) { @@ -1146,377 +603,11 @@ miner_finalize (GObject *object) g_source_remove (miner->priv->update_id); } - if (miner->priv->watch_name_id != 0) { - g_bus_unwatch_name (miner->priv->watch_name_id); - } - - if (miner->priv->registration_id != 0) { - g_dbus_connection_unregister_object (miner->priv->d_connection, - miner->priv->registration_id); - } - - if (miner->priv->introspection_data) { - g_dbus_node_info_unref (miner->priv->introspection_data); - } - - if (miner->priv->d_connection) { - g_object_unref (miner->priv->d_connection); - } - g_free (miner->priv->status); - g_free (miner->priv->name); - g_free (miner->priv->full_name); - g_free (miner->priv->full_path); if (miner->priv->connection) { g_object_unref (miner->priv->connection); } - if (miner->priv->pauses) { - g_hash_table_unref (miner->priv->pauses); - } - G_OBJECT_CLASS (tracker_miner_parent_class)->finalize (object); } - -static void -handle_method_call_start (TrackerMiner *miner, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - TrackerDBusRequest *request; - - request = tracker_g_dbus_request_begin (invocation, - "%s", - __PRETTY_FUNCTION__); - - tracker_miner_start (miner); - - tracker_dbus_request_end (request, NULL); - g_dbus_method_invocation_return_value (invocation, NULL); -} - -static void -handle_method_call_resume (TrackerMiner *miner, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - GError *local_error = NULL; - gint cookie; - TrackerDBusRequest *request; - - g_variant_get (parameters, "(i)", &cookie); - - request = tracker_g_dbus_request_begin (invocation, - "%s(cookie:%d)", - __PRETTY_FUNCTION__, - cookie); - - if (!tracker_miner_resume (miner, cookie, &local_error)) { - tracker_dbus_request_end (request, local_error); - - g_dbus_method_invocation_return_gerror (invocation, local_error); - - g_error_free (local_error); - return; - } - - tracker_dbus_request_end (request, NULL); - g_dbus_method_invocation_return_value (invocation, NULL); -} - -static void -handle_method_call_pause (TrackerMiner *miner, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - GError *local_error = NULL; - gint cookie; - const gchar *application = NULL, *reason = NULL; - TrackerDBusRequest *request; - - g_variant_get (parameters, "(&s&s)", &application, &reason); - - tracker_gdbus_async_return_if_fail (application != NULL, invocation); - tracker_gdbus_async_return_if_fail (reason != NULL, invocation); - - request = tracker_g_dbus_request_begin (invocation, - "%s(application:'%s', reason:'%s')", - __PRETTY_FUNCTION__, - application, - reason); - - cookie = miner_pause_internal (miner, application, reason, NULL, &local_error); - if (cookie == -1) { - tracker_dbus_request_end (request, local_error); - - g_dbus_method_invocation_return_gerror (invocation, local_error); - - g_error_free (local_error); - - return; - } - - tracker_dbus_request_end (request, NULL); - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(i)", cookie)); -} - -static void -handle_method_call_pause_for_process (TrackerMiner *miner, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - GError *local_error = NULL; - gint cookie; - const gchar *application = NULL, *reason = NULL; - TrackerDBusRequest *request; - - g_variant_get (parameters, "(&s&s)", &application, &reason); - - tracker_gdbus_async_return_if_fail (application != NULL, invocation); - tracker_gdbus_async_return_if_fail (reason != NULL, invocation); - - request = tracker_g_dbus_request_begin (invocation, - "%s(application:'%s', reason:'%s')", - __PRETTY_FUNCTION__, - application, - reason); - - cookie = miner_pause_internal (miner, - application, - reason, - g_dbus_method_invocation_get_sender (invocation), - &local_error); - if (cookie == -1) { - tracker_dbus_request_end (request, local_error); - - g_dbus_method_invocation_return_gerror (invocation, local_error); - - g_error_free (local_error); - - return; - } - - tracker_dbus_request_end (request, NULL); - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(i)", cookie)); -} - -static void -handle_method_call_get_pause_details (TrackerMiner *miner, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - GSList *applications, *reasons; - GStrv applications_strv, reasons_strv; - GHashTableIter iter; - gpointer key, value; - TrackerDBusRequest *request; - - request = tracker_g_dbus_request_begin (invocation, "%s()", __PRETTY_FUNCTION__); - - applications = NULL; - reasons = NULL; - g_hash_table_iter_init (&iter, miner->priv->pauses); - while (g_hash_table_iter_next (&iter, &key, &value)) { - PauseData *pd = value; - - applications = g_slist_prepend (applications, pd->application); - reasons = g_slist_prepend (reasons, pd->reason); - } - applications = g_slist_reverse (applications); - reasons = g_slist_reverse (reasons); - applications_strv = tracker_gslist_to_string_list (applications); - reasons_strv = tracker_gslist_to_string_list (reasons); - - tracker_dbus_request_end (request, NULL); - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(^as^as)", - applications_strv, - reasons_strv)); - - g_strfreev (applications_strv); - g_strfreev (reasons_strv); - g_slist_free (applications); - g_slist_free (reasons); -} - -static void -handle_method_call_get_remaining_time (TrackerMiner *miner, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - TrackerDBusRequest *request; - - request = tracker_g_dbus_request_begin (invocation, "%s()", __PRETTY_FUNCTION__); - - tracker_dbus_request_end (request, NULL); - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(i)", - miner->priv->remaining_time)); -} - -static void -handle_method_call_get_progress (TrackerMiner *miner, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - TrackerDBusRequest *request; - - request = tracker_g_dbus_request_begin (invocation, "%s()", __PRETTY_FUNCTION__); - - tracker_dbus_request_end (request, NULL); - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(d)", - miner->priv->progress)); -} - -static void -handle_method_call_get_status (TrackerMiner *miner, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - TrackerDBusRequest *request; - - request = tracker_g_dbus_request_begin (invocation, "%s()", __PRETTY_FUNCTION__); - - tracker_dbus_request_end (request, NULL); - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(s)", - miner->priv->status ? miner->priv->status : "")); - -} - -static void -handle_method_call (GDBusConnection *connection, - const gchar *sender, - const gchar *object_path, - const gchar *interface_name, - const gchar *method_name, - GVariant *parameters, - GDBusMethodInvocation *invocation, - gpointer user_data) -{ - TrackerMiner *miner = user_data; - - tracker_gdbus_async_return_if_fail (miner != NULL, invocation); - - if (g_strcmp0 (method_name, "Start") == 0) { - handle_method_call_start (miner, invocation, parameters); - } else if (g_strcmp0 (method_name, "Resume") == 0) { - handle_method_call_resume (miner, invocation, parameters); - } else if (g_strcmp0 (method_name, "Pause") == 0) { - handle_method_call_pause (miner, invocation, parameters); - } else if (g_strcmp0 (method_name, "PauseForProcess") == 0) { - handle_method_call_pause_for_process (miner, invocation, parameters); - } else if (g_strcmp0 (method_name, "GetPauseDetails") == 0) { - handle_method_call_get_pause_details (miner, invocation, parameters); - } else if (g_strcmp0 (method_name, "GetRemainingTime") == 0) { - handle_method_call_get_remaining_time (miner, invocation, parameters); - } else if (g_strcmp0 (method_name, "GetProgress") == 0) { - handle_method_call_get_progress (miner, invocation, parameters); - } else if (g_strcmp0 (method_name, "GetStatus") == 0) { - handle_method_call_get_status (miner, invocation, parameters); - } else if (miner->priv->introspection_handler != NULL) { - /* Call introspection-handler functions next */ - GDBusInterfaceMethodCallFunc func = miner->priv->introspection_handler->method_call; - - if (func != NULL) { - (func) (connection, - sender, - object_path, - interface_name, - method_name, - parameters, - invocation, - user_data); - return; - } - } else { - /* No one to handle this function? */ - g_assert_not_reached (); - } -} - -static GVariant * -handle_get_property (GDBusConnection *connection, - const gchar *sender, - const gchar *object_path, - const gchar *interface_name, - const gchar *property_name, - GError **error, - gpointer user_data) -{ - g_assert_not_reached (); - return NULL; -} - -static gboolean -handle_set_property (GDBusConnection *connection, - const gchar *sender, - const gchar *object_path, - const gchar *interface_name, - const gchar *property_name, - GVariant *value, - GError **error, - gpointer user_data) -{ - g_assert_not_reached (); - return TRUE; -} - -static void -on_tracker_store_appeared (GDBusConnection *connection, - const gchar *name, - const gchar *name_owner, - gpointer user_data) - -{ - TrackerMiner *miner = user_data; - - g_debug ("Miner:'%s' noticed store availability has changed to AVAILABLE", - miner->priv->name); - - if (miner->priv->availability_cookie != 0) { - GError *error = NULL; - - tracker_miner_resume (miner, - miner->priv->availability_cookie, - &error); - - if (error) { - g_warning ("Error happened resuming miner, %s", error->message); - g_error_free (error); - } - - miner->priv->availability_cookie = 0; - } -} - -static void -on_tracker_store_disappeared (GDBusConnection *connection, - const gchar *name, - gpointer user_data) -{ - TrackerMiner *miner = user_data; - - g_debug ("Miner:'%s' noticed store availability has changed to UNAVAILABLE", - miner->priv->name); - - if (miner->priv->availability_cookie == 0) { - GError *error = NULL; - gint cookie_id; - - cookie_id = tracker_miner_pause (miner, - _("Data store is not available"), - &error); - - if (error) { - g_warning ("Could not pause, %s", error->message); - g_error_free (error); - } else { - miner->priv->availability_cookie = cookie_id; - } - } -} diff --git a/src/libtracker-miner/tracker-miner-object.h b/src/libtracker-miner/tracker-miner-object.h index cba66cce8..180ac83a5 100644 --- a/src/libtracker-miner/tracker-miner-object.h +++ b/src/libtracker-miner/tracker-miner-object.h @@ -175,19 +175,10 @@ void tracker_miner_stop (TrackerMiner gboolean tracker_miner_is_started (TrackerMiner *miner); gboolean tracker_miner_is_paused (TrackerMiner *miner); -guint tracker_miner_get_n_pause_reasons (TrackerMiner *miner); - -gint tracker_miner_pause (TrackerMiner *miner, - const gchar *reason, - GError **error); -gboolean tracker_miner_resume (TrackerMiner *miner, - gint cookie, - GError **error); +void tracker_miner_pause (TrackerMiner *miner); +gboolean tracker_miner_resume (TrackerMiner *miner); TrackerSparqlConnection *tracker_miner_get_connection (TrackerMiner *miner); -GDBusConnection *tracker_miner_get_dbus_connection (TrackerMiner *miner); -const gchar *tracker_miner_get_dbus_full_name (TrackerMiner *miner); -const gchar *tracker_miner_get_dbus_full_path (TrackerMiner *miner); G_END_DECLS diff --git a/src/libtracker-miner/tracker-miner-online.c b/src/libtracker-miner/tracker-miner-online.c index 32dfd9f13..b1f1a6ef1 100644 --- a/src/libtracker-miner/tracker-miner-online.c +++ b/src/libtracker-miner/tracker-miner-online.c @@ -68,7 +68,7 @@ struct _TrackerMinerOnlinePrivate { NMClient *client; #endif TrackerNetworkType network_type; - gint pause_id; + gboolean paused; }; enum { @@ -329,19 +329,12 @@ _tracker_miner_online_set_network_type (TrackerMinerOnline *miner, g_signal_emit (miner, signals[DISCONNECTED], 0); } - if (cont && priv->pause_id) - tracker_miner_resume (TRACKER_MINER (miner), - priv->pause_id, &error); - else if (!cont && !priv->pause_id) { - const gchar *msg; - - msg = (type == TRACKER_NETWORK_TYPE_NONE) ? - _("No network connection") : - _("Indexing not recommended on this network connection"); - - priv->pause_id = - tracker_miner_pause (TRACKER_MINER (miner), - msg, &error); + if (cont && priv->paused) { + tracker_miner_resume (TRACKER_MINER (miner)); + priv->paused = FALSE; + } else if (!cont && !priv->paused) { + tracker_miner_pause (TRACKER_MINER (miner)); + priv->paused = TRUE; } if (error) { diff --git a/src/libtracker-miner/tracker-miner-proxy.c b/src/libtracker-miner/tracker-miner-proxy.c new file mode 100644 index 000000000..29afa4f2c --- /dev/null +++ b/src/libtracker-miner/tracker-miner-proxy.c @@ -0,0 +1,841 @@ +/* + * Copyright (C) 2017, Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * Authors: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include <glib/gi18n.h> +#include <libtracker-common/tracker-dbus.h> +#include <libtracker-common/tracker-type-utils.h> + +#include "tracker-miner-proxy.h" + +typedef struct { + TrackerMiner *miner; + GDBusConnection *d_connection; + GDBusNodeInfo *introspection_data; + gchar *dbus_path; + guint registration_id; + guint watch_name_id; + GHashTable *pauses; + gint availability_cookie; +} TrackerMinerProxyPrivate; + +typedef struct { + gint cookie; + gchar *application; + gchar *reason; + gchar *watch_name; + guint watch_name_id; +} PauseData; + +enum { + PROP_0, + PROP_MINER, + PROP_DBUS_CONNECTION, + PROP_DBUS_PATH, +}; + +static void tracker_miner_proxy_initable_iface_init (GInitableIface *iface); + +G_DEFINE_TYPE_WITH_CODE (TrackerMinerProxy, tracker_miner_proxy, G_TYPE_OBJECT, + G_ADD_PRIVATE (TrackerMinerProxy) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, tracker_miner_proxy_initable_iface_init)) + +static const gchar introspection_xml[] = + "<node>" + " <interface name='org.freedesktop.Tracker1.Miner'>" + " <method name='Start'>" + " </method>" + " <method name='GetStatus'>" + " <arg type='s' name='status' direction='out' />" + " </method>" + " <method name='GetProgress'>" + " <arg type='d' name='progress' direction='out' />" + " </method>" + " <method name='GetRemainingTime'>" + " <arg type='i' name='remaining_time' direction='out' />" + " </method>" + " <method name='GetPauseDetails'>" + " <arg type='as' name='pause_applications' direction='out' />" + " <arg type='as' name='pause_reasons' direction='out' />" + " </method>" + " <method name='Pause'>" + " <arg type='s' name='application' direction='in' />" + " <arg type='s' name='reason' direction='in' />" + " <arg type='i' name='cookie' direction='out' />" + " </method>" + " <method name='PauseForProcess'>" + " <arg type='s' name='application' direction='in' />" + " <arg type='s' name='reason' direction='in' />" + " <arg type='i' name='cookie' direction='out' />" + " </method>" + " <method name='Resume'>" + " <arg type='i' name='cookie' direction='in' />" + " </method>" + " <signal name='Started' />" + " <signal name='Stopped' />" + " <signal name='Paused' />" + " <signal name='Resumed' />" + " <signal name='Progress'>" + " <arg type='s' name='status' />" + " <arg type='d' name='progress' />" + " <arg type='i' name='remaining_time' />" + " </signal>" + " </interface>" + "</node>"; + +#define TRACKER_SERVICE "org.freedesktop.Tracker1" + +static PauseData * +pause_data_new (const gchar *application, + const gchar *reason, + const gchar *watch_name, + guint watch_name_id) +{ + PauseData *data; + static gint cookie = 1; + + data = g_slice_new0 (PauseData); + + data->cookie = cookie++; + data->application = g_strdup (application); + data->reason = g_strdup (reason); + data->watch_name = g_strdup (watch_name); + data->watch_name_id = watch_name_id; + + return data; +} + +static void +pause_data_destroy (gpointer data) +{ + PauseData *pd; + + pd = data; + + if (pd->watch_name_id) { + g_bus_unwatch_name (pd->watch_name_id); + } + + g_free (pd->watch_name); + + g_free (pd->reason); + g_free (pd->application); + + g_slice_free (PauseData, pd); +} + +static void +tracker_miner_proxy_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + TrackerMinerProxy *proxy = TRACKER_MINER_PROXY (object); + TrackerMinerProxyPrivate *priv = tracker_miner_proxy_get_instance_private (proxy); + + switch (prop_id) { + case PROP_MINER: + priv->miner = g_value_dup_object (value); + break; + case PROP_DBUS_CONNECTION: + priv->d_connection = g_value_dup_object (value); + break; + case PROP_DBUS_PATH: + priv->dbus_path = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +tracker_miner_proxy_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + TrackerMinerProxy *proxy = TRACKER_MINER_PROXY (object); + TrackerMinerProxyPrivate *priv = tracker_miner_proxy_get_instance_private (proxy); + + switch (prop_id) { + case PROP_MINER: + g_value_set_object (value, priv->miner); + break; + case PROP_DBUS_CONNECTION: + g_value_set_object (value, priv->d_connection); + break; + case PROP_DBUS_PATH: + g_value_set_string (value, priv->dbus_path); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +tracker_miner_proxy_finalize (GObject *object) +{ + TrackerMinerProxy *proxy = TRACKER_MINER_PROXY (object); + TrackerMinerProxyPrivate *priv = tracker_miner_proxy_get_instance_private (proxy); + + g_signal_handlers_disconnect_by_data (priv->miner, proxy); + g_clear_object (&priv->miner); + g_free (priv->dbus_path); + g_hash_table_unref (priv->pauses); + + if (priv->watch_name_id != 0) { + g_bus_unwatch_name (priv->watch_name_id); + } + + if (priv->registration_id != 0) { + g_dbus_connection_unregister_object (priv->d_connection, + priv->registration_id); + } + + if (priv->introspection_data) { + g_dbus_node_info_unref (priv->introspection_data); + } + + if (priv->d_connection) { + g_object_unref (priv->d_connection); + } + + G_OBJECT_CLASS (tracker_miner_proxy_parent_class)->finalize (object); +} + +static void +tracker_miner_proxy_class_init (TrackerMinerProxyClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = tracker_miner_proxy_set_property; + object_class->get_property = tracker_miner_proxy_get_property; + object_class->finalize = tracker_miner_proxy_finalize; + + g_object_class_install_property (object_class, + PROP_MINER, + g_param_spec_object ("miner", + "Miner to manage", + "Miner to manage", + TRACKER_TYPE_MINER, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, + PROP_DBUS_CONNECTION, + g_param_spec_object ("dbus-connection", + "DBus connection", + "DBus connection", + G_TYPE_DBUS_CONNECTION, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, + PROP_DBUS_PATH, + g_param_spec_string ("dbus-path", + "DBus path", + "DBus path for this miner", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); +} + +static void +tracker_miner_proxy_init (TrackerMinerProxy *proxy) +{ + TrackerMinerProxyPrivate *priv = tracker_miner_proxy_get_instance_private (proxy); + + priv->pauses = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + pause_data_destroy); +} + +static void +handle_method_call_start (TrackerMinerProxy *proxy, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + TrackerDBusRequest *request; + TrackerMinerProxyPrivate *priv; + + priv = tracker_miner_proxy_get_instance_private (proxy); + + request = tracker_g_dbus_request_begin (invocation, + "%s", + __PRETTY_FUNCTION__); + + tracker_miner_start (priv->miner); + + tracker_dbus_request_end (request, NULL); + g_dbus_method_invocation_return_value (invocation, NULL); +} + +static void +sync_miner_pause_state (TrackerMinerProxy *proxy) +{ + TrackerMinerProxyPrivate *priv; + guint n_pauses; + gboolean is_paused; + + priv = tracker_miner_proxy_get_instance_private (proxy); + n_pauses = g_hash_table_size (priv->pauses); + is_paused = tracker_miner_is_paused (priv->miner); + + if (!is_paused && n_pauses > 0) { + tracker_miner_pause (priv->miner); + } else if (is_paused && n_pauses == 0) { + tracker_miner_resume (priv->miner); + } +} + +static void +handle_method_call_resume (TrackerMinerProxy *proxy, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + gint cookie; + TrackerDBusRequest *request; + TrackerMinerProxyPrivate *priv; + + priv = tracker_miner_proxy_get_instance_private (proxy); + + g_variant_get (parameters, "(i)", &cookie); + + request = tracker_g_dbus_request_begin (invocation, + "%s(cookie:%d)", + __PRETTY_FUNCTION__, + cookie); + + if (!g_hash_table_remove (priv->pauses, GINT_TO_POINTER (cookie))) { + tracker_dbus_request_end (request, NULL); + g_dbus_method_invocation_return_error (invocation, + tracker_miner_error_quark (), + TRACKER_MINER_ERROR_INVALID_COOKIE, + _("Cookie not recognized to resume paused miner")); + } else { + sync_miner_pause_state (proxy); + tracker_dbus_request_end (request, NULL); + g_dbus_method_invocation_return_value (invocation, NULL); + } +} + +static void +pause_process_disappeared_cb (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + TrackerMinerProxy *proxy = user_data; + TrackerMinerProxyPrivate *priv = tracker_miner_proxy_get_instance_private (proxy); + GHashTableIter iter; + gpointer key, value; + + g_message ("Process with name:'%s' has disappeared", name); + + g_hash_table_iter_init (&iter, priv->pauses); + while (g_hash_table_iter_next (&iter, &key, &value)) { + PauseData *pd_iter = value; + + if (g_strcmp0 (name, pd_iter->watch_name) == 0) + g_hash_table_iter_remove (&iter); + } + + sync_miner_pause_state (proxy); +} + +static gint +pause_miner (TrackerMinerProxy *proxy, + const gchar *application, + const gchar *reason, + const gchar *calling_name, + GError **error) +{ + TrackerMinerProxyPrivate *priv; + PauseData *pd; + GHashTableIter iter; + gpointer key, value; + guint watch_name_id = 0; + + priv = tracker_miner_proxy_get_instance_private (proxy); + + /* Check this is not a duplicate pause */ + g_hash_table_iter_init (&iter, priv->pauses); + while (g_hash_table_iter_next (&iter, &key, &value)) { + PauseData *pd = value; + + if (g_strcmp0 (application, pd->application) == 0 && + g_strcmp0 (reason, pd->reason) == 0) { + /* Can't use duplicate pauses */ + g_set_error_literal (error, + tracker_miner_error_quark (), + TRACKER_MINER_ERROR_PAUSED_ALREADY, + _("Pause application and reason match an already existing pause request")); + return -1; + } + } + + if (calling_name) { + g_message ("Watching process with name:'%s'", calling_name); + watch_name_id = g_bus_watch_name (TRACKER_IPC_BUS, + calling_name, + G_BUS_NAME_WATCHER_FLAGS_NONE, + NULL, + pause_process_disappeared_cb, + proxy, + NULL); + } + + pd = pause_data_new (application, reason, calling_name, watch_name_id); + + g_hash_table_insert (priv->pauses, + GINT_TO_POINTER (pd->cookie), + pd); + + sync_miner_pause_state (proxy); + + return pd->cookie; +} + +static void +handle_method_call_pause (TrackerMinerProxy *proxy, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + GError *local_error = NULL; + gint cookie; + const gchar *application = NULL, *reason = NULL; + TrackerDBusRequest *request; + + g_variant_get (parameters, "(&s&s)", &application, &reason); + + tracker_gdbus_async_return_if_fail (application != NULL, invocation); + tracker_gdbus_async_return_if_fail (reason != NULL, invocation); + + request = tracker_g_dbus_request_begin (invocation, + "%s(application:'%s', reason:'%s')", + __PRETTY_FUNCTION__, + application, + reason); + + cookie = pause_miner (proxy, application, reason, NULL, &local_error); + if (cookie == -1) { + tracker_dbus_request_end (request, local_error); + + g_dbus_method_invocation_return_gerror (invocation, local_error); + + g_error_free (local_error); + + return; + } + + tracker_dbus_request_end (request, NULL); + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(i)", cookie)); +} + +static void +handle_method_call_pause_for_process (TrackerMinerProxy *proxy, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + GError *local_error = NULL; + gint cookie; + const gchar *application = NULL, *reason = NULL; + TrackerDBusRequest *request; + + g_variant_get (parameters, "(&s&s)", &application, &reason); + + tracker_gdbus_async_return_if_fail (application != NULL, invocation); + tracker_gdbus_async_return_if_fail (reason != NULL, invocation); + + request = tracker_g_dbus_request_begin (invocation, + "%s(application:'%s', reason:'%s')", + __PRETTY_FUNCTION__, + application, + reason); + + cookie = pause_miner (proxy, + application, + reason, + g_dbus_method_invocation_get_sender (invocation), + &local_error); + if (cookie == -1) { + tracker_dbus_request_end (request, local_error); + + g_dbus_method_invocation_return_gerror (invocation, local_error); + + g_error_free (local_error); + + return; + } + + tracker_dbus_request_end (request, NULL); + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(i)", cookie)); +} + +static void +handle_method_call_get_pause_details (TrackerMinerProxy *proxy, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + GSList *applications, *reasons; + GStrv applications_strv, reasons_strv; + GHashTableIter iter; + gpointer key, value; + TrackerDBusRequest *request; + TrackerMinerProxyPrivate *priv; + + priv = tracker_miner_proxy_get_instance_private (proxy); + request = tracker_g_dbus_request_begin (invocation, "%s()", __PRETTY_FUNCTION__); + + applications = NULL; + reasons = NULL; + g_hash_table_iter_init (&iter, priv->pauses); + while (g_hash_table_iter_next (&iter, &key, &value)) { + PauseData *pd = value; + + applications = g_slist_prepend (applications, pd->application); + reasons = g_slist_prepend (reasons, pd->reason); + } + applications = g_slist_reverse (applications); + reasons = g_slist_reverse (reasons); + applications_strv = tracker_gslist_to_string_list (applications); + reasons_strv = tracker_gslist_to_string_list (reasons); + + tracker_dbus_request_end (request, NULL); + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(^as^as)", + applications_strv, + reasons_strv)); + + g_strfreev (applications_strv); + g_strfreev (reasons_strv); + g_slist_free (applications); + g_slist_free (reasons); +} + +static void +handle_method_call_get_remaining_time (TrackerMinerProxy *proxy, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + TrackerDBusRequest *request; + TrackerMinerProxyPrivate *priv; + gint remaining_time; + + priv = tracker_miner_proxy_get_instance_private (proxy); + + request = tracker_g_dbus_request_begin (invocation, "%s()", __PRETTY_FUNCTION__); + + tracker_dbus_request_end (request, NULL); + g_object_get (G_OBJECT (priv->miner), "remaining-time", &remaining_time, NULL); + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(i)", remaining_time)); +} + +static void +handle_method_call_get_progress (TrackerMinerProxy *proxy, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + TrackerDBusRequest *request; + TrackerMinerProxyPrivate *priv; + gdouble progress; + + priv = tracker_miner_proxy_get_instance_private (proxy); + + request = tracker_g_dbus_request_begin (invocation, "%s()", __PRETTY_FUNCTION__); + + tracker_dbus_request_end (request, NULL); + g_object_get (G_OBJECT (priv->miner), "progress", &progress, NULL); + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(d)", progress)); +} + +static void +handle_method_call_get_status (TrackerMinerProxy *proxy, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + TrackerDBusRequest *request; + TrackerMinerProxyPrivate *priv; + gchar *status; + + priv = tracker_miner_proxy_get_instance_private (proxy); + + request = tracker_g_dbus_request_begin (invocation, "%s()", __PRETTY_FUNCTION__); + + tracker_dbus_request_end (request, NULL); + g_object_get (G_OBJECT (priv->miner), "status", &status, NULL); + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(s)", + status ? status : "")); + g_free (status); +} + +static void +handle_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + TrackerMinerProxy *proxy = user_data; + + if (g_strcmp0 (method_name, "Start") == 0) { + handle_method_call_start (proxy, invocation, parameters); + } else if (g_strcmp0 (method_name, "Resume") == 0) { + handle_method_call_resume (proxy, invocation, parameters); + } else if (g_strcmp0 (method_name, "Pause") == 0) { + handle_method_call_pause (proxy, invocation, parameters); + } else if (g_strcmp0 (method_name, "PauseForProcess") == 0) { + handle_method_call_pause_for_process (proxy, invocation, parameters); + } else if (g_strcmp0 (method_name, "GetPauseDetails") == 0) { + handle_method_call_get_pause_details (proxy, invocation, parameters); + } else if (g_strcmp0 (method_name, "GetRemainingTime") == 0) { + handle_method_call_get_remaining_time (proxy, invocation, parameters); + } else if (g_strcmp0 (method_name, "GetProgress") == 0) { + handle_method_call_get_progress (proxy, invocation, parameters); + } else if (g_strcmp0 (method_name, "GetStatus") == 0) { + handle_method_call_get_status (proxy, invocation, parameters); + } else { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_UNKNOWN_METHOD, + "Unknown method %s", + method_name); + } +} + +static GVariant * +handle_get_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GError **error, + gpointer user_data) +{ + return NULL; +} + +static gboolean +handle_set_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GVariant *value, + GError **error, + gpointer user_data) +{ + return FALSE; +} + +static void +emit_dbus_signal (TrackerMinerProxy *proxy, + const gchar *signal, + GVariant *variant) +{ + TrackerMinerProxyPrivate *priv; + + priv = tracker_miner_proxy_get_instance_private (proxy); + g_dbus_connection_emit_signal (priv->d_connection, + NULL, + priv->dbus_path, + TRACKER_MINER_DBUS_INTERFACE, + signal, + variant, + NULL); +} + +static void +miner_started_cb (TrackerMiner *miner, + TrackerMinerProxy *proxy) +{ + emit_dbus_signal (proxy, "Started", NULL); +} + +static void +miner_stopped_cb (TrackerMiner *miner, + TrackerMinerProxy *proxy) +{ + emit_dbus_signal (proxy, "Stopped", NULL); +} + +static void +miner_paused_cb (TrackerMiner *miner, + TrackerMinerProxy *proxy) +{ + emit_dbus_signal (proxy, "Paused", NULL); +} + +static void +miner_resumed_cb (TrackerMiner *miner, + TrackerMinerProxy *proxy) +{ + emit_dbus_signal (proxy, "Resumed", NULL); +} + +static void +miner_progress_cb (TrackerMiner *miner, + const gchar *status, + gdouble progress, + gint remaining_time, + TrackerMinerProxy *proxy) +{ + GVariant *variant; + + variant = g_variant_new ("(sdi)", status, progress, remaining_time); + /* variant reference is sunk here */ + emit_dbus_signal (proxy, "Progress", variant); +} + +static void +on_tracker_store_appeared (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) + +{ + TrackerMinerProxy *proxy = user_data; + TrackerMinerProxyPrivate *priv = tracker_miner_proxy_get_instance_private (proxy); + + g_debug ("Miner:'%s' noticed store availability has changed to AVAILABLE", + priv->dbus_path); + + if (priv->availability_cookie != 0) { + g_hash_table_remove (priv->pauses, + GINT_TO_POINTER (priv->availability_cookie)); + sync_miner_pause_state (proxy); + priv->availability_cookie = 0; + } +} + +static void +on_tracker_store_disappeared (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + TrackerMinerProxy *proxy = user_data; + TrackerMinerProxyPrivate *priv = tracker_miner_proxy_get_instance_private (proxy); + + g_debug ("Miner:'%s' noticed store availability has changed to UNAVAILABLE", + priv->dbus_path); + + if (priv->availability_cookie == 0) { + GError *error = NULL; + gint cookie_id; + + cookie_id = pause_miner (proxy, NULL, + _("Data store is not available"), + NULL, &error); + + if (error) { + g_warning ("Could not pause, %s", error->message); + g_error_free (error); + } else { + priv->availability_cookie = cookie_id; + } + } +} + +static gboolean +tracker_miner_proxy_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + TrackerMinerProxy *proxy = TRACKER_MINER_PROXY (initable); + TrackerMinerProxyPrivate *priv = tracker_miner_proxy_get_instance_private (proxy); + GError *inner_error = NULL; + GDBusInterfaceVTable interface_vtable = { + handle_method_call, + handle_get_property, + handle_set_property + }; + + priv->introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, + &inner_error); + if (inner_error) { + g_propagate_error (error, inner_error); + return FALSE; + } + + priv->registration_id = + g_dbus_connection_register_object (priv->d_connection, + priv->dbus_path, + priv->introspection_data->interfaces[0], + &interface_vtable, + proxy, + NULL, + &inner_error); + if (inner_error) { + g_propagate_error (error, inner_error); + return FALSE; + } + + priv->watch_name_id = + g_bus_watch_name_on_connection (priv->d_connection, + TRACKER_SERVICE, + G_BUS_NAME_WATCHER_FLAGS_NONE, + on_tracker_store_appeared, + on_tracker_store_disappeared, + proxy, + NULL); + + g_signal_connect (priv->miner, "started", + G_CALLBACK (miner_started_cb), proxy); + g_signal_connect (priv->miner, "stopped", + G_CALLBACK (miner_stopped_cb), proxy); + g_signal_connect (priv->miner, "paused", + G_CALLBACK (miner_paused_cb), proxy); + g_signal_connect (priv->miner, "resumed", + G_CALLBACK (miner_resumed_cb), proxy); + g_signal_connect (priv->miner, "progress", + G_CALLBACK (miner_progress_cb), proxy); + return TRUE; +} + +static void +tracker_miner_proxy_initable_iface_init (GInitableIface *iface) +{ + iface->init = tracker_miner_proxy_initable_init; +} + +TrackerMinerProxy * +tracker_miner_proxy_new (TrackerMiner *miner, + GDBusConnection *connection, + const gchar *dbus_path, + GCancellable *cancellable, + GError **error) +{ + return g_initable_new (TRACKER_TYPE_MINER_PROXY, + cancellable, error, + "miner", miner, + "dbus-connection", connection, + "dbus-path", dbus_path, + NULL); +} diff --git a/src/libtracker-miner/tracker-miner-proxy.h b/src/libtracker-miner/tracker-miner-proxy.h new file mode 100644 index 000000000..a41c39139 --- /dev/null +++ b/src/libtracker-miner/tracker-miner-proxy.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2017, Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * Authors: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef __TRACKER_MINER_PROXY_H__ +#define __TRACKER_MINER_PROXY_H__ + +#if !defined (__LIBTRACKER_MINER_H_INSIDE__) && !defined (TRACKER_COMPILATION) +#error "Only <libtracker-miner/tracker-miner.h> can be included directly." +#endif + +#include <glib-object.h> +#include <gio/gio.h> +#include "tracker-miner-object.h" + +#define TRACKER_TYPE_MINER_PROXY (tracker_miner_proxy_get_type()) +#define TRACKER_MINER_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_MINER_PROXY, TrackerMinerProxy)) +#define TRACKER_MINER_PROXY_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_MINER_PROXY, TrackerMinerProxyClass)) +#define TRACKER_IS_MINER_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_MINER_PROXY)) +#define TRACKER_IS_MINER_PROXY_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TRACKER_TYPE_MINER_PROXY)) +#define TRACKER_MINER_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_MINER_PROXY, TrackerMinerProxyClass)) + +typedef struct _TrackerMinerProxy TrackerMinerProxy; +typedef struct _TrackerMinerProxyClass TrackerMinerProxyClass; + +struct _TrackerMinerProxy { + GObject parent_instance; +}; + +struct _TrackerMinerProxyClass { + GObjectClass parent_class; + /*<private>*/ + gpointer padding[10]; +}; + +GType tracker_miner_proxy_get_type (void) G_GNUC_CONST; + +TrackerMinerProxy * tracker_miner_proxy_new (TrackerMiner *miner, + GDBusConnection *connection, + const gchar *dbus_path, + GCancellable *cancellable, + GError **error); + +#endif /* __TRACKER_MINER_PROXY_H__ */ diff --git a/src/libtracker-miner/tracker-miner.h b/src/libtracker-miner/tracker-miner.h index be46174d2..3665e33dd 100644 --- a/src/libtracker-miner/tracker-miner.h +++ b/src/libtracker-miner/tracker-miner.h @@ -32,6 +32,7 @@ #include <libtracker-miner/tracker-miner-enums.h> #include <libtracker-miner/tracker-miner-enum-types.h> #include <libtracker-miner/tracker-indexing-tree.h> +#include <libtracker-miner/tracker-miner-proxy.h> #undef __LIBTRACKER_MINER_H_INSIDE__ diff --git a/src/libtracker-miner/tracker-miner.vapi b/src/libtracker-miner/tracker-miner.vapi index a92b88f03..d6d517fea 100644 --- a/src/libtracker-miner/tracker-miner.vapi +++ b/src/libtracker-miner/tracker-miner.vapi @@ -77,21 +77,13 @@ namespace Tracker { protected Miner (); public static GLib.Quark error_quark (); public Tracker.Sparql.Connection get_connection (); - public unowned GLib.DBusConnection get_dbus_connection (); - public unowned string get_dbus_full_name (); - public unowned string get_dbus_full_path (); - public uint get_n_pause_reasons (); public bool is_paused (); public bool is_started (); - public int pause (string reason) throws GLib.Error; - public bool resume (int cookie) throws GLib.Error; + public void pause (); + public bool resume (); public void start (); public void stop (); [NoAccessorMethod] - public void* introspection_handler { get; set construct; } - [NoAccessorMethod] - public string introspection_xml { owned get; set construct; } - [NoAccessorMethod] public string name { owned get; construct; } [NoAccessorMethod] public virtual double progress { get; set construct; } diff --git a/src/miners/apps/tracker-main.c b/src/miners/apps/tracker-main.c index 5bd944ae0..8f6693b44 100644 --- a/src/miners/apps/tracker-main.c +++ b/src/miners/apps/tracker-main.c @@ -44,6 +44,9 @@ "\n" \ " http://www.gnu.org/licenses/gpl.txt\n" +#define DBUS_NAME "org.freedesktop.Tracker1.Miner.Applications" +#define DBUS_PATH "/org/freedesktop/Tracker1/Miner/Applications" + static GMainLoop *main_loop; static gint verbosity = -1; @@ -166,6 +169,8 @@ main (gint argc, gchar *argv[]) GOptionContext *context; GError *error = NULL; gchar *log_filename = NULL; + GDBusConnection *connection; + TrackerMinerProxy *proxy; main_loop = NULL; @@ -198,6 +203,21 @@ main (gint argc, gchar *argv[]) return EXIT_SUCCESS; } + connection = g_bus_get_sync (TRACKER_IPC_BUS, NULL, &error); + if (error) { + g_critical ("Could not create DBus connection: %s\n", + error->message); + g_error_free (error); + return EXIT_FAILURE; + } + + if (!tracker_dbus_request_name (connection, DBUS_NAME, &error)) { + g_critical ("Could not request DBus name '%s': %s", + DBUS_NAME, error->message); + g_error_free (error); + return EXIT_FAILURE; + } + tracker_log_init (verbosity, &log_filename); if (log_filename) { g_message ("Using log file:'%s'", log_filename); @@ -223,6 +243,14 @@ main (gint argc, gchar *argv[]) return EXIT_FAILURE; } + proxy = tracker_miner_proxy_new (miner_applications, connection, DBUS_PATH, NULL, &error); + if (!proxy) { + g_critical ("Couldn't create miner DBus proxy: %s", error->message); + g_error_free (error); + tracker_log_shutdown (); + return EXIT_FAILURE; + } + g_signal_connect (miner_applications, "finished", G_CALLBACK (miner_finished_cb), NULL); @@ -237,6 +265,8 @@ main (gint argc, gchar *argv[]) g_main_loop_unref (main_loop); g_object_unref (G_OBJECT (miner_applications)); + g_object_unref (connection); + g_object_unref (proxy); tracker_log_shutdown (); diff --git a/src/miners/apps/tracker-miner-applications.c b/src/miners/apps/tracker-miner-applications.c index 1bb6c8626..8c52b7795 100644 --- a/src/miners/apps/tracker-miner-applications.c +++ b/src/miners/apps/tracker-miner-applications.c @@ -964,7 +964,6 @@ tracker_miner_applications_new (GError **error) return g_initable_new (TRACKER_TYPE_MINER_APPLICATIONS, NULL, error, - "name", "Applications", "processing-pool-wait-limit", 10, "processing-pool-ready-limit", 100, NULL); diff --git a/src/miners/fs/tracker-main.c b/src/miners/fs/tracker-main.c index 82636339c..3219190f8 100644 --- a/src/miners/fs/tracker-main.c +++ b/src/miners/fs/tracker-main.c @@ -54,6 +54,9 @@ #define SECONDS_PER_DAY 60 * 60 * 24 +#define DBUS_NAME "org.freedesktop.Tracker1.Miner.Files" +#define DBUS_PATH "/org/freedesktop/Tracker1/Miner/Files" + static void miner_handle_next (void); static GMainLoop *main_loop; @@ -661,7 +664,7 @@ miner_needs_check (TrackerMiner *miner, /* Check whether there are more pause * reasons than the store being out. */ - return tracker_miner_get_n_pause_reasons (miner) > 1; + return tracker_miner_is_paused (miner); } } } @@ -678,6 +681,8 @@ main (gint argc, gchar *argv[]) gboolean do_mtime_checking; gboolean force_mtime_checking = FALSE; gboolean store_available; + TrackerMinerProxy *proxy; + GDBusConnection *connection; main_loop = NULL; @@ -715,6 +720,21 @@ main (gint argc, gchar *argv[]) return EXIT_SUCCESS; } + connection = g_bus_get_sync (TRACKER_IPC_BUS, NULL, &error); + if (error) { + g_critical ("Could not create DBus connection: %s\n", + error->message); + g_error_free (error); + return EXIT_FAILURE; + } + + if (!tracker_dbus_request_name (connection, DBUS_NAME, &error)) { + g_critical ("Could not request DBus name '%s': %s", + DBUS_NAME, error->message); + g_error_free (error); + return EXIT_FAILURE; + } + /* Initialize logging */ config = tracker_config_new (); @@ -756,6 +776,16 @@ main (gint argc, gchar *argv[]) return EXIT_FAILURE; } + proxy = tracker_miner_proxy_new (miner_files, connection, DBUS_PATH, NULL, &error); + if (error) { + g_critical ("Couldn't create miner proxy: %s", error->message); + g_error_free (error); + g_object_unref (config); + g_object_unref (miner_files); + tracker_log_shutdown (); + return EXIT_FAILURE; + } + tracker_writeback_init (TRACKER_MINER_FILES (miner_files), config, &error); @@ -841,6 +871,9 @@ main (gint argc, gchar *argv[]) g_slist_foreach (miners, (GFunc) finalize_miner, NULL); g_slist_free (miners); + g_object_unref (proxy); + g_object_unref (connection); + tracker_writeback_shutdown (); tracker_log_shutdown (); diff --git a/src/miners/fs/tracker-miner-files.c b/src/miners/fs/tracker-miner-files.c index 590b01923..c27584c39 100644 --- a/src/miners/fs/tracker-miner-files.c +++ b/src/miners/fs/tracker-miner-files.c @@ -81,9 +81,9 @@ struct TrackerMinerFilesPrivate { GSList *index_single_directories; guint disk_space_check_id; - guint disk_space_pause_cookie; + gboolean disk_space_pause; - guint low_battery_pause_cookie; + gboolean low_battery_pause; #if defined(HAVE_UPOWER) || defined(HAVE_HAL) TrackerPower *power; @@ -1382,19 +1382,15 @@ check_battery_status (TrackerMinerFiles *mf) if (should_pause) { /* Don't try to pause again */ - if (mf->private->low_battery_pause_cookie == 0) { - mf->private->low_battery_pause_cookie = - tracker_miner_pause (TRACKER_MINER (mf), - _("Low battery"), - NULL); + if (!mf->private->low_battery_pause) { + mf->private->low_battery_pause = TRUE; + tracker_miner_pause (TRACKER_MINER (mf)); } } else { /* Don't try to resume again */ - if (mf->private->low_battery_pause_cookie != 0) { - tracker_miner_resume (TRACKER_MINER (mf), - mf->private->low_battery_pause_cookie, - NULL); - mf->private->low_battery_pause_cookie = 0; + if (mf->private->low_battery_pause) { + tracker_miner_resume (TRACKER_MINER (mf)); + mf->private->low_battery_pause = FALSE; } } @@ -1509,19 +1505,15 @@ disk_space_check_cb (gpointer user_data) if (disk_space_check (mf)) { /* Don't try to pause again */ - if (mf->private->disk_space_pause_cookie == 0) { - mf->private->disk_space_pause_cookie = - tracker_miner_pause (TRACKER_MINER (mf), - _("Low disk space"), - NULL); + if (!mf->private->disk_space_pause) { + mf->private->disk_space_pause = TRUE; + tracker_miner_pause (TRACKER_MINER (mf)); } } else { /* Don't try to resume again */ - if (mf->private->disk_space_pause_cookie != 0) { - tracker_miner_resume (TRACKER_MINER (mf), - mf->private->disk_space_pause_cookie, - NULL); - mf->private->disk_space_pause_cookie = 0; + if (mf->private->disk_space_pause) { + tracker_miner_resume (TRACKER_MINER (mf)); + mf->private->disk_space_pause = FALSE; } } @@ -2684,7 +2676,6 @@ tracker_miner_files_new (TrackerConfig *config, return g_initable_new (TRACKER_TYPE_MINER_FILES, NULL, error, - "name", "Files", "root", NULL, "config", config, "processing-pool-wait-limit", 10, diff --git a/src/miners/rss/tracker-main.c b/src/miners/rss/tracker-main.c index 57c103925..3b759a6e5 100644 --- a/src/miners/rss/tracker-main.c +++ b/src/miners/rss/tracker-main.c @@ -29,6 +29,9 @@ #include "tracker-miner-rss.h" +#define DBUS_NAME "org.freedesktop.Tracker1.Miner.RSS" +#define DBUS_PATH "/org/freedesktop/Tracker1/Miner/RSS" + static gint verbosity = -1; static gchar *add_feed; static gchar *title; @@ -59,6 +62,7 @@ main (int argc, char **argv) GOptionContext *context; TrackerMinerRSS *miner; GError *error = NULL; + TrackerMinerProxy *proxy; setlocale (LC_ALL, ""); @@ -149,6 +153,21 @@ main (int argc, char **argv) g_free (log_filename); } + connection = g_bus_get_sync (TRACKER_IPC_BUS, NULL, &error); + if (error) { + g_critical ("Could not create DBus connection: %s\n", + error->message); + g_error_free (error); + return EXIT_FAILURE; + } + + if (!tracker_dbus_request_name (connection, DBUS_NAME, &error)) { + g_critical ("Could not request DBus name '%s': %s", + DBUS_NAME, error->message); + g_error_free (error); + return EXIT_FAILURE; + } + miner = tracker_miner_rss_new (&error); if (!miner) { g_critical ("Could not create new RSS miner: '%s', exiting...\n", @@ -157,6 +176,12 @@ main (int argc, char **argv) } tracker_miner_start (TRACKER_MINER (miner)); + proxy = tracker_miner_proxy_new (TRACKER_MINER (miner), connection, DBUS_PATH, NULL, &error); + if (error) { + g_critical ("Could not create miner DBus proxy: %s\n", error->message); + g_error_free (error); + return EXIT_FAILURE; + } loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (loop); @@ -164,6 +189,8 @@ main (int argc, char **argv) tracker_log_shutdown (); g_main_loop_unref (loop); g_object_unref (miner); + g_object_unref (connection); + g_object_unref (proxy); return EXIT_SUCCESS; } diff --git a/src/miners/rss/tracker-miner-rss.c b/src/miners/rss/tracker-miner-rss.c index e0c9c89b1..eda64934b 100644 --- a/src/miners/rss/tracker-miner-rss.c +++ b/src/miners/rss/tracker-miner-rss.c @@ -1401,6 +1401,5 @@ tracker_miner_rss_new (GError **error) return g_initable_new (TRACKER_TYPE_MINER_RSS, NULL, error, - "name", "RSS", NULL); } diff --git a/src/tracker-extract/tracker-extract-controller.c b/src/tracker-extract/tracker-extract-controller.c index 74db8de33..9c03112bb 100644 --- a/src/tracker-extract/tracker-extract-controller.c +++ b/src/tracker-extract/tracker-extract-controller.c @@ -25,15 +25,17 @@ enum { PROP_DECORATOR = 1, + PROP_CONNECTION, }; struct TrackerExtractControllerPrivate { TrackerDecorator *decorator; TrackerConfig *config; GCancellable *cancellable; + GDBusConnection *connection; guint watch_id; guint progress_signal_id; - gint pause_cookie; + gint paused; }; G_DEFINE_TYPE (TrackerExtractController, tracker_extract_controller, G_TYPE_OBJECT) @@ -42,16 +44,12 @@ static void files_miner_idleness_changed (TrackerExtractController *self, gboolean idle) { - if (idle && self->priv->pause_cookie != 0) { - tracker_miner_resume (TRACKER_MINER (self->priv->decorator), - self->priv->pause_cookie, - NULL); - self->priv->pause_cookie = 0; - } else if (!idle && self->priv->pause_cookie == 0) { - self->priv->pause_cookie = - tracker_miner_pause (TRACKER_MINER (self->priv->decorator), - "Wait for files miner", - NULL); + if (idle && self->priv->paused) { + tracker_miner_resume (TRACKER_MINER (self->priv->decorator)); + self->priv->paused = FALSE; + } else if (!idle && !self->priv->paused) { + self->priv->paused = FALSE; + tracker_miner_pause (TRACKER_MINER (self->priv->decorator)); } } @@ -149,9 +147,7 @@ files_miner_progress_cb (GDBusConnection *connection, static void disconnect_all (TrackerExtractController *self) { - GDBusConnection *conn; - - conn = tracker_miner_get_dbus_connection (TRACKER_MINER (self->priv->decorator)); + GDBusConnection *conn = self->priv->connection; if (self->priv->watch_id != 0) g_bus_unwatch_name (self->priv->watch_id); @@ -170,9 +166,7 @@ disconnect_all (TrackerExtractController *self) static void update_wait_for_miner_fs (TrackerExtractController *self) { - GDBusConnection *conn; - - conn = tracker_miner_get_dbus_connection (TRACKER_MINER (self->priv->decorator)); + GDBusConnection *conn = self->priv->connection; if (tracker_config_get_wait_for_miner_fs (self->priv->config)) { self->priv->progress_signal_id = @@ -229,6 +223,9 @@ tracker_extract_controller_get_property (GObject *object, case PROP_DECORATOR: g_value_set_object (value, self->priv->decorator); break; + case PROP_CONNECTION: + g_value_set_object (value, self->priv->connection); + break; } } @@ -245,6 +242,9 @@ tracker_extract_controller_set_property (GObject *object, g_assert (self->priv->decorator == NULL); self->priv->decorator = g_value_dup_object (value); break; + case PROP_CONNECTION: + self->priv->connection = g_value_dup_object (value); + break; } } @@ -279,6 +279,15 @@ tracker_extract_controller_class_init (TrackerExtractControllerClass *klass) G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, + PROP_CONNECTION, + g_param_spec_object ("connection", + "Connection", + "Connection", + G_TYPE_DBUS_CONNECTION, + G_PARAM_STATIC_STRINGS | + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); g_type_class_add_private (object_class, sizeof (TrackerExtractControllerPrivate)); @@ -293,11 +302,13 @@ tracker_extract_controller_init (TrackerExtractController *self) } TrackerExtractController * -tracker_extract_controller_new (TrackerDecorator *decorator) +tracker_extract_controller_new (TrackerDecorator *decorator, + GDBusConnection *connection) { g_return_val_if_fail (TRACKER_IS_DECORATOR (decorator), NULL); return g_object_new (TRACKER_TYPE_EXTRACT_CONTROLLER, "decorator", decorator, + "connection", connection, NULL); } diff --git a/src/tracker-extract/tracker-extract-controller.h b/src/tracker-extract/tracker-extract-controller.h index 2fc078cca..7d8a70816 100644 --- a/src/tracker-extract/tracker-extract-controller.h +++ b/src/tracker-extract/tracker-extract-controller.h @@ -47,7 +47,8 @@ struct TrackerExtractControllerClass { }; GType tracker_extract_controller_get_type (void) G_GNUC_CONST; -TrackerExtractController * tracker_extract_controller_new (TrackerDecorator *decorator); +TrackerExtractController * tracker_extract_controller_new (TrackerDecorator *decorator, + GDBusConnection *connection); G_END_DECLS diff --git a/src/tracker-extract/tracker-extract-decorator.c b/src/tracker-extract/tracker-extract-decorator.c index 6deab0ba3..abaf7a903 100644 --- a/src/tracker-extract/tracker-extract-decorator.c +++ b/src/tracker-extract/tracker-extract-decorator.c @@ -683,7 +683,6 @@ tracker_extract_decorator_new (TrackerExtract *extract, { return g_initable_new (TRACKER_TYPE_EXTRACT_DECORATOR, cancellable, error, - "name", "Extract", "data-source", TRACKER_EXTRACT_DATA_SOURCE, "class-names", supported_classes, "extractor", extract, diff --git a/src/tracker-extract/tracker-main.c b/src/tracker-extract/tracker-main.c index 692c39f89..6258b83a9 100644 --- a/src/tracker-extract/tracker-main.c +++ b/src/tracker-extract/tracker-main.c @@ -62,6 +62,9 @@ "\n" \ " http://www.gnu.org/licenses/gpl.txt\n" +#define DBUS_NAME "org.freedesktop.Tracker1.Miner.Extract" +#define DBUS_PATH "/org/freedesktop/Tracker1/Miner/Extract" + static GMainLoop *main_loop; static gint verbosity = -1; @@ -302,6 +305,8 @@ main (int argc, char *argv[]) TrackerExtractController *controller; gchar *log_filename = NULL; GMainLoop *my_main_loop; + GDBusConnection *connection; + TrackerMinerProxy *proxy; bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); @@ -339,6 +344,21 @@ main (int argc, char *argv[]) setlocale (LC_ALL, ""); + connection = g_bus_get_sync (TRACKER_IPC_BUS, NULL, &error); + if (error) { + g_critical ("Could not create DBus connection: %s\n", + error->message); + g_error_free (error); + return EXIT_FAILURE; + } + + if (!tracker_dbus_request_name (connection, DBUS_NAME, &error)) { + g_critical ("Could not request DBus name '%s': %s", + DBUS_NAME, error->message); + g_error_free (error); + return EXIT_FAILURE; + } + config = tracker_config_new (); /* Extractor command line arguments */ @@ -384,6 +404,16 @@ main (int argc, char *argv[]) return EXIT_FAILURE; } + proxy = tracker_miner_proxy_new (TRACKER_MINER (decorator), connection, DBUS_PATH, NULL, &error); + if (error) { + g_critical ("Could not create miner DBus proxy: %s\n", error->message); + g_error_free (error); + g_object_unref (decorator); + g_object_unref (config); + tracker_log_shutdown (); + return EXIT_FAILURE; + } + #ifdef THREAD_ENABLE_TRACE g_debug ("Thread:%p (Main) --- Waiting for extract requests...", g_thread_self ()); @@ -391,7 +421,7 @@ main (int argc, char *argv[]) tracker_locale_sanity_check (); - controller = tracker_extract_controller_new (decorator); + controller = tracker_extract_controller_new (decorator, connection); tracker_miner_start (TRACKER_MINER (decorator)); /* Main loop */ @@ -411,6 +441,8 @@ main (int argc, char *argv[]) g_object_unref (extract); g_object_unref (decorator); g_object_unref (controller); + g_object_unref (proxy); + g_object_unref (connection); tracker_log_shutdown (); |