All of lore.kernel.org
 help / color / mirror / Atom feed
From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH BlueZ 4/4] test: Add example-player
Date: Fri, 12 Jul 2019 18:13:29 +0300	[thread overview]
Message-ID: <20190712151329.11333-4-luiz.dentz@gmail.com> (raw)
In-Reply-To: <20190712151329.11333-1-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds an example of registering a player with use of
RegisterApplication.
---
 test/example-player | 203 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 203 insertions(+)
 create mode 100644 test/example-player

diff --git a/test/example-player b/test/example-player
new file mode 100644
index 000000000..2beb08e44
--- /dev/null
+++ b/test/example-player
@@ -0,0 +1,203 @@
+#!/usr/bin/python
+
+from __future__ import print_function
+
+import os
+import sys
+import dbus
+import dbus.service
+import dbus.mainloop.glib
+try:
+  from gi.repository import GObject
+except ImportError:
+  import gobject as GObject
+import bluezutils
+
+PLAYER_IFACE =       'org.mpris.MediaPlayer2.Player'
+DBUS_OM_IFACE =      'org.freedesktop.DBus.ObjectManager'
+DBUS_PROP_IFACE =    'org.freedesktop.DBus.Properties'
+
+class InvalidArgsException(dbus.exceptions.DBusException):
+    _dbus_error_name = 'org.freedesktop.DBus.Error.InvalidArgs'
+
+class Player(dbus.service.Object):
+    def __init__(self, bus, path, obj):
+        self.path = path
+        dbus.service.Object.__init__(self, bus, self.path)
+
+        if obj != None:
+            mp = dbus.Interface(bus.get_object("org.bluez", obj),
+                                                "org.bluez.MediaPlayer1")
+            prop = dbus.Interface(bus.get_object("org.bluez", obj),
+                                  "org.freedesktop.DBus.Properties")
+
+            self.properties = prop.GetAll("org.bluez.MediaPlayer1")
+
+            bus.add_signal_receiver(self.properties_changed, path = obj,
+                            dbus_interface = "org.freedesktop.DBus.Properties",
+                            signal_name = "PropertiesChanged")
+        else:
+            self.track = dbus.Dictionary({"xesam:title" : "Title",
+                                     "xesam:artist" : ["Artist"],
+                                     "xesam:album" : "Album",
+                                     "xesam:genre" : ["Genre"],
+                                     "xesam:trackNumber" : dbus.Int32(1),
+                                     "mpris:length" : dbus.Int64(10000) },
+                                     signature="sv")
+
+            self.properties = dbus.Dictionary({"PlaybackStatus" : "playing",
+                                        "Identity" : "SimplePlayer",
+                                        "LoopStatus" : "None",
+                                        "Rate" : dbus.Double(1.0),
+                                        "Shuffle" : dbus.Boolean(False),
+                                        "Metadata" : self.track,
+                                        "Volume" : dbus.Double(1.0),
+                                        "Position" : dbus.Int64(0),
+                                        "MinimumRate" : dbus.Double(1.0),
+                                        "MaximumRate" : dbus.Double(1.0),
+                                        "CanGoNext" : dbus.Boolean(False),
+                                        "CanGoPrevious" : dbus.Boolean(False),
+                                        "CanPlay" : dbus.Boolean(False),
+                                        "CanSeek" : dbus.Boolean(False),
+                                        "CanControl" : dbus.Boolean(False),
+                                        },
+                                        signature="sv")
+
+        print('Register media player with:\n\tProperties: %s' \
+              % (self.properties))
+        handler = InputHandler(self)
+        GObject.io_add_watch(sys.stdin, GObject.IO_IN, handler.handle)
+
+    @dbus.service.method("org.freedesktop.DBus.Properties",
+                         in_signature="ssv", out_signature="")
+    def Set(self, interface, key, value):
+        print("Set (%s, %s)" % (key, value), file=sys.stderr)
+        return
+
+    def get_properties(self):
+        return self.properties
+
+    def get_path(self):
+        return dbus.ObjectPath(self.path)
+
+    @dbus.service.method("org.freedesktop.DBus.Properties",
+                         in_signature='s', out_signature='a{sv}')
+    def GetAll(self, interface):
+        if interface != PLAYER_IFACE:
+            raise InvalidArgsException()
+
+        return self.get_properties()
+
+    @dbus.service.signal("org.freedesktop.DBus.Properties",
+                         signature="sa{sv}as")
+    def PropertiesChanged(self, interface, properties,
+                          invalidated = dbus.Array()):
+        """PropertiesChanged(interface, properties, invalidated)
+
+        Send a PropertiesChanged signal. 'properties' is a dictionary
+        containing string parameters as specified in doc/media-api.txt.
+        """
+        pass
+
+    def help(self, func):
+        help(self.__class__.__dict__[func])
+
+    def properties_changed(self, interface, properties, invalidated):
+        print("properties_changed(%s, %s)" % (properties, invalidated))
+
+        self.PropertiesChanged(interface, properties, invalidated)
+
+class InputHandler:
+    commands = { 'PropertiesChanged': '(interface, properties)',
+                        'help': '(cmd)' }
+    def __init__(self, player):
+        self.player = player
+        print('\n\nAvailable commands:')
+        for cmd in self.commands:
+                print('\t', cmd, self.commands[cmd], sep='')
+
+        print("\nUse python syntax to pass arguments to available methods.\n" \
+                "E.g.: PropertiesChanged({'Metadata' : {'Title': 'My title', \
+                'Album': 'my album' }})")
+        self.prompt()
+
+    def prompt(self):
+        print('\n>>> ', end='')
+        sys.stdout.flush()
+
+    def handle(self, fd, condition):
+        s = os.read(fd.fileno(), 1024).strip()
+        try:
+            cmd = s[:s.find('(')]
+            if not cmd in self.commands:
+                print("Unknown command ", cmd)
+        except ValueError:
+            print("Malformed command")
+            return True
+        try:
+            exec "self.player.%s" % s
+        except Exception as e:
+            print(e)
+            pass
+        self.prompt()
+        return True
+
+class Application(dbus.service.Object):
+    def __init__(self, bus, path, obj):
+        self.path = '/'
+        self.players = []
+        dbus.service.Object.__init__(self, bus, self.path)
+        self.add_player(Player(bus, path, obj))
+
+    def get_path(self):
+        return dbus.ObjectPath(self.path)
+
+    def add_player(self, player):
+        self.players.append(player)
+
+    @dbus.service.method(DBUS_OM_IFACE, out_signature='a{oa{sa{sv}}}')
+    def GetManagedObjects(self):
+        response = {}
+        print('GetManagedObjects')
+
+        for player in self.players:
+            response[player.get_path()] = { PLAYER_IFACE:
+                                            player.get_properties() }
+
+        return response
+
+def register_app_cb():
+    print('Media application registered')
+
+
+def register_app_error_cb(error):
+    print('Failed to register application: ' + str(error))
+    mainloop.quit()
+
+if __name__ == '__main__':
+    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+
+    bus = dbus.SystemBus()
+
+    if len(sys.argv) > 1:
+        path = bluezutils.find_adapter(sys.argv[1]).object_path
+    else:
+        path = bluezutils.find_adapter().object_path
+
+    media = dbus.Interface(bus.get_object("org.bluez", path),
+                           "org.bluez.Media1")
+
+    path = "/test/player"
+
+    if len(sys.argv) > 2:
+        app = Application(bus, path, sys.argv[2])
+    else:
+        app = Application(bus, path, None)
+
+    mainloop = GObject.MainLoop()
+
+    media.RegisterApplication(app.get_path(), {},
+                                reply_handler=register_app_cb,
+                                error_handler=register_app_error_cb)
+
+    mainloop.run()
-- 
2.21.0


  parent reply	other threads:[~2019-07-12 15:13 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-12 15:13 [PATCH BlueZ 1/4] doc/media-api: Add RegisterApplication method Luiz Augusto von Dentz
2019-07-12 15:13 ` [PATCH BlueZ 2/4] media: Add implementation of RegisterApplication Luiz Augusto von Dentz
2019-07-12 15:13 ` [PATCH BlueZ 3/4] test: Add example-endpoint Luiz Augusto von Dentz
2019-07-12 15:13 ` Luiz Augusto von Dentz [this message]
2019-07-13 14:52 ` [PATCH BlueZ 1/4] doc/media-api: Add RegisterApplication method Luiz Augusto von Dentz
2019-07-18 10:00   ` Pali Rohár
2019-07-21 15:55     ` Pali Rohár
2019-08-10  6:54       ` Luiz Augusto von Dentz
2019-08-29 12:57         ` Pasi Kärkkäinen
2019-08-29 20:05           ` Pali Rohár
2019-10-03 18:18             ` Pasi Kärkkäinen
2019-10-06 10:05               ` Pali Rohár
2019-10-06 10:53                 ` Luiz Augusto von Dentz
2019-10-06 10:56                   ` Pali Rohár
2019-10-06 11:14                     ` Luiz Augusto von Dentz
2019-10-06 11:17                       ` Pali Rohár
2019-10-06 18:02                         ` Pali Rohár
2019-10-06 12:02                   ` Pali Rohár
2019-10-07 14:33                     ` Pali Rohár
2019-10-08 10:28                       ` Luiz Augusto von Dentz
2019-10-08 10:33                         ` Pali Rohár
2019-10-09 13:15                           ` Luiz Augusto von Dentz
2019-10-09 13:19                             ` Pali Rohár
2019-10-17  9:59                               ` Pali Rohár
2019-10-18  8:37                                 ` Pasi Kärkkäinen
2019-10-18 10:55                                   ` Luiz Augusto von Dentz
2019-10-18 11:30                                     ` Pali Rohár
2019-10-09 13:20                     ` Pali Rohár
2019-11-14 11:27                       ` Pali Rohár
2020-04-14 23:07                         ` Undocumented property "DelayReporting" (Was: Re: [PATCH BlueZ 1/4] doc/media-api: Add RegisterApplication method) Pali Rohár

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190712151329.11333-4-luiz.dentz@gmail.com \
    --to=luiz.dentz@gmail.com \
    --cc=linux-bluetooth@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.