Commit 7e7b9c2a authored by Jussi Kukkonen's avatar Jussi Kukkonen Committed by Jens Georg
Browse files

renderer: Refactor AVTransport and PlayerController

Move track_metadata and track_uri state tracking to controller,
Stop modifying controller properties from many places in
AVTransport. Add set_single_play_uri() and set_playlist_uri() as the
only valid methods to set uri, metadata, etc. Also make property
setters private if setting them from AVTransport makes no sense.

The goal is to make both classes cleaner, no functional changes
are intended.

https://bugzilla.gnome.org/show_bug.cgi?id=709165
parent 1db7452f
......@@ -42,32 +42,6 @@ internal class Rygel.AVTransport : Service {
private Session session;
private string protocol_info;
public string track_metadata {
owned get { return this.player.metadata ?? ""; }
set {
if (value.has_prefix ("<")) {
this.player.metadata = this.unescape (value);
} else {
this.player.metadata = value;
}
}
}
public string track_uri {
owned get {
if (this.player.uri != null) {
return Markup.escape_text (this.player.uri);
} else {
return "";
}
}
set {
this.player.uri = value;
}
}
private string _status = "OK";
public string status {
get {
......@@ -156,10 +130,10 @@ internal class Rygel.AVTransport : Service {
this.controller.notify["track"].connect (this.notify_track_cb);
this.controller.notify["uri"].connect (this.notify_uri_cb);
this.controller.notify["metadata"].connect (this.notify_meta_data_cb);
this.controller.notify["track-uri"].connect (this.notify_track_uri_cb);
this.controller.notify["track-metadata"].connect (this.notify_track_meta_data_cb);
this.player.notify["duration"].connect (this.notify_duration_cb);
this.player.notify["uri"].connect (this.notify_track_uri_cb);
this.player.notify["metadata"].connect (this.notify_track_meta_data_cb);
var proxy = Environment.get_variable ("http_proxy");
if (proxy != null) {
......@@ -205,10 +179,10 @@ internal class Rygel.AVTransport : Service {
log.log ("CurrentTrackDuration", this.player.duration_as_str);
log.log ("CurrentMediaDuration", this.player.duration_as_str);
log.log ("CurrentTrackMetaData",
Markup.escape_text (this.track_metadata));
Markup.escape_text (this.controller.track_metadata));
log.log ("AVTransportURIMetaData",
Markup.escape_text (this.controller.metadata));
log.log ("CurrentTrackURI", this.track_uri);
log.log ("CurrentTrackURI", this.controller.track_uri);
log.log ("AVTransportURI", this.controller.uri);
log.log ("NextAVTransportURI", "NOT_IMPLEMENTED");
log.log ("NextAVTransportURIMetaData", "NOT_IMPLEMENTED");
......@@ -254,8 +228,6 @@ internal class Rygel.AVTransport : Service {
typeof (string),
out _metadata);
// remove current playlist handler
this.controller.set_playlist (null);
if (_uri.has_prefix ("http://") || _uri.has_prefix ("https://")) {
var message = new Message ("HEAD", _uri);
message.request_headers.append ("getContentFeatures.dlna.org",
......@@ -266,19 +238,7 @@ internal class Rygel.AVTransport : Service {
this.session.queue_message (message, null);
} else {
this.controller.metadata = _metadata;
this.controller.uri = _uri;
this.track_metadata = _metadata;
this.track_uri = _uri;
if (_uri == "") {
this.controller.n_tracks = 0;
this.controller.track = 0;
} else {
this.controller.n_tracks = 1;
this.controller.track = 1;
}
this.controller.set_single_play_uri (_uri, _metadata, null, null);
action.return ();
}
......@@ -436,10 +396,10 @@ internal class Rygel.AVTransport : Service {
this.player.duration_as_str,
"TrackMetaData",
typeof (string),
this.track_metadata,
this.controller.track_metadata,
"TrackURI",
typeof (string),
this.track_uri,
this.controller.track_uri,
"RelTime",
typeof (string),
this.player.position_as_str,
......@@ -695,7 +655,7 @@ internal class Rygel.AVTransport : Service {
}
private void notify_track_uri_cb (Object player, ParamSpec p) {
this.changelog.log ("CurrentTrackURI", this.track_uri);
this.changelog.log ("CurrentTrackURI", this.controller.track_uri);
}
private void notify_uri_cb (Object controller, ParamSpec p) {
......@@ -704,7 +664,7 @@ internal class Rygel.AVTransport : Service {
private void notify_track_meta_data_cb (Object player, ParamSpec p) {
this.changelog.log ("CurrentTrackMetaData",
Markup.escape_text (this.track_metadata));
Markup.escape_text (this.controller.track_metadata));
}
private void notify_meta_data_cb (Object player, ParamSpec p) {
......@@ -712,7 +672,11 @@ internal class Rygel.AVTransport : Service {
Markup.escape_text (this.controller.metadata));
}
private async void handle_playlist (ServiceAction action) {
private async void handle_playlist (ServiceAction action,
string uri,
string metadata,
string mime,
string features) {
var message = new Message ("GET", this.controller.uri);
this.session.queue_message (message, () => {
handle_playlist.callback ();
......@@ -735,21 +699,11 @@ internal class Rygel.AVTransport : Service {
return;
}
this.controller.set_playlist (collection);
this.controller.set_playlist_uri (uri, metadata, collection);
action.return ();
}
private string unescape (string input) {
var result = input.replace (""", "\"");
result = result.replace ("&lt;", "<");
result = result.replace ("&gt;", ">");
result = result.replace ("&apos;", "'");
result = result.replace ("&amp;", "&");
return result;
}
private bool is_playlist (string? mime, string? features) {
return mime == "text/xml" && features != null &&
features.has_prefix ("DLNA.ORG_PN=DIDL_S");
......@@ -804,29 +758,18 @@ internal class Rygel.AVTransport : Service {
return;
}
this.controller.metadata = _metadata;
this.controller.uri = _uri;
if (this.is_playlist (mime, features)) {
// Delay returning the action until we got some
this.handle_playlist.begin (action);
// Delay returning the action
this.handle_playlist.begin (action,
_uri,
_metadata,
mime,
features);
return;
}
// some other track
this.player.mime_type = mime;
if (features != null) {
this.player.content_features = features;
} else {
this.player.content_features = "*";
}
// Track == Media
this.track_metadata = _metadata;
this.track_uri = _uri;
this.controller.n_tracks = 1;
this.controller.track = 1;
this.controller.set_single_play_uri (_uri, _metadata, mime, features);
action.return ();
}
......
......@@ -58,20 +58,44 @@ internal class Rygel.PlayerController : Object {
public string playback_state {
get { return this._playback_state; }
set { this.player.playback_state = value; }
default = "NO_MEDIA_PRESENT";
}
public uint n_tracks { get; set; default = 0; }
public uint n_tracks { get; private set; default = 0; }
public uint track {
get { return this._track; }
set { this._track = value; this.apply_track (); }
default = 0;
}
public string uri { get; set; default = ""; }
public string metadata {
owned get { return this._metadata ?? ""; }
set { this._metadata = this.unescape (value); }
default = "";
public string uri { get; private set; default = ""; }
public string metadata { get; private set; default = ""; }
[CCode (notify = false)]
public string track_uri {
owned get {
if (this.player.uri != null) {
return Markup.escape_text (this.player.uri);
} else {
return "";
}
}
private set {
this.player.uri = value;
}
}
[CCode (notify = false)]
public string track_metadata {
owned get { return this.player.metadata ?? ""; }
private set {
if (value.has_prefix ("&lt;")) {
this.player.metadata = this.unescape (value);
} else {
this.player.metadata = value;
}
}
}
public string current_transport_actions {
......@@ -130,16 +154,14 @@ internal class Rygel.PlayerController : Object {
}
// Private members
private MediaCollection collection;
private List<DIDLLiteItem> collection_items;
private List<DIDLLiteItem> playlist;
private uint timeout_id;
private uint default_image_timeout;
private Configuration config;
// Private property variables
private string _metadata;
private uint _track;
private string _playback_state;
private string _playback_state = "NO_MEDIA_PRESENT";
public PlayerController (MediaPlayer player, string protocol_info) {
Object (player : player, protocol_info : protocol_info);
......@@ -149,6 +171,8 @@ internal class Rygel.PlayerController : Object {
base.constructed ();
this.player.notify["playback-state"].connect (this.notify_state_cb);
this.player.notify["uri"].connect (this.notify_uri_cb);
this.player.notify["metadata"].connect (this.notify_metadata_cb);
this.config = MetaConfig.get_default ();
this.config.setting_changed.connect (this.on_setting_changed);
......@@ -176,26 +200,60 @@ internal class Rygel.PlayerController : Object {
return true;
}
public void set_playlist (MediaCollection? collection) {
this.collection = collection;
public void set_single_play_uri (string uri,
string metadata,
string? mime,
string? features)
{
if (this.timeout_id != 0) {
this.timeout_id = 0;
Source.remove (this.timeout_id);
}
if (this.collection != null) {
this.collection_items = collection.get_items ();
this.n_tracks = this.collection_items.length ();
this.track = 1;
this.metadata = this.unescape (metadata);
this.uri = uri;
this.player.mime_type = mime ?? "";
this.player.content_features = features ?? "*";
this.track_metadata = this.metadata;
this.track_uri = this.uri;
this.playlist = null;
if (this.uri == "") {
this.n_tracks = 0;
this.track = 0;
} else {
this.collection_items = null;
this.n_tracks = 1;
this.track = 1;
}
}
public void set_playlist_uri (string uri,
string metadata,
MediaCollection collection) {
if (this.timeout_id != 0) {
this.timeout_id = 0;
Source.remove (this.timeout_id);
}
this.metadata = this.unescape (metadata);
this.uri = uri;
this.playlist = collection.get_items ();
this.n_tracks = this.playlist.length ();
// Track setter will set track_metadata and
// track_uri
this.track = 1;
}
private void notify_state_cb (Object player, ParamSpec p) {
var state = this.player.playback_state;
if (state == "EOS") {
if (this.collection == null) {
if (this.playlist == null) {
// Just move to stop
Idle.add (() => {
this.playback_state = "STOPPED";
......@@ -218,17 +276,25 @@ internal class Rygel.PlayerController : Object {
}
}
private void notify_uri_cb (Object player, ParamSpec p) {
notify_property ("track-uri");
}
private void notify_metadata_cb (Object player, ParamSpec p) {
notify_property ("track-metadata");
}
private void apply_track () {
// We only have something to do here if we have collection items
if (this.collection_items != null) {
var item = this.collection_items.nth (this.track - 1).data;
// We only have something to do here if we have playlist items
if (this.playlist != null) {
var item = this.playlist.nth (this.track - 1).data;
var res = item.get_compat_resource (this.protocol_info, true);
this.player.metadata = DIDL_FRAME_TEMPLATE.printf
this.track_metadata = DIDL_FRAME_TEMPLATE.printf
(item.get_xml_string ());
this.player.uri = res.get_uri ();
this.track_uri = res.get_uri ();
if (item.upnp_class.has_prefix ("object.item.image") &&
this.collection != null &&
this.playback_state != "STOPPED") {
this.setup_image_timeouts (item.lifetime);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment