~ubuntu-branches/ubuntu/trusty/indicator-sound/trusty

« back to all changes in this revision

Viewing changes to src/media-player-user.vala

  • Committer: Package Import Robot
  • Author(s): Ubuntu daily release, Michael Terry, Ted Gould, Ubuntu daily release
  • Date: 2014-04-01 23:21:06 UTC
  • mfrom: (28.220.33)
  • Revision ID: package-import@ubuntu.com-20140401232106-y47junfgt8auz425
Tags: 12.10.2+14.04.20140401-0ubuntu1
[ Michael Terry ]
* Use correct dbus name for Unity Greeter.

[ Ted Gould ]
* Don't unref the objects in the test
* Check the username has been gotten before using it. (LP: #1297078)
* Make unity-greeter-session-broadcast a suggests to avoid pulling it
  into seeds
* Remove mute from the phone greeter

[ Ubuntu daily release ]
* New rebuild forced

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2014 Canonical Ltd.
 
3
 *
 
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.
 
7
 *
 
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.
 
12
 *
 
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/>.
 
15
 *
 
16
 * Authors:
 
17
 *      Ted Gould <ted@canonical.com>
 
18
 */
 
19
 
 
20
public class MediaPlayerUser : MediaPlayer {
 
21
        Act.UserManager accounts_manager = Act.UserManager.get_default();
 
22
        string username;
 
23
        Act.User? actuser = null;
 
24
        AccountsServiceSoundSettings? proxy = null;
 
25
        GreeterBroadcast? greeter = null;
 
26
 
 
27
        HashTable<string, bool> properties_queued = new HashTable<string, bool>(str_hash, str_equal);
 
28
        uint properties_timeout = 0;
 
29
 
 
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) {
 
33
                username = user;
 
34
 
 
35
                actuser = accounts_manager.get_user(user);
 
36
                actuser.notify["is-loaded"].connect(() => {
 
37
                        debug("User loaded");
 
38
 
 
39
                        this.proxy = null;
 
40
 
 
41
                        Bus.get_proxy.begin<AccountsServiceSoundSettings> (
 
42
                                BusType.SYSTEM,
 
43
                                "org.freedesktop.Accounts",
 
44
                                actuser.get_object_path(),
 
45
                                DBusProxyFlags.GET_INVALIDATED_PROPERTIES,
 
46
                                null,
 
47
                                new_proxy);
 
48
                });
 
49
 
 
50
                Bus.get_proxy.begin<GreeterBroadcast> (
 
51
                        BusType.SYSTEM,
 
52
                        "com.canonical.Unity.Greeter.Broadcast",
 
53
                        "/com/canonical/Unity/Greeter/Broadcast",
 
54
                        DBusProxyFlags.NONE,
 
55
                        null,
 
56
                        greeter_proxy_new);
 
57
        }
 
58
 
 
59
        ~MediaPlayerUser () {
 
60
                if (properties_timeout != 0) {
 
61
                        Source.remove(properties_timeout);
 
62
                        properties_timeout = 0;
 
63
                }
 
64
        }
 
65
 
 
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;
 
70
 
 
71
                properties_queued.@foreach((key, value) => {
 
72
                        debug("Notifying '%s' changed", key);
 
73
                        this.notify_property(key);
 
74
                });
 
75
 
 
76
                properties_queued.remove_all();
 
77
 
 
78
                /* Remove source */
 
79
                return false;
 
80
        }
 
81
 
 
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);
 
86
                }
 
87
 
 
88
                switch (dbus_property_name) {
 
89
                case "Timestamp":
 
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);
 
95
                        break;
 
96
                case "PlayerName":
 
97
                        properties_queued.insert("name", true);
 
98
                        break;
 
99
                case "PlayerIcon":
 
100
                        properties_queued.insert("icon", true);
 
101
                        break;
 
102
                case "State":
 
103
                        properties_queued.insert("state", true);
 
104
                        break;
 
105
                case "Title":
 
106
                case "Artist":
 
107
                case "Album":
 
108
                case "ArtUrl":
 
109
                        properties_queued.insert("current-track", true);
 
110
                        break;
 
111
                }
 
112
        }
 
113
 
 
114
        void new_proxy (GLib.Object? obj, AsyncResult res) {
 
115
                try {
 
116
                        this.proxy = Bus.get_proxy.end (res);
 
117
 
 
118
                        var gproxy = this.proxy as DBusProxy;
 
119
                        gproxy.g_properties_changed.connect ((proxy, changed, invalidated) => {
 
120
                                string key = "";
 
121
                                Variant value;
 
122
                                VariantIter iter = new VariantIter(changed);
 
123
 
 
124
                                while (iter.next("{sv}", &key, &value)) {
 
125
                                        queue_property_notification(key);
 
126
                                }
 
127
 
 
128
                                foreach (var invalid in invalidated) {
 
129
                                        queue_property_notification(invalid);
 
130
                                }
 
131
                        });
 
132
 
 
133
                        debug("Notifying player is ready for user: %s", this.username);
 
134
                        this.notify_property("is-running");
 
135
                } catch (Error e) {
 
136
                        this.proxy = null;
 
137
                        warning("Unable to get proxy to user '%s' sound settings: %s", username, e.message);
 
138
                }
 
139
        }
 
