[rygel-gst-0-10-plugins/wip/tracking: 7/8] Add code for tracking changes in some places.



commit 7722f1eab2fd73fd3e63a20f1c4def76dbedeb2d
Author: Krzesimir Nowak <krnowak openismus com>
Date:   Wed Feb 20 16:43:33 2013 +0100

    Add code for tracking changes in some places.

 .../rygel-media-export-dummy-container.c           |   19 ++-
 .../rygel-media-export-dummy-container.h           |    6 +-
 src/media-export/rygel-media-export-harvester.c    |   17 +-
 .../rygel-media-export-harvesting-task.c           |  119 +++++++---
 src/media-export/rygel-media-export-music-item.c   |   20 ++-
 .../rygel-media-export-object-factory.c            |    3 +-
 src/media-export/rygel-media-export-photo-item.c   |   20 ++-
 src/media-export/rygel-media-export-plugin.c       |    3 +-
 .../rygel-media-export-root-container.c            |  271 ++++++++++++--------
 .../rygel-media-export-root-container.h            |    6 +-
 src/media-export/rygel-media-export-video-item.c   |   20 +-
 .../rygel-media-export-writable-db-container.c     |   49 ++--
 .../rygel-media-export-writable-db-container.h     |    6 +-
 13 files changed, 360 insertions(+), 199 deletions(-)
