Sailfish Community News, 12th August, libgbinder, 4.2.0 L10n

Subscribe to future posts here :bell:

Sailfish OS update from Jolla

We’ve looked at a range of topics in these newsletters, including news about some of the new ports that community members have been working on recently. The porting process require careful knowledge not just of the device and device drivers you’re porting to, but also the way Sailfish OS interacts with them. It’s all very low level and not an area that everyone is familiar with, so doing a deep dive into the hardware adaptation layers of the device requires some specialist knowledge. Luckily for this newsletter we have the benefit of Franz-Josef Haider, who you may know better as Frajo or krnlyng on IRC. Frajo is a software developer at Jolla who has been with the company since 2017. His main areas of work within Jolla are hardware adaptation and Android App Support. Some of you may also know him as the inventor of sfdroid. Frajo is here to tell us about libgbinder, the interface layer that sits between Sailfish OS and the drivers that wrap the device hardware on your phone, and which is gradually replacing functionality from the classic libhybris integration.

A detailed look at driver access through libgbinder

In order to understand libgbinder, it’s first important to understand the Android Binder protocol which it uses. Even if you’re not already familiar with the Binder protocol, if you’re a developer you may be familiar with D-Bus, which is widely used in Sailfish OS (and Linux more generally) for communication between processes (usually referred to as IPC, or Inter Process Communication). Binder is an IPC approach just like peer-to-peer D-Bus but using different mechanisms to communicate internally and using different APIs. Binder IPC can happen at a much lower level in the stack than D-Bus, so as an application developer you would never make binder calls directly in the way you might with D-Bus. Instead you’re much more likely to use system libraries which may at some point make binder calls on your behalf.

However, on an Android device Binder is used more widely in a very similar way to D-Bus (although, usually wrapped in a Java interface). For example if an application wants to access framework functionality such as reading sensor data, it will call the Android Java API, which then invokes a binder call to the system server which replies with the data.

Although use of Binder is a relatively new addition to the Sailfish OS stack, it’s actually been part of Android since the very beginning. Earlier versions of Sailfish OS only made use of it through drivers that were loaded by libhybris and therefore libhybris provided the only interface to the Android hardware layer. This has changed more recently with the move to support devices based on Android 8 and beyond.

Android 8 introduced the HIDL (HAL Interface definition language) which replaced various APIs that were previously implemented through loadable shared libraries (for example the sensors.socname.so sensor API) with Binder HIDL interfaces instead. Prior to these changes libhybris had been dynamically loading these libraries in order to access the hardware, making them available to Qt through a standard interface. For example, in the Android source tree we can still see examples of the header files that the Sailfish OS middleware would previously have compiled against, with the ABI accessed using libhybris. For this purpose sensorfw used the hw_get_module function from libhybris which is a wrapper around the Android function with the same name to obtain an instance of the sensor_module_t object from sensors.socname.so. It would then use the header to access functions from this object, such as get_sensors_list.

Android also uses the AIDL for internal communication. For this purpose Android distinguishes between 3 binder devices. The /dev/hwbinder device is used for HIDL communication which is used by HAL processes. The /dev/binder and /dev/vndbinder devices are both using AIDL communication and are intended for framework IPC and IPC between vendor processes respectively. While libgbinder is capable of speaking this language as well, which is configurable via /etc/gbinder.conf{,.d}, for hardware adaptation purposes knowledge about HIDL suffices. The /dev/{,vnd,hw}binder devices are managed by the {,vnd,hw}servicemanager daemons respectively. These daemons deal with service registration and service lookup requests.

With the introduction of Android 8, these changes precipitated changes in Sailfish OS as well, with the first changes being to the modem implementation. The Android modem implementation — and hence the device drivers — switched from a socket API to using HIDL. As a result it was necessary for Slava Monich (also a software developer at Jolla, and an expert in all things comms, amongst other things) to reimplement the modem interface to use binder rather than sockets. Rather than link against the Android libbinder through libhybris, Slava chose to split off the HIDL access into its own library, libgbinder, which also then made the HIDL interfaces for other parts of hardware access available without going through libhybris.

Now the history is clear, let’s take a look at how it’s used in practice. As implied above, Binder is used through libgbinder which is our own implementation of Android’s Binder kernel API. For example, suppose a Sailfish OS application wants to access sensor readings (e.g. orientation info from the accelerometer data). The usual method would be to use the Qt sensor APIs available from QML and C++. This example QML code taken from the camera UI shows how this might be done.

