Using system functions D-Bus in Sailfish OS
Introduction
This article is a continuation of about using the system API in Sailfish OS and on the functions of the D-Bus in the operating system. Details will be disassembled interaction with the standard calendar and flash. A list of other basic functions D-Bus system presented at the end of the article.
For understanding of the material presented requires knowledge of the basics of developing for Sailfish OS and the principles of interaction with D-Bus under the operating system. A good starting point are the relevant articles from FRUCT:
[1] Start developing for Sailfish OS;
[2] Develop for Sailfish OS: D-Bus.
the
the Theory
There are two ways to obtain information about available interfaces and functions of D-Bus. The first approach is to study registered in the system interfaces with the help of special tools (for example,
Visual D-Bus
and D-Bus Inspector
) or the command line (figure 1). The second approach uses described in the previous Chapter the methodology of the study of the source code.
[figure 1 — Example get a list of interfaces with D-Bus.]
A great advantage of the first approach is the possibility of obtaining information about interfaces that are hardcoded in the binary and not in text form, but this way you can analyze only the currently active interfaces. The second approach used in this article, described inverts plus and minus of the first approach.
the
Equipment
D-Bus can be caused (or determined) from code in C++ (which is not available in the system) from the QML code from desktop-file applications. Accordingly, when searching for information about the interfaces that you need to understand, first, about the module
org.nemomobile.dbus
; second, how to access D-Bus from desktop file.QML-module
org.nemomobile.dbus
provides two main components for working with D-Bus: DBusAdaptor
and DBusInterface
. The first allows you to create your application interface, the second is to use an existing one. In General the search interest of both, as they allow us to learn how you can interact with the application from outside, and how the application uses third-party interfaces, respectively.For example, to determine which interfaces with D-Bus uses the application settings you want to change to the directory
/usr/share/jolla-settings
to check for D-Bus:grep -i-H 'dbus' * && grep -A 5 'DBusAdaptor' ./settings.qml
$ cd /usr/share/jolla-settings/
$ grep -i-H 'dbus' *
settings.qml:import org.nemomobile.dbus 2.0
settings.qml: DBusAdaptor {
$ grep -A 5 'DBusAdaptor' ./settings.qml
DBusAdaptor {
service: "com.jolla.settings"
path: "/com/jolla/settings/ui"
iface: "com.jolla.settings.ui"
function showSettings() {
At the same time, when parsing desktop files, it must be remembered that, first, desktop files are stored in the directory
/usr/share/applications
; second, the use of these functions starts an instance of the application; thirdly, the description of the interaction with D-Bus uses a field prefix X-Maemo
:the
-
the
X-Maemo-Service
service, or the location of the application on the user or the system bus;
the X-Maemo-Object-Path
— the path name of the object.
the X-Maemo-Method
— the name of the invoked method.
Wonder
Prefix

[Figure 2 — dependence of the Sailfish OS from other operating systems (Wikipedia).]
It is worth noting that in the desktop files it is possible to use the field
X-Maemo
appears in Sailfish OS as a legacy from the operating system Maemo (figure 2), previously developed by the company Nokia. They allow you to declare D-Bus functions so that you can access them without first running of the program. These functions allow you to launch programs with the implementation before opening some preliminary work.[Figure 2 — dependence of the Sailfish OS from other operating systems (Wikipedia).]
It is worth noting that in the desktop files it is possible to use the field
MimeType
to specify the types of files that can be processed by the program. An example implementation is available at GitHub.Thus, to get a list of all apps that support running using D-Bus you want to change to the directory
/usr/share/applications
to search one of the keywords:grep -H 'X-Maemo-Service' *
$ cd /usr/share/applications/
$ grep -H 'X-Maemo-Service' *
jolla-calendar-import.desktop:X-Maemo-Service=com.jolla.calendar.ui
jolla-calendar.desktop:X-Maemo-Service=com.jolla.calendar.ui
jolla-camera-viewfinder.desktop:X-Maemo-Service=com.jolla.camera
jolla-clock.desktop:X-Maemo-Service=com.jolla.clock
jolla-contacts-import.desktop:X-Maemo-Service=com.jolla.contacts.ui
jolla-email.desktop:X-Maemo-Service=com.jolla.email.ui
jolla-gallery-openfile.desktop:X-Maemo-Service=com.jolla.gallery
jolla-gallery-playvideostream.desktop:X-Maemo-Service=com.jolla.gallery
jolla-mediaplayer-openfile.desktop:X-Maemo-Service=com.jolla.mediaplayer
jolla-mediaplayer.desktop:X-Maemo-Service=com.jolla.mediaplayer
jolla-messages-openurl.desktop:X-Maemo-Service=org.nemomobile.qmlmessages
jolla-messages.desktop:X-Maemo-Service=org.nemomobile.qmlmessages
jolla-notes-import.desktop:X-Maemo-Service=com.jolla.notes
jolla-notes.desktop:X-Maemo-Service=com.jolla.notes
jolla-settings.desktop:X-Maemo-Service=com.jolla.settings
new-mail.desktop:X-Maemo-Service=com.jolla.email.ui
open-url.desktop:X-Maemo-Service=org.sailfishos.browser.ui
ovpn-import.desktop:X-Maemo-Service=com.jolla.settings
sailfish-office-openfile.desktop:X-Maemo-Service=org.sailfish.office
sailfish-office.desktop:X-Maemo-Service=org.sailfish.office
simkit.desktop:X-Maemo-Service=org.sailfish.simkit
voicecall-ui-openurl.desktop:X-Maemo-Service=com.jolla.voicecall.ui
voicecall-ui.desktop:X-Maemo-Service=com.jolla.voicecall.ui
Summary table of the main system functions API and D-Bus is given in the end of the article.
the
Practice
The theoretical material presented in the current and previous articles, allows you to implement your components to work with the system D-Bus.
Create a component that allows you to access the schedule for the current day. This requires change to the directory
/usr/share/jolla-calendar
(the naming of directories is described in previous the article) and find out which files have a reference to D-Bus:grep -r-i -H 'dbus' *
$ cd /usr/share/jolla-calendar/
$ grep -r-i -H 'dbus' *
DbusInvoker.qml:import org.nemomobile.dbus 2.0
DbusInvoker.qml:DBusAdaptor {
calendar.qml:import org.nemomobile.dbus 2.0
calendar.qml: DbusInvoker {}
From the result of the command shows that the interface definition is in the file
DbusInvoker.qml
that contains only interface definitions and functions D-Bus:cat ./DbusInvoker.qml -n
$ cat ./DbusInvoker.qml -n
1 import QtQuick 2.0
2 import Sailfish.Silica 1.0
3 import org.nemomobile.dbus 2.0
4 import Calendar.dateParser 1.0
5
6 DBusAdaptor {
7 service: "com.jolla.calendar.ui"
8 path: "/com/jolla/calendar/ui"
9 iface: "com.jolla.calendar.ui"
10
11 function viewEvent(id, recurrenceId, startDate) {
12 var occurrence = DateParser.parseTime(startDate)
13 if (isNaN(occurrence.getTime())) {
14 console.warn("Invalid event start date, unable to show event")
15 return
16 }
17
18 if (pageStack.currentPage.objectName === "EventViewPage") {
19 pageStack.currentPage.uniqueId = id
20 pageStack.currentPage.recurrenceId = recurrenceId
21 pageStack.currentPage.startTime = occurrence
22 } else {
23 pageStack.push("pages/EventViewPage.qml",
24 { uniqueId: id, recurrenceId: recurrenceId, startTime: occurrence },
25 PageStackAction.Immediate)
26 }
27 requestActive.start()
28 }
29
30 function viewDate(dateTime) {
31 var parsedDate = new Date(dateTime)
32 if (isNaN(parsedDate.getTime())) {
33 console.warn("Invalid date, unable to show events for date")
34 return
35 }
36
37 if (pageStack.currentPage.objectName === "DayPage") {
38 pageStack.currentPage.date = parsedDate
39 } else {
40 pageStack.push("pages/DayPage.qml", { date: parsedDate }, PageStackAction.Immediate)
41 }
42 requestActive.start()
43 }
44
45 function importFile(fileName) {
46 if (pageStack.currentPage.objectName === "ImportPage") {
47 pageStack.currentPage.fileName = fileName
48 } else {
49 pageStack.push("pages/ImportPage.qml", { "fileName": fileName }, PageStackAction.Immediate)
50 }
51 requestActive.start()
52 }
53
54 function activateWindow(arg) {
55 app.activate()
56 }
57 }
From the code of the adapter is seen that in the generated component needs to connect to the service
com.jolla.calendar.ui
and use /com/jolla/calendar/ui
and the interface com.jolla.calendar.ui
(lines 7-9). After this it will be available advertised feature, of which, in the framework of the task, interest only viewDate
(lines 30-43), which takes as argument one of the views date recognized by an object Date
. The obtained results allow to implement your component to work with the calendar:CalendarController.qml
import QtQuick 2.0
import Sailfish.Silica 1.0
import org.nemomobile.dbus 2.0
Item {
id: calendarControl
/* Open the calendar to the current date.
*/
showAgenda function() {
calendar.call('viewDate', Date.now())
}
DBusInterface {
id: calendar
service: 'com.jolla.calendar.ui'
path: '/com/jolla/calendar/ui'
iface: 'com.jolla.calendar.ui'
}
}
On the same principle are formed, and other components that interact with D-Bus system.
Consider the process of flash control. For this, according to the directory
/usr/share/jolla-settings/pages/flashlight
, you must connect to the service com.jolla.settings.system.flashlight
and use /com/jolla/settings/system/flashlight
and the interface com.jolla.settings.system.flashlight
. After that, calling function toggleFlashlight without parameters, it becomes possible to enable and disable the flash.However, in some problems, you may need to obtain information about the current status of flash — it is enabled or disabled. For this, use the function
getProperty
passed to it by the parameter "flashlightOn"
. In this case it returns a Boolean value.grep -i-H 'dbus' ./pages/flashlight/* && grep -A 5 -i-H 'DBusInterface' ./pages/flashlight/Flashlight.qml
$ cd /usr/share/jolla-settings
$ grep -i-H "dbus" ./pages/flashlight/*
./pages/flashlight/Flashlight.qml:import org.nemomobile.dbus 2.0
./pages/flashlight/Flashlight.qml: flashlightDbus.call("toggleFlashlight", undefined, handleToggle, handleError)
./pages/flashlight/Flashlight.qml: property QtObject flashlightDbus: DBusInterface {
./pages/flashlight/Flashlight.qml: flashlight.flashlightOn = flashlightDbus.getProperty("flashlightOn")
$ grep -A 5-i-H "DBusInterface" ./pages/flashlight/Flashlight.qml
./pages/flashlight/Flashlight.qml: property QtObject flashlightDbus: DBusInterface {
./pages/flashlight/Flashlight.qml - signalsEnabled: true
./pages/flashlight/Flashlight.qml - service: "com.jolla.settings.system.flashlight"
./pages/flashlight/Flashlight.qml - path: "/com/jolla/settings/system/flashlight"
./pages/flashlight/Flashlight.qml - iface: "com.jolla.settings.system.flashlight"
./pages/flashlight/Flashlight.qml - function flashlightOnChanged(newOn) {
Given the above, is implemented by a component to interact with flash:
FlashlightController.qml
import QtQuick 2.0
import Sailfish.Silica 1.0
import org.nemomobile.dbus 2.0
Item {
id: flashlightControl
// The flash status.
property bool flashlightOn
// Enables or disables the flash.
function toggleFlashlight() {
flashlightOn = !flashlightOn;
flashlight.call("toggleFlashlight", undefined);
}
DBusInterface {
id: flashlight
service: "com.jolla.settings.system.flashlight"
path: "/com/jolla/settings/system/flashlight"
iface: "com.jolla.settings.system.flashlight"
signalsEnabled: true
function flashlightOnChanged(newOn) {
flashlightControl.flashlightOn = newOn
}
}
Component.onCompleted: {
flashlightControl.flashlightOn = flashlight.getProperty("flashlightOn")
}
}
the
Conclusion
This article describes two ways of searching information on the features of D-Bus in Sailfish OS, and demolished one of them is search in the source code. With its use developed and commented examples for the components to communicate with flash and the standard calendar. Code these and other modules are available on GitHub.
But do not forget that the decision part of the task may simple run interested program with the required arguments. For example, start the standard browser with opening the website can be done with the command
sailfish-browser https://google.com/
. But it is beyond the scope described in the manuscript material.sailfish-browser https://google.com/
$ sailfish-browser https://google.com/
[D] unknown:0 - Using Wayland-EGL
greHome from GRE_HOME:/usr/bin
libxul.so is not found, in /usr/bin/libxul.so
Created LOG for EmbedLite
[D] onCompleted:103 - ViewPlaceholder requires a parent SilicaFlickable
XulDir Loaded:/usr/lib/xulrunner-qt5-38.8.0/libxul.so, appDir:/usr/bin
EmbedLiteExt virtual nsresult EmbedChromeManager::Observe(nsISupports*, const char*, const char16_t*):82: obj:(nil), top:app-startup
EmbedLiteExt virtual nsresult EmbedTouchManager::Observe(nsISupports*, const char*, const char16_t*):86: obj:(nil), top:app-startup
EmbedLiteGlobalHelper app-startup
EmbedLiteSyncService app-startup
PREFS SERVICE INITAILIZED
EmbedPrefService app-startup
EmbedliteDownloadManager initialized
UserAgentOverrideHelper app-startup
1505073762747 addons.manager DEBUG Application has been upgraded
1505073762892 addons.manager DEBUG Loaded provider scope for resource://gre/modules/addons/XPIProvider.jsm: ["XPIProvider"]
1505073762912 addons.manager DEBUG Loaded provider scope for resource://gre/modules/LightweightThemeManager.jsm: ["LightweightThemeManager"]
1505073762942 addons.manager DEBUG Loaded provider scope for resource://gre/modules/addons/GMPProvider.jsm
1505073762968 addons.Starting DEBUG manager provider: XPIProvider
1505073762973 addons.xpi DEBUG startup
1505073762982 addons.xpi DEBUG checkForChanges
1505073762993 addons.xpi DEBUG Loaded add-on state from prefs: {}
1505073763000 addons.xpi DEBUG getInstallState changed: false, state: {}
1505073763009 addons.xpi DEBUG Empty XPI database, setting schema version preference to 16
1505073763012 addons.xpi DEBUG No changes found
1505073763015 addons.manager DEBUG Registering shutdown blocker for XPIProvider
1505073763021 addons.manager Provider startup finished DEBUG: XPIProvider
1505073763022 addons.Starting DEBUG manager provider: LightweightThemeManager
1505073763024 addons.manager DEBUG Registering shutdown blocker for LightweightThemeManager
1505073763029 addons.manager Provider startup finished DEBUG: LightweightThemeManager
1505073763032 addons.Starting DEBUG manager provider: GMPProvider
1505073763046 addons.manager DEBUG Registering shutdown blocker for GMPProvider
1505073763050 addons.manager Provider startup finished DEBUG: GMPProvider
1505073763052 addons.Starting DEBUG manager provider: PluginProvider
1505073763055 addons.manager DEBUG Registering shutdown blocker for PluginProvider
1505073763059 addons.manager Provider startup finished DEBUG: PluginProvider
1505073763060 addons.manager DEBUG Completed startup sequence
Created LOG for EmbedPrefs
[D] QMozWindowPrivate::setSize:71 - Trying to set empty size: QSize(-1, -1)
Attempting load of libEGL.so
EmbedLiteExt virtual nsresult EmbedTouchManager::Observe(nsISupports*, const char*, const char16_t*):86: obj:0xb225a130, top:domwindowopened
EmbedLiteExt void EmbedChromeManager::WindowCreated(nsIDOMWindow*):91: WindowOpened: 0xb225a140
EmbedLiteExt void EmbedTouchManager::WindowCreated(nsIDOMWindow*):95: WindowOpened: 0xb225a140
EmbedLiteExt void EmbedTouchManager::WindowCreated(nsIDOMWindow*):108: id for window: 1
###################################### SelectAsyncHelper.js loaded
###################################### embedhelper.js loaded
### ContextMenuHandler.js loaded
### SelectionPrototype.js loaded
### SelectionHandler.js loaded
Init Called:[object Object]
JavaScript warning: https://www.google.ru/xjs/_/js/k=xjs.mhp.en_US.2vKAz7DqmvI.O/m=sb_mobh,hjsa,d,csi/am=AAAD/rt=j/d=1/t=zcms/rs=ACT90oFx8AHVqc9lMfPQBwURKXyQ4qaFia line 7: mutating the [[Prototype]] of an object will cause your code to run very slowly; instead create the object with the correct initial [[Prototype]] value using Object.create
Basic system API functions:
the
Description | Required data |
---|---|
Create ambiance |
|
adjust brightness |
|
set screen orientation |
|
Automatically adjust screen brightness |
|
setup time enable sleep mode |
|
setup display status while charging |
|
configure system font size |
|
system volume |
|
vibration setting |
|
Enable/disable sounds for system events | ProfileControl { id: soundSettings } soundSettings.systemSoundLevel = false // Off soundSettings.systemSoundLevel = true // Enable|
Enable/disable WLAN |
|
Enable/disable General Internet access |
|
Enable/disable airplane mode |
|
Turn on/off Bluetooth |
|
fundamental D-Bus function:
the
Description | Required data |
---|---|
View events calendar | Service:com.jolla.calendar.ui Path: /com/jolla/calendar/ui Interface com.jolla.calendar.ui Function: viewEvent(id, recurrenceId, startDate) |
day View in the calendar | Service:com.jolla.calendar.ui Path: /com/jolla/calendar/ui Interface com.jolla.calendar.ui Function: viewDate(dateTime) |
open the camera in the last state | Service:com.jolla.camera Path: / Interface com.jolla.camera.ui Function: showViewfinder() |
Open front camera | Service:com.jolla.camera Path: / Interface com.jolla.camera.ui Function: showFrontViewfinder() |
Create alarm | Service:com.jolla.clock Path: / Interface com.jolla.clock Function: newAlarm() |
View contact | Service:com.jolla.contacts.ui Path: /com/jolla/contacts/ui Interface com.jolla.contacts.ui Function: showContact(contactId int) |
Edit contact | Service:com.jolla.contacts.ui Path: /com/jolla/contacts/ui Interface com.jolla.contacts.ui Function: editContact(int contactId) |
Import contacts | Service:com.jolla.contacts.ui Path: /com/jolla/contacts/ui Interface com.jolla.contacts.ui Function: importWizard() |
Play an audio file URL | Service:com.jolla.mediaplayer Path: /com/jolla/mediaplayer/ui Interface com.jolla.mediaplayer.ui Function: openUrl(url) |
Create new note | Service:com.jolla.notes Path: / Interface com.jolla.notes Function: newNote() |
View settings | Service:com.jolla.settings Path: /com/jolla/settings/ui Interface com.jolla.settings.ui Function: showSettings() |
View list | Service:com.jolla.settings Path: /com/jolla/settings/ui Interface com.jolla.settings.ui Function: |
View list of accounts | Service:com.jolla.settings Path: /com/jolla/settings/ui Interface com.jolla.settings.ui Function: showAccounts() |
View settings recording telephone conversations | Service:com.jolla.settings Path: /com/jolla/settings/ui Interface com.jolla.settings.ui Function: showCallRecordings() |
Enable/disable support for Android | Service:com.jolla.apkd Path: /com/jolla/apkd Interface com.jolla.apkd Function: controlService(true/false) |
Turn on/off the flash | Service:com.jolla.settings.system.flashlight Path: /com/jolla/settings/system/flashlight Interface com.jolla.settings.system.flashlight Function: toggleFlashlight() |
Reload a device | Service:com.nokia.dsme Path: /com/nokia/dsme/request Interface com.nokia.dsme.request Function: req_reboot() |
Disable device | Service:com.nokia.dsme Path: /com/nokia/dsme/request Interface com.nokia.dsme.request Function: req_shutdown |
Call | Service:com.jolla.voicecall.ui Path: / Interface com.jolla.voicecall.ui Function: the dial(number) |
Open images in the gallery | Service:com.jolla.gallery Path: /com/jolla/gallery/ui Interface com.jolla.gallery.ui Function: showImages(array_of_urls) |
Open video in gallery | Service:com.jolla.gallery Path: /com/jolla/gallery/ui Interface com.jolla.gallery.ui Function: playVideoStream(url) |
Create new email | Service:com.jolla.email.ui Path: /com/jolla/email/ui Interface com.jolla.email.ui Function: mailto() |
Search for WLAN networks | Service:com.jolla.lipstick.ConnectionSelector Path: / Interface com.jolla.lipstick.ConnectionSelectorIf Function: openConnectionNow('wifi') |
Arising in the course of development of ideas and questions you can discuss at Telegram chat and Facebook page.
Комментарии
Отправить комментарий