Документация

РОСА Push клиент, документация интерфейса для разработчиков приложений

Взаимодействие приложения с РОСА Push клиентом происходит по системной шине DBus. Для ее использования на стороне приложения нужно будет создать DBus интерфейс, включить его в сборку и использовать для межпроцессного общения.

DBus интерфейс

DBus интерфейс состоит из нескольких файлов, которые нужно будет создать на стороне приложения.

rosa_push_daemon.xml

Интерфейсный файл с описание структуры API DBus. Здесь описаны все методы и сигналы с аргументами, которые будут доступны через шину DBus. Из файла будет сгенерирован интерфейс RuRosalinuxRpd_appsideInterface, по которому происходит общение с РОСА Push.





 

    

        

        

    

    

        

        

    

    

        

        

        

    

 


Методы:

inline QDBusPendingReply<> register_app(ApplicationData data)

Метод регистрирует приложение с его данными в РОСА Push и генерирует для приложения уникальный Push токен на стороне Push сервера

  • data - данные приложения для создания нотификаций и регистрации самого приложения. Описание типа ApplicationData смотрите ниже

inline QDBusPendingReply<> operation_with_value(const QString &operation, const QString &value)

Метод отправляет операцию (управляющую команду) для всех нотификаций, хранящихся в РОСА Push. Получив операцию, РОСА Push для каждой имеющейся нотификации проверяет, от какого приложения пришла операция и совпадает ли критерий для ее выполнения. Если все совпадает, то операция для нотификации выполняется.

  • operation - имя операции
  • value - значение, которое может быть использовано для критерия выполнения операции

Чтобы операция выполнилась, она должна поддерживаться на стороне РОСА Push клиента. Смотрите список доступных операций ниже.

Сигналы:

void push_token(const QString &deviceId, const QString &applicationId, const QString &pushToken)

РОСА Push демон отсылает сигнал в ответ на запрос регистрации приложения на Push сервере. Если приложение уже зарегестрировано на Push сервере, то Push демон берет Push токен из своей локальной базы данных

  • deviceId - сгенерированный в Rosa Push уникальный id устройства (на текущий момент при апдейте данных, когда регистрация уже пройдена, похоже вместо deviceId отсылается machineId, так как у него частично инвертирован порядок байт)
  • applicationId - тот же appId, который был отослан приложением в ApplicationData на регистрацию в методе register_app, позволяет определить, для какого приложения был отослан сигнал об окончании регистрации
  • pushToken - уникальный сгенерированный на Push сервере Push токен, позволяющий определить, кому адресованы поступающие с сервера сообщения

Аргументы:

  • direction - направление передачи аргумента относительно РОСА Push - в него или из него, может быть "in" или "out" соответственно
  • type - сигнатура аргумента
  • annotation - все сложные типы данных, неизвестные DBus, должны быть объявлены здесь сразу после описания аргумента с типом

Сигнатуры аргументов:

Все аргументы должны быть описаны понятным DBus способом через сигнатуры простых типов данных. А все сложные типы данных должны быть описаны через простые в последовательности передачи их полей в сообщении.

Основные поддерживаемые DBus сигнатуры данных:

b - boolean

i - 32-bit signed integer

d - double-precision floating point

s - UTF-8 string

v - variant type

a - array followed by type

(...) - structure (fixed sequence of elements)

a{...} - dictionary/map (array of dictionary entries)

Сигнатура ApplicationData полностью соответствует ее описанию через простые типы данных.

 (ssssssssa{ss}) - структура, состоящая из строк и map из строк по ключу и значению 

rosa_push_daemon_types.h

Файл с описанием типов данных, используемых для передачи по DBus. Интерфейс RuRosalinuxRpd_appsideInterface должен включать в себя это описание.

#ifndef ROSA_PUSH_DAEMON_TYPES_H

#define ROSA_PUSH_DAEMON_TYPES_H



#include 

#include 

#include 

#include 



typedef QMap SupportedOperations;



struct ApplicationData

{

    QString appId;

    QString appName;

    QString appCommand;

    QString action1Name;

    QString action1Command;

    QString action2Name;

    QString action2Command;

    QString iconName;

    SupportedOperations supportedOperations;

};



Q_DECLARE_METATYPE(SupportedOperations)

Q_DECLARE_METATYPE(ApplicationData)



QDBusArgument &operator<<(QDBusArgument &argument, const ApplicationData &data);

const QDBusArgument &operator>>(const QDBusArgument &argument, ApplicationData &data);



#endif // ROSA_PUSH_DAEMON_TYPES_H

Типы данных:

ApplicationData

Структура, содержащая данные приложения для регистрации и создания нотификаций

  • appId - уникальный id приложения, использующийся для генерации Push токена. Должен быть в формате "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  • appName - имя приложения, используется в заголовке нотификации, если в сообщении от Push сервера он пустой
  • appCommand - storage id приложения для его запуска из РОСА Push через AppLauncher, соотвествует имени .desktop файла приложения
  • action1Name - имя левой кнопки нотификации (может быть пустым)
  • action1Command - аргумент для запуска приложения при нажатии левой кнопки нотификации (может быть пустым)
  • action2Name - имя правой кнопки нотификации (может быть пустым)
  • action2Command - аргумент для запуска приложения при нажатии правой кнопки нотификации (может быть пустым)
  • iconName - имя иконки для отображения внутри нотификаций
  • supportedOperations - список поддерживаемых операций со значениями, представляет из себя map с ключем (именем операции) и значением в виде строк. Для имен ключей и значений есть ограничение - нельзя при их задании использовать символы ',' и ':'