OrientationSensor {
    active: captureView.effectiveActive

    onReadingChanged: {
        switch (reading.orientation) {
        case OrientationReading.TopUp:
            _pictureRotation = 0; break
        case OrientationReading.TopDown:
            _pictureRotation = 180; break
        case OrientationReading.LeftUp:
            _pictureRotation = 270; break
        case OrientationReading.RightUp:
            _pictureRotation = 90; break
        default:
            // Keep device orientation at previous state
        }
    }
}

The OrientationSensor QML component calls the Qt sensor library which communicates via D-Bus with the Sailfish sensor framework service. This would previously have linked to libhybris, but with the introduction of Android 8 this now uses libgbinder API to communicate with the HIDL service provided by the vendor (for most community users this would be the device manufacturer, Sony).

In more detail, we can see the readingChanged signal being emitted by QtSensors, which itself is triggered by the dataAvailable signal from sensorfw. By digging deeper we eventually find that the data arrives via a Binder message in the hybrisadaptor of sensorfw.

The HIDL interface relating to these events can be seen in the Android source code.

/**
 * Generate a vector of sensor events containing at most "maxCount"
 * entries.
 *
 * Additionally a vector of SensorInfos is returned for any dynamic sensors
 * connected as notified by returned events of type DYNAMIC_SENSOR_META.
 *
 * If there is no sensor event when this function is being called, block
 * until there are sensor events available.
 *
 * @param  maxCount max number of samples can be returned, must be > 0.
 *         Actual number of events returned in data must be <= maxCount
 *         and > 0.
 * @return result OK on success or BAD_VALUE if maxCount <= 0.
 * @return data vector of Event contains sensor events.
 * @return dynamicSensorsAdded vector of SensorInfo contains dynamic sensor
 *         added. Each element corresponds to a dynamic sensor meta events
 *         in data.
 */
poll(int32_t maxCount)
    generates (
            Result result,
            vec<Event> data,
            vec<SensorInfo> dynamicSensorsAdded);

The process used by libgbinder removes the the need to dynamically load vendor blobs or Android libraries into the sensorfw process.

As discussed earlier, with the introduction of Android 8 on the XA2 there were various hardware access libraries that had transitioned from using libraries to using HIDL interfaces. A new approach was therefore needed that made use of the new interface. As Android develops it increasingly drops the legacy libraries, so this transition makes Sailfish OS compatible with more recent Android HAL versions. The transition will continue into the future.

Although the obvious place where this is used, and which we’ve already looked at in some detail is for access to sensors, it’s now used in almost all situations where access to hardware is needed (apart from rendering and audio). These include the sensors framework, GPS location data, the Bluetooth interface, the modem, and the fingerprint reader. Although audio still currently uses libhybris, it’s a potential case where we could see a switch to libgbinder in the future. It hasn’t so far because the legacy HALs were all still available on all of the devices we’ve so-far encountered.

What does this all mean for developers? Well if you’re a porter, the question of how this affects you will depend on the device you’re developing for and which version of Android (if any) is used on it. Native porters can ignore this entirely. If you’re using a device that only has support for Android earlier than 8 then you need to ensure that you’re using the legacy APIs, while if you’re using a device running Android 8 or or later, then you’ll need to be using the libgbinder APIs. See the droid-hal-device build script.

If you’re an application developer all of this is entirely abstracted for you by the Qt and Sailfish middleware libraries.

Finally, for end users this is also entirely transparent. You won’t see any difference on your device whether it’s using libgbinder, libhybris, or as now, a mixture of both.

For the future, it’s possible more Android APIs will transition to Binder-only interfaces, in which case Sailfish OS will have no trouble moving over to them. You might ask why it isn’t used everywhere. It does have some limitations. For example graphics will continue to rely on libhybris for performance reasons.

HIDL has become an integral part of the Android HAL and there’s no indication that Android will be introducing an alternative any time soon. However, there have been developments in the Binder API itself. Between Android 8 and 10 there were some changes in how binder IPC communication happens, and therefore libgbinder was made aware of API levels in order to target Android 8, 9 and 10 devices. It is also capable of handling differences between the 32 bit Binder API and the 64 bit API, which are selected in the kernel via CONFIG_ANDROID_BINDER_IPC_32BIT.

The current architecture using mostly libgbinder interfaces with some areas still relying on libhybris, is working very well.

Community Shout-Out

The 4.2.0 L10n round is concluding and we are immensely grateful to all who translated despite the holiday months! Here is the list of thanks, starting with languages and users with the most contributions:

