tracker-0.16.2/src/libtracker-miner/tracker-miner-manager.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found tracker-miner-manager.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
   1 /*
   2  * Copyright (C) 2009, Nokia <ivan.frade@nokia.com>
   3  *
   4  * This library is free software; you can redistribute it and/or
   5  * modify it under the terms of the GNU Lesser General Public
   6  * License as published by the Free Software Foundation; either
   7  * version 2.1 of the License, or (at your option) any later version.
   8  *
   9  * This library is distributed in the hope that it will be useful,
  10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12  * Lesser General Public License for more details.
  13  *
  14  * You should have received a copy of the GNU Lesser General Public
  15  * License along with this library; if not, write to the
  16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  17  * Boston, MA  02110-1301, USA.
  18  */
  19 
  20 #include "config.h"
  21 
  22 #include <gio/gio.h>
  23 
  24 #include <libtracker-common/tracker-dbus.h>
  25 #include <libtracker-common/tracker-type-utils.h>
  26 
  27 #include "tracker-crawler.h"
  28 #include "tracker-miner-object.h"
  29 #include "tracker-miner-manager.h"
  30 #include "tracker-marshal.h"
  31 #include "tracker-miner-dbus.h"
  32 
  33 /**
  34  * SECTION:tracker-miner-manager
  35  * @short_description: External control and monitoring of miners
  36  * @include: libtracker-miner/tracker-miner.h
  37  *
  38  * #TrackerMinerManager keeps track of available miners, their current
  39  * progress/status, and also allows basic external control on them, such
  40  * as pausing or resuming data processing.
  41  **/
  42 
  43 #define TRACKER_MINER_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_MINER_MANAGER, TrackerMinerManagerPrivate))
  44 
  45 #define DESKTOP_ENTRY_GROUP "Desktop Entry"
  46 #define DBUS_NAME_KEY "DBusName"
  47 #define DBUS_PATH_KEY "DBusPath"
  48 #define DISPLAY_NAME_KEY "Name"
  49 #define DESCRIPTION_KEY "Comment"
  50 
  51 typedef struct TrackerMinerManagerPrivate TrackerMinerManagerPrivate;
  52 typedef struct MinerData MinerData;
  53 
  54 struct MinerData {
  55 	gchar *dbus_name;
  56 	gchar *dbus_path;
  57 	gchar *display_name;
  58 	gchar *description;
  59 
  60 	GDBusConnection *connection;
  61 	guint progress_signal;
  62 	guint paused_signal;
  63 	guint resumed_signal;
  64 	guint watch_name_id;
  65 	GObject *manager; /* weak */
  66 };
  67 
  68 struct TrackerMinerManagerPrivate {
  69 	GDBusConnection *connection;
  70 	GList *miners;
  71 	GHashTable *miner_proxies;
  72 
  73 	/* Property values */
  74 	gboolean auto_start;
  75 };
  76 
  77 static void miner_manager_initable_iface_init (GInitableIface         *iface);
  78 static void miner_manager_set_property        (GObject             *object,
  79                                                guint                param_id,
  80                                                const GValue        *value,
  81                                                GParamSpec          *pspec);
  82 static void miner_manager_get_property        (GObject             *object,
  83                                                guint                param_id,
  84                                                GValue              *value,
  85                                                GParamSpec          *pspec);
  86 static void miner_manager_finalize            (GObject             *object);
  87 static void initialize_miners_data            (TrackerMinerManager *manager);
  88 
  89 G_DEFINE_TYPE_WITH_CODE (TrackerMinerManager, tracker_miner_manager, G_TYPE_OBJECT,
  90                          G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
  91                                                 miner_manager_initable_iface_init));
  92 
  93 enum {
  94 	PROP_0,
  95 	PROP_AUTO_START
  96 };
  97 
  98 enum {
  99 	MINER_PROGRESS,
 100 	MINER_PAUSED,
 101 	MINER_RESUMED,
 102 	MINER_ACTIVATED,
 103 	MINER_DEACTIVATED,
 104 	LAST_SIGNAL
 105 };
 106 
 107 static guint signals [LAST_SIGNAL] = { 0 };
 108 
 109 static void
 110 tracker_miner_manager_class_init (TrackerMinerManagerClass *klass)
 111 {
 112 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 113 
 114 	object_class->set_property = miner_manager_set_property;
 115 	object_class->get_property = miner_manager_get_property;
 116 	object_class->finalize = miner_manager_finalize;
 117 
 118 	g_object_class_install_property (object_class,
 119 	                                 PROP_AUTO_START,
 120 	                                 g_param_spec_boolean ("auto-start",
 121 	                                                      "Auto Start",
 122 	                                                      "If set, auto starts miners when querying their status",
 123 	                                                       TRUE,
 124 	                                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 125 
 126 	/**
 127 	 * TrackerMinerManager::miner-progress:
 128 	 * @manager: the #TrackerMinerManager
 129 	 * @miner: miner reference
 130 	 * @status: miner status
 131 	 * @progress: miner progress, from 0 to 1
 132 	 * @remaining_time: remaining processing time
 133 	 *
 134 	 * The ::miner-progress signal is meant to report status/progress changes
 135 	 * in any tracked miner.
 136 	 *
 137 	 * Since: 0.12
 138 	 **/
 139 	signals [MINER_PROGRESS] =
 140 		g_signal_new ("miner-progress",
 141 		              G_OBJECT_CLASS_TYPE (object_class),
 142 		              G_SIGNAL_RUN_LAST,
 143 		              G_STRUCT_OFFSET (TrackerMinerManagerClass, miner_progress),
 144 		              NULL, NULL,
 145 		              tracker_marshal_VOID__STRING_STRING_DOUBLE_INT,
 146 		              G_TYPE_NONE, 4,
 147 		              G_TYPE_STRING,
 148 		              G_TYPE_STRING,
 149 		              G_TYPE_DOUBLE,
 150 		              G_TYPE_INT);
 151 	/**
 152 	 * TrackerMinerManager::miner-paused:
 153 	 * @manager: the #TrackerMinerManager
 154 	 * @miner: miner reference
 155 	 *
 156 	 * The ::miner-paused signal will be emitted whenever a miner
 157 	 * (referenced by @miner) is paused.
 158 	 *
 159 	 * Since: 0.8
 160 	 **/
 161 	signals [MINER_PAUSED] =
 162 		g_signal_new ("miner-paused",
 163 		              G_OBJECT_CLASS_TYPE (object_class),
 164 		              G_SIGNAL_RUN_LAST,
 165 		              G_STRUCT_OFFSET (TrackerMinerManagerClass, miner_paused),
 166 		              NULL, NULL,
 167 		              g_cclosure_marshal_VOID__STRING,
 168 		              G_TYPE_NONE, 1,
 169 		              G_TYPE_STRING);
 170 	/**
 171 	 * TrackerMinerManager::miner-resumed:
 172 	 * @manager: the #TrackerMinerManager
 173 	 * @miner: miner reference
 174 	 *
 175 	 * The ::miner-resumed signal will be emitted whenever a miner
 176 	 * (referenced by @miner) is resumed.
 177 	 *
 178 	 * Since: 0.8
 179 	 **/
 180 	signals [MINER_RESUMED] =
 181 		g_signal_new ("miner-resumed",
 182 		              G_OBJECT_CLASS_TYPE (object_class),
 183 		              G_SIGNAL_RUN_LAST,
 184 		              G_STRUCT_OFFSET (TrackerMinerManagerClass, miner_resumed),
 185 		              NULL, NULL,
 186 		              g_cclosure_marshal_VOID__STRING,
 187 		              G_TYPE_NONE, 1,
 188 		              G_TYPE_STRING);
 189 	/**
 190 	 * TrackerMinerManager::miner-activated:
 191 	 * @manager: the #TrackerMinerManager
 192 	 * @miner: miner reference
 193 	 *
 194 	 * The ::miner-activated signal will be emitted whenever a miner
 195 	 * (referenced by @miner) is activated (technically, this means
 196 	 * the miner has appeared in the session bus).
 197 	 *
 198 	 * Since: 0.8
 199 	 **/
 200 	signals [MINER_ACTIVATED] =
 201 		g_signal_new ("miner-activated",
 202 		              G_OBJECT_CLASS_TYPE (object_class),
 203 		              G_SIGNAL_RUN_LAST,
 204 		              G_STRUCT_OFFSET (TrackerMinerManagerClass, miner_activated),
 205 		              NULL, NULL,
 206 		              g_cclosure_marshal_VOID__STRING,
 207 		              G_TYPE_NONE, 1,
 208 		              G_TYPE_STRING);
 209 	/**
 210 	 * TrackerMinerManager::miner-deactivated:
 211 	 * @manager: the #TrackerMinerManager
 212 	 * @miner: miner reference
 213 	 *
 214 	 * The ::miner-deactivated signal will be emitted whenever a miner
 215 	 * (referenced by @miner) is deactivated (technically, this means
 216 	 * the miner has disappeared from the session bus).
 217 	 *
 218 	 * Since: 0.8
 219 	 **/
 220 	signals [MINER_DEACTIVATED] =
 221 		g_signal_new ("miner-deactivated",
 222 		              G_OBJECT_CLASS_TYPE (object_class),
 223 		              G_SIGNAL_RUN_LAST,
 224 		              G_STRUCT_OFFSET (TrackerMinerManagerClass, miner_deactivated),
 225 		              NULL, NULL,
 226 		              g_cclosure_marshal_VOID__STRING,
 227 		              G_TYPE_NONE, 1,
 228 		              G_TYPE_STRING);
 229 
 230 	g_type_class_add_private (object_class, sizeof (TrackerMinerManagerPrivate));
 231 }
 232 
 233 static void
 234 miner_manager_set_property (GObject      *object,
 235                             guint         prop_id,
 236                             const GValue *value,
 237                             GParamSpec   *pspec)
 238 {
 239 	TrackerMinerManager *manager;
 240 	TrackerMinerManagerPrivate *priv;
 241 
 242 	manager = TRACKER_MINER_MANAGER (object);
 243 	priv = TRACKER_MINER_MANAGER_GET_PRIVATE (manager);
 244 
 245 	switch (prop_id) {
 246 	case PROP_AUTO_START:
 247 		priv->auto_start = g_value_get_boolean (value);
 248 		break;
 249 	default:
 250 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 251 		break;
 252 	}
 253 }
 254 
 255 static void
 256 miner_manager_get_property (GObject    *object,
 257                             guint       prop_id,
 258                             GValue     *value,
 259                             GParamSpec *pspec)
 260 {
 261 	TrackerMinerManager *manager;
 262 	TrackerMinerManagerPrivate *priv;
 263 
 264 	manager = TRACKER_MINER_MANAGER (object);
 265 	priv = TRACKER_MINER_MANAGER_GET_PRIVATE (manager);
 266 
 267 	switch (prop_id) {
 268 	case PROP_AUTO_START:
 269 		g_value_set_boolean (value, priv->auto_start);
 270 		break;
 271 	default:
 272 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 273 		break;
 274 	}
 275 }
 276 
 277 static GDBusProxy *
 278 find_miner_proxy (TrackerMinerManager *manager,
 279                   const gchar         *name,
 280                   gboolean             try_suffix)
 281 {
 282 	TrackerMinerManagerPrivate *priv;
 283 	GHashTableIter iter;
 284 	gpointer key, value;
 285 
 286 	priv = TRACKER_MINER_MANAGER_GET_PRIVATE (manager);
 287 	g_hash_table_iter_init (&iter, priv->miner_proxies);
 288 
 289 	while (g_hash_table_iter_next (&iter, &key, &value)) {
 290 		if (g_strcmp0 (name, (gchar *) value) == 0) {
 291 			return key;
 292 		}
 293 
 294 		if (try_suffix) {
 295 			if (g_str_has_suffix (value, name)) {
 296 				return key;
 297 			}
 298 		}
 299 	}
 300 
 301 	return NULL;
 302 }
 303 
 304 static void
 305 miner_appears (GDBusConnection *connection,
 306                const gchar     *name,
 307                const gchar     *name_owner,
 308                gpointer         user_data)
 309 {
 310 	MinerData *data = user_data;
 311 	if (data->manager) {
 312 		g_signal_emit (data->manager, signals[MINER_ACTIVATED], 0, data->dbus_name);
 313 	}
 314 }
 315 
 316 static void
 317 miner_disappears (GDBusConnection *connection,
 318                   const gchar     *name,
 319                   gpointer         user_data)
 320 {
 321 	MinerData *data = user_data;
 322 	if (data->manager) {
 323 		g_signal_emit (data->manager, signals[MINER_DEACTIVATED], 0, data->dbus_name);
 324 	}
 325 }
 326 
 327 static void
 328 miner_progress_changed (GDBusConnection *connection,
 329                         const gchar     *sender_name,
 330                         const gchar     *object_path,
 331                         const gchar     *interface_name,
 332                         const gchar     *signal_name,
 333                         GVariant        *parameters,
 334                         gpointer         user_data)
 335 {
 336 	MinerData *data = user_data;
 337 	const gchar *status = NULL;
 338 	gdouble progress = 0;
 339 	gint remaining_time = -1;
 340 
 341 	g_variant_get (parameters, "(&sdi)", &status, &progress, &remaining_time);
 342 	if (data->manager) {
 343 		g_signal_emit (data->manager, signals[MINER_PROGRESS], 0, data->dbus_name, status, progress, remaining_time);
 344 	}
 345 }
 346 
 347 static void
 348 miner_paused (GDBusConnection *connection,
 349               const gchar     *sender_name,
 350               const gchar     *object_path,
 351               const gchar     *interface_name,
 352               const gchar     *signal_name,
 353               GVariant        *parameters,
 354               gpointer         user_data)
 355 {
 356 	MinerData *data = user_data;
 357 	if (data->manager) {
 358 		g_signal_emit (data->manager, signals[MINER_PAUSED], 0, data->dbus_name);
 359 	}
 360 }
 361 
 362 static void
 363 miner_resumed (GDBusConnection *connection,
 364                const gchar     *sender_name,
 365                const gchar     *object_path,
 366                const gchar     *interface_name,
 367                const gchar     *signal_name,
 368                GVariant        *parameters,
 369                gpointer         user_data)
 370 {
 371 	MinerData *data = user_data;
 372 	if (data->manager) {
 373 		g_signal_emit (data->manager, signals[MINER_RESUMED], 0, data->dbus_name);
 374 	}
 375 }
 376 
 377 static void
 378 data_manager_weak_notify (gpointer user_data, GObject *old_object)
 379 {
 380 	MinerData *data = user_data;
 381 	data->manager = NULL;
 382 }
 383 
 384 static void
 385 tracker_miner_manager_init (TrackerMinerManager *manager)
 386 {
 387 	TrackerMinerManagerPrivate *priv;
 388 
 389 	priv = TRACKER_MINER_MANAGER_GET_PRIVATE (manager);
 390 
 391 	priv->miner_proxies = g_hash_table_new_full (NULL, NULL,
 392 	                                             (GDestroyNotify) g_object_unref,
 393 	                                             (GDestroyNotify) g_free);
 394 }
 395 
 396 static gboolean
 397 miner_manager_initable_init (GInitable     *initable,
 398                              GCancellable  *cancellable,
 399                              GError       **error)
 400 {
 401 	TrackerMinerManager *manager;
 402 	GError *inner_error = NULL;
 403 	TrackerMinerManagerPrivate *priv;
 404 	GList *m;
 405 
 406 	manager = TRACKER_MINER_MANAGER (initable);
 407 	priv = TRACKER_MINER_MANAGER_GET_PRIVATE (manager);
 408 
 409 	priv->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &inner_error);
 410 	if (!priv->connection) {
 411 		g_propagate_error (error, inner_error);
 412 		return FALSE;
 413 	}
 414 
 415 	initialize_miners_data (manager);
 416 
 417 	for (m = priv->miners; m; m = m->next) {
 418 		GDBusProxy *proxy;
 419 		MinerData *data;
 420 
 421 		data = m->data;
 422 		data->connection = g_object_ref (priv->connection);
 423 		data->manager = G_OBJECT (manager);
 424 		g_object_weak_ref (data->manager, data_manager_weak_notify, data);
 425 
 426 		proxy = g_dbus_proxy_new_sync (priv->connection,
 427 		                               (priv->auto_start ?
 428 		                                G_DBUS_PROXY_FLAGS_NONE :
 429 		                                G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START),
 430 		                               NULL,
 431 		                               data->dbus_name,
 432 		                               data->dbus_path,
 433 		                               TRACKER_MINER_DBUS_INTERFACE,
 434 		                               NULL,
 435 		                               &inner_error);
 436 		/* This error shouldn't be considered fatal */
 437 		if (inner_error) {
 438 			g_critical ("Could not create proxy on the D-Bus session bus, %s",
 439 			            inner_error ? inner_error->message : "no error given.");
 440 			g_clear_error (&inner_error);
 441 			continue;
 442 		}
 443 
 444 		data->progress_signal = g_dbus_connection_signal_subscribe (priv->connection,
 445 		                                                            data->dbus_name,
 446 		                                                            TRACKER_MINER_DBUS_INTERFACE,
 447 		                                                            "Progress",
 448 		                                                            data->dbus_path,
 449 		                                                            NULL,
 450 		                                                            G_DBUS_SIGNAL_FLAGS_NONE,
 451 		                                                            miner_progress_changed,
 452 		                                                            data,
 453 		                                                            NULL);
 454 
 455 		data->paused_signal = g_dbus_connection_signal_subscribe (priv->connection,
 456 		                                                          data->dbus_name,
 457 		                                                          TRACKER_MINER_DBUS_INTERFACE,
 458 		                                                          "Paused",
 459 		                                                          data->dbus_path,
 460 		                                                          NULL,
 461 		                                                          G_DBUS_SIGNAL_FLAGS_NONE,
 462 		                                                          miner_paused,
 463 		                                                          data,
 464 		                                                          NULL);
 465 
 466 
 467 		data->resumed_signal = g_dbus_connection_signal_subscribe (priv->connection,
 468 		                                                           data->dbus_name,
 469 		                                                           TRACKER_MINER_DBUS_INTERFACE,
 470 		                                                           "Resumed",
 471 		                                                           data->dbus_path,
 472 		                                                           NULL,
 473 		                                                           G_DBUS_SIGNAL_FLAGS_NONE,
 474 		                                                           miner_resumed,
 475 		                                                           data,
 476 		                                                           NULL);
 477 
 478 		g_hash_table_insert (priv->miner_proxies, proxy, g_strdup (data->dbus_name));
 479 
 480 		data->watch_name_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
 481 		                                        data->dbus_name,
 482 		                                        G_BUS_NAME_WATCHER_FLAGS_NONE,
 483 		                                        miner_appears,
 484 		                                        miner_disappears,
 485 		                                        data,
 486 		                                        NULL);
 487 
 488 	}
 489 
 490 	return TRUE;
 491 }
 492 
 493 static void
 494 miner_manager_initable_iface_init (GInitableIface *iface)
 495 {
 496 	iface->init = miner_manager_initable_init;
 497 }
 498 
 499 
 500 static void
 501 miner_data_free (MinerData *data)
 502 {
 503 	if (data->watch_name_id != 0) {
 504 		g_bus_unwatch_name (data->watch_name_id);
 505 	}
 506 
 507 	if (data->progress_signal) {
 508 		g_dbus_connection_signal_unsubscribe (data->connection,
 509 		                                      data->progress_signal);
 510 	}
 511 
 512 	if (data->paused_signal) {
 513 		g_dbus_connection_signal_unsubscribe (data->connection,
 514 		                                      data->paused_signal);
 515 	}
 516 
 517 	if (data->resumed_signal) {
 518 		g_dbus_connection_signal_unsubscribe (data->connection,
 519 		                                      data->resumed_signal);
 520 	}
 521 
 522 	if (data->connection) {
 523 		g_object_unref (data->connection);
 524 	}
 525 
 526 	if (data->manager) {
 527 		g_object_weak_unref (data->manager, data_manager_weak_notify, data);
 528 	}
 529 
 530 	g_free (data->dbus_path);
 531 	g_free (data->display_name);
 532 	g_slice_free (MinerData, data);
 533 }
 534 
 535 static void
 536 miner_manager_finalize (GObject *object)
 537 {
 538 	TrackerMinerManagerPrivate *priv;
 539 
 540 	priv = TRACKER_MINER_MANAGER_GET_PRIVATE (object);
 541 
 542 	if (priv->connection) {
 543 		g_object_unref (priv->connection);
 544 	}
 545 
 546 	g_list_foreach (priv->miners, (GFunc) miner_data_free, NULL);
 547 	g_list_free (priv->miners);
 548 	g_hash_table_unref (priv->miner_proxies);
 549 
 550 	G_OBJECT_CLASS (tracker_miner_manager_parent_class)->finalize (object);
 551 }
 552 
 553 /**
 554  * tracker_miner_manager_new:
 555  *
 556  * Creates a new #TrackerMinerManager instance.
 557  *
 558  * Note: Auto-starting miners when querying status will be enabled.
 559  *
 560  * Returns: a #TrackerMinerManager or #NULL if an error happened.
 561  *
 562  * Since: 0.8
 563  **/
 564 TrackerMinerManager *
 565 tracker_miner_manager_new (void)
 566 {
 567 	GError *inner_error = NULL;
 568 	TrackerMinerManager *manager;
 569 
 570 	manager = g_initable_new (TRACKER_TYPE_MINER_MANAGER,
 571 	                          NULL,
 572 	                          &inner_error,
 573 	                          NULL);
 574 	if (!manager) {
 575 		g_critical ("Couldn't create new TrackerMinerManager: '%s'",
 576 		            inner_error ? inner_error->message : "unknown error");
 577 		g_clear_error (&inner_error);
 578 	}
 579 
 580 	return manager;
 581 }
 582 
 583 /**
 584  * tracker_miner_manager_new_full:
 585  * @auto_start: Flag to disable auto-starting the miners when querying status
 586  * @error: a #GError to report errors.
 587  *
 588  * Creates a new #TrackerMinerManager.
 589  *
 590  * Returns: a #TrackerMinerManager. On error, #NULL is returned and @error is set
 591  * accordingly.
 592  *
 593  * Since: 0.10.5
 594  **/
 595 TrackerMinerManager *
 596 tracker_miner_manager_new_full (gboolean   auto_start,
 597                                 GError   **error)
 598 {
 599 	GError *inner_error = NULL;
 600 	TrackerMinerManager *manager;
 601 
 602 	manager = g_initable_new (TRACKER_TYPE_MINER_MANAGER,
 603 	                          NULL,
 604 	                          &inner_error,
 605 	                          "auto-start", auto_start,
 606 	                          NULL);
 607 	if (inner_error)
 608 		g_propagate_error (error, inner_error);
 609 
 610 	return manager;
 611 }
 612 
 613 /**
 614  * tracker_miner_manager_get_running:
 615  * @manager: a #trackerMinerManager
 616  *
 617  * Returns a list of references for all active miners. Active miners
 618  * are miners which are running within a process.
 619  *
 620  * Returns: (transfer full) (element-type utf8): a #GSList which must
 621  * be freed with g_slist_free() and all contained data with g_free().
 622  * Otherwise %NULL is returned if there are no miners.
 623  *
 624  * Since: 0.8
 625  **/
 626 GSList *
 627 tracker_miner_manager_get_running (TrackerMinerManager *manager)
 628 {
 629 	TrackerMinerManagerPrivate *priv;
 630 	GSList *list = NULL;
 631 	GError *error = NULL;
 632 	GVariant *v;
 633 	GVariantIter *iter;
 634 	const gchar *str = NULL;
 635 
 636 	g_return_val_if_fail (TRACKER_IS_MINER_MANAGER (manager), NULL);
 637 
 638 	priv = TRACKER_MINER_MANAGER_GET_PRIVATE (manager);
 639 
 640 	if (!priv->connection) {
 641 		return NULL;
 642 	}
 643 
 644 	v = g_dbus_connection_call_sync (priv->connection,
 645 	                                 "org.freedesktop.DBus",
 646 	                                 "/org/freedesktop/DBus",
 647 	                                 "org.freedesktop.DBus",
 648 	                                 "ListNames",
 649 	                                 NULL,
 650 	                                 G_VARIANT_TYPE ("(as)"),
 651 	                                 G_DBUS_CALL_FLAGS_NONE,
 652 	                                 -1,
 653 	                                 NULL,
 654 	                                 &error);
 655 
 656 	if (error) {
 657 		g_critical ("Could not get a list of names registered on the session bus, %s",
 658 		            error ? error->message : "no error given");
 659 		g_clear_error (&error);
 660 		return NULL;
 661 	}
 662 
 663 	g_variant_get (v, "(as)", &iter);
 664 	while (g_variant_iter_loop (iter, "&s", &str)) {
 665 		if (!g_str_has_prefix (str, TRACKER_MINER_DBUS_NAME_PREFIX)) {
 666 			continue;
 667 		}
 668 
 669 		/* Special case miner-fs which has
 670 		 * additional D-Bus interface.
 671 		 */
 672 		if (strcmp (str, "org.freedesktop.Tracker1.Miner.Files.Index") == 0) {
 673 			continue;
 674 		}
 675 
 676 		list = g_slist_prepend (list, g_strdup (str));
 677 	}
 678 
 679 	g_variant_iter_free (iter);
 680 	g_variant_unref (v);
 681 
 682 	list = g_slist_reverse (list);
 683 
 684 	return list;
 685 }
 686 
 687 static gboolean
 688 crawler_check_file_cb (TrackerCrawler *crawler,
 689                        GFile          *file,
 690                        gpointer        user_data)
 691 {
 692 	TrackerMinerManager *manager;
 693 	TrackerMinerManagerPrivate *priv;
 694 	GKeyFile *key_file;
 695 	gchar *path, *dbus_path, *dbus_name, *display_name, *description;
 696 	GError *error = NULL;
 697 	MinerData *data;
 698 
 699 	manager = user_data;
 700 	path = g_file_get_path (file);
 701 	priv = TRACKER_MINER_MANAGER_GET_PRIVATE (manager);
 702 
 703 	if (!g_str_has_suffix (path, ".desktop")) {
 704 		return FALSE;
 705 	}
 706 
 707 	key_file = g_key_file_new ();
 708 	g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, &error);
 709 
 710 	if (error) {
 711 		g_warning ("Error parsing miner .desktop file: %s", error->message);
 712 		g_error_free (error);
 713 		g_key_file_free (key_file);
 714 
 715 		return FALSE;
 716 	}
 717 
 718 	dbus_path = g_key_file_get_string (key_file, DESKTOP_ENTRY_GROUP, DBUS_PATH_KEY, NULL);
 719 	dbus_name = g_key_file_get_string (key_file, DESKTOP_ENTRY_GROUP, DBUS_NAME_KEY, NULL);
 720 	display_name = g_key_file_get_locale_string (key_file, DESKTOP_ENTRY_GROUP, DISPLAY_NAME_KEY, NULL, NULL);
 721 
 722 	if (!dbus_path || !dbus_name || !display_name) {
 723 		g_warning ("Essential data (DBusPath, DBusName or Name) are missing in miner .desktop file");
 724 		g_key_file_free (key_file);
 725 		g_free (dbus_path);
 726 		g_free (display_name);
 727 		g_free (dbus_name);
 728 
 729 		return FALSE;
 730 	}
 731 
 732 	description = g_key_file_get_locale_string (key_file, DESKTOP_ENTRY_GROUP, DESCRIPTION_KEY, NULL, NULL);
 733 
 734 	data = g_slice_new0 (MinerData);
 735 	data->dbus_path = dbus_path;
 736 	data->dbus_name = dbus_name;
 737 	data->display_name = display_name;
 738 	data->description = description;
 739 
 740 	priv->miners = g_list_prepend (priv->miners, data);
 741 
 742 	g_key_file_free (key_file);
 743 	g_free (path);
 744 
 745 	return TRUE;
 746 }
 747 
 748 static void
 749 crawler_finished_cb (TrackerCrawler *crawler,
 750                      gboolean        was_interrupted,
 751                      gpointer        user_data)
 752 {
 753 	g_main_loop_quit (user_data);
 754 }
 755 
 756 static void
 757 initialize_miners_data (TrackerMinerManager *manager)
 758 {
 759 	GMainLoop *main_loop;
 760 	GFile *file;
 761 	TrackerCrawler *crawler;
 762 	const gchar *miners_dir;
 763 
 764 	crawler = tracker_crawler_new ();
 765 	main_loop = g_main_loop_new (NULL, FALSE);
 766 
 767 	g_signal_connect (crawler, "check-file",
 768 	                  G_CALLBACK (crawler_check_file_cb),
 769 	                  manager);
 770 	g_signal_connect (crawler, "finished",
 771 	                  G_CALLBACK (crawler_finished_cb),
 772 	                  main_loop);
 773 
 774 	/* Go through service files */
 775 	miners_dir = g_getenv ("TRACKER_MINERS_DIR");
 776 	if (G_LIKELY (miners_dir == NULL)) {
 777 		miners_dir = TRACKER_MINERS_DIR;
 778 	} else {
 779 		g_message ("Crawling miners in '%s' (set in env)", miners_dir);
 780 	}
 781 
 782 	file = g_file_new_for_path (miners_dir);
 783 	tracker_crawler_start (crawler, file, TRUE);
 784 	g_object_unref (file);
 785 
 786 	g_main_loop_run (main_loop);
 787 
 788 	g_main_loop_unref (main_loop);
 789 	g_object_unref (crawler);
 790 }
 791 
 792 /**
 793  * tracker_miner_manager_get_available:
 794  * @manager: a #TrackerMinerManager
 795  *
 796  * Returns a list of references for all available miners. Available
 797  * miners are miners which may or may not be running in a process at
 798  * the current time.
 799  *
 800  * Returns: (transfer full) (element-type utf8): a #GSList which must
 801  * be freed with g_slist_free() and all contained data with g_free().
 802  * Otherwise %NULL is returned if there are no miners.
 803  *
 804  * Since: 0.8
 805  **/
 806 GSList *
 807 tracker_miner_manager_get_available (TrackerMinerManager *manager)
 808 {
 809 	TrackerMinerManagerPrivate *priv;
 810 	GSList *list = NULL;
 811 	GList *m;
 812 
 813 	priv = TRACKER_MINER_MANAGER_GET_PRIVATE (manager);
 814 
 815 	for (m = priv->miners; m; m = m->next) {
 816 		MinerData *data = m->data;
 817 
 818 		list = g_slist_prepend (list, g_strdup (data->dbus_name));
 819 	}
 820 
 821 	return g_slist_reverse (list);
 822 }
 823 
 824 /**
 825  * tracker_miner_manager_pause:
 826  * @manager: a #TrackerMinerManager.
 827  * @miner: miner reference
 828  * @reason: reason to pause
 829  * @cookie: (out) (allow-none): return location for the pause cookie ID
 830  *
 831  * Asks @miner to pause. a miner could be paused by
 832  * several reasons, and its activity won't be resumed
 833  * until all pause requests have been resumed.
 834  *
 835  * Returns: %TRUE if the miner was paused successfully, otherwise
 836  * %FALSE.
 837  *
 838  * Since: 0.8
 839  **/
 840 gboolean
 841 tracker_miner_manager_pause (TrackerMinerManager *manager,
 842                              const gchar         *miner,
 843                              const gchar         *reason,
 844                              guint32             *cookie)
 845 {
 846 	GDBusProxy *proxy;
 847 	const gchar *app_name;
 848 	GError *error = NULL;
 849 	GVariant *v;
 850 
 851 	g_return_val_if_fail (TRACKER_IS_MINER_MANAGER (manager), FALSE);
 852 	g_return_val_if_fail (miner != NULL, FALSE);
 853 	g_return_val_if_fail (reason != NULL, FALSE);
 854 
 855 	proxy = find_miner_proxy (manager, miner, TRUE);
 856 
 857 	if (!proxy) {
 858 		g_critical ("No D-Bus proxy found for miner '%s'", miner);
 859 		return FALSE;
 860 	}
 861 
 862 	/* Find a reasonable app name */
 863 	app_name = g_get_application_name ();
 864 
 865 	if (!app_name) {
 866 		app_name = g_get_prgname ();
 867 	}
 868 
 869 	if (!app_name) {
 870 		app_name = "TrackerMinerManager client";
 871 	}
 872 
 873 	v = g_dbus_proxy_call_sync (proxy,
 874 	                            "Pause",
 875 	                            g_variant_new ("(ss)", app_name, reason),
 876 	                            G_DBUS_CALL_FLAGS_NONE,
 877 	                            -1,
 878 	                            NULL,
 879 	                            &error);
 880 
 881 	if (error) {
 882 		g_critical ("Could not pause miner '%s': %s", miner, error->message);
 883 		g_error_free (error);
 884 		return FALSE;
 885 	}
 886 
 887 	if (cookie) {
 888 		g_variant_get (v, "(i)", cookie);
 889 	}
 890 
 891 	g_variant_unref (v);
 892 
 893 	return TRUE;
 894 }
 895 
 896 /**
 897  * tracker_miner_manager_pause_for_process:
 898  * @manager: a #TrackerMinerManager.
 899  * @miner: miner reference
 900  * @reason: reason to pause
 901  * @cookie: (out) (allow-none): return location for the pause cookie ID
 902  *
 903  * This function operates exactly the same way as
 904  * tracker_miner_manager_pause() with the exception that if the calling
 905  * process dies, the pause is resumed. This API is useful for cases
 906  * where the calling process has a risk of crashing without resuming
 907  * the pause.
 908  *
 909  * NOTE: If you call g_object_unref() on the @manager before you
 910  * intend to resume the pause and it finalizes, it will automatically
 911  * resume.
 912  *
 913  * Returns: %TRUE if the miner was paused successfully, otherwise
 914  * %FALSE.
 915  *
 916  * Since: 0.10.15
 917  **/
 918 gboolean
 919 tracker_miner_manager_pause_for_process (TrackerMinerManager *manager,
 920                                          const gchar         *miner,
 921                                          const gchar         *reason,
 922                                          guint32             *cookie)
 923 {
 924 	GDBusProxy *proxy;
 925 	const gchar *app_name;
 926 	GError *error = NULL;
 927 	GVariant *v;
 928 
 929 	g_return_val_if_fail (TRACKER_IS_MINER_MANAGER (manager), FALSE);
 930 	g_return_val_if_fail (miner != NULL, FALSE);
 931 	g_return_val_if_fail (reason != NULL, FALSE);
 932 
 933 	proxy = find_miner_proxy (manager, miner, TRUE);
 934 
 935 	if (!proxy) {
 936 		g_critical ("No D-Bus proxy found for miner '%s'", miner);
 937 		return FALSE;
 938 	}
 939 
 940 	/* Find a reasonable app name */
 941 	app_name = g_get_application_name ();
 942 
 943 	if (!app_name) {
 944 		app_name = g_get_prgname ();
 945 	}
 946 
 947 	if (!app_name) {
 948 		app_name = "TrackerMinerManager client";
 949 	}
 950 
 951 	v = g_dbus_proxy_call_sync (proxy,
 952 	                            "PauseForProcess",
 953 	                            g_variant_new ("(ss)", app_name, reason),
 954 	                            G_DBUS_CALL_FLAGS_NONE,
 955 	                            -1,
 956 	                            NULL,
 957 	                            &error);
 958 
 959 	if (error) {
 960 		g_critical ("Could not pause miner '%s': %s", miner, error->message);
 961 		g_error_free (error);
 962 		return FALSE;
 963 	}
 964 
 965 	if (cookie) {
 966 		g_variant_get (v, "(i)", cookie);
 967 	}
 968 
 969 	g_variant_unref (v);
 970 
 971 	return TRUE;
 972 }
 973 
 974 /**
 975  * tracker_miner_manager_resume:
 976  * @manager: a #TrackerMinerManager
 977  * @miner: miner reference
 978  * @cookie: pause cookie
 979  *
 980  * Tells @miner to resume activity. The miner won't actually resume
 981  * operations until all pause requests have been resumed.
 982  *
 983  * Returns: %TRUE if the miner was successfully resumed, otherwise
 984  * %FALSE.
 985  *
 986  * Since: 0.8
 987  **/
 988 gboolean
 989 tracker_miner_manager_resume (TrackerMinerManager *manager,
 990                               const gchar         *miner,
 991                               guint32              cookie)
 992 {
 993 	GDBusProxy *proxy;
 994 	GError *error = NULL;
 995 	GVariant *v;
 996 
 997 	g_return_val_if_fail (TRACKER_IS_MINER_MANAGER (manager), FALSE);
 998 	g_return_val_if_fail (miner != NULL, FALSE);
 999 	proxy = find_miner_proxy (manager, miner, TRUE);
1000 
1001 	if (!proxy) {
1002 		g_critical ("No D-Bus proxy found for miner '%s'", miner);
1003 		return FALSE;
1004 	}
1005 
1006 	v = g_dbus_proxy_call_sync (proxy,
1007 	                            "Resume",
1008 	                            g_variant_new ("(i)", (gint) cookie),
1009 	                            G_DBUS_CALL_FLAGS_NONE,
1010 	                            -1,
1011 	                            NULL,
1012 	                            &error);
1013 
1014 	if (error) {
1015 		g_critical ("Could not resume miner '%s': %s", miner, error->message);
1016 		g_error_free (error);
1017 		return FALSE;
1018 	}
1019 
1020 	g_variant_unref (v);
1021 
1022 	return TRUE;
1023 }
1024 
1025 /**
1026  * tracker_miner_manager_is_active:
1027  * @manager: a #TrackerMinerManager
1028  * @miner: miner reference
1029  *
1030  * Returns the miner's current activity.
1031  *
1032  * Returns: %TRUE if the @miner is active, otherwise %FALSE.
1033  *
1034  * Since: 0.8
1035  **/
1036 gboolean
1037 tracker_miner_manager_is_active (TrackerMinerManager *manager,
1038                                  const gchar         *miner)
1039 {
1040 	TrackerMinerManagerPrivate *priv;
1041 	GError *error = NULL;
1042 	gboolean active = FALSE;
1043 	GVariant *v;
1044 
1045 	g_return_val_if_fail (TRACKER_IS_MINER_MANAGER (manager), FALSE);
1046 	g_return_val_if_fail (miner != NULL, FALSE);
1047 
1048 	priv = TRACKER_MINER_MANAGER_GET_PRIVATE (manager);
1049 
1050 	v = g_dbus_connection_call_sync (priv->connection,
1051 	                                 "org.freedesktop.DBus",
1052 	                                 "/org/freedesktop/DBus",
1053 	                                 "org.freedesktop.DBus",
1054 	                                 "NameHasOwner",
1055 	                                 g_variant_new ("(s)", miner),
1056 	                                 (GVariantType *) "(b)",
1057 	                                 G_DBUS_CALL_FLAGS_NONE,
1058 	                                 -1,
1059 	                                 NULL,
1060 	                                 &error);
1061 
1062 	if (error) {
1063 		g_critical ("Could not check whether miner '%s' is currently active: %s",
1064 		            miner, error ? error->message : "no error given");
1065 		g_error_free (error);
1066 		return FALSE;
1067 	}
1068 
1069 	g_variant_get (v, "(b)", &active);
1070 	g_variant_unref (v);
1071 
1072 	return active;
1073 }
1074 
1075 /**
1076  * tracker_miner_manager_get_status:
1077  * @manager: a #TrackerMinerManager
1078  * @miner: miner reference
1079  * @status: (out) (allow-none): return location for status
1080  * @progress: (out) (allow-none): return location for progress
1081  * @remaining_time: (out) (allow-none): return location for remaining time
1082  *
1083  * Returns the current status, progress and remaining time for @miner.
1084  * @remaining_time will be 0 if not possible to compute it yet,
1085  * and less than zero if it is not applicable.
1086  *
1087  * Returns: %TRUE if the status could be retrieved successfully,
1088  * otherwise %FALSE
1089  *
1090  * Since: 0.12
1091  **/
1092 gboolean
1093 tracker_miner_manager_get_status (TrackerMinerManager  *manager,
1094                                   const gchar          *miner,
1095                                   gchar               **status,
1096                                   gdouble              *progress,
1097                                   gint                 *remaining_time)
1098 {
1099 	GDBusProxy *proxy;
1100 
1101 	g_return_val_if_fail (TRACKER_IS_MINER_MANAGER (manager), FALSE);
1102 	g_return_val_if_fail (miner != NULL, FALSE);
1103 	/* At least one of them should be asked */
1104 	g_return_val_if_fail (status != NULL ||
1105 	                      progress != NULL ||
1106 	                      remaining_time != NULL, FALSE);
1107 
1108 	proxy = find_miner_proxy (manager, miner, TRUE);
1109 
1110 	if (!proxy) {
1111 		g_critical ("No D-Bus proxy found for miner '%s'", miner);
1112 		return FALSE;
1113 	}
1114 
1115 	if (progress) {
1116 		GError *error = NULL;
1117 		GVariant *v;
1118 
1119 		v = g_dbus_proxy_call_sync (proxy,
1120 		                            "GetProgress",
1121 		                            NULL,
1122 		                            G_DBUS_CALL_FLAGS_NONE,
1123 		                            -1,
1124 		                            NULL,
1125 		                            &error);
1126 		if (error) {
1127 			/* We handle this error as a special case, some
1128 			 * plugins don't have .service files.
1129 			 */
1130 			if (error->code != G_DBUS_ERROR_SERVICE_UNKNOWN) {
1131 				g_critical ("Could not get miner progress for '%s': %s", miner,
1132 				            error->message);
1133 			}
1134 
1135 			g_error_free (error);
1136 
1137 			return FALSE;
1138 		}
1139 
1140 		g_variant_get (v, "(d)", progress);
1141 		g_variant_unref (v);
1142 	}
1143 
1144 	if (status) {
1145 		GError *error = NULL;
1146 		GVariant *v;
1147 
1148 		v = g_dbus_proxy_call_sync (proxy,
1149 		                            "GetStatus",
1150 		                            NULL,
1151 		                            G_DBUS_CALL_FLAGS_NONE,
1152 		                            -1,
1153 		                            NULL,
1154 		                            &error);
1155 		if (error) {
1156 			g_critical ("Could not get miner status for '%s': %s", miner,
1157 			            error->message);
1158 			g_error_free (error);
1159 			return FALSE;
1160 		}
1161 
1162 		g_variant_get (v, "(s)", status);
1163 		g_variant_unref (v);
1164 	}
1165 
1166 	if (remaining_time) {
1167 		GError *error = NULL;
1168 		GVariant *v;
1169 
1170 		v = g_dbus_proxy_call_sync (proxy,
1171 		                            "GetRemainingTime",
1172 		                            NULL,
1173 		                            G_DBUS_CALL_FLAGS_NONE,
1174 		                            -1,
1175 		                            NULL,
1176 		                            &error);
1177 		if (error) {
1178 			g_critical ("Could not get miner remaining processing "
1179 			            "time for '%s': %s", miner,
1180 			            error->message);
1181 			g_error_free (error);
1182 			return FALSE;
1183 		}
1184 
1185 		g_variant_get (v, "(i)", remaining_time);
1186 		g_variant_unref (v);
1187 	}
1188 
1189 	return TRUE;
1190 }
1191 
1192 /**
1193  * tracker_miner_manager_is_paused:
1194  * @manager: a #TrackerMinerManager
1195  * @miner: miner reference
1196  * @applications: (out callee-allocates) (allow-none) (transfer full):
1197  * return location for application names.
1198  * @reasons: (out callee-allocates) (allow-none) (transfer full):
1199  * return location for pause reasons.
1200  *
1201  * This function either returns %FALSE if the miner is not paused,
1202  * or returns %TRUE and fills in @applications and @reasons with
1203  * the pause reasons and the applications that asked for it. Both
1204  * arrays will have the same lengh, and will be sorted so the
1205  * application/pause reason pairs have the same index.
1206  *
1207  * Returns: %TRUE if @miner is paused, otherwise %FALSE.
1208  *
1209  * Since: 0.8
1210  **/
1211 gboolean
1212 tracker_miner_manager_is_paused (TrackerMinerManager *manager,
1213                                  const gchar         *miner,
1214                                  GStrv               *applications,
1215                                  GStrv               *reasons)
1216 {
1217 	GDBusProxy *proxy;
1218 	GStrv apps, r;
1219 	GError *error = NULL;
1220 	gboolean paused;
1221 	GVariant *v;
1222 
1223 	if (applications) {
1224 		*applications = NULL;
1225 	}
1226 
1227 	if (reasons) {
1228 		*reasons = NULL;
1229 	}
1230 
1231 	g_return_val_if_fail (TRACKER_IS_MINER_MANAGER (manager), TRUE);
1232 	g_return_val_if_fail (miner != NULL, TRUE);
1233 
1234 	proxy = find_miner_proxy (manager, miner, TRUE);
1235 
1236 	if (!proxy) {
1237 		g_critical ("No D-Bus proxy found for miner '%s'", miner);
1238 		return FALSE;
1239 	}
1240 
1241 	v = g_dbus_proxy_call_sync (proxy,
1242 	                            "GetPauseDetails",
1243 	                            NULL,
1244 	                            G_DBUS_CALL_FLAGS_NONE,
1245 	                            -1,
1246 	                            NULL,
1247 	                            &error);
1248 
1249 	if (error) {
1250 		g_critical ("Could not get pause details for miner '%s': %s", miner,
1251 		            error->message);
1252 		g_error_free (error);
1253 		return FALSE;
1254 	}
1255 
1256 	g_variant_get (v, "(^as^as)", &apps, &r);
1257 	g_variant_unref (v);
1258 
1259 	paused = (g_strv_length (apps) > 0);
1260 
1261 	if (applications) {
1262 		*applications = apps;
1263 	} else {
1264 		g_strfreev (apps);
1265 	}
1266 
1267 	if (reasons) {
1268 		*reasons = r;
1269 	} else  {
1270 		g_strfreev (r);
1271 	}
1272 
1273 	return paused;
1274 }
1275 
1276 /**
1277  * tracker_miner_manager_get_display_name:
1278  * @manager: a #TrackerMinerManager
1279  * @miner: miner reference
1280  *
1281  * Returns a translated display name for @miner.
1282  *
1283  * Returns: (transfer none): A string which should not be freed or %NULL.
1284  *
1285  * Since: 0.8
1286  **/
1287 const gchar *
1288 tracker_miner_manager_get_display_name (TrackerMinerManager *manager,
1289                                         const gchar         *miner)
1290 {
1291 	TrackerMinerManagerPrivate *priv;
1292 	GList *m;
1293 
1294 	g_return_val_if_fail (TRACKER_IS_MINER_MANAGER (manager), NULL);
1295 	g_return_val_if_fail (miner != NULL, NULL);
1296 
1297 	priv = TRACKER_MINER_MANAGER_GET_PRIVATE (manager);
1298 
1299 	for (m = priv->miners; m; m = m->next) {
1300 		MinerData *data = m->data;
1301 
1302 		if (strcmp (miner, data->dbus_name) == 0) {
1303 			return data->display_name;
1304 		}
1305 	}
1306 
1307 	return NULL;
1308 }
1309 
1310 /**
1311  * tracker_miner_manager_get_description:
1312  * @manager: a #TrackerMinerManager
1313  * @miner: miner reference
1314  *
1315  * Returns the description for the given @miner.
1316  *
1317  * Returns: (transfer none): A string which should not be freed or %NULL if none is specified.
1318  *
1319  * Since: 0.8
1320  **/
1321 const gchar *
1322 tracker_miner_manager_get_description (TrackerMinerManager *manager,
1323                                        const gchar         *miner)
1324 {
1325 	TrackerMinerManagerPrivate *priv;
1326 	GList *m;
1327 
1328 	g_return_val_if_fail (TRACKER_IS_MINER_MANAGER (manager), NULL);
1329 	g_return_val_if_fail (miner != NULL, NULL);
1330 
1331 	priv = TRACKER_MINER_MANAGER_GET_PRIVATE (manager);
1332 
1333 	for (m = priv->miners; m; m = m->next) {
1334 		MinerData *data = m->data;
1335 
1336 		if (strcmp (miner, data->dbus_name) == 0) {
1337 			return data->description;
1338 		}
1339 	}
1340 
1341 	return NULL;
1342 }
1343 
1344 #ifndef TRACKER_DISABLE_DEPRECATED
1345 
1346 /**
1347  * tracker_miner_manager_ignore_next_update:
1348  * @manager: a #TrackerMinerManager
1349  * @miner: miner reference
1350  * @urls: (in): the subjects to ignore the next updates of
1351  *
1352  * Tells the @miner to ignore any events for the next @urls. This is
1353  * used for cases where a file is updated by Tracker by the
1354  * tracker-writeback service. This API is used to avoid signalling up
1355  * the stack the changes to @urls.
1356  *
1357  * Returns: %TRUE on success, otherwise %FALSE.
1358  *
1359  * Since: 0.8
1360  *
1361  * Deprecated: 0.12
1362  **/
1363 gboolean
1364 tracker_miner_manager_ignore_next_update (TrackerMinerManager *manager,
1365                                           const gchar         *miner,
1366                                           const gchar        **urls)
1367 {
1368 	GDBusProxy *proxy;
1369 	GError *error = NULL;
1370 	GVariant *v;
1371 
1372 	g_return_val_if_fail (TRACKER_IS_MINER_MANAGER (manager), FALSE);
1373 	g_return_val_if_fail (miner != NULL, FALSE);
1374 
1375 	proxy = find_miner_proxy (manager, miner, TRUE);
1376 
1377 	if (!proxy) {
1378 		g_warning ("No D-Bus proxy found for miner '%s'", miner);
1379 		return FALSE;
1380 	}
1381 
1382 	v = g_dbus_proxy_call_sync (proxy,
1383 	                            "IgnoreNextUpdate",
1384 	                            g_variant_new ("(^as)", urls),
1385 	                            G_DBUS_CALL_FLAGS_NONE,
1386 	                            -1,
1387 	                            NULL,
1388 	                            &error);
1389 
1390 	if (error) {
1391 		g_warning ("Could not ignore next update for miner '%s': %s", miner, error->message);
1392 		g_error_free (error);
1393 		return FALSE;
1394 	}
1395 
1396 	g_variant_unref (v);
1397 
1398 	return TRUE;
1399 }
1400 
1401 #endif /* TRACKER_DISABLE_DEPRECATED */
1402 
1403 /**
1404  * tracker_miner_manager_error_quark:
1405  *
1406  * Returns: the #GQuark used to identify miner manager errors in
1407  * GError structures.
1408  *
1409  * Since: 0.8
1410  **/
1411 GQuark
1412 tracker_miner_manager_error_quark (void)
1413 {
1414 	static GQuark error_quark = 0;
1415 
1416 	if (G_UNLIKELY (error_quark == 0)) {
1417 		error_quark = g_quark_from_static_string ("tracker-miner-manager-error-quark");
1418 	}
1419 
1420 	return error_quark;
1421 }
1422 
1423 /**
1424  * tracker_miner_manager_reindex_by_mimetype:
1425  * @manager: a #TrackerMinerManager
1426  * @mimetypes: (in): an array of mimetypes (E.G. "text/plain"). All items
1427  * with a mimetype in that list will be reindexed.
1428  * @error: (out callee-allocates) (transfer full) (allow-none): return location for errors
1429  *
1430  * Tells the filesystem miner to reindex any file with a mimetype in
1431  * the @mimetypes list.
1432  *
1433  * On failure @error will be set.
1434  *
1435  * Returns: %TRUE on success, otherwise %FALSE.
1436  *
1437  * Since: 0.10
1438  **/
1439 gboolean
1440 tracker_miner_manager_reindex_by_mimetype (TrackerMinerManager  *manager,
1441                                            const GStrv           mimetypes,
1442                                            GError              **error)
1443 {
1444 	TrackerMinerManagerPrivate *priv;
1445 	GVariant *v;
1446 	GError *new_error = NULL;
1447 
1448 	g_return_val_if_fail (TRACKER_IS_MINER_MANAGER (manager), FALSE);
1449 	g_return_val_if_fail (mimetypes != NULL, FALSE);
1450 
1451 	if (!tracker_miner_manager_is_active (manager,
1452 	                                      "org.freedesktop.Tracker1.Miner.Files")) {
1453 		g_set_error_literal (error,
1454 		                     TRACKER_MINER_MANAGER_ERROR,
1455 		                     TRACKER_MINER_MANAGER_ERROR_NOT_AVAILABLE,
1456 		                     "Filesystem miner is not active");
1457 		return FALSE;
1458 	}
1459 
1460 	priv = TRACKER_MINER_MANAGER_GET_PRIVATE (manager);
1461 
1462 	v = g_dbus_connection_call_sync (priv->connection,
1463 	                                 "org.freedesktop.Tracker1.Miner.Files.Index",
1464 	                                 "/org/freedesktop/Tracker1/Miner/Files/Index",
1465 	                                 "org.freedesktop.Tracker1.Miner.Files.Index",
1466 	                                 "ReindexMimeTypes",
1467 	                                 g_variant_new ("(^as)", mimetypes),
1468 	                                 NULL,
1469 	                                 G_DBUS_CALL_FLAGS_NONE,
1470 	                                 -1,
1471 	                                 NULL,
1472 	                                 &new_error);
1473 
1474 	if (new_error) {
1475 		g_propagate_error (error, new_error);
1476 		return FALSE;
1477 	}
1478 
1479 	g_variant_unref (v);
1480 
1481 	return FALSE;
1482 }
1483 
1484 static gboolean
1485 miner_manager_index_file_sync (TrackerMinerManager *manager,
1486                                GFile               *file,
1487                                GCancellable        *cancellable,
1488                                GError             **error)
1489 {
1490 	TrackerMinerManagerPrivate *priv;
1491 	gchar *uri;
1492 	GVariant *v;
1493 	GError *new_error = NULL;
1494 
1495 	if (!g_file_query_exists (file, cancellable)) {
1496 		g_set_error_literal (error,
1497 		                     TRACKER_MINER_MANAGER_ERROR,
1498 		                     TRACKER_MINER_MANAGER_ERROR_NOENT,
1499 		                     "File or directory does not exist");
1500 		return FALSE;
1501 	}
1502 
1503 	if (!tracker_miner_manager_is_active (manager,
1504 	                                      "org.freedesktop.Tracker1.Miner.Files")) {
1505 		g_set_error_literal (error,
1506 		                     TRACKER_MINER_MANAGER_ERROR,
1507 		                     TRACKER_MINER_MANAGER_ERROR_NOT_AVAILABLE,
1508 		                     "Filesystem miner is not active");
1509 		return FALSE;
1510 	}
1511 
1512 	priv = TRACKER_MINER_MANAGER_GET_PRIVATE (manager);
1513 
1514 	uri = g_file_get_uri (file);
1515 
1516 	v = g_dbus_connection_call_sync (priv->connection,
1517 	                                 "org.freedesktop.Tracker1.Miner.Files.Index",
1518 	                                 "/org/freedesktop/Tracker1/Miner/Files/Index",
1519 	                                 "org.freedesktop.Tracker1.Miner.Files.Index",
1520 	                                 "IndexFile",
1521 	                                 g_variant_new ("(s)", uri),
1522 	                                 NULL,
1523 	                                 G_DBUS_CALL_FLAGS_NONE,
1524 	                                 -1,
1525 	                                 cancellable,
1526 	                                 &new_error);
1527 
1528 	g_free (uri);
1529 
1530 	if (new_error) {
1531 		g_propagate_error (error, new_error);
1532 		return FALSE;
1533 	}
1534 
1535 	g_variant_unref (v);
1536 
1537 	return FALSE;
1538 }
1539 
1540 static void
1541 miner_manager_index_file_thread (GTask *task,
1542                                  gpointer source_object,
1543                                  gpointer task_data,
1544                                  GCancellable *cancellable)
1545 {
1546 	TrackerMinerManager *manager = source_object;
1547 	GFile *file = task_data;
1548 	GError *error = NULL;
1549 
1550 	miner_manager_index_file_sync (manager, file, cancellable, &error);
1551 	if (error != NULL) {
1552 		g_task_return_error (task, error);
1553 	} else {
1554 		g_task_return_boolean (task, TRUE);
1555 	}
1556 }
1557 
1558 /**
1559  * tracker_miner_manager_index_file:
1560  * @manager: a #TrackerMinerManager
1561  * @file: a URL valid in GIO of a file to give to the miner for processing
1562  * @error: (out callee-allocates) (transfer full) (allow-none): return location for errors
1563  *
1564  * Tells the filesystem miner to index the @file.
1565  *
1566  * On failure @error will be set.
1567  *
1568  * Returns: %TRUE on success, otherwise %FALSE.
1569  *
1570  * Since: 0.10
1571  **/
1572 gboolean
1573 tracker_miner_manager_index_file (TrackerMinerManager  *manager,
1574                                   GFile                *file,
1575                                   GError              **error)
1576 {
1577 	g_return_val_if_fail (TRACKER_IS_MINER_MANAGER (manager), FALSE);
1578 	g_return_val_if_fail (G_IS_FILE (file), FALSE);
1579 
1580 	return miner_manager_index_file_sync (manager, file, NULL, error);
1581 }
1582 
1583 /**
1584  * tracker_miner_manager_index_file_async:
1585  * @manager: a #TrackerMinerManager
1586  * @file: a URL valid in GIO of a file to give to the miner for processing
1587  * @cancellable: (allow-none): a #GCancellable, or %NULL
1588  * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
1589  * @user_data: the data to pass to the callback function
1590  *
1591  * Tells the filesystem miner to index the @file. When the operation is called,
1592  * @callback will be called. You can then call tracker_miner_manager_index_file_finish()
1593  * to get the result of the operation.
1594  *
1595  * Since: 0.16
1596  **/
1597 void
1598 tracker_miner_manager_index_file_async (TrackerMinerManager *manager,
1599                                         GFile               *file,
1600                                         GCancellable        *cancellable,
1601                                         GAsyncReadyCallback  callback,
1602                                         gpointer             user_data)
1603 {
1604 	GTask *task = g_task_new (manager, cancellable, callback, user_data);
1605 	g_task_set_task_data (task, g_object_ref (file), (GDestroyNotify) g_object_unref);
1606 	g_task_run_in_thread (task, miner_manager_index_file_thread);
1607 	g_object_unref (task);
1608 }
1609 
1610 /**
1611  * tracker_miner_manager_index_file_finish:
1612  * @manager: a #TrackerMinerManager
1613  * @result: a #GAsyncResult
1614  * @error: (out callee-allocates) (transfer full) (allow-none): return location for errors
1615  *
1616  * Finishes a request to index a file. See tracker_miner_manager_index_file_async()
1617  *
1618  * On failure @error will be set.
1619  *
1620  * Returns: %TRUE on success, otherwise %FALSE.
1621  *
1622  * Since: 0.16
1623  **/
1624 gboolean
1625 tracker_miner_manager_index_file_finish (TrackerMinerManager *manager,
1626                                          GAsyncResult        *result,
1627                                          GError             **error)
1628 {
1629 	return g_task_propagate_boolean (G_TASK (result), error);
1630 }