2
* Copyright © 2014 Canonical Ltd.
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; version 3.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17
* Ted Gould <ted@canonical.com>
20
public class MediaPlayerUser : MediaPlayer {
21
Act.UserManager accounts_manager = Act.UserManager.get_default();
23
Act.User? actuser = null;
24
AccountsServiceSoundSettings? proxy = null;
25
GreeterBroadcast? greeter = null;
27
HashTable<string, bool> properties_queued = new HashTable<string, bool>(str_hash, str_equal);
28
uint properties_timeout = 0;
30
/* Grab the user from the Accounts service and, when it is loaded then
31
set up a proxy to its sound settings */
32
public MediaPlayerUser(string user) {
35
actuser = accounts_manager.get_user(user);
36
actuser.notify["is-loaded"].connect(() => {
41
Bus.get_proxy.begin<AccountsServiceSoundSettings> (
43
"org.freedesktop.Accounts",
44
actuser.get_object_path(),
45
DBusProxyFlags.GET_INVALIDATED_PROPERTIES,
50
Bus.get_proxy.begin<GreeterBroadcast> (
52
"com.canonical.Unity.Greeter.Broadcast",
53
"/com/canonical/Unity/Greeter/Broadcast",
60
if (properties_timeout != 0) {
61
Source.remove(properties_timeout);
62
properties_timeout = 0;
66
/* Ensure that we've collected all the changes so that we only signal
67
once for variables like 'track' */
68
bool properties_idle () {
69
properties_timeout = 0;
71
properties_queued.@foreach((key, value) => {
72
debug("Notifying '%s' changed", key);
73
this.notify_property(key);
76
properties_queued.remove_all();
82
/* Turns the DBus names into the object properties */
83
void queue_property_notification (string dbus_property_name) {
84
if (properties_timeout == 0) {
85
properties_timeout = Idle.add(properties_idle);
88
switch (dbus_property_name) {
90
properties_queued.insert("name", true);
91
properties_queued.insert("icon", true);
92
properties_queued.insert("state", true);
93
properties_queued.insert("current-track", true);
94
properties_queued.insert("is-running", true);
97
properties_queued.insert("name", true);
100
properties_queued.insert("icon", true);
103
properties_queued.insert("state", true);
109
properties_queued.insert("current-track", true);
114
void new_proxy (GLib.Object? obj, AsyncResult res) {
116
this.proxy = Bus.get_proxy.end (res);
118
var gproxy = this.proxy as DBusProxy;
119
gproxy.g_properties_changed.connect ((proxy, changed, invalidated) => {
122
VariantIter iter = new VariantIter(changed);
124
while (iter.next("{sv}", &key, &value)) {
125
queue_property_notification(key);
128
foreach (var invalid in invalidated) {
129
queue_property_notification(invalid);
133
debug("Notifying player is ready for user: %s", this.username);
134
this.notify_property("is-running");
137
warning("Unable to get proxy to user '%s' sound settings: %s", username, e.message);
141
bool proxy_is_valid () {
142
if (this.proxy == null) {
146
/* More than 10 minutes old */
147
if (this.proxy.timestamp < GLib.get_monotonic_time() - 10 * 60 * 1000 * 1000) {
154
public override string id {
155
get { return username; }
158
/* These values come from the proxy */
160
public override string name {
162
if (proxy_is_valid()) {
163
name_cache = this.proxy.player_name;
164
debug("Player Name: %s", name_cache);
172
public override string state {
174
if (proxy_is_valid()) {
175
state_cache = this.proxy.state;
176
debug("State: %s", state_cache);
185
public override Icon? icon {
187
if (proxy_is_valid()) {
188
icon_cache = Icon.deserialize(this.proxy.player_icon);
197
public override string dbus_name { get { return ""; } }
199
/* If it's shown externally it's running */
200
public override bool is_running { get { return proxy_is_valid(); } }
201
/* A bit weird. Not sure how we should handle this. */
202
public override bool can_raise { get { return true; } }
204
/* Fill out the track based on the values in the proxy */
205
MediaPlayer.Track track_cache;
206
public override MediaPlayer.Track? current_track {
208
if (proxy_is_valid()) {
209
track_cache = new MediaPlayer.Track(
223
void greeter_proxy_new (GLib.Object? obj, AsyncResult res) {
225
this.greeter = Bus.get_proxy.end (res);
228
warning("Unable to get greeter proxy: %s", e.message);
232
/* Control functions through unity-greeter-session-broadcast */
233
public override void activate () {
236
public override void play_pause () {
237
debug("Play Pause for user: %s", this.username);
239
if (this.greeter != null) {
240
this.greeter.RequestSoundPlayPause.begin(this.username, (obj, res) => {
242
(obj as GreeterBroadcast).RequestSoundPlayPause.end(res);
244
warning("Unable to send play pause: %s", e.message);
248
warning("No unity-greeter-session-broadcast to send play-pause");
251
public override void next () {
252
debug("Next for user: %s", this.username);
254
if (this.greeter != null) {
255
this.greeter.RequestSoundNext.begin(this.username, (obj, res) => {
257
(obj as GreeterBroadcast).RequestSoundNext.end(res);
259
warning("Unable to send next: %s", e.message);
263
warning("No unity-greeter-session-broadcast to send next");
266
public override void previous () {
267
debug("Previous for user: %s", this.username);
269
if (this.greeter != null) {
270
this.greeter.RequestSoundPrev.begin(this.username, (obj, res) => {
272
(obj as GreeterBroadcast).RequestSoundPrev.end(res);
274
warning("Unable to send previous: %s", e.message);
278
warning("No unity-greeter-session-broadcast to send previous");
282
/* Play list functions are all null as we don't support the
283
playlist feature on the greeter */
284
public override uint get_n_playlists() {
287
public override string get_playlist_id (int index) {
290
public override string get_playlist_name (int index) {
293
public override void activate_playlist_by_name (string playlist) {