From 58f10c864fd301fbe509c232488cab7b5c99a6b8 Mon Sep 17 00:00:00 2001 From: Xavi Garcia Mena Date: Mon, 7 Sep 2015 15:11:19 +0200 Subject: test version for gmenuharness --- tests/integration/utils/dbus-pulse-volume.cpp | 252 ++++++++++++++++++++++++++ tests/integration/utils/dbus-pulse-volume.h | 57 ++++++ tests/integration/utils/get-volume.cpp | 33 ++++ tests/integration/utils/set-volume.cpp | 36 ++++ 4 files changed, 378 insertions(+) create mode 100644 tests/integration/utils/dbus-pulse-volume.cpp create mode 100644 tests/integration/utils/dbus-pulse-volume.h create mode 100644 tests/integration/utils/get-volume.cpp create mode 100644 tests/integration/utils/set-volume.cpp (limited to 'tests/integration/utils') diff --git a/tests/integration/utils/dbus-pulse-volume.cpp b/tests/integration/utils/dbus-pulse-volume.cpp new file mode 100644 index 0000000..6989754 --- /dev/null +++ b/tests/integration/utils/dbus-pulse-volume.cpp @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2015 Canonical, Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * Author: Xavi Garcia + */ + +#include "dbus_properties_interface.h" +#include "dbus_accounts_interface.h" +#include "dbus_accountssound_interface.h" +#include "stream_restore_interface.h" + +#include +#include "dbus-pulse-volume.h" + +#include + +unsigned int volumeDoubleToUint(double volume) +{ + double tmp = (double)(PA_VOLUME_NORM - PA_VOLUME_MUTED) * volume; + return (unsigned int)tmp + PA_VOLUME_MUTED; +} + +double volumeUIntToDoulbe(uint volume) +{ + double tmp = (double)(volume - PA_VOLUME_MUTED); + return tmp / (double)(PA_VOLUME_NORM - PA_VOLUME_MUTED); +} + +DBusPulseVolume::DBusPulseVolume() : + QObject() +{ + std::unique_ptr basicConnectionInterface(new DBusPropertiesInterface("org.PulseAudio1", + "/org/pulseaudio/server_lookup1", + QDBusConnection::sessionBus(), 0)); + + QDBusReply connection_string = basicConnectionInterface->call(QLatin1String("Get"), + QLatin1String("org.PulseAudio.ServerLookup1"), + QLatin1String("Address")); + + if (!connection_string.isValid()) + { + qWarning() << "DBusPulseVolume::DBusPulseVolume(): D-Bus error: " << connection_string.error().message(); + } + + qDebug() << "********************************Connetion: " << connection_string.value().toString(); + +// connection_.reset(new QDBusConnection(QDBusConnection::connectToPeer(connection_string.value().toString(), "set-volume"))); + + connection_.reset(new QDBusConnection(QDBusConnection::connectToPeer("unix:path=/run/user/1000/pulse/dbus-socket", "set-volume"))); + qDebug() << "Is connected " << connection_->isConnected(); + + if (connection_->isConnected()) + { + interface_paths_.reset(new StreamRestoreInterface("org.PulseAudio.Ext.StreamRestore1", + "/org/pulseaudio/stream_restore1", + *(connection_.get()), 0)); + qDebug() << "Interface " << (void *)interface_paths_.get(); + + if (interface_paths_) + { + // get the role paths + fillRolePath("multimedia"); + fillRolePath("alert"); + fillRolePath("alarm"); + fillRolePath("phone"); + } + + initializeAccountsInterface(); + } + else + { + qWarning() << "DBusPulseVolume::DBusPulseVolume(): Error connecting: " << connection_->lastError().message(); + } +} + +DBusPulseVolume::~DBusPulseVolume() +{ + connection_->disconnectFromPeer("unix:path=/run/user/1000/pulse/dbus-socket"); +} + +QString DBusPulseVolume::fillRolePath(QString const &role) +{ + QString role_complete_name = QString("sink-input-by-media-role:") + role; + // get the role paths + QDBusReply objectPath = interface_paths_->call(QLatin1String("GetEntryByName"), role_complete_name); + if (!objectPath.isValid()) + { + qWarning() << "SetVolume::fillRolePath(): D-Bus error: " << objectPath.error().message(); + return ""; + } + qDebug() << "XGM: path for role " << role << "=" << objectPath.value().path(); + auto role_info = std::make_shared(); + role_info->interface_.reset(new DBusPropertiesInterface("org.PulseAudio.Ext.StreamRestore1.RestoreEntry", + objectPath.value().path(), + *(connection_.get()), 0)); + if (!role_info->interface_) + { + qWarning() << "SetVolume::fillRolePath() - Error obtaining properties interface"; + return ""; + } + role_info->path_ = objectPath.value().path(); + roles_map_[role] = role_info; + return role_info->path_; +} + +bool DBusPulseVolume::setVolume(QString const & role, double volume) +{ + if (!interface_paths_) + { + qWarning() << "SetVolume::setVolume(): error: Volume interfaces are not initialized"; + return false; + } + RolesMap::const_iterator iter = roles_map_.find(role); + if (iter != roles_map_.end()) + { + QDBusReply prev_vol = (*iter).second->interface_->call(QLatin1String("Get"), + QLatin1String("org.PulseAudio.Ext.StreamRestore1.RestoreEntry"), + QLatin1String("Volume")); + + if (!prev_vol.isValid()) + { + qWarning() << "SetVolume::setVolume(): D-Bus error: " << prev_vol.error().message(); + return false; + } + QDBusArgument arg = prev_vol.value().value(); + PulseaudioVolumeArray element; + arg >> element; + + PulseaudioVolume signal_vol(0, 4000); + PulseaudioVolumeArray vol_array; + vol_array.addItem(signal_vol); + + QVariant var; + PulseaudioVolumeArray t; + PulseaudioVolume vv(0, volumeDoubleToUint(volume)); + t.addItem(vv); + var.setValue(t); + QDBusVariant dbusVar(var); + QDBusReply set_vol = (*iter).second->interface_->call(QLatin1String("Set"), + QVariant::fromValue(QString("org.PulseAudio.Ext.StreamRestore1.RestoreEntry")), + QVariant::fromValue(QString("Volume")), + QVariant::fromValue(dbusVar)); + + if (!set_vol.isValid()) + { + qWarning() << "SetVolume::setVolume(): D-Bus error: " << set_vol.error().message(); + return false; + } + + if (accounts_interface_) + { + QDBusVariant dbusVar(QVariant::fromValue(volume)); + QDBusReply set_vol = accounts_interface_->call(QLatin1String("Set"), + QVariant::fromValue(QString("com.ubuntu.AccountsService.Sound")), + QVariant::fromValue(QString("Volume")), + QVariant::fromValue(dbusVar)); + if (!set_vol.isValid()) + { + qWarning() << "SetVolume::setVolume(): D-Bus error: " << set_vol.error().message(); + return false; + } + } + } + return true; +} + +double DBusPulseVolume::getVolume(QString const & role) +{ + if (interface_paths_) + { + RolesMap::const_iterator iter = roles_map_.find(role); + if (iter != roles_map_.end()) + { + QDBusReply prev_vol = (*iter).second->interface_->call(QLatin1String("Get"), + QLatin1String("org.PulseAudio.Ext.StreamRestore1.RestoreEntry"), + QLatin1String("Volume")); + + if (!prev_vol.isValid()) + { + qWarning() << "SetVolume::setVolume(): D-Bus error: " << prev_vol.error().message(); + } + QDBusArgument arg = prev_vol.value().value(); + PulseaudioVolumeArray element; + arg >> element; + return volumeUIntToDoulbe(element.getItem(0).getVolume()); + } + } + return -1.0; +} + +void DBusPulseVolume::initializeAccountsInterface() +{ + auto username = qgetenv("USER"); + if (username != "") + { + qDebug() << "Setting Accounts interface for user: " << username; + std::unique_ptr setInterface(new AccountsInterface("org.freedesktop.Accounts", + "/org/freedesktop/Accounts", + QDBusConnection::systemBus(), 0)); + qDebug() << "Interface: " << setInterface.get(); + + QDBusReply userResp = setInterface->call(QLatin1String("FindUserByName"), + QLatin1String(username)); + + if (!userResp.isValid()) + { + qWarning() << "SetVolume::initializeAccountsInterface(): D-Bus error: " << userResp.error().message(); + } + auto userPath = userResp.value().path(); + if (userPath != "") + { + std::unique_ptr soundInterface(new AccountsSoundInterface("org.freedesktop.Accounts", + userPath, + QDBusConnection::systemBus(), 0)); + + accounts_interface_.reset(new DBusPropertiesInterface("org.freedesktop.Accounts", + userPath, + soundInterface->connection(), 0)); + qDebug() << "Interface for setting volume: " << accounts_interface_.get(); + if (!accounts_interface_->isValid()) + { + qWarning() << "SetVolume::initializeAccountsInterface(): D-Bus error: " << accounts_interface_->lastError().message(); + } + signal_spy_volume_changed_.reset(new QSignalSpy(accounts_interface_.get(),&DBusPropertiesInterface::PropertiesChanged)); + } + } +} + +bool DBusPulseVolume::waitForVolumeChangedInAccountsService() +{ + if (signal_spy_volume_changed_) + { + return signal_spy_volume_changed_->wait(); + } + else + { + qWarning() << "DBusPulseVolume::waitForVolumeChangedInAccountsService(): signal was not instantiated"; + } + return false; +} diff --git a/tests/integration/utils/dbus-pulse-volume.h b/tests/integration/utils/dbus-pulse-volume.h new file mode 100644 index 0000000..2d55e89 --- /dev/null +++ b/tests/integration/utils/dbus-pulse-volume.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2015 Canonical, Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * Author: Xavi Garcia + */ +#pragma once + +#include +#include + +#include +#include + +class StreamRestoreInterface; +class DBusPropertiesInterface; +class AccountsInterface; +class AccountsSoundInterface; +class QSignalSpy; + +struct RoleInformation +{ + std::unique_ptr interface_; + QString path_; +}; + +class DBusPulseVolume : public QObject +{ +public: + DBusPulseVolume(); + ~DBusPulseVolume(); + + bool setVolume(QString const & role, double volume); + double getVolume(QString const & role); + bool waitForVolumeChangedInAccountsService(); + +protected: + QString fillRolePath(QString const &role); + void initializeAccountsInterface(); + std::unique_ptr connection_; + std::unique_ptr interface_paths_; + typedef std::map> RolesMap; + RolesMap roles_map_; + std::unique_ptr accounts_interface_; + std::unique_ptr signal_spy_volume_changed_; +}; diff --git a/tests/integration/utils/get-volume.cpp b/tests/integration/utils/get-volume.cpp new file mode 100644 index 0000000..309da36 --- /dev/null +++ b/tests/integration/utils/get-volume.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2015 Canonical, Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * Author: Xavi Garcia + */ + +#include "dbus-types.h" + +#include +#include "dbus-pulse-volume.h" + +int main(int argc, char **argv) +{ + DBusTypes::registerMetaTypes(); + if (argc == 2) + { + DBusPulseVolume volume; + volume.getVolume(argv[1]); + } + return 0; +} diff --git a/tests/integration/utils/set-volume.cpp b/tests/integration/utils/set-volume.cpp new file mode 100644 index 0000000..d29e5ef --- /dev/null +++ b/tests/integration/utils/set-volume.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2015 Canonical, Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * Author: Xavi Garcia + */ + +#include "dbus-types.h" + +#include +#include "dbus-pulse-volume.h" + +int main(int argc, char **argv) +{ + DBusTypes::registerMetaTypes(); + if (argc == 3) + { + DBusPulseVolume volume; + if(!volume.setVolume(argv[1], std::stod(argv[2]))) + { + return 1; + } + } + return 0; +} -- cgit v1.2.3 From 913282e093a723b7e3a7bb899a77a068edafcd01 Mon Sep 17 00:00:00 2001 From: Xavi Garcia Mena Date: Sun, 20 Sep 2015 20:16:27 +0200 Subject: Updated set-volume utility --- tests/integration/utils/dbus-pulse-volume.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests/integration/utils') diff --git a/tests/integration/utils/dbus-pulse-volume.cpp b/tests/integration/utils/dbus-pulse-volume.cpp index 6989754..b42ea15 100644 --- a/tests/integration/utils/dbus-pulse-volume.cpp +++ b/tests/integration/utils/dbus-pulse-volume.cpp @@ -56,9 +56,9 @@ DBusPulseVolume::DBusPulseVolume() : qDebug() << "********************************Connetion: " << connection_string.value().toString(); -// connection_.reset(new QDBusConnection(QDBusConnection::connectToPeer(connection_string.value().toString(), "set-volume"))); + connection_.reset(new QDBusConnection(QDBusConnection::connectToPeer(connection_string.value().toString(), "set-volume"))); - connection_.reset(new QDBusConnection(QDBusConnection::connectToPeer("unix:path=/run/user/1000/pulse/dbus-socket", "set-volume"))); +// connection_.reset(new QDBusConnection(QDBusConnection::connectToPeer("unix:path=/run/user/1000/pulse/dbus-socket", "set-volume"))); qDebug() << "Is connected " << connection_->isConnected(); if (connection_->isConnected()) -- cgit v1.2.3 From ae0602ca11090c6c70cdf289ce3871766d36519c Mon Sep 17 00:00:00 2001 From: Xavi Garcia Mena Date: Mon, 21 Sep 2015 11:53:31 +0200 Subject: code cleanup --- tests/integration/utils/dbus-pulse-volume.cpp | 33 ++++----------------------- 1 file changed, 4 insertions(+), 29 deletions(-) (limited to 'tests/integration/utils') diff --git a/tests/integration/utils/dbus-pulse-volume.cpp b/tests/integration/utils/dbus-pulse-volume.cpp index b42ea15..a282f77 100644 --- a/tests/integration/utils/dbus-pulse-volume.cpp +++ b/tests/integration/utils/dbus-pulse-volume.cpp @@ -16,13 +16,14 @@ * Author: Xavi Garcia */ +#include "dbus-pulse-volume.h" + #include "dbus_properties_interface.h" #include "dbus_accounts_interface.h" #include "dbus_accountssound_interface.h" #include "stream_restore_interface.h" #include -#include "dbus-pulse-volume.h" #include @@ -54,20 +55,13 @@ DBusPulseVolume::DBusPulseVolume() : qWarning() << "DBusPulseVolume::DBusPulseVolume(): D-Bus error: " << connection_string.error().message(); } - qDebug() << "********************************Connetion: " << connection_string.value().toString(); - connection_.reset(new QDBusConnection(QDBusConnection::connectToPeer(connection_string.value().toString(), "set-volume"))); -// connection_.reset(new QDBusConnection(QDBusConnection::connectToPeer("unix:path=/run/user/1000/pulse/dbus-socket", "set-volume"))); - qDebug() << "Is connected " << connection_->isConnected(); - if (connection_->isConnected()) { interface_paths_.reset(new StreamRestoreInterface("org.PulseAudio.Ext.StreamRestore1", "/org/pulseaudio/stream_restore1", *(connection_.get()), 0)); - qDebug() << "Interface " << (void *)interface_paths_.get(); - if (interface_paths_) { // get the role paths @@ -87,7 +81,6 @@ DBusPulseVolume::DBusPulseVolume() : DBusPulseVolume::~DBusPulseVolume() { - connection_->disconnectFromPeer("unix:path=/run/user/1000/pulse/dbus-socket"); } QString DBusPulseVolume::fillRolePath(QString const &role) @@ -100,7 +93,7 @@ QString DBusPulseVolume::fillRolePath(QString const &role) qWarning() << "SetVolume::fillRolePath(): D-Bus error: " << objectPath.error().message(); return ""; } - qDebug() << "XGM: path for role " << role << "=" << objectPath.value().path(); + auto role_info = std::make_shared(); role_info->interface_.reset(new DBusPropertiesInterface("org.PulseAudio.Ext.StreamRestore1.RestoreEntry", objectPath.value().path(), @@ -122,26 +115,10 @@ bool DBusPulseVolume::setVolume(QString const & role, double volume) qWarning() << "SetVolume::setVolume(): error: Volume interfaces are not initialized"; return false; } + RolesMap::const_iterator iter = roles_map_.find(role); if (iter != roles_map_.end()) { - QDBusReply prev_vol = (*iter).second->interface_->call(QLatin1String("Get"), - QLatin1String("org.PulseAudio.Ext.StreamRestore1.RestoreEntry"), - QLatin1String("Volume")); - - if (!prev_vol.isValid()) - { - qWarning() << "SetVolume::setVolume(): D-Bus error: " << prev_vol.error().message(); - return false; - } - QDBusArgument arg = prev_vol.value().value(); - PulseaudioVolumeArray element; - arg >> element; - - PulseaudioVolume signal_vol(0, 4000); - PulseaudioVolumeArray vol_array; - vol_array.addItem(signal_vol); - QVariant var; PulseaudioVolumeArray t; PulseaudioVolume vv(0, volumeDoubleToUint(volume)); @@ -209,7 +186,6 @@ void DBusPulseVolume::initializeAccountsInterface() std::unique_ptr setInterface(new AccountsInterface("org.freedesktop.Accounts", "/org/freedesktop/Accounts", QDBusConnection::systemBus(), 0)); - qDebug() << "Interface: " << setInterface.get(); QDBusReply userResp = setInterface->call(QLatin1String("FindUserByName"), QLatin1String(username)); @@ -228,7 +204,6 @@ void DBusPulseVolume::initializeAccountsInterface() accounts_interface_.reset(new DBusPropertiesInterface("org.freedesktop.Accounts", userPath, soundInterface->connection(), 0)); - qDebug() << "Interface for setting volume: " << accounts_interface_.get(); if (!accounts_interface_->isValid()) { qWarning() << "SetVolume::initializeAccountsInterface(): D-Bus error: " << accounts_interface_->lastError().message(); -- cgit v1.2.3 From 22de41f3cc382adbf06be8642af5cfa7ec664c8e Mon Sep 17 00:00:00 2001 From: Xavi Garcia Mena Date: Mon, 21 Sep 2015 16:01:33 +0200 Subject: Added separated integration tests for desktop and phone, with different instances of pulseaudio --- tests/integration/utils/dbus-pulse-volume.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tests/integration/utils') diff --git a/tests/integration/utils/dbus-pulse-volume.cpp b/tests/integration/utils/dbus-pulse-volume.cpp index a282f77..c8b6ae6 100644 --- a/tests/integration/utils/dbus-pulse-volume.cpp +++ b/tests/integration/utils/dbus-pulse-volume.cpp @@ -150,6 +150,11 @@ bool DBusPulseVolume::setVolume(QString const & role, double volume) } } } + else + { + qWarning() << "SetVolume::setVolume(): role " << role << " was not found."; + return false; + } return true; } -- cgit v1.2.3