DavidGaliza for Galician (from zero to 60% done!), nthn for Dutch (:belgium:Belgium), emva and comradekingu for :norway:Norwegian BokmĂĄl, lhodas for :slovakia:Slovak, carmenfdezb for :es:Spanish, xiaobixu for Chinese (:hong_kong:Hong Kong), nephros, maus, and starfish for :de:German, hge for :cn:Chinese (Simplified), hanhsuan for Chinese (:taiwan:Taiwan), nthn for :netherlands:Dutch, sponka and ender for :slovenia:Slovenian, martonmiklos, Zgp, and zlutor for :hungary:Hungarian, dglent and ApB for :greece:Greek, werdinand for :estonia:Estonian, atlochowski for :poland:Polish, ncartron and Joearchi for :fr:French, aserg for Tatar, amaretzek and yield for :portugal:Portuguese, fravaccaro for :it:Italian, ljo and attah for :sweden: Swedish, susenerajce and Karry for :czech_republic:Czech, caio2k and MarcosAM for Portuguese (:brazil:Brazil).

Energy from the Community

More apps have been returning to Harbour sporting new translations, features and designs. As always it’s sadly not possible to cover them all, but here are a quartet of recent updates for you to try out. If you’ve updated your own app recently, do let us know so we can feature it here.

Editor

Sailfish OS already comes with its own Notes application for scribbling down your idle thoughts (or writing your Nobel-prize-winning novel). So why would you need another one? While Jolla’s Notes application is great for, well, notes, it’s not designed to edit arbitrary text files given that it stores its data in a database. Editor on the other hand allows you to load up any text file you have access to on the filesystem. Developed by Alexander Dydychkin (GoAlexander), the Editor app is packed full of useful features and includes a number of interesting design decisions to give it it’s own unique style. For example, the pulley menu is positioned at the bottom of the screen rather than the top, but in practice the majority of the features are accessed through the clean but clear three-stage toolbar.

Editing is straightforward and the presentation is nicely configurable through the settings (my first change after installation was to switch to a monospace font). The Tab, Undo and Redo buttons feature prominently on the toolbar, a good start for some nice functionality. Open up the secondary toolbar and you get some more useful but necessary features (New, Open, Save). What really pleased me was the tertiary toolbar, where you can set the file to Read Only (great for reading files without the distraction or danger of accidental keyboard fumbling), write a quick-note without having to go through the process of opening and closing a new file, or set the highlight mode for the file. What’s clear is that the functions have been chosen to fulfil real-world requirements refined through practical text-editing experience. The latest version has enjoyed a lot of improvements. Custom encodings are now supported, an improved UI including the ability to pick your own colour scheme, improved notifications and the obligatory bug fixes.

Alexander is looking for feedback, especially if you have knowledge of the best encodings to support for Asian languages, so do get in touch if you have ideas. Editor is available from the Jolla Store and OpenRepos.

Foil Auth

It’s generally accepted that passwords are a very poor way to authenticate. As my former boss used to say, they can be summed up as telling users to “think of something you can’t remember, then don’t write it down”. As network security has become more important and the failures of passwords have become more apparent, many services have started making Multi-Factor Authentication (MFA) a requirement. Time-based One Time Passwords (TOTPs) were one of the earliest ways to provide a second factor and their use has become quite widespread. As something that can only generated by your device (something you have), they make a valid second factor when combined with your password (something you know). Foil Auth from Slava Monich (slava) provides one of several apps on Sailfish OS for generating RFC6238 compliant TOTPs. The way this works is pretty simple: if your account requires you to use MFA the service will provide you with a token which you can either type into your device manually or scan in via a QR code shown on the website. Foil Auth will then generate a 6-digit numerical password that changes every 30 seconds. When you want to log in to the site again, you provide your normal password, plus the currently valid numerical password.

The security of this approach relies on the keys stored by your phone remaining secret. If someone else gets hold of the keys, they can also generate the same TOTPs, which takes them one step closer to breaking in to your account. A key feature of Foil Auth is that it encrypts the keys using a password entered when the app is first started. Without this password, an attacker can’t read your keys (at least, not without spending effort brute-forcing them). What’s particularly nice is that the key is shared between Slava’s other apps: Foil Pics and Foil Notes. There are other nice features as well, including the ability to share the keys between devices using a QR code either individually or in batches, plus the ability to copy a one-time password directly to the clipboard. I’m also a big fan of the very functional cover that comes with the app as well. The latest version increases the number of supported digest algorithms, as well as adding the ability to manage multiple tokens at once. If you need to use TOTP it’s a great tool, available from the Jolla Store and OpenRepos.

Watchlist