Список доступных операций, которые поддерживаются Rosa Push:

  • closeOnValue - закрывает нотификацию при совпадении значения операции со значением, хранящимся в нотификации

Поля action1Command, action2Command и supportedOperations.value() могут содержать в себе идентификатор сообщения, заключенный в фигурные скобки. Например, "--chat={collapse_id}" для action1Command в РОСА Мессенджер. Текст, заключенный в фигурные скобки { }, при формировании нотификации будет заменен на значение этого идентификатора, полученного в сообщении от Push сервера. Таким образом можно запускать приложения с опциями, отличительными для конкретных нотификаций, и отправлять операции, предназначенные также каким-то конкретным нотификациям.

В файле также регистрируются кастомные типы данных в системе мета объектов Qt. Это делается через Q_DECLARE_METATYPE(SupportedOperations) и Q_DECLARE_METATYPE(ApplicationData). Это позволяет использовать эти типы данных как аргументы в сигналах и слотах, а также хранить объекты этих типов в QVariant.

rosa_push_daemon_types.cpp

Файл с описанием сериализации типов данных. Маршалинг позволяет преобразовывать все типы данных в формат, понятный DBus, путем создания единого сообщения через последовательную передачу полей.

#include "rosapushdaemontypes.h"



// Marshall (Send)

QDBusArgument &operator<<(QDBusArgument &argument, const ApplicationData &data) {

    argument.beginStructure();

    argument << data.appId << data.appName << data.appCommand

             << data.action1Name << data.action1Command << data.action2Name

             << data.action2Command << data.iconName << data.supportedOperations;

    argument.endStructure();

    return argument;

}



// Demarshall (Receive)

const QDBusArgument &operator>>(const QDBusArgument &argument, ApplicationData &data) {

    argument.beginStructure();

    argument >> data.appId >> data.appName >> data.appCommand

             >> data.action1Name >> data.action1Command >> data.action2Name

             >> data.action2Command >> data.iconName >> data.supportedOperations;

    argument.endStructure();

    return argument;

}

Включение интерфейса зависит от типа сборки. В файл сборки нужно добавить все исходные файлы интерфейса и дополнительно подключить в генерируемом файле самого интерфейса описание кастомных типов

В случае сборки через qmake с использованием .pro файла нужно добавить в .pro файл:

QT += dbus



SOURCES += \

    rosa_push_daemon_types.cpp \



HEADERS += \

    rosa_push_daemon_types.h \



DBUS_INTERFACES += rosa_push_daemon

rosa_push_daemon.files = ./rosa_push_daemon.xml

rosa_push_daemon.header_flags = -i rosa_push_daemon_types.h

Взаимодействие с РОСА Push клиентом

После создания и включения DBus интерфейса в сборку можно его использовать для регистрации приложения, установки данных при формировании нотификаций и управления нотификациями.

Кроме регистрации кастомных типов в системе мета данных через Q_DECLARE_METATYPE в rosa_push_daemon_types.h, также нужно единократно их зарегистрировать при запуске приложения для QDBus. Обычно это делается в файле main.cpp или в файле, работающем с QDBus.

#include "rosa_push_daemon_types.h"



...

qDBusRegisterMetaType();

qDBusRegisterMetaType();

...

В файле, работающим с QDBus, надо создать объект сгенерированного интерфейса RuRosalinuxRpd_appsideInterface, по которому будет происходить общение с РОСА Push клиентом:

#include "rosa_push_daemon_interface.h"



...

RuRosalinuxRpd_appsideInterface *m_pushDaemonInterface;

m_pushDaemonInterface = new RuRosalinuxRpd_appsideInterface("ru.rosalinux.rpd_appside", "/ru/rosalinux/rpd_appside", QDBusConnection::systemBus(), this);

...

В объекте интерфейса RuRosalinuxRpd_appsideInterface вызываются методы, отсылающие по DBus сообщения в РОСА Push:

#include "rosa_push_daemon_types.h"



const QString ApplicationId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";



void registerApp(...)

{

    ApplicationData data = {ApplicationId,

                            appName,

                            appCommand,

                            action1Name,

                            action1Command,

                            action2Name,

                            action2Command,

                            iconName,

                            supportedOperations};



    m_pushDaemonInterface->register_app(data);

}



void sendOperationWithValue(...)

{

    m_pushDaemonInterface->operation_with_value(operation, value);

}

Для получения сигнала от Push демона о завершении регистрации нужно его подключить к объекту интерфейса RuRosalinuxRpd_appsideInterface:

const QString ApplicationId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";



...

connect(m_pushDaemonInterface, &RuRosalinuxRpd_appsideInterface::push_token, this, &pushToken);

...



void pushToken(const QString &deviceId, const QString &applicationId, const QString &token)

{

    if (applicationId == ApplicationId) {

        ...

    }

}