140
 
 
141
        bool proxy_is_valid () {
 
142
                if (this.proxy == null) {
 
143
                        return false;
 
144
                }
 
145
 
 
146
                /* More than 10 minutes old */
 
147
                if (this.proxy.timestamp < GLib.get_monotonic_time() - 10 * 60 * 1000 * 1000) {
 
148
                        return false;
 
149
                }
 
150
 
 
151
                return true;
 
152
        }
 
153
 
 
154
        public override string id {
 
155
                get { return username; }
 
156
        }
 
157
 
 
158
        /* These values come from the proxy */
 
159
        string name_cache;
 
160
        public override string name { 
 
161
                get {
 
162
                        if (proxy_is_valid()) {
 
163
                                name_cache = this.proxy.player_name;
 
164
                                debug("Player Name: %s", name_cache);
 
165
                                return name_cache;
 
166
                        } else {
 
167
                                return "";
 
168
                        }
 
169
                }
 
170
        }
 
171
        string state_cache;
 
172
        public override string state {
 
173
                get {
 
174
                        if (proxy_is_valid()) {
 
175
                                state_cache = this.proxy.state;
 
176
                                debug("State: %s", state_cache);
 
177
                                return state_cache;
 
178
                        } else {
 
179
                                return "";
 
180
                        }
 
181
                }
 
182
                set { }
 
183
        }
 
184
        Icon icon_cache;
 
185
        public override Icon? icon { 
 
186
                get { 
 
187
                        if (proxy_is_valid()) {
 
188
                                icon_cache = Icon.deserialize(this.proxy.player_icon);
 
189
                                return icon_cache;
 
190
                        } else {
 
191
                                return null;
 
192
                        }
 
193
                }
 
194
        }
 
195
 
 
196
        /* Placeholder */
 
197
        public override string dbus_name { get { return ""; } }
 
198
 
 
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; } }
 
203
 
 
204
        /* Fill out the track based on the values in the proxy */
 
205
        MediaPlayer.Track track_cache;
 
206
        public override MediaPlayer.Track? current_track {
 
207
                get { 
 
208
                        if (proxy_is_valid()) {
 
209
                                track_cache = new MediaPlayer.Track(
 
210
                                        this.proxy.artist,
 
211
                                        this.proxy.title,
 
212
                                        this.proxy.album,
 
213
                                        this.proxy.art_url
 
214
                                );
 
215
                                return track_cache;
 
216
                        } else {
 
217
                                return null;
 
218
                        }
 
219
                }
 
220
                set { }
 
221
        }
 
222
 
 
223
        void greeter_proxy_new (GLib.Object? obj, AsyncResult res) {
 
224
                try {
 
225
                        this.greeter = Bus.get_proxy.end (res);
 
226
                } catch (Error e) {
 
227
                        this.greeter = null;
 
228
                        warning("Unable to get greeter proxy: %s", e.message);
 
229
                }
 
230
        }
 
231
 
 
232
        /* Control functions through unity-greeter-session-broadcast */
 
233
        public override void activate () {
 
234
                /* TODO: */
 
235
        }
 
236
        public override void play_pause () {
 
237
                debug("Play Pause for user: %s", this.username);
 
238
 
 
239
                if (this.greeter != null) {
 
240
                        this.greeter.RequestSoundPlayPause.begin(this.username, (obj, res) => {
 
241
                                try {
 
242
                                        (obj as GreeterBroadcast).RequestSoundPlayPause.end(res);
 
243
                                } catch (Error e) {
 
244
                                        warning("Unable to send play pause: %s", e.message);
 
245
                                }
 
246
                        });
 
247
                } else {
 
248
                        warning("No unity-greeter-session-broadcast to send play-pause");
 
249
                }
 
250
        }
 
251
        public override void next () {
 
252
                debug("Next for user: %s", this.username);
 
253
 
 
254
                if (this.greeter != null) {
 
255
                        this.greeter.RequestSoundNext.begin(this.username, (obj, res) => {
 
256
                                try {
 
257
                                        (obj as GreeterBroadcast).RequestSoundNext.end(res);
 
258
                                } catch (Error e) {
 
259
                                        warning("Unable to send next: %s", e.message);
 
260
                                }
 
261
                        });
 
262
                } else {
 
263
                        warning("No unity-greeter-session-broadcast to send next");
 
264
                }
 
265
        }
 
266
        public override void previous () {
 
267
                debug("Previous for user: %s", this.username);
 
268
 
 
269
                if (this.greeter != null) {
 
270
                        this.greeter.RequestSoundPrev.begin(this.username, (obj, res) => {
 
271
                                try {
 
272
                                        (obj as GreeterBroadcast).RequestSoundPrev.end(res);
 
273
                                } catch (Error e) {
 
274
                                        warning("Unable to send previous: %s", e.message);
 
275
                                }
 
276
                        });
 
277
                } else {
 
278
                        warning("No unity-greeter-session-broadcast to send previous");
 
279
                }
 
280
        }
 
281
 
 
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() {
 
285
                return 0;
 
286
        }
 
287
        public override string get_playlist_id (int index) {
 
288
                return "";
 
289
        }
 
290
        public override string get_playlist_name (int index) {
 
291
                return "";
 
292
        }
 
293
        public override void activate_playlist_by_name (string playlist) {
 
294
        }
 
295
}