mpris_player/
mpris_player.rs

1extern crate dbus;
2extern crate glib;
3use dbus::arg::{RefArg, Variant};
4use dbus::tree::{Factory, Interface, MTFn};
5use dbus::{tree, BusType, Connection, Path, SignalArgs};
6use std::collections::HashMap;
7
8use std::cell::Cell;
9use std::cell::RefCell;
10use std::rc::Rc;
11use std::sync::Arc;
12use std::time::Duration;
13
14use generated::mediaplayer2::org_mpris_media_player2_server;
15use generated::mediaplayer2_player::{
16    org_mpris_media_player2_player_server, OrgFreedesktopDBusPropertiesPropertiesChanged,
17};
18
19use OrgMprisMediaPlayer2;
20use OrgMprisMediaPlayer2Player;
21
22use LoopStatus;
23use Metadata;
24use PlaybackStatus;
25
26pub struct MprisPlayer {
27    connection: Arc<Connection>,
28    factory: Arc<Factory<MTFn<TData>, TData>>,
29
30    // OrgMprisMediaPlayer2         Type
31    can_quit: Cell<bool>,                        // R
32    fullscreen: Cell<bool>,                      // R/W
33    can_set_fullscreen: Cell<bool>,              // R
34    can_raise: Cell<bool>,                       // R
35    has_track_list: Cell<bool>,                  // R
36    identify: String,                            // R
37    desktop_entry: String,                       // R
38    supported_uri_schemes: RefCell<Vec<String>>, // R
39    supported_mime_types: RefCell<Vec<String>>,  // R
40
41    // OrgMprisMediaPlayer2Player   Type
42    playback_status: Cell<PlaybackStatus>, // R
43    loop_status: Cell<LoopStatus>,         // R/W
44    rate: Cell<f64>,                       // R/W
45    shuffle: Cell<bool>,                   // R/W
46    metadata: RefCell<Metadata>,           // R
47    volume: Cell<f64>,                     // R/W
48    position: Cell<i64>,                   // R
49    minimum_rate: Cell<f64>,               // R
50    maximum_rate: Cell<f64>,               // R
51    can_go_next: Cell<bool>,               // R
52    can_go_previous: Cell<bool>,           // R
53    can_play: Cell<bool>,                  // R
54    can_pause: Cell<bool>,                 // R
55    can_seek: Cell<bool>,                  // R
56    can_control: Cell<bool>,               // R
57
58    // Callbacks
59    raise_cb: RefCell<Vec<Rc<RefCell<dyn FnMut()>>>>,
60    quit_cb: RefCell<Vec<Rc<RefCell<dyn FnMut()>>>>,
61    next_cb: RefCell<Vec<Rc<RefCell<dyn FnMut()>>>>,
62    previous_cb: RefCell<Vec<Rc<RefCell<dyn FnMut()>>>>,
63    pause_cb: RefCell<Vec<Rc<RefCell<dyn FnMut()>>>>,
64    play_pause_cb: RefCell<Vec<Rc<RefCell<dyn FnMut()>>>>,
65    stop_cb: RefCell<Vec<Rc<RefCell<dyn FnMut()>>>>,
66    play_cb: RefCell<Vec<Rc<RefCell<dyn FnMut()>>>>,
67    seek_cb: RefCell<Vec<Rc<RefCell<dyn FnMut(i64)>>>>,
68    open_uri_cb: RefCell<Vec<Rc<RefCell<dyn FnMut(&str)>>>>,
69    fullscreen_cb: RefCell<Vec<Rc<RefCell<dyn FnMut(bool)>>>>,
70    loop_status_cb: RefCell<Vec<Rc<RefCell<dyn FnMut(LoopStatus)>>>>,
71    rate_cb: RefCell<Vec<Rc<RefCell<dyn FnMut(f64)>>>>,
72    shuffle_cb: RefCell<Vec<Rc<RefCell<dyn FnMut(bool)>>>>,
73    volume_cb: RefCell<Vec<Rc<RefCell<dyn FnMut(f64)>>>>,
74}
75
76impl MprisPlayer {
77    pub fn new(mpris_name: String, identify: String, desktop_entry: String) -> Arc<Self> {
78        let connection = Arc::new(Connection::get_private(BusType::Session).unwrap());
79        let factory = Arc::new(Factory::new_fn());
80
81        let mpris_player = Arc::new(MprisPlayer {
82            connection,
83            factory,
84
85            can_quit: Cell::new(false),
86            fullscreen: Cell::new(false),
87            can_set_fullscreen: Cell::new(false),
88            can_raise: Cell::new(false),
89            has_track_list: Cell::new(false),
90            identify,
91            desktop_entry,
92            supported_uri_schemes: RefCell::new(Vec::new()),
93            supported_mime_types: RefCell::new(Vec::new()),
94
95            playback_status: Cell::new(PlaybackStatus::Paused),
96            loop_status: Cell::new(LoopStatus::None),
97            rate: Cell::new(0_f64),
98            shuffle: Cell::new(false),
99            metadata: RefCell::new(Metadata::new()),
100            volume: Cell::new(0_f64),
101            position: Cell::new(0),
102            minimum_rate: Cell::new(0_f64),
103            maximum_rate: Cell::new(0_f64),
104            can_go_next: Cell::new(true),
105            can_go_previous: Cell::new(true),
106            can_play: Cell::new(true),
107            can_pause: Cell::new(true),
108            can_seek: Cell::new(false),
109            can_control: Cell::new(true),
110
111            raise_cb: RefCell::new(Vec::new()),
112            quit_cb: RefCell::new(Vec::new()),
113            next_cb: RefCell::new(Vec::new()),
114            previous_cb: RefCell::new(Vec::new()),
115            pause_cb: RefCell::new(Vec::new()),
116            play_pause_cb: RefCell::new(Vec::new()),
117            stop_cb: RefCell::new(Vec::new()),
118            play_cb: RefCell::new(Vec::new()),
119            seek_cb: RefCell::new(Vec::new()),
120            open_uri_cb: RefCell::new(Vec::new()),
121            fullscreen_cb: RefCell::new(Vec::new()),
122            loop_status_cb: RefCell::new(Vec::new()),
123            rate_cb: RefCell::new(Vec::new()),
124            shuffle_cb: RefCell::new(Vec::new()),
125            volume_cb: RefCell::new(Vec::new()),
126        });
127
128        // Create OrgMprisMediaPlayer2 interface
129        let root_iface: Interface<MTFn<TData>, TData> =
130            org_mpris_media_player2_server(&mpris_player.factory, (), |m| {
131                let a: &Arc<MprisPlayer> = m.path.get_data();
132                let b: &MprisPlayer = a;
133                b
134            });
135
136        // Create OrgMprisMediaPlayer2Player interface
137        let player_iface: Interface<MTFn<TData>, TData> =
138            org_mpris_media_player2_player_server(&mpris_player.factory, (), |m| {
139                let a: &Arc<MprisPlayer> = m.path.get_data();
140                let b: &MprisPlayer = a;
141                b
142            });
143
144        // Create dbus tree
145        let mut tree = mpris_player.factory.tree(());
146        tree = tree.add(
147            mpris_player
148                .factory
149                .object_path("/org/mpris/MediaPlayer2", mpris_player.clone())
150                .introspectable()
151                .add(root_iface)
152                .add(player_iface),
153        );
154
155        // Setup dbus connection
156        mpris_player
157            .connection
158            .register_name(&format!("org.mpris.MediaPlayer2.{}", mpris_name), 0)
159            .unwrap();
160        tree.set_registered(&mpris_player.connection, true).unwrap();
161        mpris_player.connection.add_handler(tree);
162
163        let connection = mpris_player.connection.clone();
164        glib::source::timeout_add_local(Duration::from_millis(250), move || {
165            connection.incoming(5).next();
166            glib::Continue(true)
167        });
168
169        mpris_player
170    }
171
172    pub fn property_changed<T: 'static>(&self, name: String, value: T)
173    where
174        T: dbus::arg::RefArg,
175    {
176        let mut changed_properties = HashMap::new();
177        let x = Box::new(value) as Box<dyn RefArg>;
178        changed_properties.insert(name, Variant(x));
179
180        let signal = OrgFreedesktopDBusPropertiesPropertiesChanged {
181            changed_properties,
182            interface_name: "org.mpris.MediaPlayer2.Player".to_string(),
183            invalidated_properties: Vec::new(),
184        };
185
186        self.connection
187            .send(signal.to_emit_message(&Path::new("/org/mpris/MediaPlayer2").unwrap()))
188            .unwrap();
189    }
190
191    //
192    // OrgMprisMediaPlayer2 setters...
193    //
194
195    pub fn set_supported_mime_types(&self, value: Vec<String>) {
196        if *self.supported_mime_types.borrow_mut() != value {
197            *self.supported_mime_types.borrow_mut() = value;
198            self.property_changed(
199                "SupportedMimeTypes".to_string(),
200                self.get_supported_mime_types().unwrap(),
201            );
202        }
203    }
204
205    pub fn set_supported_uri_schemes(&self, value: Vec<String>) {
206        if *self.supported_uri_schemes.borrow_mut() != value {
207            *self.supported_uri_schemes.borrow_mut() = value;
208            self.property_changed(
209                "SupportedUriSchemes".to_string(),
210                self.get_supported_uri_schemes().unwrap(),
211            );
212        }
213    }
214
215    pub fn set_can_quit(&self, value: bool) {
216        if self.can_quit.get() != value {
217            self.can_quit.set(value);
218            self.property_changed("CanQuit".to_string(), self.get_can_quit().unwrap());
219        }
220    }
221
222    pub fn set_can_raise(&self, value: bool) {
223        if self.can_raise.get() != value {
224            self.can_raise.set(value);
225            self.property_changed("CanRaise".to_string(), self.get_can_raise().unwrap());
226        }
227    }
228
229    pub fn set_can_set_fullscreen(&self, value: bool) {
230        if self.can_set_fullscreen.get() != value {
231            self.can_set_fullscreen.set(value);
232            self.property_changed(
233                "CanSetFullscreen".to_string(),
234                self.get_can_set_fullscreen().unwrap(),
235            );
236        }
237    }
238
239    pub fn set_has_track_list(&self, value: bool) {
240        if self.has_track_list.get() != value {
241            self.has_track_list.set(value);
242            self.property_changed(
243                "HasTrackList".to_string(),
244                self.get_has_track_list().unwrap(),
245            );
246        }
247    }
248
249    //
250    // OrgMprisMediaPlayer2Player setters...
251    //
252
253    pub fn set_playback_status(&self, value: PlaybackStatus) {
254        if self.playback_status.get() != value {
255            self.playback_status.set(value);
256            self.property_changed(
257                "PlaybackStatus".to_string(),
258                self.get_playback_status().unwrap(),
259            );
260        }
261    }
262
263    pub fn set_loop_status(&self, value: LoopStatus) {
264        if self.loop_status.get() != value {
265            self.loop_status.set(value);
266            self.property_changed("LoopStatus".to_string(), self.get_loop_status().unwrap());
267        }
268    }
269
270    pub fn set_metadata(&self, metadata: Metadata) {
271        if *self.metadata.borrow_mut() != metadata {
272            *self.metadata.borrow_mut() = metadata;
273            self.property_changed("Metadata".to_string(), self.get_metadata().unwrap());
274        }
275    }
276
277    pub fn set_position(&self, value: i64) {
278        if self.position.get() != value {
279            self.position.set(value);
280            self.property_changed("Position".to_string(), self.get_position().unwrap());
281        }
282    }
283
284    pub fn set_minimum_rate(&self, value: f64) {
285        if self.minimum_rate.get() != value {
286            self.minimum_rate.set(value);
287            self.property_changed("MinimumRate".to_string(), self.get_minimum_rate().unwrap());
288        }
289    }
290
291    pub fn set_maximum_rate(&self, value: f64) {
292        if self.maximum_rate.get() != value {
293            self.maximum_rate.set(value);
294            self.property_changed("MaximumRate".to_string(), self.get_maximum_rate().unwrap());
295        }
296    }
297
298    pub fn set_can_go_next(&self, value: bool) {
299        if self.can_go_next.get() != value {
300            self.can_go_next.set(value);
301            self.property_changed("CanGoNext".to_string(), self.get_can_go_next().unwrap());
302        }
303    }
304
305    pub fn set_can_go_previous(&self, value: bool) {
306        if self.can_go_previous.get() != value {
307            self.can_go_previous.set(value);
308            self.property_changed(
309                "CanGoPrevious".to_string(),
310                self.get_can_go_previous().unwrap(),
311            );
312        }
313    }
314
315    pub fn set_can_play(&self, value: bool) {
316        if self.can_play.get() != value {
317            self.can_play.set(value);
318            self.property_changed("CanPlay".to_string(), self.get_can_play().unwrap());
319        }
320    }
321
322    pub fn set_can_pause(&self, value: bool) {
323        if self.can_pause.get() != value {
324            self.can_pause.set(value);
325            self.property_changed("CanPause".to_string(), self.get_can_pause().unwrap());
326        }
327    }
328
329    pub fn set_can_seek(&self, value: bool) {
330        if self.can_seek.get() != value {
331            self.can_seek.set(value);
332            self.property_changed("CanSeek".to_string(), self.get_can_seek().unwrap());
333        }
334    }
335
336    pub fn set_can_control(&self, value: bool) {
337        if self.can_control.get() != value {
338            self.can_control.set(value);
339            self.property_changed("CanControl".to_string(), self.get_can_control().unwrap());
340        }
341    }
342
343    //
344    // Callbacks
345    //
346
347    pub fn connect_raise<F: FnMut() + 'static>(&self, callback: F) {
348        let cell = Rc::new(RefCell::new(callback));
349        self.raise_cb.borrow_mut().push(cell);
350    }
351
352    pub fn connect_quit<F: FnMut() + 'static>(&self, callback: F) {
353        let cell = Rc::new(RefCell::new(callback));
354        self.quit_cb.borrow_mut().push(cell);
355    }
356
357    pub fn connect_next<F: FnMut() + 'static>(&self, callback: F) {
358        let cell = Rc::new(RefCell::new(callback));
359        self.next_cb.borrow_mut().push(cell);
360    }
361
362    pub fn connect_previous<F: FnMut() + 'static>(&self, callback: F) {
363        let cell = Rc::new(RefCell::new(callback));
364        self.previous_cb.borrow_mut().push(cell);
365    }
366
367    pub fn connect_pause<F: FnMut() + 'static>(&self, callback: F) {
368        let cell = Rc::new(RefCell::new(callback));
369        self.pause_cb.borrow_mut().push(cell);
370    }
371
372    pub fn connect_play_pause<F: FnMut() + 'static>(&self, callback: F) {
373        let cell = Rc::new(RefCell::new(callback));
374        self.play_pause_cb.borrow_mut().push(cell);
375    }
376
377    pub fn connect_stop<F: FnMut() + 'static>(&self, callback: F) {
378        let cell = Rc::new(RefCell::new(callback));
379        self.stop_cb.borrow_mut().push(cell);
380    }
381
382    pub fn connect_play<F: FnMut() + 'static>(&self, callback: F) {
383        let cell = Rc::new(RefCell::new(callback));
384        self.play_cb.borrow_mut().push(cell);
385    }
386
387    pub fn connect_seek<F: FnMut(i64) + 'static>(&self, callback: F) {
388        let cell = Rc::new(RefCell::new(callback));
389        self.seek_cb.borrow_mut().push(cell);
390    }
391
392    pub fn connect_open_uri<F: FnMut(&str) + 'static>(&self, callback: F) {
393        let cell = Rc::new(RefCell::new(callback));
394        self.open_uri_cb.borrow_mut().push(cell);
395    }
396
397    pub fn connect_fullscreen<F: FnMut(bool) + 'static>(&self, callback: F) {
398        let cell = Rc::new(RefCell::new(callback));
399        self.fullscreen_cb.borrow_mut().push(cell);
400    }
401
402    pub fn connect_loop_status<F: FnMut(LoopStatus) + 'static>(&self, callback: F) {
403        let cell = Rc::new(RefCell::new(callback));
404        self.loop_status_cb.borrow_mut().push(cell);
405    }
406
407    pub fn connect_rate<F: FnMut(f64) + 'static>(&self, callback: F) {
408        let cell = Rc::new(RefCell::new(callback));
409        self.rate_cb.borrow_mut().push(cell);
410    }
411
412    pub fn connect_shuffle<F: FnMut(bool) + 'static>(&self, callback: F) {
413        let cell = Rc::new(RefCell::new(callback));
414        self.shuffle_cb.borrow_mut().push(cell);
415    }
416
417    pub fn connect_volume<F: FnMut(f64) + 'static>(&self, callback: F) {
418        let cell = Rc::new(RefCell::new(callback));
419        self.volume_cb.borrow_mut().push(cell);
420    }
421}
422
423impl OrgMprisMediaPlayer2 for MprisPlayer {
424    type Err = tree::MethodErr;
425
426    fn raise(&self) -> Result<(), Self::Err> {
427        for callback in self.raise_cb.borrow_mut().iter() {
428            let mut closure = callback.borrow_mut();
429            (&mut *closure)();
430        }
431        Ok(())
432    }
433
434    fn quit(&self) -> Result<(), Self::Err> {
435        for callback in self.quit_cb.borrow_mut().iter() {
436            let mut closure = callback.borrow_mut();
437            (&mut *closure)();
438        }
439        Ok(())
440    }
441
442    fn get_can_quit(&self) -> Result<bool, Self::Err> {
443        Ok(self.can_quit.get())
444    }
445
446    fn get_fullscreen(&self) -> Result<bool, Self::Err> {
447        Ok(self.fullscreen.get())
448    }
449
450    fn set_fullscreen(&self, value: bool) -> Result<(), Self::Err> {
451        self.fullscreen.set(value);
452        self.property_changed("Fullscreen".to_string(), self.get_fullscreen().unwrap());
453        for callback in self.fullscreen_cb.borrow_mut().iter() {
454            let mut closure = callback.borrow_mut();
455            (&mut *closure)(value);
456        }
457        Ok(())
458    }
459
460    fn get_can_set_fullscreen(&self) -> Result<bool, Self::Err> {
461        Ok(self.can_set_fullscreen.get())
462    }
463
464    fn get_can_raise(&self) -> Result<bool, Self::Err> {
465        Ok(self.can_raise.get())
466    }
467
468    fn get_has_track_list(&self) -> Result<bool, Self::Err> {
469        Ok(self.has_track_list.get())
470    }
471
472    fn get_identity(&self) -> Result<String, Self::Err> {
473        Ok(self.identify.clone())
474    }
475
476    fn get_desktop_entry(&self) -> Result<String, Self::Err> {
477        Ok(self.desktop_entry.clone())
478    }
479
480    fn get_supported_uri_schemes(&self) -> Result<Vec<String>, Self::Err> {
481        Ok(self.supported_uri_schemes.borrow().to_vec())
482    }
483
484    fn get_supported_mime_types(&self) -> Result<Vec<String>, Self::Err> {
485        Ok(self.supported_mime_types.borrow().to_vec())
486    }
487}
488
489impl OrgMprisMediaPlayer2Player for MprisPlayer {
490    type Err = tree::MethodErr;
491
492    fn next(&self) -> Result<(), Self::Err> {
493        for callback in self.next_cb.borrow_mut().iter() {
494            let mut closure = callback.borrow_mut();
495            (&mut *closure)();
496        }
497        Ok(())
498    }
499
500    fn previous(&self) -> Result<(), Self::Err> {
501        for callback in self.previous_cb.borrow_mut().iter() {
502            let mut closure = callback.borrow_mut();
503            (&mut *closure)();
504        }
505        Ok(())
506    }
507
508    fn pause(&self) -> Result<(), Self::Err> {
509        for callback in self.pause_cb.borrow_mut().iter() {
510            let mut closure = callback.borrow_mut();
511            (&mut *closure)();
512        }
513        Ok(())
514    }
515
516    fn play_pause(&self) -> Result<(), Self::Err> {
517        for callback in self.play_pause_cb.borrow_mut().iter() {
518            let mut closure = callback.borrow_mut();
519            (&mut *closure)();
520        }
521        Ok(())
522    }
523
524    fn stop(&self) -> Result<(), Self::Err> {
525        for callback in self.stop_cb.borrow_mut().iter() {
526            let mut closure = callback.borrow_mut();
527            (&mut *closure)();
528        }
529        Ok(())
530    }
531
532    fn play(&self) -> Result<(), Self::Err> {
533        for callback in self.play_cb.borrow_mut().iter() {
534            let mut closure = callback.borrow_mut();
535            (&mut *closure)();
536        }
537        Ok(())
538    }
539
540    fn seek(&self, offset: i64) -> Result<(), Self::Err> {
541        for callback in self.seek_cb.borrow_mut().iter() {
542            let mut closure = callback.borrow_mut();
543            (&mut *closure)(offset);
544        }
545        Ok(())
546    }
547
548    fn set_position(&self, _track_id: dbus::Path, position: i64) -> Result<(), Self::Err> {
549        self.position.set(position);
550        self.property_changed("Position".to_string(), self.get_position().unwrap());
551        Ok(())
552    }
553
554    fn open_uri(&self, uri: &str) -> Result<(), Self::Err> {
555        for callback in self.open_uri_cb.borrow_mut().iter() {
556            let mut closure = callback.borrow_mut();
557            (&mut *closure)(uri);
558        }
559        Ok(())
560    }
561
562    fn get_playback_status(&self) -> Result<String, Self::Err> {
563        Ok(self.playback_status.get().value())
564    }
565
566    fn get_loop_status(&self) -> Result<String, Self::Err> {
567        Ok(self.loop_status.get().value())
568    }
569
570    fn set_loop_status(&self, value: String) -> Result<(), Self::Err> {
571        let ls = match value.as_ref() {
572            "Track" => LoopStatus::Track,
573            "Playlist" => LoopStatus::Playlist,
574            _ => LoopStatus::None,
575        };
576        self.loop_status.set(ls);
577        self.property_changed("LoopStatus".to_string(), self.get_loop_status().unwrap());
578        for callback in self.loop_status_cb.borrow_mut().iter() {
579            let mut closure = callback.borrow_mut();
580            (&mut *closure)(ls);
581        }
582        Ok(())
583    }
584
585    fn get_rate(&self) -> Result<f64, Self::Err> {
586        Ok(self.rate.get())
587    }
588
589    fn set_rate(&self, value: f64) -> Result<(), Self::Err> {
590        self.rate.set(value);
591        self.property_changed("Rate".to_string(), self.get_rate().unwrap());
592        for callback in self.rate_cb.borrow_mut().iter() {
593            let mut closure = callback.borrow_mut();
594            (&mut *closure)(value);
595        }
596        Ok(())
597    }
598
599    fn get_shuffle(&self) -> Result<bool, Self::Err> {
600        Ok(self.shuffle.get())
601    }
602
603    fn set_shuffle(&self, value: bool) -> Result<(), Self::Err> {
604        self.shuffle.set(value);
605        self.property_changed("Shuffle".to_string(), self.get_volume().unwrap());
606        for callback in self.shuffle_cb.borrow_mut().iter() {
607            let mut closure = callback.borrow_mut();
608            (&mut *closure)(value);
609        }
610        Ok(())
611    }
612
613    fn get_metadata(
614        &self,
615    ) -> Result<HashMap<String, Variant<Box<dyn RefArg + 'static>>>, Self::Err> {
616        let metadata = self.metadata.borrow().to_hashmap();
617        Ok(metadata)
618    }
619
620    fn get_volume(&self) -> Result<f64, Self::Err> {
621        Ok(self.volume.get())
622    }
623
624    fn set_volume(&self, value: f64) -> Result<(), Self::Err> {
625        self.volume.set(value);
626        self.property_changed("Volume".to_string(), self.get_volume().unwrap());
627        for callback in self.volume_cb.borrow_mut().iter() {
628            let mut closure = callback.borrow_mut();
629            (&mut *closure)(value);
630        }
631        Ok(())
632    }
633
634    fn get_position(&self) -> Result<i64, Self::Err> {
635        Ok(self.position.get())
636    }
637
638    fn get_minimum_rate(&self) -> Result<f64, Self::Err> {
639        Ok(self.minimum_rate.get())
640    }
641
642    fn get_maximum_rate(&self) -> Result<f64, Self::Err> {
643        Ok(self.maximum_rate.get())
644    }
645
646    fn get_can_go_next(&self) -> Result<bool, Self::Err> {
647        Ok(self.can_go_next.get())
648    }
649
650    fn get_can_go_previous(&self) -> Result<bool, Self::Err> {
651        Ok(self.can_go_previous.get())
652    }
653
654    fn get_can_play(&self) -> Result<bool, Self::Err> {
655        Ok(self.can_play.get())
656    }
657
658    fn get_can_pause(&self) -> Result<bool, Self::Err> {
659        Ok(self.can_pause.get())
660    }
661
662    fn get_can_seek(&self) -> Result<bool, Self::Err> {
663        Ok(self.can_seek.get())
664    }
665
666    fn get_can_control(&self) -> Result<bool, Self::Err> {
667        Ok(self.can_control.get())
668    }
669}
670
671impl ::std::fmt::Debug for MprisPlayer {
672    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
673        write!(f, "mprisplayer")
674    }
675}
676
677#[derive(Copy, Clone, Default, Debug)]
678pub struct TData;
679impl tree::DataType for TData {
680    type Tree = ();
681    type ObjectPath = Arc<MprisPlayer>;
682    type Property = ();
683    type Interface = ();
684    type Method = ();
685    type Signal = ();
686}