Как быстро получать данные из ОС Аврора через интерфейс D-Bus во Flutter-приложении

от автора

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

В этой статье я расскажу, как с помощью интерфейса D-Bus можно быстро получить необходимую вам информацию из системы Аврора.

Что такое интерфейс D-Bus

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

На схеме изображена работа D-Bus.

У Авроры, как у unix-системы, есть открытые интерфейсы D-Bus. Познакомиться с ними можно по ссылке.

  1. ru.omp.deviceinfo.Features дает информацию об основных параметрах и функциях устройства: версии ОС, модели, разрешении экрана, данных о ЦП, ОЗУ и камере, наличии модулей связи.

  2. ru.omp.deviceinfo.SIM предоставляет данные о SIM-карте и позволяет отслеживать события, связанные с ней.

  3. 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. Чтобы их изучить, достаточно просто написать название в любом поисковике.

Если у вас что-то не получилось, можно клонировать проект из гитхаба.

Надеюсь, статья будет вам полезна. С удовольствием отвечу на вопросы в комментариях.


ссылка на оригинал статьи https://habr.com/ru/articles/799855/