---
diff --git a/src/media-export/rygel-media-export-dummy-container.c 
b/src/media-export/rygel-media-export-dummy-container.c
index 085523b..fe13ba2 100644
--- a/src/media-export/rygel-media-export-dummy-container.c
+++ b/src/media-export/rygel-media-export-dummy-container.c
@@ -24,7 +24,7 @@
 
 G_DEFINE_TYPE (RygelMediaExportDummyContainer,
                rygel_media_export_dummy_container,
-               RYGEL_MEDIA_EXPORT_TYPE_NULL_CONTAINER)
+               RYGEL_MEDIA_EXPORT_TYPE_TRACKABLE_DB_CONTAINER)
 
 struct _RygelMediaExportDummyContainerPrivate {
   GFile *file;
@@ -131,13 +131,30 @@ rygel_media_export_dummy_container_constructed (GObject *object)
 {
   RygelMediaExportDummyContainer *dummy = RYGEL_MEDIA_EXPORT_DUMMY_CONTAINER (object);
   RygelMediaObject *media_object = RYGEL_MEDIA_OBJECT (object);
+  RygelMediaContainer *media_container = RYGEL_MEDIA_CONTAINER (object);
   GeeAbstractCollection *uris;
   gchar *uri = g_file_get_uri (dummy->priv->file);
+  RygelMediaExportMediaCache *media_db;
+  guint32 object_update_id = 0;
+  guint32 container_update_id = 0;
+  guint32 total_deleted_child_count = 0;
 
   G_OBJECT_CLASS (rygel_media_export_dummy_container_parent_class)->constructed (object);
   uris = GEE_ABSTRACT_COLLECTION (media_object->uris);
   gee_abstract_collection_add (uris, uri);
   g_free (uri);
+
+  media_db = rygel_media_export_media_cache_get_default ();
+  rygel_media_export_media_cache_get_track_properties (media_db,
+                                                       rygel_media_object_get_id (media_object),
+                                                       &object_update_id,
+                                                       &container_update_id,
+                                                       &total_deleted_child_count);
+  g_object_unref (media_db);
+
+  rygel_media_object_set_object_update_id (media_object, object_update_id);
+  media_container->update_id = container_update_id;
+  media_container->total_deleted_child_count = total_deleted_child_count;
 }
 
 static void
diff --git a/src/media-export/rygel-media-export-dummy-container.h 
b/src/media-export/rygel-media-export-dummy-container.h
index f27514f..7899b43 100644
--- a/src/media-export/rygel-media-export-dummy-container.h
+++ b/src/media-export/rygel-media-export-dummy-container.h
@@ -26,7 +26,7 @@
 #include <gio/gio.h>
 #include <gee.h>
 
-#include "rygel-media-export-null-container.h"
+#include "rygel-media-export-trackable-db-container.h"
 
 G_BEGIN_DECLS
 
@@ -42,12 +42,12 @@ typedef struct _RygelMediaExportDummyContainerClass RygelMediaExportDummyContain
 typedef struct _RygelMediaExportDummyContainerPrivate RygelMediaExportDummyContainerPrivate;
 
 struct _RygelMediaExportDummyContainer {
-  RygelMediaExportNullContainer parent_instance;
+  RygelMediaExportTrackableDbContainer parent_instance;
   RygelMediaExportDummyContainerPrivate* priv;
 };
 
 struct _RygelMediaExportDummyContainerClass {
-  RygelMediaExportNullContainerClass parent_class;
+  RygelMediaExportTrackableDbContainerClass parent_class;
 };
 
 GType
diff --git a/src/media-export/rygel-media-export-harvester.c b/src/media-export/rygel-media-export-harvester.c
index e63e97a..3f1d1eb 100644
--- a/src/media-export/rygel-media-export-harvester.c
+++ b/src/media-export/rygel-media-export-harvester.c
@@ -154,7 +154,8 @@ rygel_media_export_harvester_on_file_added (RygelMediaExportHarvester *self,
         current = parent;
       }
       g_object_unref (parent);
-      if (gee_abstract_collection_contains (abstract_locations, current)) {
+      if (!parent_container &&
+          gee_abstract_collection_contains (abstract_locations, current)) {
         RygelMediaObject* another_object = rygel_media_export_media_cache_get_object (cache,
                                                                                       
RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_FILESYSTEM_FOLDER_ID,
                                                                                       &error);
@@ -296,17 +297,8 @@ rygel_media_export_harvester_on_file_removed (RygelMediaExportHarvester  *self,
       g_object_unref (parent);
     }
     parent = tmp_parent;
-    rygel_media_export_media_cache_remove_object (cache, object, &inner_error);
-    if (inner_error) {
-      if (parent) {
-        g_object_unref (parent);
-      }
-      g_object_unref (object);
-      g_warning (_("Error removing object from database: %s"),
-                 inner_error->message);
-      g_error_free (inner_error);
-
-      goto out;
+    if (RYGEL_IS_TRACKABLE_CONTAINER (parent)) {
+      rygel_trackable_container_remove_child_tracked (RYGEL_TRACKABLE_CONTAINER (parent), object, NULL, 
NULL);
     }
     if (!parent) {
       break;
@@ -321,6 +313,7 @@ rygel_media_export_harvester_on_file_removed (RygelMediaExportHarvester  *self,
   }
   if (parent) {
     rygel_media_container_updated (parent, NULL, RYGEL_OBJECT_EVENT_TYPE_MODIFIED, FALSE);
+    rygel_media_export_media_cache_save_container (cache, parent, NULL);
   }
  out:
   if (parent) {
diff --git a/src/media-export/rygel-media-export-harvesting-task.c 
b/src/media-export/rygel-media-export-harvesting-task.c
index 52c19a5..db522df 100644
--- a/src/media-export/rygel-media-export-harvesting-task.c
+++ b/src/media-export/rygel-media-export-harvesting-task.c
@@ -40,6 +40,7 @@ G_DEFINE_TYPE_WITH_CODE (RygelMediaExportHarvestingTask,
 
 typedef struct _RygelMediaExportHarvestingTaskRunData RygelMediaExportHarvestingTaskRunData;
 typedef struct _RygelMediaExportHarvestingTaskEnumerateDirectoryData 
RygelMediaExportHarvestingTaskEnumerateDirectoryData;
+typedef struct _FileQueueEntry FileQueueEntry;
 
 struct _RygelMediaExportHarvestingTaskPrivate {
   RygelMediaExportMetadataExtractor *extractor;
@@ -66,6 +67,52 @@ struct _RygelMediaExportHarvestingTaskEnumerateDirectoryData {
   RygelMediaExportDummyContainer *container;
 };
 
+struct _FileQueueEntry {
+  volatile gint ref_count;
+  GFile *file;
+  gboolean known;
+};
+
+FileQueueEntry *
+file_queue_entry_new (GFile *file,
+                      gboolean known) {
+  FileQueueEntry *entry;
+
+  g_return_val_if_fail (G_IS_FILE (file), NULL);
+
+  entry = g_new (FileQueueEntry, 1);
+  entry->ref_count = 1;
+  entry->file = g_object_ref (file);
+  entry->known = known;
+
+  return entry;
+}
+
+FileQueueEntry *
+file_queue_entry_ref (FileQueueEntry *self) {
+  g_return_val_if_fail (self != NULL, NULL);
+
+  g_atomic_int_inc (&self->ref_count);
+
+  return self;
+}
+
+void
+file_queue_entry_unref (FileQueueEntry *self) {
+  g_return_if_fail (self != NULL);
+
+  if (g_atomic_int_dec_and_test (&self->ref_count)) {
+    g_object_unref (self->file);
+    g_free (self);
+  }
+}
+
+#define RYGEL_MEDIA_EXPORT_TYPE_FILE_QUEUE_ENTRY (file_queue_entry_get_type ())
+
+G_DEFINE_BOXED_TYPE (FileQueueEntry,
+                     file_queue_entry,
+                     file_queue_entry_ref,
+                     file_queue_entry_unref)
 
 #define RYGEL_MEDIA_EXPORT_HARVESTING_TASK_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), 
RYGEL_MEDIA_EXPORT_TYPE_HARVESTING_TASK, RygelMediaExportHarvestingTaskPrivate))
 enum  {
@@ -195,11 +242,11 @@ rygel_media_export_harvesting_task_push_if_changed_or_unknown (RygelMediaExportH
 
     if (mtime > timestamp ||
         g_file_info_get_size (info) != size) {
-      gee_queue_offer (priv->files, file);
+      gee_queue_offer (priv->files, file_queue_entry_new (file, TRUE));
       return TRUE;
     }
   } else {
-    gee_queue_offer (priv->files, file);
+    gee_queue_offer (priv->files, file_queue_entry_new (file, FALSE));
     return TRUE;
   }
 
@@ -401,15 +448,15 @@ rygel_media_export_harvesting_task_on_idle (RygelMediaExportHarvestingTask *self
   }
 
   if (!gee_collection_get_is_empty (GEE_COLLECTION (priv->files))) {
-    GFile *file;
+    FileQueueEntry *entry;
     gchar *uri;
 
-    file = G_FILE (gee_queue_peek (self->priv->files));
-    uri = g_file_get_uri (file);
+    entry = gee_queue_peek (self->priv->files);
+    uri = g_file_get_uri (entry->file);
     g_debug ("Scheduling file %s for meta-data extraction…", uri);
     g_free (uri);
-    rygel_media_export_metadata_extractor_extract (priv->extractor, file);
-    g_object_unref (file);
+    rygel_media_export_metadata_extractor_extract (priv->extractor, entry->file);
+    file_queue_entry_unref (entry);
   } else if (!g_queue_is_empty (priv->containers)) {
       rygel_media_export_harvesting_task_enumerate_directory (self, NULL, NULL);
   } else {
@@ -417,6 +464,7 @@ rygel_media_export_harvesting_task_on_idle (RygelMediaExportHarvestingTask *self
       rygel_media_export_media_cache_flag_object (priv->cache, priv->origin, priv->flag, NULL);
     }
     rygel_media_container_updated (priv->parent, RYGEL_MEDIA_OBJECT (priv->parent), 
RYGEL_OBJECT_EVENT_TYPE_MODIFIED, FALSE);
+    rygel_media_export_media_cache_save_container (priv->cache, priv->parent, NULL);
     g_signal_emit_by_name (RYGEL_STATE_MACHINE (self), "completed");
   }
   return FALSE;
@@ -445,13 +493,13 @@ rygel_media_export_harvesting_task_do_update (RygelMediaExportHarvestingTask *se
     if (error) {
       goto out;
     }
-    if (size > 0) {
-      rygel_media_container_updated (container, RYGEL_MEDIA_OBJECT (container), 
RYGEL_OBJECT_EVENT_TYPE_MODIFIED, FALSE);
-    } else {
-      rygel_media_export_media_cache_remove_by_id (priv->cache, rygel_media_object_get_id 
(RYGEL_MEDIA_OBJECT (container)), &error);
-      if (error) {
-        goto out;
-      }
+    if (size == 0) {
+      RygelTrackableContainer *trackable = RYGEL_TRACKABLE_CONTAINER (rygel_media_object_get_parent 
(RYGEL_MEDIA_OBJECT (container)));
+
+      rygel_trackable_container_remove_child_tracked (trackable,
+                                                      RYGEL_MEDIA_OBJECT (container),
+                                                      NULL,
+                                                      NULL);
     }
   out:
     if (error) {
@@ -472,7 +520,7 @@ rygel_media_export_harvesting_task_on_extracted_cb (RygelMediaExportHarvestingTa
                                                     GFileInfo                      *file_info) {
   RygelMediaExportHarvestingTaskPrivate *priv;
   gboolean ignore;
-  GFile *top_file;
+  FileQueueEntry *entry;
   RygelMediaItem *item;
   RygelMediaContainer *container;
 
@@ -488,12 +536,10 @@ rygel_media_export_harvesting_task_on_extracted_cb (RygelMediaExportHarvestingTa
     g_signal_emit_by_name (RYGEL_STATE_MACHINE (self), "completed");
   }
 
-  top_file = gee_queue_peek (priv->files);
-  ignore = (!top_file || !g_file_equal (file, top_file));
-  if (top_file) {
-    g_object_unref (top_file);
-  }
+  entry = gee_queue_peek (priv->files);
+  ignore = (!entry->file || !g_file_equal (file, entry->file));
   if (ignore) {
+    file_queue_entry_unref (entry);
     return;
   }
   container = RYGEL_MEDIA_CONTAINER (g_queue_peek_head (priv->containers));
@@ -508,14 +554,20 @@ rygel_media_export_harvesting_task_on_extracted_cb (RygelMediaExportHarvestingTa
                                                              file_info);
   }
   if (item) {
-    rygel_media_object_set_parent_ref (RYGEL_MEDIA_OBJECT (item), container);
-    rygel_media_export_media_cache_save_item (priv->cache, item, NULL);
+    RygelTrackableContainer *trackable;
+    RygelMediaObject *object = RYGEL_MEDIA_OBJECT (item);
+
+    rygel_media_object_set_parent_ref (object, container);
+    if (entry->known) {
+      rygel_updatable_object_commit (RYGEL_UPDATABLE_OBJECT (item), NULL, NULL);
+    } else {
+      trackable = RYGEL_TRACKABLE_CONTAINER (rygel_media_object_get_parent (object));
+      rygel_trackable_container_add_child_tracked (trackable, object, NULL, NULL);
+    }
     g_object_unref (item);
   }
-  top_file = G_FILE (gee_queue_poll (priv->files));
-  if (top_file) {
-    g_object_unref (top_file);
-  }
+  file_queue_entry_unref (entry);
+  file_queue_entry_unref (gee_queue_poll (priv->files));
   rygel_media_export_harvesting_task_do_update (self);
 }
 
@@ -540,16 +592,16 @@ rygel_media_export_harvesting_task_on_extractor_error_cb (RygelMediaExportHarves
   RygelMediaExportHarvestingTaskPrivate *priv;
   gboolean ignore;
   gchar *uri;
-  GFile *entry;
+  FileQueueEntry *entry;
 
   g_return_if_fail (RYGEL_MEDIA_EXPORT_IS_HARVESTING_TASK (self));
   g_return_if_fail (G_IS_FILE (file));
   g_return_if_fail (error != NULL);
 
   priv = self->priv;
-  entry = G_FILE (gee_queue_peek (priv->files));
-  ignore = (!entry || !g_file_equal (file, entry));
-  g_object_unref (entry);
+  entry = gee_queue_peek (priv->files);
+  ignore = (!entry->file || !g_file_equal (file, entry->file));
+  file_queue_entry_unref (entry);
 
   if (ignore) {
     return;
@@ -558,7 +610,7 @@ rygel_media_export_harvesting_task_on_extractor_error_cb (RygelMediaExportHarves
   uri = g_file_get_uri (file);
   g_debug ("Skipping %s; extraction completely failed: %s", uri, error->message);
   g_free (uri);
-  g_object_unref (gee_queue_poll (priv->files));
+  file_queue_entry_unref (gee_queue_poll (priv->files));
   rygel_media_export_harvesting_task_do_update (self);
 }
 
@@ -887,7 +939,10 @@ rygel_media_export_harvesting_task_constructed (GObject *object) {
                            G_CALLBACK 
(rygel_media_export_harvesting_task_on_extractor_error_cb_rygel_media_export_metadata_extractor_error),
                            self,
                            0);
-  priv->files = GEE_QUEUE (gee_linked_list_new (G_TYPE_FILE, (GBoxedCopyFunc) g_object_ref, g_object_unref, 
NULL, NULL, NULL));
+  priv->files = GEE_QUEUE (gee_linked_list_new (RYGEL_MEDIA_EXPORT_TYPE_FILE_QUEUE_ENTRY,
+                                                (GBoxedCopyFunc) file_queue_entry_ref,
+                                                (GBoxedFreeFunc) file_queue_entry_unref,
+                                                NULL, NULL, NULL));
   priv->containers = g_queue_new ();
 }
 
diff --git a/src/media-export/rygel-media-export-music-item.c 
b/src/media-export/rygel-media-export-music-item.c
index 3b974b5..0d65a85 100644
--- a/src/media-export/rygel-media-export-music-item.c
+++ b/src/media-export/rygel-media-export-music-item.c
@@ -24,10 +24,19 @@
 #include "rygel-media-export-music-item.h"
 #include "rygel-media-export-media-cache.h"
 
-static void rygel_media_export_music_item_rygel_updatable_object_interface_init (RygelUpdatableObjectIface 
*iface);
+static void
+rygel_media_export_music_item_rygel_updatable_object_interface_init (RygelUpdatableObjectIface *iface);
+
+static void
+rygel_media_export_music_item_rygel_trackable_item_interface_init (RygelTrackableItemIface *iface);
 
-G_DEFINE_TYPE_WITH_CODE (RygelMediaExportMusicItem, rygel_media_export_music_item, RYGEL_TYPE_MUSIC_ITEM,
-       G_IMPLEMENT_INTERFACE (RYGEL_TYPE_UPDATABLE_OBJECT, 
rygel_media_export_music_item_rygel_updatable_object_interface_init))
+G_DEFINE_TYPE_WITH_CODE (RygelMediaExportMusicItem,
+                         rygel_media_export_music_item,
+                         RYGEL_TYPE_MUSIC_ITEM,
+                         G_IMPLEMENT_INTERFACE (RYGEL_TYPE_UPDATABLE_OBJECT,
+                                                
rygel_media_export_music_item_rygel_updatable_object_interface_init)
+                         G_IMPLEMENT_INTERFACE (RYGEL_TYPE_TRACKABLE_ITEM,
+                                                
rygel_media_export_music_item_rygel_trackable_item_interface_init))
 
 static void rygel_media_export_music_item_real_commit (RygelUpdatableObject *base, GAsyncReadyCallback 
callback_, gpointer user_data);
 
@@ -53,6 +62,7 @@ rygel_media_export_music_item_real_commit (RygelUpdatableObject *base, GAsyncRea
   g_return_if_fail (self);
   g_return_if_fail (callback);
 
+  rygel_trackable_item_changed (RYGEL_TRACKABLE_ITEM (self));
   /* Setup the async result.
    */
   GSimpleAsyncResult *async_result =
@@ -99,5 +109,9 @@ rygel_media_export_music_item_rygel_updatable_object_interface_init (RygelUpdata
 }
 
 static void
+rygel_media_export_music_item_rygel_trackable_item_interface_init (RygelTrackableItemIface *iface 
G_GNUC_UNUSED) {
+}
+
+static void
 rygel_media_export_music_item_init (RygelMediaExportMusicItem *self G_GNUC_UNUSED) {
 }
diff --git a/src/media-export/rygel-media-export-object-factory.c 
b/src/media-export/rygel-media-export-object-factory.c
index 8575a22..614fe9d 100644
--- a/src/media-export/rygel-media-export-object-factory.c
+++ b/src/media-export/rygel-media-export-object-factory.c
@@ -28,6 +28,7 @@
 #include "rygel-media-export-query-container.h"
 #include "rygel-media-export-root-container.h"
 #include "rygel-media-export-object-factory.h"
+#include "rygel-media-export-trackable-db-container.h"
 #include "rygel-media-export-video-item.h"
 #include "rygel-media-export-writable-db-container.h"
 
@@ -73,7 +74,7 @@ rygel_media_export_object_factory_real_get_container (RygelMediaExportObjectFact
   }
 
   if (!uri) {
-    return rygel_media_export_db_container_new (id, title);
+    return RYGEL_MEDIA_EXPORT_DB_CONTAINER (rygel_media_export_trackable_db_container_new (id, title));
   }
 
   return RYGEL_MEDIA_EXPORT_DB_CONTAINER (rygel_media_export_writable_db_container_new (id, title));
diff --git a/src/media-export/rygel-media-export-photo-item.c 
b/src/media-export/rygel-media-export-photo-item.c
index cf56fc4..8b2fc40 100644
--- a/src/media-export/rygel-media-export-photo-item.c
+++ b/src/media-export/rygel-media-export-photo-item.c
@@ -23,10 +23,19 @@
 #include "rygel-media-export-photo-item.h"
 #include "rygel-media-export-media-cache.h"
 
-static void rygel_media_export_photo_item_rygel_updatable_object_interface_init (RygelUpdatableObjectIface 
*iface);
+static void
+rygel_media_export_photo_item_rygel_updatable_object_interface_init (RygelUpdatableObjectIface *iface);
+
+static void
+rygel_media_export_photo_item_rygel_trackable_item_interface_init (RygelTrackableItemIface *iface);
 
-G_DEFINE_TYPE_WITH_CODE (RygelMediaExportPhotoItem, rygel_media_export_photo_item, RYGEL_TYPE_PHOTO_ITEM,
-  G_IMPLEMENT_INTERFACE (RYGEL_TYPE_UPDATABLE_OBJECT, 
rygel_media_export_photo_item_rygel_updatable_object_interface_init))
+G_DEFINE_TYPE_WITH_CODE (RygelMediaExportPhotoItem,
+                         rygel_media_export_photo_item,
+                         RYGEL_TYPE_PHOTO_ITEM,
+                         G_IMPLEMENT_INTERFACE (RYGEL_TYPE_UPDATABLE_OBJECT,
+                                                
rygel_media_export_photo_item_rygel_updatable_object_interface_init)
+                         G_IMPLEMENT_INTERFACE (RYGEL_TYPE_TRACKABLE_ITEM,
+                                                
rygel_media_export_photo_item_rygel_trackable_item_interface_init))
 
 RygelMediaExportPhotoItem *rygel_media_export_photo_item_construct (GType object_type, const gchar *id, 
RygelMediaContainer *parent, const gchar *title, const gchar *upnp_class);
 static void rygel_media_export_photo_item_real_commit (RygelUpdatableObject *base, GAsyncReadyCallback 
callback, gpointer user_data);
@@ -53,6 +62,7 @@ static void rygel_media_export_photo_item_real_commit (RygelUpdatableObject *bas
   g_return_if_fail (self);
   g_return_if_fail (callback);
 
+  rygel_trackable_item_changed (RYGEL_TRACKABLE_ITEM (self));
   /* Setup the async result.
    */
   GSimpleAsyncResult *async_result =
@@ -99,5 +109,9 @@ rygel_media_export_photo_item_rygel_updatable_object_interface_init (RygelUpdata
 }
 
 static void
+rygel_media_export_photo_item_rygel_trackable_item_interface_init (RygelTrackableItemIface *iface 
G_GNUC_UNUSED) {
+}
+
+static void
 rygel_media_export_photo_item_init (RygelMediaExportPhotoItem *self G_GNUC_UNUSED) {
 }
diff --git a/src/media-export/rygel-media-export-plugin.c b/src/media-export/rygel-media-export-plugin.c
index ea41821..440e388 100644
--- a/src/media-export/rygel-media-export-plugin.c
+++ b/src/media-export/rygel-media-export-plugin.c
@@ -73,7 +73,8 @@ rygel_media_export_plugin_new (GError **error) {
                                                                            root,
                                                                            RYGEL_MEDIA_EXPORT_PLUGIN_NAME,
                                                                            NULL,
-                                                                           
RYGEL_PLUGIN_CAPABILITIES_UPLOAD));
+                                                                           RYGEL_PLUGIN_CAPABILITIES_UPLOAD |
+                                                                           
RYGEL_PLUGIN_CAPABILITIES_TRACK_CHANGES));
   g_object_unref (root);
   return plugin;
 }
diff --git a/src/media-export/rygel-media-export-root-container.c 
b/src/media-export/rygel-media-export-root-container.c
index 531409e..d23b583 100644
--- a/src/media-export/rygel-media-export-root-container.c
+++ b/src/media-export/rygel-media-export-root-container.c
@@ -36,11 +36,16 @@
 static void
 rygel_media_export_root_container_rygel_searchable_container_interface_init (RygelSearchableContainerIface 
*iface);
 
+static void
+rygel_media_export_root_container_rygel_trackable_container_interface_init (RygelTrackableContainerIface 
*iface);
+
 G_DEFINE_TYPE_WITH_CODE (RygelMediaExportRootContainer,
                          rygel_media_export_root_container,
-                         RYGEL_MEDIA_EXPORT_TYPE_DB_CONTAINER,
+                         RYGEL_MEDIA_EXPORT_TYPE_TRACKABLE_DB_CONTAINER,
                          G_IMPLEMENT_INTERFACE (RYGEL_TYPE_SEARCHABLE_CONTAINER,
-                                                
rygel_media_export_root_container_rygel_searchable_container_interface_init))
+                                                
rygel_media_export_root_container_rygel_searchable_container_interface_init)
+                         G_IMPLEMENT_INTERFACE (RYGEL_TYPE_TRACKABLE_CONTAINER,
+                                                
rygel_media_export_root_container_rygel_trackable_container_interface_init))
 
 typedef struct _RygelMediaExportFolderDefinition RygelMediaExportFolderDefinition;
 typedef struct _RygelMediaExportRootContainerFindObjectData RygelMediaExportRootContainerFindObjectData;
@@ -56,6 +61,7 @@ struct _RygelMediaExportRootContainerPrivate {
   GCancellable *cancellable;
   RygelMediaContainer *filesystem_container;
   gulong harvester_signal_id;
+  gboolean initialized;
 };
 
 struct _RygelMediaExportRootContainerFindObjectData {
@@ -74,6 +80,7 @@ struct _RygelMediaExportRootContainerSearchData {
 
 static RygelMediaContainer *rygel_media_export_root_container_instance = NULL;
 static RygelSearchableContainerIface *parent_searchable_container_iface = NULL;
+static RygelTrackableContainerIface *parent_trackable_container_iface = NULL;
 
 #define RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_GET_PRIVATE(o) \
   (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
@@ -519,6 +526,139 @@ rygel_media_export_root_container_real_search_finish (RygelSearchableContainer
 }
 
 static void
+rygel_media_export_root_container_updated (RygelMediaExportRootContainer *self) {
+  RygelMediaContainer *media_container = RYGEL_MEDIA_CONTAINER (self);
+  RygelMediaExportMediaCache *media_db = rygel_media_export_db_container_get_media_db 
(RYGEL_MEDIA_EXPORT_DB_CONTAINER (self));
+
+  rygel_media_container_updated (media_container,
+                                 NULL,
+                                 RYGEL_OBJECT_EVENT_TYPE_MODIFIED,
+                                 FALSE);
+  rygel_media_export_media_cache_save_container (media_db, media_container, NULL);
+}
+
+static GeeArrayList *
+rygel_media_export_root_container_get_shared_uris (RygelMediaExportRootContainer *self);
+
+static void
+rygel_media_export_root_container_on_initial_harvesting_done_rygel_media_export_harvester_done 
(RygelMediaExportHarvester *sender G_GNUC_UNUSED,
+                                                                                                gpointer     
              self);
+
+static gboolean
+rygel_media_export_root_container_late_init (gpointer user_data) {
+  RygelMediaExportRootContainer *self = RYGEL_MEDIA_EXPORT_ROOT_CONTAINER (user_data);
+  RygelMediaExportRootContainerPrivate *priv = self->priv;
+  RygelMediaExportMediaCache* db;
+  GError *error = NULL;
+  GeeArrayList* ids;
+  GeeAbstractCollection *abstract_ids;
+  GeeAbstractList *abstract_list_ids;
+  RygelMediaContainer *media_container = RYGEL_MEDIA_CONTAINER (self);
+  GeeArrayList *shared_uris;
+  GeeArrayList *locations;
+  GeeAbstractList *abstract_locations;
+  gint iter;
+  gint size;
+
+  priv->cancellable = g_cancellable_new ();
+  db = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (self));
+  rygel_media_export_media_cache_save_container (db, media_container, &error);
+  if (error) {
+    g_warning ("Failed to save root container into db: %s",
+               error->message);
+    g_error_free (error);
+    error = NULL;
+  }
+
+  priv->filesystem_container = RYGEL_MEDIA_CONTAINER (rygel_media_export_trackable_db_container_new 
(RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_FILESYSTEM_FOLDER_ID,
+                                                                                           
_(RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_FILESYSTEM_FOLDER_NAME)));
+  rygel_media_object_set_parent (RYGEL_MEDIA_OBJECT (priv->filesystem_container),
+                                 media_container);
+  rygel_media_export_media_cache_save_container (db, RYGEL_MEDIA_CONTAINER (priv->filesystem_container), 
&error);
+  if (error) {
+    g_warning ("Failed to save filesystem container into db: %s",
+               error->message);
+    g_error_free (error);
+    error = NULL;
+  }
+
+  ids = rygel_media_export_media_cache_get_child_ids (db, 
RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_FILESYSTEM_FOLDER_ID, &error);
+  if (error) {
+    g_warning ("Failed to get child ids of %s from db: %s",
+               RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_FILESYSTEM_FOLDER_ID,
+               error->message);
+    g_error_free (error);
+    error = NULL;
+    ids = gee_array_list_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, NULL, NULL, NULL);
+  }
+  abstract_ids = GEE_ABSTRACT_COLLECTION (ids);
+
+  shared_uris = rygel_media_export_root_container_get_shared_uris (self);
+  priv->harvester = rygel_media_export_harvester_new (priv->cancellable, shared_uris);
+  if (shared_uris) {
+    g_object_unref (shared_uris);
+  }
+  priv->harvester_signal_id = g_signal_connect_object (priv->harvester,
+                                                       "done",
+                                                       G_CALLBACK 
(rygel_media_export_root_container_on_initial_harvesting_done_rygel_media_export_harvester_done),
+                                                       self,
+                                                       0);
+
+  locations = rygel_media_export_harvester_get_locations (priv->harvester);
+  abstract_locations = GEE_ABSTRACT_LIST (locations);
+  size = gee_abstract_collection_get_size (GEE_ABSTRACT_COLLECTION (locations));
+
+  for (iter = 0; iter < size; ++iter) {
+    GFile *file = gee_abstract_list_get (abstract_locations, iter);
+    gchar *file_id = rygel_media_export_media_cache_get_id (file);
+
+    gee_abstract_collection_remove (abstract_ids, file_id);
+    rygel_media_export_harvester_schedule (priv->harvester,
+                                           file,
+                                           priv->filesystem_container,
+                                           NULL);
+    g_free (file_id);
+    g_object_unref (file);
+  }
+
+  size = gee_abstract_collection_get_size (abstract_ids);
+  abstract_list_ids = GEE_ABSTRACT_LIST (ids);
+  for (iter = 0; iter < size; ++iter) {
+    gchar *id = gee_abstract_list_get (abstract_list_ids, iter);
+
+    g_debug ("ID %s no longer in config; deleting...", id);
+    rygel_media_export_media_cache_remove_by_id (db, id, &error);
+    if (error) {
+      g_warning ("Failed to remove entry %s: %s",
+                 id,
+                 error->message);
+      g_error_free (error);
+      error = NULL;
+    }
+    g_free (id);
+  }
+  if (!gee_collection_get_is_empty (GEE_COLLECTION (ids))) {
+    rygel_media_export_root_container_updated (self);
+  }
+  g_object_unref (ids);
+
+  return FALSE;
+}
+
+static guint32
+rygel_media_export_root_container_real_get_system_update_id (RygelTrackableContainer *base) {
+  guint32 id = parent_trackable_container_iface->get_system_update_id (base);
+  RygelMediaExportRootContainer *self = RYGEL_MEDIA_EXPORT_ROOT_CONTAINER (base);
+
+  if (!self->priv->initialized) {
+    self->priv->initialized = TRUE;
+    g_idle_add (rygel_media_export_root_container_late_init, self);
+  }
+
+  return id;
+}
+
+static void
 replace_in_string (gchar       **self,
                    const gchar  *old_part,
                    const gchar  *new_part)
@@ -787,7 +927,7 @@ on_filesystem_container_updated (RygelMediaContainer *sender G_GNUC_UNUSED,
   RygelMediaExportRootContainer *self = RYGEL_MEDIA_EXPORT_ROOT_CONTAINER (user_data);
 
   rygel_media_export_root_container_add_default_virtual_folders (self);
-  rygel_media_container_updated (RYGEL_MEDIA_CONTAINER (self), NULL, RYGEL_OBJECT_EVENT_TYPE_MODIFIED, 
FALSE);
+  rygel_media_export_root_container_updated (self);
 }
 
 static void
@@ -795,9 +935,10 @@ rygel_media_export_root_container_on_initial_harvesting_done (RygelMediaExportRo
   g_return_if_fail (self != NULL);
 
   g_signal_handler_disconnect (G_OBJECT (self->priv->harvester), self->priv->harvester_signal_id);
+  self->priv->harvester_signal_id = 0;
   rygel_media_export_media_cache_debug_statistics (rygel_media_export_db_container_get_media_db 
(RYGEL_MEDIA_EXPORT_DB_CONTAINER (self)));
   rygel_media_export_root_container_add_default_virtual_folders (self);
-  rygel_media_container_updated (RYGEL_MEDIA_CONTAINER (self), NULL, RYGEL_OBJECT_EVENT_TYPE_MODIFIED, 
FALSE);
+  rygel_media_export_root_container_updated (self);
   g_signal_connect_object (self->priv->filesystem_container,
                            "container-updated",
                            G_CALLBACK (on_filesystem_container_updated),
@@ -807,113 +948,11 @@ rygel_media_export_root_container_on_initial_harvesting_done (RygelMediaExportRo
 
 static void
 rygel_media_export_root_container_on_initial_harvesting_done_rygel_media_export_harvester_done 
(RygelMediaExportHarvester *sender G_GNUC_UNUSED,
-                                                                                                 gpointer    
               self) {
+                                                                                                gpointer     
              self) {
   rygel_media_export_root_container_on_initial_harvesting_done (self);
 }
 
 static void
-rygel_media_export_root_container_constructed (GObject *object) {
-  RygelMediaExportRootContainer *self = RYGEL_MEDIA_EXPORT_ROOT_CONTAINER (object);
-  RygelMediaExportRootContainerPrivate *priv = self->priv;
-  RygelMediaExportMediaCache* db;
-  GError *error = NULL;
-  GeeArrayList* ids;
-  GeeAbstractCollection *abstract_ids;
-  GeeAbstractList *abstract_list_ids;
-  RygelMediaContainer *media_container = RYGEL_MEDIA_CONTAINER (self);
-  GeeArrayList *shared_uris;
-  GeeArrayList *locations;
-  GeeAbstractList *abstract_locations;
-  gint iter;
-  gint size;
-
-  G_OBJECT_CLASS (rygel_media_export_root_container_parent_class)->constructed (object);
-
-  priv->cancellable = g_cancellable_new ();
-  db = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (self));
-  rygel_media_export_media_cache_save_container (db, media_container, &error);
-  if (error) {
-    g_warning ("Failed to save root container into db: %s",
-               error->message);
-    g_error_free (error);
-    error = NULL;
-  }
-
-  priv->filesystem_container = RYGEL_MEDIA_CONTAINER (rygel_media_export_db_container_new 
(RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_FILESYSTEM_FOLDER_ID,
-                                                                                           
_(RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_FILESYSTEM_FOLDER_NAME)));
-  rygel_media_object_set_parent (RYGEL_MEDIA_OBJECT (priv->filesystem_container),
-                                 media_container);
-  rygel_media_export_media_cache_save_container (db, RYGEL_MEDIA_CONTAINER (priv->filesystem_container), 
&error);
-  if (error) {
-    g_warning ("Failed to save filesystem container into db: %s",
-               error->message);
-    g_error_free (error);
-    error = NULL;
-  }
-
-  ids = rygel_media_export_media_cache_get_child_ids (db, 
RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_FILESYSTEM_FOLDER_ID, &error);
-  if (error) {
-    g_warning ("Failed to get child ids of %s from db: %s",
-               RYGEL_MEDIA_EXPORT_ROOT_CONTAINER_FILESYSTEM_FOLDER_ID,
-               error->message);
-    g_error_free (error);
-    error = NULL;
-    ids = gee_array_list_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, NULL, NULL, NULL);
-  }
-  abstract_ids = GEE_ABSTRACT_COLLECTION (ids);
-
-  shared_uris = rygel_media_export_root_container_get_shared_uris (self);
-  priv->harvester = rygel_media_export_harvester_new (priv->cancellable, shared_uris);
-  if (shared_uris) {
-    g_object_unref (shared_uris);
-  }
-  priv->harvester_signal_id = g_signal_connect_object (priv->harvester,
-                                                       "done",
-                                                       G_CALLBACK 
(rygel_media_export_root_container_on_initial_harvesting_done_rygel_media_export_harvester_done),
-                                                       self,
-                                                       0);
-
-  locations = rygel_media_export_harvester_get_locations (priv->harvester);
-  abstract_locations = GEE_ABSTRACT_LIST (locations);
-  size = gee_abstract_collection_get_size (GEE_ABSTRACT_COLLECTION (locations));
-
-  for (iter = 0; iter < size; ++iter) {
-    GFile *file = gee_abstract_list_get (abstract_locations, iter);
-    gchar *file_id = rygel_media_export_media_cache_get_id (file);
-
-    gee_abstract_collection_remove (abstract_ids, file_id);
-    rygel_media_export_harvester_schedule (priv->harvester,
-                                           file,
-                                           priv->filesystem_container,
-                                           NULL);
-    g_free (file_id);
-    g_object_unref (file);
-  }
-
-  size = gee_abstract_collection_get_size (abstract_ids);
-  abstract_list_ids = GEE_ABSTRACT_LIST (ids);
-  for (iter = 0; iter < size; ++iter) {
-    gchar *id = gee_abstract_list_get (abstract_list_ids, iter);
-
-    g_debug ("ID %s no longer in config; deleting...", id);
-    rygel_media_export_media_cache_remove_by_id (db, id, &error);
-    if (error) {
-      g_warning ("Failed to remove entry %s: %s",
-                 id,
-                 error->message);
-      g_error_free (error);
-      error = NULL;
-    }
-    g_free (id);
-  }
-  rygel_media_container_updated (media_container,
-                                 NULL,
-                                 RYGEL_OBJECT_EVENT_TYPE_MODIFIED,
-                                 FALSE);
-  g_object_unref (ids);
-}
-
-static void
 rygel_media_export_root_container_dispose (GObject *object) {
   RygelMediaExportRootContainer *self = RYGEL_MEDIA_EXPORT_ROOT_CONTAINER (object);
   RygelMediaExportRootContainerPrivate *priv = self->priv;
@@ -947,7 +986,6 @@ rygel_media_export_root_container_class_init (RygelMediaExportRootContainerClass
 
   container_class->find_object = rygel_media_export_root_container_real_find_object;
   container_class->find_object_finish = rygel_media_export_root_container_real_find_object_finish;
-  object_class->constructed = rygel_media_export_root_container_constructed;
   object_class->dispose = rygel_media_export_root_container_dispose;
 
   g_type_class_add_private (root_class, sizeof (RygelMediaExportRootContainerPrivate));
@@ -970,3 +1008,20 @@ rygel_media_export_root_container_rygel_searchable_container_interface_init (Ryg
    * iface->set_search_classes = parent_searchable_container_iface->set_search_classes;
    */
 }
+
+static void
+rygel_media_export_root_container_rygel_trackable_container_interface_init (RygelTrackableContainerIface 
*iface)
+{
+  parent_trackable_container_iface = g_type_interface_peek_parent (iface);
+  iface->get_system_update_id = rygel_media_export_root_container_real_get_system_update_id;
+  /* iface should be a copy of parent_trackable_container_iface, so
+   * we don't have to override the rest of functions.
+   *
+   * iface->add_child = parent_trackable_container_iface->add_child;
+   * iface->add_child_finish = parent_trackable_container_iface->add_child_finish;
+   * iface->remove_child = parent_trackable_container_iface->remove_child;
+   * iface->remove_child_finish = parent_trackable_container_iface->remove_child_finish;
+   * iface->get_service_reset_token = parent_trackable_container_iface->get_service_reset_token;
+   * iface->set_service_reset_token = parent_trackable_container_iface->set_service_reset_token;
+   */
+}
diff --git a/src/media-export/rygel-media-export-root-container.h 
b/src/media-export/rygel-media-export-root-container.h
index 166c006..d0e4eff 100644
--- a/src/media-export/rygel-media-export-root-container.h
+++ b/src/media-export/rygel-media-export-root-container.h
@@ -24,7 +24,7 @@
 #include <glib.h>
 #include <glib-object.h>
 
-#include "rygel-media-export-db-container.h"
+#include "rygel-media-export-trackable-db-container.h"
 
 G_BEGIN_DECLS
 
@@ -43,12 +43,12 @@ typedef struct _RygelMediaExportRootContainerClass RygelMediaExportRootContainer
 typedef struct _RygelMediaExportRootContainerPrivate RygelMediaExportRootContainerPrivate;
 
 struct _RygelMediaExportRootContainer {
-  RygelMediaExportDBContainer parent_instance;
+  RygelMediaExportTrackableDbContainer parent_instance;
   RygelMediaExportRootContainerPrivate *priv;
 };
 
 struct _RygelMediaExportRootContainerClass {
-  RygelMediaExportDBContainerClass parent_class;
+  RygelMediaExportTrackableDbContainerClass parent_class;
 };
 
 GType
diff --git a/src/media-export/rygel-media-export-video-item.c 
b/src/media-export/rygel-media-export-video-item.c
index a60ea23..c11b8e7 100644
--- a/src/media-export/rygel-media-export-video-item.c
+++ b/src/media-export/rygel-media-export-video-item.c
@@ -23,12 +23,19 @@
 #include "rygel-media-export-video-item.h"
 #include "rygel-media-export-media-cache.h"
 
-static void rygel_media_export_video_item_rygel_trackable_item_interface_init (RygelTrackableItemIface 
*iface);
-static void rygel_media_export_video_item_rygel_updatable_object_interface_init (RygelUpdatableObjectIface 
*iface);
+static void
+rygel_media_export_video_item_rygel_updatable_object_interface_init (RygelUpdatableObjectIface *iface);
+
+static void
+rygel_media_export_video_item_rygel_trackable_item_interface_init (RygelTrackableItemIface *iface);
 
-G_DEFINE_TYPE_WITH_CODE (RygelMediaExportVideoItem, rygel_media_export_video_item, RYGEL_TYPE_VIDEO_ITEM,
-  G_IMPLEMENT_INTERFACE (RYGEL_TYPE_TRACKABLE_ITEM, 
rygel_media_export_video_item_rygel_trackable_item_interface_init)
-  G_IMPLEMENT_INTERFACE (RYGEL_TYPE_UPDATABLE_OBJECT, 
rygel_media_export_video_item_rygel_updatable_object_interface_init))
+G_DEFINE_TYPE_WITH_CODE (RygelMediaExportVideoItem,
+                         rygel_media_export_video_item,
+                         RYGEL_TYPE_VIDEO_ITEM,
+                         G_IMPLEMENT_INTERFACE (RYGEL_TYPE_UPDATABLE_OBJECT,
+                                                
rygel_media_export_video_item_rygel_updatable_object_interface_init)
+                         G_IMPLEMENT_INTERFACE (RYGEL_TYPE_TRACKABLE_ITEM,
+                                                
rygel_media_export_video_item_rygel_trackable_item_interface_init))
 
 static void rygel_media_export_video_item_real_commit (RygelUpdatableObject *base, GAsyncReadyCallback 
_callback_, gpointer _user_data_);
 
@@ -54,7 +61,8 @@ static void rygel_media_export_video_item_real_commit (RygelUpdatableObject *bas
   g_return_if_fail (self);
   g_return_if_fail (callback);
 
- /* Setup the async result.
+  rygel_trackable_item_changed (RYGEL_TRACKABLE_ITEM (self));
+  /* Setup the async result.
    */
   GSimpleAsyncResult *async_result =
     g_simple_async_result_new (G_OBJECT (self), callback, user_data,
diff --git a/src/media-export/rygel-media-export-writable-db-container.c 
b/src/media-export/rygel-media-export-writable-db-container.c
index 6a560c2..5504673 100644
--- a/src/media-export/rygel-media-export-writable-db-container.c
+++ b/src/media-export/rygel-media-export-writable-db-container.c
@@ -28,7 +28,7 @@ rygel_media_export_writable_db_container_rygel_writable_container_interface_init
 
 G_DEFINE_TYPE_WITH_CODE (RygelMediaExportWritableDbContainer,
                          rygel_media_export_writable_db_container,
-                         RYGEL_MEDIA_EXPORT_TYPE_DB_CONTAINER,
+                         RYGEL_MEDIA_EXPORT_TYPE_TRACKABLE_DB_CONTAINER,
                          G_IMPLEMENT_INTERFACE (RYGEL_TYPE_WRITABLE_CONTAINER,
                                                 
rygel_media_export_writable_db_container_rygel_writable_container_interface_init));
 
@@ -61,6 +61,16 @@ rygel_media_export_writable_db_container_new (const gchar *id,
 }
 
 static void
+tracked_action_ready (GObject *source_object G_GNUC_UNUSED,
+                      GAsyncResult *res G_GNUC_UNUSED,
+                      gpointer user_data) {
+  GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT (user_data);
+
+  g_simple_async_result_complete (result);
+  g_object_unref (result);
+}
+
+static void
 rygel_media_export_writable_db_container_real_add_item (RygelWritableContainer *base,
                                                         RygelMediaItem         *item,
                                                         GCancellable           *cancellable G_GNUC_UNUSED,
@@ -70,9 +80,10 @@ rygel_media_export_writable_db_container_real_add_item (RygelWritableContainer *
   gchar *uri;
   GFile *file;
   gchar *id;
-  RygelMediaExportMediaCache *cache;
-  GError *error = NULL;
-  GSimpleAsyncResult *simple;
+  GSimpleAsyncResult *simple = g_simple_async_result_new (G_OBJECT (base),
+                                                          callback,
+                                                          user_data,
+                                                          
rygel_media_export_writable_db_container_real_add_item);
 
   rygel_media_object_set_parent (object, RYGEL_MEDIA_CONTAINER (base));
   uri = gee_abstract_list_get (GEE_ABSTRACT_LIST (object->uris), 0);
@@ -85,22 +96,11 @@ rygel_media_export_writable_db_container_real_add_item (RygelWritableContainer *
   g_object_unref (file);
   rygel_media_object_set_id (object, id);
   g_free (id);
-  cache = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (base));
-  rygel_media_export_media_cache_save_item (cache, item, &error);
 
-  if (error) {
-    simple = g_simple_async_result_new_take_error (G_OBJECT (base),
-                                                   callback,
-                                                   user_data,
-                                                   error);
-  } else {
-    simple = g_simple_async_result_new (G_OBJECT (base),
-                                        callback,
-                                        user_data,
-                                        rygel_media_export_writable_db_container_real_add_item);
-  }
-  g_simple_async_result_complete_in_idle (simple);
-  g_object_unref (simple);
+  rygel_trackable_container_add_child_tracked (RYGEL_TRACKABLE_CONTAINER (base),
+                                               object,
+                                               tracked_action_ready,
+                                               simple);
 }
 
 static void
@@ -120,22 +120,25 @@ rygel_media_export_writable_db_container_real_remove_item (RygelWritableContaine
   RygelMediaExportMediaCache *cache = rygel_media_export_db_container_get_media_db (db_container);
   GError *error = NULL;
   GSimpleAsyncResult *simple;
-
-  rygel_media_export_media_cache_remove_by_id (cache, id, &error);
+  RygelMediaObject *object = rygel_media_export_media_cache_get_object (cache, id, &error);
 
   if (error) {
     simple = g_simple_async_result_new_take_error (G_OBJECT (base),
                                                    callback,
                                                    user_data,
                                                    error);
+    g_simple_async_result_complete_in_idle (simple);
+    g_object_unref (simple);
   } else {
     simple = g_simple_async_result_new (G_OBJECT (base),
                                         callback,
                                         user_data,
                                         rygel_media_export_writable_db_container_real_remove_item);
+    rygel_trackable_container_remove_child_tracked (RYGEL_TRACKABLE_CONTAINER (base),
+                                                    object,
+                                                    tracked_action_ready,
+                                                    simple);
   }
-  g_simple_async_result_complete_in_idle (simple);
-  g_object_unref (simple);
 }
 
 static void
diff --git a/src/media-export/rygel-media-export-writable-db-container.h 
b/src/media-export/rygel-media-export-writable-db-container.h
index bb257b2..6acc5ae 100644
--- a/src/media-export/rygel-media-export-writable-db-container.h
+++ b/src/media-export/rygel-media-export-writable-db-container.h
@@ -27,7 +27,7 @@
 #include <glib.h>
 #include <glib-object.h>
 
-#include "rygel-media-export-db-container.h"
+#include "rygel-media-export-trackable-db-container.h"
 
 G_BEGIN_DECLS
 
@@ -43,12 +43,12 @@ typedef struct _RygelMediaExportWritableDbContainerClass RygelMediaExportWritabl
 typedef struct _RygelMediaExportWritableDbContainerPrivate RygelMediaExportWritableDbContainerPrivate;
 
 struct _RygelMediaExportWritableDbContainer {
-  RygelMediaExportDBContainer parent_instance;
+  RygelMediaExportTrackableDbContainer parent_instance;
   RygelMediaExportWritableDbContainerPrivate *priv;
 };
 
 struct _RygelMediaExportWritableDbContainerClass {
-  RygelMediaExportDBContainerClass parent_class;
+  RygelMediaExportTrackableDbContainerClass parent_class;
 };
 
 GType


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]