diff options
author | Ludovic Ferrandis <ludovic.ferrandis@intel.com> | 2013-03-29 16:04:23 +0100 |
---|---|---|
committer | Mark Ryan <mark.d.ryan@intel.com> | 2013-04-04 13:43:39 +0200 |
commit | 046bdc897b0799f4e55bc42977b9554d908df42b (patch) | |
tree | 8bf7e34eae3d07b35d78d9db4e1a492d5fdf8299 | |
parent | a1722b37153205e0ea46888c2e5766d4e23a8b9a (diff) | |
download | dleyna-server-046bdc897b0799f4e55bc42977b9554d908df42b.tar.gz |
[Property] Add MediaItem2 resource properties to Container. Fix UpdateCount.
Add URLs, Size, DLNAProfile & Mime/Types resources
We can now filter out URLs for Container, using SetProtocolInfo API
Second part for bug https://github.com/01org/dleyna-server/issues/5
In addition this commit fixes the UpdateCount property that wasn't
managed in the Get_Prop() method.
Signed-off-by: Ludovic Ferrandis <ludovic.ferrandis@intel.com>
-rw-r--r-- | doc/server/dbus/API.txt | 17 | ||||
-rw-r--r-- | libdleyna/server/device.c | 10 | ||||
-rw-r--r-- | libdleyna/server/props.c | 190 | ||||
-rw-r--r-- | libdleyna/server/props.h | 4 | ||||
-rw-r--r-- | libdleyna/server/server.c | 8 |
5 files changed, 171 insertions, 58 deletions
diff --git a/doc/server/dbus/API.txt b/doc/server/dbus/API.txt index 66533d4..dbfc755 100644 --- a/doc/server/dbus/API.txt +++ b/doc/server/dbus/API.txt @@ -565,9 +565,22 @@ Additional properties unsupported by org.gnome.MediaContainer2 | | | | deleted from a container object | | | | | since the last initialization | |---------------------------------------------------------------------------| -| Resources |aa{sv}| o | Returns the set of resources | -| | | | associated with a container | +| Resources |aa{sv}| o | Returns the set of resources | +| | | | associated with a container | |---------------------------------------------------------------------------| +| DLNAProfile | s | o | | +| MIMEType | s | o | See "Container properties" | +| Size | x | o | paragraph below. | +| UpdateCount | u | o | | +| URLs | as | o | | +|---------------------------------------------------------------------------| + +Container properties: +--------------------- + The properties of one of the Resources properties may be duplicated in the + Container object. The algorithm for selecting the resource whose properties + are exposed directly in the Container object is given in the section + "Transcoding and org.gnome.UPnP.MediaItem2". New Methods: ------------ diff --git a/libdleyna/server/device.c b/libdleyna/server/device.c index 0702180..ce86a56 100644 --- a/libdleyna/server/device.c +++ b/libdleyna/server/device.c @@ -1101,6 +1101,7 @@ static void prv_found_child(GUPnPDIDLLiteParser *parser, dls_props_add_container(builder->vb, (GUPnPDIDLLiteContainer *)object, cb_task_data->filter_mask, + cb_task_data->protocol_info, &have_child_count); if (!have_child_count && (cb_task_data->filter_mask & @@ -1354,6 +1355,7 @@ static void prv_get_container(GUPnPDIDLLiteParser *parser, dls_props_add_container(cb_task_data->vb, (GUPnPDIDLLiteContainer *)object, DLS_UPNP_MASK_ALL_PROPS, + cb_task_data->protocol_info, &have_child_count); if (!have_child_count) cb_task_data->need_child_count = TRUE; @@ -1408,6 +1410,7 @@ static void prv_get_all(GUPnPDIDLLiteParser *parser, cb_task_data->vb, (GUPnPDIDLLiteContainer *) object, DLS_UPNP_MASK_ALL_PROPS, + cb_task_data->protocol_info, &have_child_count); if (!have_child_count) cb_task_data->need_child_count = TRUE; @@ -2088,13 +2091,15 @@ static void prv_get_container_property(GUPnPDIDLLiteParser *parser, dls_async_task_t *cb_data = user_data; dls_task_t *task = &cb_data->task; dls_task_get_prop_t *task_data = &task->ut.get_prop; + dls_async_get_prop_t *cb_task_data = &cb_data->ut.get_prop; if (cb_data->task.result) goto on_error; cb_data->task.result = dls_props_get_container_prop( - task_data->prop_name, - object); + task_data->prop_name, + object, + cb_task_data->protocol_info); on_error: @@ -2525,6 +2530,7 @@ static void prv_found_target(GUPnPDIDLLiteParser *parser, dls_props_add_container(builder->vb, (GUPnPDIDLLiteContainer *)object, cb_task_data->filter_mask, + cb_task_data->protocol_info, &have_child_count); if (!have_child_count && (cb_task_data->filter_mask & diff --git a/libdleyna/server/props.c b/libdleyna/server/props.c index c8b7388..a9b60d5 100644 --- a/libdleyna/server/props.c +++ b/libdleyna/server/props.c @@ -930,21 +930,49 @@ static GUPnPDIDLLiteResource *prv_get_matching_resource return retval; } -static void prv_parse_resources(GVariantBuilder *item_vb, - GUPnPDIDLLiteResource *res, - dls_upnp_prop_mask filter_mask) +static void prv_parse_common_resources(GVariantBuilder *item_vb, + GUPnPDIDLLiteResource *res, + dls_upnp_prop_mask filter_mask) { GUPnPProtocolInfo *protocol_info; - int int_val; gint64 int64_val; - const char *str_val; guint uint_val; + const char *str_val; if (filter_mask & DLS_UPNP_MASK_PROP_SIZE) { int64_val = gupnp_didl_lite_resource_get_size64(res); prv_add_int64_prop(item_vb, DLS_INTERFACE_PROP_SIZE, int64_val); } + if (filter_mask & DLS_UPNP_MASK_PROP_UPDATE_COUNT) { + uint_val = gupnp_didl_lite_resource_get_update_count(res); + prv_add_uint_prop(item_vb, DLS_INTERFACE_PROP_UPDATE_COUNT, + uint_val); + } + + protocol_info = gupnp_didl_lite_resource_get_protocol_info(res); + + if (filter_mask & DLS_UPNP_MASK_PROP_DLNA_PROFILE) { + str_val = gupnp_protocol_info_get_dlna_profile(protocol_info); + prv_add_string_prop(item_vb, DLS_INTERFACE_PROP_DLNA_PROFILE, + str_val); + } + + if (filter_mask & DLS_UPNP_MASK_PROP_MIME_TYPE) { + str_val = gupnp_protocol_info_get_mime_type(protocol_info); + prv_add_string_prop(item_vb, DLS_INTERFACE_PROP_MIME_TYPE, + str_val); + } +} + +static void prv_parse_all_resources(GVariantBuilder *item_vb, + GUPnPDIDLLiteResource *res, + dls_upnp_prop_mask filter_mask) +{ + int int_val; + + prv_parse_common_resources(item_vb, res, filter_mask); + if (filter_mask & DLS_UPNP_MASK_PROP_BITRATE) { int_val = gupnp_didl_lite_resource_get_bitrate(res); prv_add_int_prop(item_vb, DLS_INTERFACE_PROP_BITRATE, int_val); @@ -982,26 +1010,6 @@ static void prv_parse_resources(GVariantBuilder *item_vb, prv_add_int_prop(item_vb, DLS_INTERFACE_PROP_COLOR_DEPTH, int_val); } - - if (filter_mask & DLS_UPNP_MASK_PROP_UPDATE_COUNT) { - uint_val = gupnp_didl_lite_resource_get_update_count(res); - prv_add_uint_prop(item_vb, DLS_INTERFACE_PROP_UPDATE_COUNT, - uint_val); - } - - protocol_info = gupnp_didl_lite_resource_get_protocol_info(res); - - if (filter_mask & DLS_UPNP_MASK_PROP_DLNA_PROFILE) { - str_val = gupnp_protocol_info_get_dlna_profile(protocol_info); - prv_add_string_prop(item_vb, DLS_INTERFACE_PROP_DLNA_PROFILE, - str_val); - } - - if (filter_mask & DLS_UPNP_MASK_PROP_MIME_TYPE) { - str_val = gupnp_protocol_info_get_mime_type(protocol_info); - prv_add_string_prop(item_vb, DLS_INTERFACE_PROP_MIME_TYPE, - str_val); - } } static GVariant *prv_compute_create_classes(GUPnPDIDLLiteContainer *container) @@ -1179,7 +1187,8 @@ static GVariant *prv_props_get_dlna_managed_dict(GUPnPOCMFlags flags) } static GVariant *prv_compute_resources(GUPnPDIDLLiteObject *object, - dls_upnp_prop_mask filter_mask) + dls_upnp_prop_mask filter_mask, + gboolean all_res) { GUPnPDIDLLiteResource *res = NULL; GList *resources; @@ -1202,7 +1211,12 @@ static GVariant *prv_compute_resources(GUPnPDIDLLiteObject *object, prv_add_string_prop(res_vb, DLS_INTERFACE_PROP_URL, str_val); } - prv_parse_resources(res_vb, res, filter_mask); + + if (all_res) + prv_parse_all_resources(res_vb, res, filter_mask); + else + prv_parse_common_resources(res_vb, res, filter_mask); + g_variant_builder_add(res_array_vb, "@a{sv}", g_variant_builder_end(res_vb)); g_variant_builder_unref(res_vb); @@ -1219,11 +1233,12 @@ static GVariant *prv_compute_resources(GUPnPDIDLLiteObject *object, static void prv_add_resources(GVariantBuilder *item_vb, GUPnPDIDLLiteObject *object, - dls_upnp_prop_mask filter_mask) + dls_upnp_prop_mask filter_mask, + gboolean all_res) { GVariant *val; - val = prv_compute_resources(object, filter_mask); + val = prv_compute_resources(object, filter_mask, all_res); g_variant_builder_add(item_vb, "{sv}", DLS_INTERFACE_PROP_RESOURCES, val); } @@ -1307,11 +1322,14 @@ on_error: void dls_props_add_container(GVariantBuilder *item_vb, GUPnPDIDLLiteContainer *object, dls_upnp_prop_mask filter_mask, + const gchar *protocol_info, gboolean *have_child_count) { int child_count; gboolean searchable; guint uint_val; + GUPnPDIDLLiteResource *res; + const char *str_val; *have_child_count = FALSE; if (filter_mask & DLS_UPNP_MASK_PROP_CHILD_COUNT) { @@ -1352,7 +1370,20 @@ void dls_props_add_container(GVariantBuilder *item_vb, } if (filter_mask & DLS_UPNP_MASK_PROP_RESOURCES) - prv_add_resources(item_vb, GUPNP_DIDL_LITE_OBJECT(object), filter_mask); + prv_add_resources(item_vb, GUPNP_DIDL_LITE_OBJECT(object), + filter_mask, FALSE); + + res = prv_get_matching_resource(GUPNP_DIDL_LITE_OBJECT(object), + protocol_info); + if (res) { + if (filter_mask & DLS_UPNP_MASK_PROP_URLS) { + str_val = gupnp_didl_lite_resource_get_uri(res); + prv_add_strv_prop(item_vb, DLS_INTERFACE_PROP_URLS, + &str_val, 1); + } + prv_parse_common_resources(item_vb, res, filter_mask); + g_object_unref(res); + } } void dls_props_add_item(GVariantBuilder *item_vb, @@ -1421,12 +1452,12 @@ void dls_props_add_item(GVariantBuilder *item_vb, prv_add_strv_prop(item_vb, DLS_INTERFACE_PROP_URLS, &str_val, 1); } - prv_parse_resources(item_vb, res, filter_mask); + prv_parse_all_resources(item_vb, res, filter_mask); g_object_unref(res); } if (filter_mask & DLS_UPNP_MASK_PROP_RESOURCES) - prv_add_resources(item_vb, object, filter_mask); + prv_add_resources(item_vb, object, filter_mask, TRUE); } void dls_props_add_resource(GVariantBuilder *item_vb, @@ -1444,17 +1475,22 @@ void dls_props_add_resource(GVariantBuilder *item_vb, prv_add_string_prop(item_vb, DLS_INTERFACE_PROP_URL, str_val); } - prv_parse_resources(item_vb, res, filter_mask); + + if (GUPNP_IS_DIDL_LITE_CONTAINER(object)) + prv_parse_common_resources(item_vb, res, filter_mask); + else + prv_parse_all_resources(item_vb, res, filter_mask); + g_object_unref(res); } } -static GVariant *prv_get_resource_property(const gchar *prop, - GUPnPDIDLLiteResource *res) +static GVariant *prv_get_common_resource_property(const gchar *prop, + GUPnPDIDLLiteResource *res) { - int int_val; gint64 int64_val; + guint uint_val; const char *str_val; GVariant *retval = NULL; GUPnPProtocolInfo *protocol_info; @@ -1480,48 +1516,70 @@ static GVariant *prv_get_resource_property(const gchar *prop, if (int64_val == -1) goto on_error; retval = g_variant_ref_sink(g_variant_new_int64(int64_val)); - } else if (!strcmp(prop, DLS_INTERFACE_PROP_DURATION)) { + } else if (!strcmp(prop, DLS_INTERFACE_PROP_URLS)) { + str_val = gupnp_didl_lite_resource_get_uri(res); + if (str_val) + retval = g_variant_ref_sink(g_variant_new_strv(&str_val, + 1)); + } else if (!strcmp(prop, DLS_INTERFACE_PROP_UPDATE_COUNT)) { + uint_val = gupnp_didl_lite_resource_get_update_count(res); + retval = g_variant_ref_sink(g_variant_new_uint32(uint_val)); + } + +on_error: + + return retval; +} + +static GVariant *prv_get_item_resource_property(const gchar *prop, + GUPnPDIDLLiteResource *res) +{ + int int_val; + GVariant *retval; + + retval = prv_get_common_resource_property(prop, res); + + if (retval) + goto on_exit; + + if (!strcmp(prop, DLS_INTERFACE_PROP_DURATION)) { int_val = (int) gupnp_didl_lite_resource_get_duration(res); if (int_val == -1) - goto on_error; + goto on_exit; retval = g_variant_ref_sink(g_variant_new_int32(int_val)); } else if (!strcmp(prop, DLS_INTERFACE_PROP_BITRATE)) { int_val = gupnp_didl_lite_resource_get_bitrate(res); if (int_val == -1) - goto on_error; + goto on_exit; retval = g_variant_ref_sink(g_variant_new_int32(int_val)); } else if (!strcmp(prop, DLS_INTERFACE_PROP_SAMPLE_RATE)) { int_val = gupnp_didl_lite_resource_get_sample_freq(res); if (int_val == -1) - goto on_error; + goto on_exit; retval = g_variant_ref_sink(g_variant_new_int32(int_val)); } else if (!strcmp(prop, DLS_INTERFACE_PROP_BITS_PER_SAMPLE)) { int_val = gupnp_didl_lite_resource_get_bits_per_sample(res); if (int_val == -1) - goto on_error; + goto on_exit; retval = g_variant_ref_sink(g_variant_new_int32(int_val)); } else if (!strcmp(prop, DLS_INTERFACE_PROP_WIDTH)) { int_val = (int) gupnp_didl_lite_resource_get_width(res); if (int_val == -1) - goto on_error; + goto on_exit; retval = g_variant_ref_sink(g_variant_new_int32(int_val)); } else if (!strcmp(prop, DLS_INTERFACE_PROP_HEIGHT)) { int_val = (int) gupnp_didl_lite_resource_get_height(res); if (int_val == -1) - goto on_error; + goto on_exit; retval = g_variant_ref_sink(g_variant_new_int32(int_val)); } else if (!strcmp(prop, DLS_INTERFACE_PROP_COLOR_DEPTH)) { int_val = (int) gupnp_didl_lite_resource_get_color_depth(res); if (int_val == -1) - goto on_error; + goto on_exit; retval = g_variant_ref_sink(g_variant_new_int32(int_val)); - } else if (!strcmp(prop, DLS_INTERFACE_PROP_URLS)) { - str_val = gupnp_didl_lite_resource_get_uri(res); - if (str_val) - retval = g_variant_new_strv(&str_val, 1); } -on_error: +on_exit: return retval; } @@ -1711,7 +1769,8 @@ GVariant *dls_props_get_item_prop(const gchar *prop, const gchar *root_path, g_free(path); } else if (!strcmp(prop, DLS_INTERFACE_PROP_RESOURCES)) { retval = g_variant_ref_sink( - prv_compute_resources(object, DLS_UPNP_MASK_ALL_PROPS)); + prv_compute_resources(object, DLS_UPNP_MASK_ALL_PROPS, + TRUE)); #if DLEYNA_LOG_LEVEL & DLEYNA_LOG_LEVEL_DEBUG prop_str = g_variant_print(retval, FALSE); DLEYNA_LOG_DEBUG("Prop %s = %s", prop, prop_str); @@ -1722,8 +1781,15 @@ GVariant *dls_props_get_item_prop(const gchar *prop, const gchar *root_path, if (!res) goto on_error; - retval = prv_get_resource_property(prop, res); + retval = prv_get_item_resource_property(prop, res); +#if DLEYNA_LOG_LEVEL & DLEYNA_LOG_LEVEL_DEBUG + if (retval) { + prop_str = g_variant_print(retval, FALSE); + DLEYNA_LOG_DEBUG("Prop %s = %s", prop, prop_str); + g_free(prop_str); + } +#endif g_object_unref(res); } @@ -1733,13 +1799,15 @@ on_error: } GVariant *dls_props_get_container_prop(const gchar *prop, - GUPnPDIDLLiteObject *object) + GUPnPDIDLLiteObject *object, + const gchar *protocol_info) { gint child_count; gboolean searchable; GUPnPDIDLLiteContainer *container; GVariant *retval = NULL; guint uint_val; + GUPnPDIDLLiteResource *res; #if DLEYNA_LOG_LEVEL & DLEYNA_LOG_LEVEL_DEBUG gchar *prop_str; #endif @@ -1791,12 +1859,28 @@ GVariant *dls_props_get_container_prop(const gchar *prop, retval = g_variant_ref_sink(g_variant_new_uint32(uint_val)); } else if (!strcmp(prop, DLS_INTERFACE_PROP_RESOURCES)) { retval = g_variant_ref_sink( - prv_compute_resources(object, DLS_UPNP_MASK_ALL_PROPS)); + prv_compute_resources(object, DLS_UPNP_MASK_ALL_PROPS, + FALSE)); #if DLEYNA_LOG_LEVEL & DLEYNA_LOG_LEVEL_DEBUG prop_str = g_variant_print(retval, FALSE); DLEYNA_LOG_DEBUG("Prop %s = %s", prop, prop_str); g_free(prop_str); #endif + } else { + res = prv_get_matching_resource(object, protocol_info); + if (!res) + goto on_error; + + retval = prv_get_common_resource_property(prop, res); + +#if DLEYNA_LOG_LEVEL & DLEYNA_LOG_LEVEL_DEBUG + if (retval) { + prop_str = g_variant_print(retval, FALSE); + DLEYNA_LOG_DEBUG("Prop %s = %s", prop, prop_str); + g_free(prop_str); + } +#endif + g_object_unref(res); } on_error: diff --git a/libdleyna/server/props.h b/libdleyna/server/props.h index 610fcea..459dd30 100644 --- a/libdleyna/server/props.h +++ b/libdleyna/server/props.h @@ -105,12 +105,14 @@ GVariant *dls_props_get_object_prop(const gchar *prop, const gchar *root_path, void dls_props_add_container(GVariantBuilder *item_vb, GUPnPDIDLLiteContainer *object, dls_upnp_prop_mask filter_mask, + const gchar *protocol_info, gboolean *have_child_count); void dls_props_add_child_count(GVariantBuilder *item_vb, gint value); GVariant *dls_props_get_container_prop(const gchar *prop, - GUPnPDIDLLiteObject *object); + GUPnPDIDLLiteObject *object, + const gchar *protocol_info); void dls_props_add_resource(GVariantBuilder *item_vb, GUPnPDIDLLiteObject *object, diff --git a/libdleyna/server/server.c b/libdleyna/server/server.c index e1d1c22..7a00624 100644 --- a/libdleyna/server/server.c +++ b/libdleyna/server/server.c @@ -295,6 +295,14 @@ static const gchar g_server_introspection[] = " access='read'/>" " <property type='aa{sv}' name='"DLS_INTERFACE_PROP_RESOURCES"'" " access='read'/>" + " <property type='as' name='"DLS_INTERFACE_PROP_URLS"'" + " access='read'/>" + " <property type='s' name='"DLS_INTERFACE_PROP_MIME_TYPE"'" + " access='read'/>" + " <property type='s' name='"DLS_INTERFACE_PROP_DLNA_PROFILE"'" + " access='read'/>" + " <property type='x' name='"DLS_INTERFACE_PROP_SIZE"'" + " access='read'/>" " </interface>" " <interface name='"DLS_INTERFACE_MEDIA_ITEM"'>" " <method name='"DLS_INTERFACE_GET_COMPATIBLE_RESOURCE"'>" |