Привет, Хабр! Меня зовут Юрий Петров, я автор ютуб-канала «Мобильный разработчик» и Flutter Tech Lead в компании Friflex. Мы разрабатываем мобильные приложения для бизнеса и специализируемся на Flutter.
В этой статье я расскажу, как с помощью интерфейса D-Bus можно быстро получить необходимую вам информацию из системы Аврора.

Что такое интерфейс D-Bus
D-Bus — как почтальон, доставляет сообщения от одного процесса к другому в unix-системах. С помощью D-Bus мы можем обратиться к конкретной службе в системе и получить необходимую информацию.
На схеме изображена работа D-Bus.

У Авроры, как у unix-системы, есть открытые интерфейсы D-Bus. Познакомиться с ними можно по ссылке.
ru.omp.deviceinfo.Features дает информацию об основных параметрах и функциях устройства: версии ОС, модели, разрешении экрана, данных о ЦП, ОЗУ и камере, наличии модулей связи.
ru.omp.deviceinfo.SIM предоставляет данные о SIM-карте и позволяет отслеживать события, связанные с ней.
ru.omp.deviceinfo.Storages дает доступ к информации о памяти на устройстве: флэш-памяти, внешнем хранилище, разделах пользователей.
Есть и другие интерфейсы. Я покажу, как их можно получать напрямую из системы. Для примера, попробуем получить из ОС Аврора информацию о заряде батареи смартфона.
Получаем информацию о заряде батареи
Создаем Flutter-проект с названием flutter_dbus. Добавляем поддержку системы Аврора в проект командой:
flutter create --platforms=aurora --org=com.example .
Если не знаете, как начать писать для системы Авроры на Flutter, можно посмотреть мои обучающие видео на Youtube или почитать статьи ОМП на Хабре.
Переходим в появившуюся папку aurora, далее в папку desktop и в файл com.example.flutter_dbus.desktop.
В разделе [X-Application] разрешите читать данные об устройстве Permissions=DeviceInfo:
[Desktop Entry] Type=Application Name=flutter_dbus Comment=A new Flutter project. Icon=com.example.flutter_dbus Exec=/usr/bin/com.example.flutter_dbus X-Nemo-Application-Type=silica-qt5 [X-Application] Permissions=DeviceInfo OrganizationName=com.example ApplicationName=flutter_dbus
После этого нам нужно установить глобально специальный пакет для работы с D-Bus на языке Dart.
Вызываем команду:
dart pub global activate dbus
И добавляем в pubspec.yaml данный пакет:
dependencies: dbus: ^0.7.10
Пакет D-bus очень простой. Описываем интерфейс в файле .xml, и пакет создает готовый код для работы с интерфейсом.
Создаем файл data.xml в корне проекта. В нем описываем интерфейс ru.omp.deviceinfo.Features.
<node> <interface name="ru.omp.deviceinfo.Features"> </interface> </node>
В теле интерфейса указываем метод получения заряда батареи. Список доступных методов можно изучить на странице интерфейса.
<node> <interface name="ru.omp.deviceinfo.Features"> <method name="getBatteryChargePercentage"> </method> </interface> </node>

Важно указать правильный тип возвращаемого значения. Мы видим, что метод getBatteryChargePercentage(uint &chargePercentage) возвращает целочисленное значение типа integer.
<node> <interface name="ru.omp.deviceinfo.Features"> <method name="getBatteryChargePercentage"> <arg name="output" type="u" direction="out" /> </method> </interface> </node>
В аргументах описания метода указываем, что он вернет целое число. Теперь генерируем код при помощи команды:
dart-dbus generate-remote-object data.xml -o lib/data.dart
После генерации в папке lib data.dart появляется файл:
// This file was generated using the following command and may be overwritten. // dart-dbus generate-remote-object data.xml import 'dart:io'; import 'package:dbus/dbus.dart'; class RuOmpDeviceinfoFeatures extends DBusRemoteObject { RuOmpDeviceinfoFeatures(DBusClient client, String destination, DBusObjectPath path) : super(client, name: destination, path: path); /// Invokes ru.omp.deviceinfo.Features.getBatteryChargePercentage() Future<int> callgetBatteryChargePercentage({bool noAutoStart = false, bool allowInteractiveAuthorization = false}) async { var result = await callMethod('ru.omp.deviceinfo.Features', 'getBatteryChargePercentage', [], replySignature: DBusSignature('u'), noAutoStart: noAutoStart, allowInteractiveAuthorization: allowInteractiveAuthorization); return result.returnValues[0].asUint32(); } }
В файле находится код, с помощью которого можно запросить из системы данные о заряде батареи.
Осталось добавить в проект следующий код:
Создаем запрос в платформу
Создаем клиента:
final client = DBusClient.session();
Создаем объект для работы с интерфейсом D-Bus:
final features = RuOmpDeviceinfoFeatures( client, 'ru.omp.deviceinfo', DBusObjectPath('/ru/omp/deviceinfo/Features'), );
Получаем заряд батареи из системы:
final percent = await features.callgetBatteryChargePercentage();
Отображаем в MaterialApp:
runApp(MaterialApp( home: Scaffold( body: Center( child: Text( percent.toString(), ), ))));
При запуске проекта в системе получаем отображение заряда батареи:
Результат

Получаем список всех интерфейсов D-Bus
Как и обещал, рассказываю, как получить список всех интерфейсов D-Bus. Подключаемся к смартфону через ssh, и вводим команду списка интерфейсов в этой сессии:
dbus-send --session \ --dest=org.freedesktop.DBus \ --type=method_call \ --print-reply \ /org/freedesktop/DBus \ org.freedesktop.DBus.ListNames.
В терминале отобразится список всех поддерживаемых интерфейсов D-Bus. По-другому получить этот список можно при помощи команды:
dbus-send --system \ --dest=org.freedesktop.DBus \ --type=method_call \ --print-reply \ /org/freedesktop/DBus \ org.freedesktop.DBus.ListNames
Этот запрос вернет все доступные системные интерфейсы D-Bus. Чтобы их изучить, достаточно просто написать название в любом поисковике.
Если у вас что-то не получилось, можно клонировать проект из гитхаба.
Надеюсь, статья будет вам полезна. С удовольствием отвечу на вопросы в комментариях.
P.S. Мы ведем дружелюбный канал про Flutter в Telegram. Присоединяйтесь!