Market data and stocks have always seemed mysterious and exotic to me. From what I can tell they work like Bitcoin, but a closed-source version and with much worse documentation. Given how little I know about the topic I might not be the best person to be looking at this, but you have to start somewhere and maybe Watchlist, by Andreas Wüst (AndyWuest), will be my way in. We already reviewed Andreas’s really nice Pollenflug app a few newsletters ago, so my expectations are pretty high, even despite my minimal knowledge. And the fact is Watchlist is really easy to use and gives very clear information. The app has two main pages. The Market data page allows you select from a list of markets (for example currency or commodity markets) which are then added to the page showing current value and change information. With clear colouring you can instantly see which markets are going up and which are going down. The Stock quotes page is similar, but allows your choice of stocks from a variety of exchanges to be added. Out of the two, the Stock quotes page is the better featured. After adding a stock you can quickly see the value and change in value, with a coloured bar under each name giving a really clear indication of which stocks are doing better and which are doing worse. Selecting a stock opens a separate triplet of pages showing full details of a stock, graphs of activity over periods of a day, month, three months, the last year and the last three years. If I knew more about stocks those kind of charts might be just what I need to identify trends. Finally you can also read recent news items about the stock, all of which is likely to be very helpful for deciding when or whether to invest. You can even configure an alarm to go off in case a particular stock falls below or rises above specified levels or set a reference price to gauge performance since a stock was at a particular price.

The latest version allows you to add your own notes to each stock for later reference. This, plus a cover that can show either the best or worst performing stocks from your list, rounds off a really nice app. The latest update has a whole host of improvements, not just including the ability to add notes, but also a new backend, many bug fixes and continuous integration that will hopefully allow Andreas to get new versions out more quickly in future. Given my poor knowledge of the subject matter I’d be interested to know what you think of Watchlist — please add your thoughts to the thread — but Watchlist looks to me like a very useful and well-presented app. It’s available from both the Jolla Store and OpenRepos.

CarBudget

If you’re obsessed by measuring and recording things like I am, and if you run at least one car, then you’ll love CarBudget. It allows you to keep track of multiple aspects of your car ownership, including how much it costs to run, average cost per kilometre (or per mile if you’ve not moved to metric yet), and even your tire usage. It requires a bit of effort to set up and some diligence in keeping things up-to-date, but entering this information on your phone is a lot easier and more convenient than trying to keep a paper trail using receipts and physical records. The app itself is developed by Proriol Faben (condo4) although the About page also lists six other contributors at the time of writing. The latest version is primarily a bug-fixing update, as well as providing aarch64 support.

The app is very well-presented with nicely laid-out forms for entering data, very clear icons to perform the four main functions (fuel usage info, maintenance costs, tire management and statistics), and a summary of the statistics on the app cover. The fact you can also store data about multiple cars will also be important for some. Finally you can also import and export the app data in the form of a SQLlite database which is very handy for backups or in case you’re upgrading to a new phone.

CarBudget really is a very nice app. The only thing it would be good to see in a future release is more emphasis on fuelling methods other than petrol (electricity, for example). It’s a small quibble, but I’m sure one that the increasing number of drivers of electric vehicles would love to see addressed. CarBudget is available from the Jolla Store and OpenRepos.

Please feed us your news

This is a community update, and frankly we can’t always keep up with all the exciting stuff happening in the Sailfish community. Plus, the less of this we have to actually write ourselves the better. So please help us out by posting your Sailfish news updates to the forum as a reply to this post. We’ll collate as much of it as possible into one easily digestible post for the next update.

And don’t forget to join us at the community meeting every other Thursday on IRC. It’s a great place to discuss any of the content you see here, or to share your ideas for future updates. The next meeting will be on the 19th August, full details here.

21 Likes

Great write up on libgbinder @flypig and thanks @krnlyng … one question… libgbinder is C-based, and im currently porting an android10 device which uses sensor HAL2 only. Sensor HAL 2 uses Fast Message Queues (FMQ) for the sensor data. The FMQ lib is a templated C++ library. How do you plan to tackle this? Any code out there already? UBPorts gets around this issue using linux-hidl, but I gather that isnt ideal for sfos, so im very interested to know how this will be tackled. :slight_smile:

3 Likes

:thinking: :sweden:  

4 Likes

Ooops, thank you @attah for the correction :+1:

1 Like

Very well written - even for a noob like me, thank you!

2 Likes

What’s done in C++ (with templates or not) can also be implemented in C. Support for fmq will be added as soon as it’s required (or once I figure out how to test it).

2 Likes

Thanks for the mention.

1 Like