Привет, Хабр! Меня зовут Юрий Петров, я автор ютуб-канала «Мобильный разработчик» и 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. Присоединяйтесь!