Add full support for org.mpris.MediaPlayer2 interface (not including TrackList and Player)

This commit is contained in:
Stein Magnus Jodal 2010-10-27 23:06:09 +02:00
parent 54f294879d
commit a8b8725403

View File

@ -1,21 +1,22 @@
import gobject
gobject.threads_init()
import logging
import multiprocessing
import socket
import time
try:
import dbus
import dbus.service
from dbus.mainloop.glib import DBusGMainLoop
except ImportError as import_error:
from mopidy import OptionalDependencyError
raise OptionalDependencyError(import_error)
from mopidy import get_version, settings, SettingsError
from mopidy.frontends.base import BaseFrontend
from mopidy.utils.process import BaseThread
logger = logging.getLogger('mopidy.frontends.mpris')
BUS_NAME = u'org.mpris.MediaPlayer2.mopidy'
class MprisFrontend(BaseFrontend):
"""
@ -50,7 +51,12 @@ class MprisFrontendThread(BaseThread):
super(MprisFrontendThread, self).__init__(core_queue)
self.name = u'MprisFrontendThread'
self.connection = connection
self.bus = None
self.dbus_objects = []
def destroy(self):
for dbus_object in self.dbus_objects:
dbus_object.remove_from_connection()
self.dbus_objects = []
def run_inside_try(self):
self.setup()
@ -60,8 +66,111 @@ class MprisFrontendThread(BaseThread):
self.process_message(message)
def setup(self):
self.bus = dbus.SystemBus()
logger.info(u'Connected to D-Bus/MPRIS')
self.dbus_objects.append(MprisObject(self.core_queue))
# TODO Move to another thread if we need to process messages
logger.debug(u'Starting GLib main loop')
loop = gobject.MainLoop()
loop.run()
def process_message(self, message):
pass # Ignore commands for other frontends
class MprisObject(dbus.service.Object):
"""Implements http://www.mpris.org/2.0/spec/"""
bus_name = 'org.mpris.MediaPlayer2.mopidy'
object_path = '/org/mpris/MediaPlayer2'
property_interface = 'org.freedesktop.DBus.Properties'
root_interface = 'org.mpris.MediaPlayer2'
player_interface = 'org.mpris.MediaPlayer2.Player'
properties = {
root_interface: {
'CanQuit': (True, None),
'CanRaise': (False, None),
# TODO Add track list support
'HasTrackList': (False, None),
'Identity': ('Mopidy', None),
# TODO Return URI schemes supported by backend configuration
'SupportedUriSchemes': (dbus.Array(signature='s'), None),
# TODO Return MIME types supported by local backend if active
'SupportedMimeTypes': (dbus.Array(signature='s'), None),
},
player_interface: {
# TODO
},
}
def __init__(self, core_queue):
self.core_queue = core_queue
logger.debug(u'Prepare the D-Bus main loop before connecting')
DBusGMainLoop(set_as_default=True)
logger.info(u'Connecting to D-Bus')
bus = dbus.SessionBus()
logger.debug(u'Connecting to D-Bus: claiming service name')
# FIXME We segfault at the next line 80% of the time
bus_name = dbus.service.BusName(self.bus_name, bus)
logger.debug(u'Connecting to D-Bus: registering service object')
super(MprisObject, self).__init__(object_path=self.object_path,
bus_name=bus_name)
logger.debug(u'Connecting to D-Bus: done')
### Property interface
@dbus.service.method(dbus_interface=property_interface,
in_signature='ss', out_signature='v')
def Get(self, interface, prop):
getter, setter = self.properties[interface][prop]
return getter() if callable(getter) else getter
@dbus.service.method(dbus_interface=property_interface,
in_signature='s', out_signature='a{sv}')
def GetAll(self, interface):
"""
To test, start Mopidy and then run the following in a Python shell::
import dbus
bus = dbus.SessionBus()
player = bus.get_object('org.mpris.MediaPlayer2.mopidy',
'/org/mpris/MediaPlayer2')
props = player.GetAll('org.mpris.MediaPlayer2',
dbus_interface='org.freedesktop.DBus.Properties')
"""
getters = {}
for key, (getter, setter) in self.properties[interface].iteritems():
getters[key] = getter() if callable(getter) else getter
return getters
@dbus.service.method(dbus_interface=property_interface,
in_signature='ssv', out_signature='')
def Set(self, interface, prop, value):
getter, setter = self.properties[interface][prop]
if setter is not None:
setter(value)
### Root interface
@dbus.service.method(dbus_interface=root_interface)
def Raise(self):
pass # We do not have a GUI
@dbus.service.method(dbus_interface=root_interface)
def Quit(self):
"""
To test, start Mopidy and then run the following in a Python shell::
import dbus
bus = dbus.SessionBus()
player = bus.get_object('org.mpris.MediaPlayer2.mopidy',
'/org/mpris/MediaPlayer2')
player.Quit(dbus_interface='org.mpris.MediaPlayer2')
"""
self.core_queue.put({'to': 'core', 'command': 'exit'})
### Player interface
# TODO