Уголок СУ-11 на просторах вселенной

вторник, 30 декабря 2008 г.

очень занятный материал по работе с D-Bus из шэла

Для начала разберемся с тем, что такое D-Bus
D-Bus — это система межпроцессного взаимодействия, которая предоставляет приложениям несколько шин для передачи сообщений.
D-Bus является частью проекта freedesktop.org. Он обладает высокой скоростью работы, интегрируется во многие рабочие среды. D-Bus доступен для Glib, Java (GCJ), Mono, Qt, Python и прозрачен для сети.
D-Bus предоставляет системе несколько шин:

1) Системная шина. Создаётся при старте демона D-BUS. С её помощью происходит общение различных демонов, она практически недоступна для пользовательских приложений

2) Сессионная шина. Создаётся для пользователя, авторизировавшегося в системе. Для каждой такой шины запускается отдельная копия демона, посредством неё будут общаться приложения, с которыми работает пользователь.

Каждое сообщение D-BUS, передаваемое по шине, имеет своего отправителя и своего получателя, их адреса называются путями объектов, поскольку D-BUS предполагает, что каждое приложение состоит из набора объектов, а сообщения пересылаются не между приложениями, а между объектами этих самых приложений.

Каждый объект может поддерживать один или более интерфейсов, которые представлены здесь в виде именованных групп методов и сигналов — аналогично интерфейсам Glib, Qt или Java.

D-BUS также предусматривает концепцию сервисов. Сервис — уникальное местоположение приложения на шине. При запуске приложение регистрирует один или несколько сервисов, которыми оно будет владеть до тех пор, пока самостоятельно не освободит, до этого момента никакое другое приложение, претендующее на тот же сервис, занять его не сможет. Именуются сервисы аналогично интерфейсам.

Сервисы делают доступной ещё одну функцию — запуск необходимых приложений в случае поступления сообщений для них. Для этого должна быть включена автоактивация, а в конфигурации D-BUS за этим сервисом должно быть закреплено одно приложение. Тогда D-BUS сможет его запустить при появлении сообщения.

После закрытия приложения ассоциированные сервисы также разрегистрируются, а D-BUS посылает сигнал о том, что сервис закрыт. Другие приложения могут получать такие сигналы и соответствующим образом реагировать.

После подключения к шине приложение должно указать, какие сообщения оно желает получать, путём добавления масок совпадений (matchers). Маски представляют собой наборы правил для сообщений, которые будут доставляться приложению, фильтрация может основываться на интерфейсах, путях объектов и методах. Таким образом, приложения будут получать только то, что им необходимо, проблемы доставки в этом случае берет на себя D-BUS.

Сообщения в D-BUS бывают четырёх видов: вызовы методов, результаты вызовов методов, сигналы и ошибки. Первые предназначены для выполнения методов над объектами, подключенными к D-BUS; посылая такое сообщение, вы выдаете задание объекту, а он после обработки обязан возвратить вам либо результат вызова, либо ошибку через сообщения соответствующих типов. Сигнальные же сообщения, как им и полагается, ничуть не заботятся о том, что и как делается объектами, они вольны воспринимать их как угодно (равно как и не получать их вовсе).

Чтобы сообщение достигло определённого объекта, необходим способ сослаться на объект. Во многих языках программирования это реализуется с помощью указателя. Однако, эти указатели реализуются как адреса памяти, относящиеся к локальному адресному пространству приложения, и не могут быть переданы от одного приложения другому.

Поэтому в D-Bus у каждого объекта своё, уникальное имя, которое выглядит как путь в файловой системе. Например, объект может быть именован как /org/kde/kspread/sheets/3/cells/4/5. Предпочтительны имена, которые несут какую-либо смысловую нагрузку, тем не менее, разработчики могут выбрать и имя /com/mycompany/c5yo817y0c1y1c5b, если это имеет смысл для их приложения.

Имена объектов находятся в пространствах имён, чтобы обеспечить разграничение разных программных модулей. Пространствам имён обычно даётся префикс, специфичный для разработчика, например /org/kde.


Теперь перейдем к управлению:

Управление десктоп приложениями из shell при помощи D-Bus [исправить]

В качестве консольной утилиты для работы с D-Bus можно использовать "qdbus" из состава Qt4.

При выполнении без аргументов, утилита qdbus выведет список активных шин:

qdbus

org.freedesktop.ScreenSaver
org.freedesktop.Notifications
org.freedesktop.PowerManagement
org.freedesktop.DBus

Отобразим список объектов для шины ScreenSaver:

qdbus org.freedesktop.ScreenSaver

/
/App
/Interface
/KBookmarkManager
/KBookmarkManager/konqueror
/KDebug
/MainApplication
/ManagerIface_contact
/ScreenSaver

Просмотрим методы объекта "/ScreenSaver":

qdbus org.freedesktop.ScreenSaver /ScreenSaver

signal void org.freedesktop.ScreenSaver.ActiveChanged(bool)
method bool org.freedesktop.ScreenSaver.GetActive()
method uint org.freedesktop.ScreenSaver.GetActiveTime()
method bool org.freedesktop.ScreenSaver.SetActive(bool e)
method void org.freedesktop.ScreenSaver.Lock()
method uint org.freedesktop.ScreenSaver.Inhibit(QString application_name, QString reason_for_inhibit)
...

Посмотрим значение текущего счетчика времени неактивности, после которого
активируется хранитель экрана. Просмотрим текущее значение:

qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.GetSessionIdleTime

0

С момента последнего нажатия клавиши прошло 0 сек. Попробуем ничего не нажимать:

sleep 5 ; qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.GetSessionIdleTime

4

Попробуем активировать хранитель экрана через метод org.freedesktop.ScreenSaver.SetActive:

qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.SetActive True

true

Блокируем экран:

qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.Lock

В случае когда нужно предотвратить запуск хранителя экрана, например, во время просмотра видео, можно использовать:

qdbus org.freedesktop.ScreenSaver /ScreenSaver \
org.freedesktop.ScreenSaver.Inhibit "$$" "Testing D-Bus Interface"

5822

где, "$$" - имя приложения запретившего активацию хранителя экрана,
в нашем случае это PID текущего shell (5822).
второй аргумент - причина сдерживания хранителя экрана.

После того как хранитель экрана можно опять активировать, выполняем:

qdbus org.freedesktop.ScreenSaver /ScreenSaver \
org.freedesktop.ScreenSaver.UnInhibit 5822


Другие примеры.
Просмотрим список заметок из Tomboy.

qdbus org.gnome.Tomboy /org/gnome/Tomboy/RemoteControl org.gnome.Tomboy.RemoteControl.ListAllNotes

note://tomboy/5e900d91-bd77-4f41-89d8-e71baaafd364
note://tomboy/f647c681-b1b9-4eca-bdab-fd4b04cb37f6

Отобразим содержимое одной из них:

qdbus org.gnome.Tomboy /org/gnome/Tomboy/RemoteControl \
org.gnome.Tomboy.RemoteControl.GetNoteContents note://tomboy/5e900d91-bd77-4f41-89d8-e71baaafd364

Комментариев нет: