/* * 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 "indicator-sound-test-base.h" #include "dbus_menus_interface.h" #include "dbus_properties_interface.h" #include "dbus_accounts_interface.h" #include "dbus_accountssound_interface.h" #include "dbus-types.h" #include #include #include "utils/dbus-pulse-volume.h" using namespace QtDBusTest; using namespace QtDBusMock; using namespace std; using namespace testing; namespace mh = unity::gmenuharness; IndicatorSoundTestBase::IndicatorSoundTestBase() : dbusMock(dbusTestRunner) { } IndicatorSoundTestBase::~IndicatorSoundTestBase() { } bool IndicatorSoundTestBase::setVolume(QString const &role, double volume) { QProcess setVolume; setVolume.start(VOLUME_SET_BIN, QStringList() << role << QString("%1").arg(volume)); if (!setVolume.waitForStarted()) return false; if (!setVolume.waitForFinished()) return false; return setVolume.exitCode() == 0; } bool IndicatorSoundTestBase::startTestSound(QString const &role) { testSoundProcess.terminate(); testSoundProcess.start("paplay", QStringList() << "-s" << "127.0.0.1" << TEST_SOUND << QString("--property=media.role=%1").arg(role)); if (!testSoundProcess.waitForStarted()) return false; // sleep(1); return true; } void IndicatorSoundTestBase::stopTestSound() { testSoundProcess.terminate(); } void IndicatorSoundTestBase::startPulse() { try { pulseaudio.reset( new QProcessDBusService(DBusTypes::DBUS_PULSE, QDBusConnection::SessionBus, "pulseaudio", QStringList() << "--start" << "-vvvv" << "--disable-shm=true" << "--daemonize=false" << "--use-pid-file=false" << "--system=false" << "--exit-idle-time=-1" << "-n" << "--load=module-null-sink" << "--log-target=file:/tmp/pulse-daemon.log" << QString("--load=module-stream-restore restore_device=false restore_muted=false fallback_table=%1").arg(STREAM_RESTORE_TABLE) << "--load=module-dbus-protocol" << "--load=module-native-protocol-tcp auth-ip-acl=127.0.0.1" )); pulseaudio->start(dbusTestRunner.sessionConnection()); } catch (exception const& e) { cout << "pulseaudio(): " << e.what() << endl; throw; } } void IndicatorSoundTestBase::startAccountsService() { try { accountsService.reset( new QProcessDBusService(DBusTypes::ACCOUNTS_SERVICE, QDBusConnection::SystemBus, ACCOUNTS_SERVICE_BIN, QStringList() )); accountsService->start(dbusTestRunner.systemConnection()); initializeAccountsInterface(); } catch (exception const& e) { cout << "accountsService(): " << e.what() << endl; throw; } } void IndicatorSoundTestBase::startIndicator() { try { setenv("PULSE_SERVER", "127.0.0.1", true); indicator.reset( new QProcessDBusService(DBusTypes::DBUS_NAME, QDBusConnection::SessionBus, SOUND_SERVICE_BIN, QStringList())); indicator->start(dbusTestRunner.sessionConnection()); } catch (exception const& e) { cout << "startIndicator(): " << e.what() << endl; throw; } } // /usr/bin/pulseaudio --start -vvvv --disable-shm=true --daemonize=false --use-pid-file=false --system=false --exit-idle-time=-1 -n "--load=module-null-sink sink_name=multimedia" --load=module-stream-restore mh::MenuMatcher::Parameters IndicatorSoundTestBase::desktopParameters() { return mh::MenuMatcher::Parameters( "com.canonical.indicator.sound", { { "indicator", "/com/canonical/indicator/sound" } }, "/com/canonical/indicator/sound/desktop"); } void IndicatorSoundTestBase::SetUp() { setenv("GSETTINGS_SCHEMA_DIR", SCHEMA_DIR, true); setenv("GSETTINGS_BACKEND", "memory", true); setenv("DBUS_SYSTEM_BUS_ADDRESS", dbusTestRunner.systemBus().toStdString().c_str(), true); } void IndicatorSoundTestBase::TearDown() { unsetenv("GSETTINGS_SCHEMA_DIR"); unsetenv("GSETTINGS_BACKEND"); unsetenv("PULSE_SERVER"); } void gvariant_deleter(GVariant* varptr) { if (varptr != nullptr) { g_variant_unref(varptr); } } std::shared_ptr IndicatorSoundTestBase::volume_variant(double volume) { GVariantBuilder builder; g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); g_variant_builder_add(&builder, "{sv}", "title", g_variant_new_string("_Sound")); g_variant_builder_add(&builder, "{sv}", "accessible-desc", g_variant_new_string("_Sound")); auto icon = g_themed_icon_new("icon"); g_variant_builder_add(&builder, "{sv}", "icon", g_icon_serialize(icon)); g_variant_builder_add(&builder, "{sv}", "visible", g_variant_new_boolean(true)); return shared_ptr(g_variant_builder_end(&builder), &gvariant_deleter); } unity::gmenuharness::MenuItemMatcher IndicatorSoundTestBase::volumeSlider(double volume) { return mh::MenuItemMatcher().radio() .label("Volume") .round_doubles(0.1) .pass_through_double_attribute("action", volume); } bool IndicatorSoundTestBase::waitMenuChange() { if (!menu_interface_) { menu_interface_.reset(new MenusInterface("com.canonical.indicator.sound", "/com/canonical/indicator/sound/desktop", QDBusConnection::sessionBus(), 0)); } if (menu_interface_) { qDebug() << "Waiting for signal"; QSignalSpy spy(menu_interface_.get(), &MenusInterface::Changed); qDebug() << "Signal count " << spy.count(); return spy.wait(); } return false; } bool IndicatorSoundTestBase::waitVolumeChangedInIndicator() { if (signal_spy_volume_changed_) { return signal_spy_volume_changed_->wait(); } return false; } void IndicatorSoundTestBase::initializeAccountsInterface() { auto username = qgetenv("USER"); if (username != "") { std::unique_ptr setInterface(new AccountsInterface("org.freedesktop.Accounts", "/org/freedesktop/Accounts", QDBusConnection::systemBus(), 0)); 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)); 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)); } } }