== App Developer Week -- Take control of your desktop easily with DBus -- alecu -- Wed, Apr 13th, 2011 == {{{#!irc [18:56] hello all [18:56] There are 5 minutes remaining in the current session. [18:56] let's wait a couple more minutes and then we'll start [18:58] chadadavis asked: What's the best way to stay up to date on the API documentation status? [18:58] chadadavis, watch the U1 blog where we'll announce that the developer site is available [19:01] hello all === ChanServ changed the topic of #ubuntu-classroom to: Welcome to the Ubuntu Classroom - https://wiki.ubuntu.com/Classroom || Support in #ubuntu || Upcoming Schedule: http://is.gd/8rtIi || Questions in #ubuntu-classroom-chat || Event: Ubuntu App Developer Week - Current Session: Take control of your desktop easily with DBus - Instructors: alecu [19:01] My name is alecu, some people also call me "Alejandro J. Cura" [19:01] Logs for this session will be available at http://irclogs.ubuntu.com/2011/04/13/%23ubuntu-classroom.html following the conclusion of the session. [19:02] I'm a developer on the Ubuntu One team, currently working on the desktop side of Ubuntu One. [19:03] For the past year or so I've been using DBus a lot to do bits and pieces of my work, so I'd like to share a bit of that during this session. [19:03] As you all probably know, DBus is a way for applications to request services from other applications. [19:04] For instance, Ubuntu One asks the gnome-keyring daemon for passwords. [19:04] Or the sound menu asks the music players to start playing or to change tracks. [19:04] so, let's dive into an example... [19:04] for this we need to have d-feet installed [19:05] sudo apt-get install d-feet [19:05] so, everybody has d-feet installed by now? [19:06] open it, and let's browse the Dbus bus a bit [19:06] go to File -> Connect to Session [19:06] and we will be able to explore the Session Bus [19:07] on the left we have a list of Bus Names. It's common for each application that's providing a service to use one, but some apps export more than one Bus Name. [19:07] clicking on one of the Bus Names, we'll see a list of Object Paths on the right [19:08] it's very common for one application to export more than one Object Path [19:09] if you click on one Bus Name and no object paths appear, that means that the application is not providing introspection data, and that means that we'll need to ask the app developers for more info on how to use those services thru dbus. [19:09] but the common case is to have both introspection data and some dbus documentation... [19:10] let's look at one example [19:10] let's open banshee, or some rhythmbox [19:11] when we run banshee, we'll see on d-feet that a new "Bus Name" was published to provide services to other apps [19:11] try clicking on d-feet on it: org.bansheeproject.Banshee [19:12] on the right hand we'll see a few Object Paths [19:12] let's open /org/mpris/MediaPlayer2 [19:12] and open the "org.mpris.MediaPlayer2.Player" interface === kevin4896 is now known as kdemarest [19:13] Inside that interface we'll see a list of Methods, Properties and Signals === tubadaz is now known as tubadaz_away [19:13] let's try one Method: play [19:13] sorry, Play() [19:14] double click on it, and a new small window opens "Execute D-Bus Method" [19:14] just click on Execute [19:14] banshee should start playing [19:15] (if it does not, try making it play some song by hand, then pausing it thru d-feet) [19:17] and then try playing with the other methods [19:17] for instance, Seek takes a parameter, try 30000000 [19:18] or -30000000 [19:18] chadadavis asked: there are a few 'play' methods under other object paths. Why are there so many? What's the difference, in the case of banshee here? [19:18] chadadavis, you mean Play and PlayPause? [19:19] I think Play always plays, but PlayPause is like a toggle. [19:19] chadadavis, the thing is that I don't know exactly how that works, and since it won't be documented in a DBus browser like d-feet we need to find some spec [19:20] and I was just pointing all of you to this example, because there's a lovely documentation for this interface, and it's common to many-many media players. [19:21] it's http://xmms2.org/wiki/MPRIS [19:22] and for the work I've been doing for the gnome-keyring and kwallet, I've been using the "Secrets Service API" http://people.collabora.co.uk/~stefw/secret-service/ === tubadaz_away is now known as tubadaz [19:23] so you'll probably need some similar docs for the service you are trying to use [19:23] or just use an explorer like d-feet to experiment with the interface you want. [19:24] So, after finding some service that you want to use, and some docs on it, you'll want to use DBus from your own application. [19:24] I've mostly used python for this, but I understand that other bindings are similar. [19:25] Here's a few examples I've made, so we can go over: [19:25] bzr branch lp:~alecu/+junk/dbus-lessons [19:26] crazedpsyc asked: if credentials are transported through DBus, can't I, or anyone else see them by using something like dbus-monitor? [19:27] crazedpsyc, there is one instance of DBus running for the system, and an instance per user that's logged in. [19:28] crazedpsyc, DBus connections are always local, and are either in the context of your computer or your session. [19:28] crazedpsyc, there are security rules on the system DBus, so apps are limited on what they can listen to. [19:29] crazedpsyc, for the session DBus I haven't seen any security restrictions, so afaict any app can listen for all the Dbus traffic for every other app. [19:30] crazedpsyc, that includes listening for the same logged in user credentials, but any X window app can capture all keystrokes anyway, so there's no point in securing that. [19:30] crazedpsyc, makes sense? [19:31] crazedpsyc, we can discuss this on much detail later, since app sandboxing is an issue I find very interesting to work on. [19:32] anyway, let's go back to the samples [19:32] let's look at the first one: 01-call_method.py [19:34] DBus usually has to work together with the main loop of your application [19:34] usually it's the gtk or kde main loop, and DBus supports it. [19:34] But you can also use the twisted reactor as a main loop, and we'll be able to integrate that as well. [19:35] in this example I'm using the gobject main loop, as used by gtk. [19:35] this line joins dbus with the loop: "DBusGMainLoop(set_as_default=True)" [19:36] and on the following lines we get at the "Session Bus", get an object from it using a "Bus Name" and an "Object Path" [19:36] and we get an "Interface" from that object. [19:36] as you can see, it all matches what we are able to see on d-feet. [19:37] once we get an Interface, we can call on the Methods on it, and access its Properties [19:38] in this example I'm just changing the brightness of my laptop display, and depending on your hardware it might not work. [19:38] So I'll ask you all for homework to modify it so it changes the volume of the music player. [19:39] psusi asked: What is the use of naming the Interface of an object separtely from the name of the object itself? Can this be used to publish versioned interfaces to, for instance, add a new argument to a signal without breaking applications that depend on the interface without the argument? [19:41] psusi, exactly. We can add more than one interface for an object, to group interfaces per intent, so for instance the MPRIS spec separates the methods in the Player from the Playlist interfaces, and also as you very correctly point out to create a new interface and not break compatibility with older interfaces. [19:42] Ok, let's look a bit further into arguments for the Methods === crazedpsyc is now known as crazedpsyc_away [19:43] since DBus is language agnostic, it defines a way to specify the types of the arguments and return values of DBus Methods [19:44] each language binding will try to match it to native types. For instance the python binding will usually transform DBus byte arrays into python strings [19:44] (python 2 strings, that is :-) ) [19:45] so Dbus has a way of specifying a small string that will act as the signature for the types in a DBus method call === crazedpsyc_away is now known as crazedpsyc [19:47] for instance let's browse with d-feet the org.mpris.MediaPlayer2.Playlists interface [19:47] the GetPlaylists method has a very complicated signature [19:47] Uint32 index, Uint32 maxcount, String order, Boolean reverse_order [19:48] in dbus you'll usually see this as "uusb" [19:49] and the return value for that method is array of [struct of (object path, string, string)] [19:49] you'll see it defined as "a(oss)" [19:50] for a complete reference of this, and much more, try this tutorial: http://dbus.freedesktop.org/doc/dbus-python/doc/tutorial.html#data-types [19:50] we'll need to define strings similar to this when we export our own objects on DBus as services [19:51] so let's look at example 03-export_object.py [19:51] There are 10 minutes remaining in the current session. [19:52] in this example I'm exporting a DBus object on a given "Bus Name" and with a given "Object Path" [19:52] and when I run the example, I can use d-feet to call the example_method. Go ahead, try it. [19:53] In addition to the Method, I'm also exporting a "Signal" [19:53] Signals work backwards [19:54] Usually a dbus client calls a method. [19:54] But the clients subscribe to signals, and the dbus service calls them. [19:54] We can see how to subscribe to a signal in example 2 [19:55] in 02-listen_signal.py we connect to the bus, and using a "Bus Name", an "Object Path" and an "Interface", we connect a function of our code to a DBus signal. [19:56] There are 5 minutes remaining in the current session. [19:56] in this example I also use the BackLight, but as homework as well you may change listen to media player signals as well. [19:57] ok, this was a brief overview of how to use DBus in your code. [19:57] I hope you follow the examples and start using DBus to take control of all the apps in your desktop. [19:58] Let's do a bit of Q/A if we have a bit more time. [19:58] And don't hesitate to ask me more questions by mail if you have any problems when working with DBus. [20:00] and please let me know what you ended up doing with DBus! :-) [20:01] chadadavis asked: so, when you setup a signal for others to subscribe to, you're responsible for sending them? Can you chain signals, with intermediate changes, to provide variations of existing signals from other services? }}}