From ee2ba9c677721724c8385ff2c9f32f7a9f090f0d Mon Sep 17 00:00:00 2001 From: Xavi Garcia Mena Date: Fri, 22 Jan 2016 14:10:07 -0600 Subject: Code for Bug 1213907 added. Only showing active players playback controls --- src/service.vala | 2 +- src/sound-menu.vala | 92 ++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 68 insertions(+), 26 deletions(-) diff --git a/src/service.vala b/src/service.vala index 29b8670..2228ba2 100644 --- a/src/service.vala +++ b/src/service.vala @@ -94,7 +94,7 @@ public class IndicatorSound.Service: Object { this.menus = new HashTable (str_hash, str_equal); this.menus.insert ("desktop_greeter", new SoundMenu (null, SoundMenu.DisplayFlags.SHOW_MUTE | SoundMenu.DisplayFlags.HIDE_PLAYERS | SoundMenu.DisplayFlags.GREETER_PLAYERS)); this.menus.insert ("phone_greeter", new SoundMenu (null, SoundMenu.DisplayFlags.SHOW_SILENT_MODE | SoundMenu.DisplayFlags.HIDE_INACTIVE_PLAYERS | SoundMenu.DisplayFlags.GREETER_PLAYERS)); - this.menus.insert ("desktop", new SoundMenu ("indicator.desktop-settings", SoundMenu.DisplayFlags.SHOW_MUTE)); + this.menus.insert ("desktop", new SoundMenu ("indicator.desktop-settings", SoundMenu.DisplayFlags.SHOW_MUTE | SoundMenu.DisplayFlags.HIDE_INACTIVE_PLAYERS_PLAY_CONTROLS)); this.menus.insert ("phone", new SoundMenu ("indicator.phone-settings", SoundMenu.DisplayFlags.SHOW_SILENT_MODE | SoundMenu.DisplayFlags.HIDE_INACTIVE_PLAYERS)); this.menus.@foreach ( (profile, menu) => { diff --git a/src/sound-menu.vala b/src/sound-menu.vala index bdb8df2..fde1a6c 100644 --- a/src/sound-menu.vala +++ b/src/sound-menu.vala @@ -25,9 +25,18 @@ public class SoundMenu: Object HIDE_INACTIVE_PLAYERS = 2, HIDE_PLAYERS = 4, GREETER_PLAYERS = 8, - SHOW_SILENT_MODE = 16 + SHOW_SILENT_MODE = 16, + HIDE_INACTIVE_PLAYERS_PLAY_CONTROLS = 32 } + public enum PlayerSectionPosistion { + LABEL = 0, + PLAYER_CONTROLS = 1, + PLAYLIST = 2 + } + + const string PLAYBACK_ITEM_TYPE = "com.canonical.unity.playback-item"; + public SoundMenu (string? settings_action, DisplayFlags flags) { /* A sound menu always has at least two sections: the volume section (this.volume_section) * at the start of the menu, and the settings section at the end. Between those two, @@ -68,6 +77,7 @@ public class SoundMenu: Object this.hide_players = (flags & DisplayFlags.HIDE_PLAYERS) != 0; this.hide_inactive = (flags & DisplayFlags.HIDE_INACTIVE_PLAYERS) != 0; + this.hide_inactive_player_controls = (flags & DisplayFlags.HIDE_INACTIVE_PLAYERS_PLAY_CONTROLS) != 0; this.notify_handlers = new HashTable (direct_hash, direct_equal); this.greeter_players = (flags & DisplayFlags.GREETER_PLAYERS) != 0; @@ -148,6 +158,15 @@ public class SoundMenu: Object return -1; } + public void update_all_players_play_section() { + foreach (var player_stored in notify_handlers.get_keys ()) { + int index = this.find_player_section(player_stored); + if (index != -1) { + // just update to verify if we must hide the player controls + update_player_section (player_stored, index); + } + } + } public void add_player (MediaPlayer player) { if (this.notify_handlers.contains (player)) @@ -158,21 +177,32 @@ public class SoundMenu: Object this.update_playlists (player); var handler_id = player.notify["is-running"].connect ( () => { + int index = this.find_player_section(player); if (player.is_running) { - int index = this.find_player_section(player); if (index == -1) { this.insert_player_section (player); } else { update_player_section (player, index); } + number_of_running_players++; } else { + number_of_running_players--; if (this.hide_inactive) this.remove_player_section (player); + else { + if (index != -1) { + // just update to verify if we must hide the player controls + update_player_section (player, index); + } + } } - this.update_playlists (player); + + // we need to update the rest of players, because we might have + // a non running player still showing the playback controls + update_all_players_play_section(); }); this.notify_handlers.insert (player, handler_id); @@ -239,8 +269,10 @@ public class SoundMenu: Object bool high_volume_warning_shown = false; bool hide_inactive; bool hide_players = false; + bool hide_inactive_player_controls = false; HashTable notify_handlers; bool greeter_players = false; + int number_of_running_players = 0; /* returns the position in this.menu of the section that's associated with @player */ int find_player_section (MediaPlayer player) { @@ -261,9 +293,24 @@ public class SoundMenu: Object return -1; } + int find_player_playback_controls_section (Menu player_menu) { + int n = player_menu.get_n_items (); + for (int i = 0; i < n; i++) { + string type; + player_menu.get_item_attribute (i, "x-canonical-type", "s", out type); + if (type == PLAYBACK_ITEM_TYPE) + return i; + } + + return -1; + } + MenuItem create_playback_menu_item (MediaPlayer player) { var playback_item = new MenuItem (null, null); playback_item.set_attribute ("x-canonical-type", "s", "com.canonical.unity.playback-item"); + playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id + ".disabled"); + playback_item.set_attribute ("x-canonical-next-action", "s", "indicator.next." + player.id + ".disabled"); + playback_item.set_attribute ("x-canonical-previous-action", "s", "indicator.previous." + player.id + ".disabled"); if (player.is_running) { if (player.can_do_play) { playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id); @@ -301,24 +348,10 @@ public class SoundMenu: Object player_item.set_attribute_value ("icon", icon.serialize ()); section.append_item (player_item); - var playback_item = new MenuItem (null, null); - playback_item.set_attribute ("x-canonical-type", "s", "com.canonical.unity.playback-item"); - playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id + ".disabled"); - playback_item.set_attribute ("x-canonical-next-action", "s", "indicator.next." + player.id + ".disabled"); - playback_item.set_attribute ("x-canonical-previous-action", "s", "indicator.previous." + player.id + ".disabled"); - - if (player.is_running) { - if (player.can_do_play) { - playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id); - } - if (player.can_do_next) { - playback_item.set_attribute ("x-canonical-next-action", "s", "indicator.next." + player.id); - } - if (player.can_do_prev) { - playback_item.set_attribute ("x-canonical-previous-action", "s", "indicator.previous." + player.id); - } + var playback_item = create_playback_menu_item (player); + if (player.is_running|| !this.hide_inactive_player_controls) { + section.insert_item (PlayerSectionPosistion.PLAYER_CONTROLS, playback_item); } - section.append_item (playback_item); /* Add new players to the end of the player sections, just before the settings */ if (settings_shown) { @@ -339,12 +372,21 @@ public class SoundMenu: Object void update_player_section (MediaPlayer player, int index) { var player_section = this.menu.get_item_link(index, Menu.LINK_SECTION) as Menu; - if (player_section.get_n_items () == 2) { - // we have 2 items, the second one is the playback item - // remove it first - player_section.remove (1); + + int play_control_index = find_player_playback_controls_section (player_section); + if (player.is_running || !this.hide_inactive_player_controls) { MenuItem playback_item = create_playback_menu_item (player); - player_section.append_item (playback_item); + if (play_control_index != -1) { + player_section.remove (PlayerSectionPosistion.PLAYER_CONTROLS); + } + player_section.insert_item (PlayerSectionPosistion.PLAYER_CONTROLS, playback_item); + } else { + if (play_control_index != -1 && number_of_running_players >= 1) { + warning("REMOVING SECTION number of running players: %d", number_of_running_players); + // remove both, playlist and play controls + player_section.remove (PlayerSectionPosistion.PLAYLIST); + player_section.remove (PlayerSectionPosistion.PLAYER_CONTROLS); + } } } -- cgit v1.2.3 From 12715ce7e03fec9544d7261c87aa9ddaa39b75ad Mon Sep 17 00:00:00 2001 From: Xavi Garcia Mena Date: Fri, 29 Jan 2016 12:16:34 +0100 Subject: added integration tests for adding/removing players and playback controls --- src/sound-menu.vala | 3 - tests/integration/indicator-sound-test-base.cpp | 43 +- tests/integration/indicator-sound-test-base.h | 9 + tests/integration/test-indicator.cpp | 568 +++++++++++++++++++++ .../applications/testplayer2.desktop | 21 + .../applications/testplayer3.desktop | 21 + tests/sound-menu.cc | 16 - 7 files changed, 659 insertions(+), 22 deletions(-) create mode 100644 tests/service-mocks/media-player-mpris-mock/applications/testplayer2.desktop create mode 100644 tests/service-mocks/media-player-mpris-mock/applications/testplayer3.desktop diff --git a/src/sound-menu.vala b/src/sound-menu.vala index fde1a6c..d100be1 100644 --- a/src/sound-menu.vala +++ b/src/sound-menu.vala @@ -308,9 +308,6 @@ public class SoundMenu: Object MenuItem create_playback_menu_item (MediaPlayer player) { var playback_item = new MenuItem (null, null); playback_item.set_attribute ("x-canonical-type", "s", "com.canonical.unity.playback-item"); - playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id + ".disabled"); - playback_item.set_attribute ("x-canonical-next-action", "s", "indicator.next." + player.id + ".disabled"); - playback_item.set_attribute ("x-canonical-previous-action", "s", "indicator.previous." + player.id + ".disabled"); if (player.is_running) { if (player.can_do_play) { playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id); diff --git a/tests/integration/indicator-sound-test-base.cpp b/tests/integration/indicator-sound-test-base.cpp index 91abf42..f61857e 100644 --- a/tests/integration/indicator-sound-test-base.cpp +++ b/tests/integration/indicator-sound-test-base.cpp @@ -192,16 +192,53 @@ bool IndicatorSoundTestBase::runProcess(QProcess& proc) bool IndicatorSoundTestBase::startTestMprisPlayer(QString const& playerName) { - testPlayer1.terminate(); - testPlayer1.start(MEDIA_PLAYER_MPRIS_BIN, QStringList() + if (!stopTestMprisPlayer(playerName)) + { + return false; + } + TestPlayer player; + player.name = playerName; + player.process.reset(new QProcess()); + player.process->start(MEDIA_PLAYER_MPRIS_BIN, QStringList() << playerName); - if (!testPlayer1.waitForStarted()) + if (!player.process->waitForStarted()) + { + qWarning() << "ERROR STARTING PLAYER " << playerName; return false; + } + testPlayers.push_back(player); return true; } +bool IndicatorSoundTestBase::stopTestMprisPlayer(QString const& playerName) +{ + bool terminateOK = true; + int index = findRunningTestMprisPlayer(playerName); + if (index != -1) + { + testPlayers[index].process->terminate(); + if (!testPlayers[index].process->waitForFinished()) + terminateOK = false; + testPlayers.remove(index); + } + + return terminateOK; +} + +int IndicatorSoundTestBase::findRunningTestMprisPlayer(QString const& playerName) +{ + for (int i = 0; i < testPlayers.size(); i++) + { + if (testPlayers.at(i).name == playerName) + { + return i; + } + } + return -1; +} + bool IndicatorSoundTestBase::setTestMprisPlayerProperty(QString const &testPlayer, QString const &property, bool value) { QProcess setProperty; diff --git a/tests/integration/indicator-sound-test-base.h b/tests/integration/indicator-sound-test-base.h index d9d3289..969fd69 100644 --- a/tests/integration/indicator-sound-test-base.h +++ b/tests/integration/indicator-sound-test-base.h @@ -81,6 +81,8 @@ protected: bool runProcess(QProcess&); bool startTestMprisPlayer(QString const& playerName); + bool stopTestMprisPlayer(QString const& playerName); + int findRunningTestMprisPlayer(QString const& playerName); bool setTestMprisPlayerProperty(QString const &testPlayer, QString const &property, bool value); @@ -156,6 +158,13 @@ protected: QProcess testPlayer1; + struct TestPlayer + { + std::shared_ptr process; + QString name; + }; + QVector testPlayers; + std::unique_ptr menu_interface_; std::unique_ptr accounts_interface_; diff --git a/tests/integration/test-indicator.cpp b/tests/integration/test-indicator.cpp index 9224b73..050c306 100644 --- a/tests/integration/test-indicator.cpp +++ b/tests/integration/test-indicator.cpp @@ -367,6 +367,574 @@ TEST_F(TestIndicator, DesktopAddMprisPlayer) .label("Sound Settings…") ) ).match()); + + // stop the test player + EXPECT_TRUE(stopTestMprisPlayer("testplayer1")); + + EXPECT_MATCHRESULT(mh::MenuMatcher(desktopParameters()) + .item(mh::MenuItemMatcher() + .action("indicator.root") + .string_attribute("x-canonical-type", "com.canonical.indicator.root") + .string_attribute("x-canonical-secondary-action", "indicator.mute") + .mode(mh::MenuItemMatcher::Mode::all) + .submenu() + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher().checkbox() + .label("Mute") + ) + .item(volumeSlider(INITIAL_VOLUME, "Volume")) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer1.desktop") + .label("TestPlayer1") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + .item(mh::MenuItemMatcher() + .string_attribute("x-canonical-previous-action","indicator.previous.testplayer1.desktop") + .string_attribute("x-canonical-play-action","indicator.play.testplayer1.desktop") + .string_attribute("x-canonical-next-action","indicator.next.testplayer1.desktop") + .string_attribute("x-canonical-type","com.canonical.unity.playback-item") + ) + ) + .item(mh::MenuItemMatcher() + .label("Sound Settings…") + ) + ).match()); +} + +TEST_F(TestIndicator, DesktopMprisPlayersPlaybackControls) +{ + double INITIAL_VOLUME = 0.0; + + ASSERT_NO_THROW(startAccountsService()); + EXPECT_TRUE(clearGSettingsPlayers()); + ASSERT_NO_THROW(startPulseDesktop()); + + // initialize volumes in pulseaudio + EXPECT_FALSE(setStreamRestoreVolume("alert", INITIAL_VOLUME)); + EXPECT_TRUE(setSinkVolume(INITIAL_VOLUME)); + + // start the test player + EXPECT_TRUE(startTestMprisPlayer("testplayer1")); + + // start now the indicator, so it picks the new volumes + ASSERT_NO_THROW(startIndicator()); + + // check that the player is added + EXPECT_MATCHRESULT(mh::MenuMatcher(desktopParameters()) + .item(mh::MenuItemMatcher() + .action("indicator.root") + .string_attribute("x-canonical-type", "com.canonical.indicator.root") + .string_attribute("x-canonical-secondary-action", "indicator.mute") + .mode(mh::MenuItemMatcher::Mode::all) + .submenu() + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher().checkbox() + .label("Mute") + ) + .item(volumeSlider(INITIAL_VOLUME, "Volume")) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer1.desktop") + .label("TestPlayer1") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + .item(mh::MenuItemMatcher() + .string_attribute("x-canonical-previous-action","indicator.previous.testplayer1.desktop") + .string_attribute("x-canonical-play-action","indicator.play.testplayer1.desktop") + .string_attribute("x-canonical-next-action","indicator.next.testplayer1.desktop") + .string_attribute("x-canonical-type","com.canonical.unity.playback-item") + ) + ) + .item(mh::MenuItemMatcher() + .label("Sound Settings…") + ) + ).match()); + + // start the second test player + EXPECT_TRUE(startTestMprisPlayer("testplayer2")); + + // check that the player is added + EXPECT_MATCHRESULT(mh::MenuMatcher(desktopParameters()) + .item(mh::MenuItemMatcher() + .action("indicator.root") + .string_attribute("x-canonical-type", "com.canonical.indicator.root") + .string_attribute("x-canonical-secondary-action", "indicator.mute") + .mode(mh::MenuItemMatcher::Mode::all) + .submenu() + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher().checkbox() + .label("Mute") + ) + .item(volumeSlider(INITIAL_VOLUME, "Volume")) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer1.desktop") + .label("TestPlayer1") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + .item(mh::MenuItemMatcher() + .string_attribute("x-canonical-previous-action","indicator.previous.testplayer1.desktop") + .string_attribute("x-canonical-play-action","indicator.play.testplayer1.desktop") + .string_attribute("x-canonical-next-action","indicator.next.testplayer1.desktop") + .string_attribute("x-canonical-type","com.canonical.unity.playback-item") + ) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer2.desktop") + .label("TestPlayer2") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + .item(mh::MenuItemMatcher() + .string_attribute("x-canonical-previous-action","indicator.previous.testplayer2.desktop") + .string_attribute("x-canonical-play-action","indicator.play.testplayer2.desktop") + .string_attribute("x-canonical-next-action","indicator.next.testplayer2.desktop") + .string_attribute("x-canonical-type","com.canonical.unity.playback-item") + ) + ) + .item(mh::MenuItemMatcher() + .label("Sound Settings…") + ) + ).match()); + + // start the third test player + EXPECT_TRUE(startTestMprisPlayer("testplayer3")); + + // check that the player is added + EXPECT_MATCHRESULT(mh::MenuMatcher(desktopParameters()) + .item(mh::MenuItemMatcher() + .action("indicator.root") + .string_attribute("x-canonical-type", "com.canonical.indicator.root") + .string_attribute("x-canonical-secondary-action", "indicator.mute") + .mode(mh::MenuItemMatcher::Mode::all) + .submenu() + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher().checkbox() + .label("Mute") + ) + .item(volumeSlider(INITIAL_VOLUME, "Volume")) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer1.desktop") + .label("TestPlayer1") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + .item(mh::MenuItemMatcher() + .string_attribute("x-canonical-previous-action","indicator.previous.testplayer1.desktop") + .string_attribute("x-canonical-play-action","indicator.play.testplayer1.desktop") + .string_attribute("x-canonical-next-action","indicator.next.testplayer1.desktop") + .string_attribute("x-canonical-type","com.canonical.unity.playback-item") + ) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer2.desktop") + .label("TestPlayer2") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + .item(mh::MenuItemMatcher() + .string_attribute("x-canonical-previous-action","indicator.previous.testplayer2.desktop") + .string_attribute("x-canonical-play-action","indicator.play.testplayer2.desktop") + .string_attribute("x-canonical-next-action","indicator.next.testplayer2.desktop") + .string_attribute("x-canonical-type","com.canonical.unity.playback-item") + ) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer3.desktop") + .label("TestPlayer3") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + .item(mh::MenuItemMatcher() + .string_attribute("x-canonical-previous-action","indicator.previous.testplayer3.desktop") + .string_attribute("x-canonical-play-action","indicator.play.testplayer3.desktop") + .string_attribute("x-canonical-next-action","indicator.next.testplayer3.desktop") + .string_attribute("x-canonical-type","com.canonical.unity.playback-item") + ) + ) + .item(mh::MenuItemMatcher() + .label("Sound Settings…") + ) + ).match()); + + // stop the test player + EXPECT_TRUE(stopTestMprisPlayer("testplayer3")); + + // check that player 3 is present, but it has no playback controls + EXPECT_MATCHRESULT(mh::MenuMatcher(desktopParameters()) + .item(mh::MenuItemMatcher() + .action("indicator.root") + .string_attribute("x-canonical-type", "com.canonical.indicator.root") + .string_attribute("x-canonical-secondary-action", "indicator.mute") + .mode(mh::MenuItemMatcher::Mode::all) + .submenu() + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher().checkbox() + .label("Mute") + ) + .item(volumeSlider(INITIAL_VOLUME, "Volume")) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer1.desktop") + .label("TestPlayer1") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + .item(mh::MenuItemMatcher() + .string_attribute("x-canonical-previous-action","indicator.previous.testplayer1.desktop") + .string_attribute("x-canonical-play-action","indicator.play.testplayer1.desktop") + .string_attribute("x-canonical-next-action","indicator.next.testplayer1.desktop") + .string_attribute("x-canonical-type","com.canonical.unity.playback-item") + ) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer2.desktop") + .label("TestPlayer2") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + .item(mh::MenuItemMatcher() + .string_attribute("x-canonical-previous-action","indicator.previous.testplayer2.desktop") + .string_attribute("x-canonical-play-action","indicator.play.testplayer2.desktop") + .string_attribute("x-canonical-next-action","indicator.next.testplayer2.desktop") + .string_attribute("x-canonical-type","com.canonical.unity.playback-item") + ) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer3.desktop") + .label("TestPlayer3") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + ) + .item(mh::MenuItemMatcher() + .label("Sound Settings…") + ) + ).match()); + + EXPECT_TRUE(stopTestMprisPlayer("testplayer2")); + + // check that player 2 is present, but it has no playback controls + EXPECT_MATCHRESULT(mh::MenuMatcher(desktopParameters()) + .item(mh::MenuItemMatcher() + .action("indicator.root") + .string_attribute("x-canonical-type", "com.canonical.indicator.root") + .string_attribute("x-canonical-secondary-action", "indicator.mute") + .mode(mh::MenuItemMatcher::Mode::all) + .submenu() + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher().checkbox() + .label("Mute") + ) + .item(volumeSlider(INITIAL_VOLUME, "Volume")) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer1.desktop") + .label("TestPlayer1") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + .item(mh::MenuItemMatcher() + .string_attribute("x-canonical-previous-action","indicator.previous.testplayer1.desktop") + .string_attribute("x-canonical-play-action","indicator.play.testplayer1.desktop") + .string_attribute("x-canonical-next-action","indicator.next.testplayer1.desktop") + .string_attribute("x-canonical-type","com.canonical.unity.playback-item") + ) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer2.desktop") + .label("TestPlayer2") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer3.desktop") + .label("TestPlayer3") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + ) + .item(mh::MenuItemMatcher() + .label("Sound Settings…") + ) + ).match()); + + EXPECT_TRUE(stopTestMprisPlayer("testplayer1")); + + // check that player 1 is present, and it still has the playback controls + // as it was the last one being executed + EXPECT_MATCHRESULT(mh::MenuMatcher(desktopParameters()) + .item(mh::MenuItemMatcher() + .action("indicator.root") + .string_attribute("x-canonical-type", "com.canonical.indicator.root") + .string_attribute("x-canonical-secondary-action", "indicator.mute") + .mode(mh::MenuItemMatcher::Mode::all) + .submenu() + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher().checkbox() + .label("Mute") + ) + .item(volumeSlider(INITIAL_VOLUME, "Volume")) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer1.desktop") + .label("TestPlayer1") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + .item(mh::MenuItemMatcher() + .string_attribute("x-canonical-previous-action","indicator.previous.testplayer1.desktop") + .string_attribute("x-canonical-play-action","indicator.play.testplayer1.desktop") + .string_attribute("x-canonical-next-action","indicator.next.testplayer1.desktop") + .string_attribute("x-canonical-type","com.canonical.unity.playback-item") + ) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer2.desktop") + .label("TestPlayer2") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer3.desktop") + .label("TestPlayer3") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + ) + .item(mh::MenuItemMatcher() + .label("Sound Settings…") + ) + ).match()); + + // start the third test player + EXPECT_TRUE(startTestMprisPlayer("testplayer3")); + + // check that player 3 is the only one with playback controls + EXPECT_MATCHRESULT(mh::MenuMatcher(desktopParameters()) + .item(mh::MenuItemMatcher() + .action("indicator.root") + .string_attribute("x-canonical-type", "com.canonical.indicator.root") + .string_attribute("x-canonical-secondary-action", "indicator.mute") + .mode(mh::MenuItemMatcher::Mode::all) + .submenu() + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher().checkbox() + .label("Mute") + ) + .item(volumeSlider(INITIAL_VOLUME, "Volume")) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer1.desktop") + .label("TestPlayer1") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer2.desktop") + .label("TestPlayer2") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer3.desktop") + .label("TestPlayer3") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + .item(mh::MenuItemMatcher() + .string_attribute("x-canonical-previous-action","indicator.previous.testplayer3.desktop") + .string_attribute("x-canonical-play-action","indicator.play.testplayer3.desktop") + .string_attribute("x-canonical-next-action","indicator.next.testplayer3.desktop") + .string_attribute("x-canonical-type","com.canonical.unity.playback-item") + ) + ) + .item(mh::MenuItemMatcher() + .label("Sound Settings…") + ) + ).match()); + + // start the rest of players + EXPECT_TRUE(startTestMprisPlayer("testplayer1")); + EXPECT_TRUE(startTestMprisPlayer("testplayer2")); + + EXPECT_MATCHRESULT(mh::MenuMatcher(desktopParameters()) + .item(mh::MenuItemMatcher() + .action("indicator.root") + .string_attribute("x-canonical-type", "com.canonical.indicator.root") + .string_attribute("x-canonical-secondary-action", "indicator.mute") + .mode(mh::MenuItemMatcher::Mode::all) + .submenu() + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher().checkbox() + .label("Mute") + ) + .item(volumeSlider(INITIAL_VOLUME, "Volume")) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer1.desktop") + .label("TestPlayer1") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + .item(mh::MenuItemMatcher() + .string_attribute("x-canonical-previous-action","indicator.previous.testplayer1.desktop") + .string_attribute("x-canonical-play-action","indicator.play.testplayer1.desktop") + .string_attribute("x-canonical-next-action","indicator.next.testplayer1.desktop") + .string_attribute("x-canonical-type","com.canonical.unity.playback-item") + ) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer2.desktop") + .label("TestPlayer2") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + .item(mh::MenuItemMatcher() + .string_attribute("x-canonical-previous-action","indicator.previous.testplayer2.desktop") + .string_attribute("x-canonical-play-action","indicator.play.testplayer2.desktop") + .string_attribute("x-canonical-next-action","indicator.next.testplayer2.desktop") + .string_attribute("x-canonical-type","com.canonical.unity.playback-item") + ) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer3.desktop") + .label("TestPlayer3") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + .item(mh::MenuItemMatcher() + .string_attribute("x-canonical-previous-action","indicator.previous.testplayer3.desktop") + .string_attribute("x-canonical-play-action","indicator.play.testplayer3.desktop") + .string_attribute("x-canonical-next-action","indicator.next.testplayer3.desktop") + .string_attribute("x-canonical-type","com.canonical.unity.playback-item") + ) + ) + .item(mh::MenuItemMatcher() + .label("Sound Settings…") + ) + ).match()); + + // stop all players + EXPECT_TRUE(stopTestMprisPlayer("testplayer1")); + EXPECT_TRUE(stopTestMprisPlayer("testplayer2")); + EXPECT_TRUE(stopTestMprisPlayer("testplayer3")); + + // check that player 3 is the only one with playback controls + // as it was the last one being stopped + EXPECT_MATCHRESULT(mh::MenuMatcher(desktopParameters()) + .item(mh::MenuItemMatcher() + .action("indicator.root") + .string_attribute("x-canonical-type", "com.canonical.indicator.root") + .string_attribute("x-canonical-secondary-action", "indicator.mute") + .mode(mh::MenuItemMatcher::Mode::all) + .submenu() + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher().checkbox() + .label("Mute") + ) + .item(volumeSlider(INITIAL_VOLUME, "Volume")) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer1.desktop") + .label("TestPlayer1") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer2.desktop") + .label("TestPlayer2") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + ) + .item(mh::MenuItemMatcher() + .section() + .item(mh::MenuItemMatcher() + .action("indicator.testplayer3.desktop") + .label("TestPlayer3") + .themed_icon("icon", {"testplayer"}) + .string_attribute("x-canonical-type", "com.canonical.unity.media-player") + ) + .item(mh::MenuItemMatcher() + .string_attribute("x-canonical-previous-action","indicator.previous.testplayer3.desktop") + .string_attribute("x-canonical-play-action","indicator.play.testplayer3.desktop") + .string_attribute("x-canonical-next-action","indicator.next.testplayer3.desktop") + .string_attribute("x-canonical-type","com.canonical.unity.playback-item") + ) + ) + .item(mh::MenuItemMatcher() + .label("Sound Settings…") + ) + ).match()); } TEST_F(TestIndicator, DesktopMprisPlayerButtonsState) diff --git a/tests/service-mocks/media-player-mpris-mock/applications/testplayer2.desktop b/tests/service-mocks/media-player-mpris-mock/applications/testplayer2.desktop new file mode 100644 index 0000000..579a0bf --- /dev/null +++ b/tests/service-mocks/media-player-mpris-mock/applications/testplayer2.desktop @@ -0,0 +1,21 @@ +[Desktop Entry] +Name=TestPlayer2 +GenericName=Test Player 2 +X-GNOME-FullName=Test Player 2 +Comment=Play and organize your music collection +Keywords=Audio;Song;MP3;CD;Podcast;MTP;iPod;Playlist;Last.fm;UPnP;DLNA;Radio; +Exec=echo %U +Terminal=false +Type=Application +Icon=testplayer +X-GNOME-DocPath=testplayer/testplayer.xml +Categories=GNOME;GTK;AudioVideo;Audio;Player; +MimeType=application/x-ogg;application/ogg;audio/x-vorbis+ogg;audio/x-scpls;audio/x-mp3;audio/x-mpeg;audio/mpeg;audio/x-mpegurl;audio/x-flac;audio/mp4;x-scheme-handler/itms;x-scheme-handler/itmss; +StartupNotify=true +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=testplayer +X-GNOME-Bugzilla-Component=general +X-GNOME-Bugzilla-OtherBinaries=rhythmbox-client;rhythmbox-metadata; +X-GNOME-Bugzilla-Version=3.1 +X-GNOME-UsesNotifications=true + diff --git a/tests/service-mocks/media-player-mpris-mock/applications/testplayer3.desktop b/tests/service-mocks/media-player-mpris-mock/applications/testplayer3.desktop new file mode 100644 index 0000000..b3bfc6b --- /dev/null +++ b/tests/service-mocks/media-player-mpris-mock/applications/testplayer3.desktop @@ -0,0 +1,21 @@ +[Desktop Entry] +Name=TestPlayer3 +GenericName=Test Player 3 +X-GNOME-FullName=Test Player 3 +Comment=Play and organize your music collection +Keywords=Audio;Song;MP3;CD;Podcast;MTP;iPod;Playlist;Last.fm;UPnP;DLNA;Radio; +Exec=echo %U +Terminal=false +Type=Application +Icon=testplayer +X-GNOME-DocPath=testplayer/testplayer.xml +Categories=GNOME;GTK;AudioVideo;Audio;Player; +MimeType=application/x-ogg;application/ogg;audio/x-vorbis+ogg;audio/x-scpls;audio/x-mp3;audio/x-mpeg;audio/mpeg;audio/x-mpegurl;audio/x-flac;audio/mp4;x-scheme-handler/itms;x-scheme-handler/itmss; +StartupNotify=true +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=testplayer +X-GNOME-Bugzilla-Component=general +X-GNOME-Bugzilla-OtherBinaries=rhythmbox-client;rhythmbox-metadata; +X-GNOME-Bugzilla-Version=3.1 +X-GNOME-UsesNotifications=true + diff --git a/tests/sound-menu.cc b/tests/sound-menu.cc index 75a661b..9f0181c 100644 --- a/tests/sound-menu.cc +++ b/tests/sound-menu.cc @@ -170,20 +170,4 @@ TEST_F(SoundMenuTest, AddRemovePlayer) { return; } -TEST_F(SoundMenuTest, AddRemovePlayerNoPlayNextPrev) { - check_player_control_buttons(false, false, false); -} - -TEST_F(SoundMenuTest, AddRemovePlayerNoNext) { - check_player_control_buttons(true, false, true); -} - -TEST_F(SoundMenuTest, AddRemovePlayerNoPrev) { - check_player_control_buttons(true, true, false); -} - -TEST_F(SoundMenuTest, AddRemovePlayerNoPlay) { - check_player_control_buttons(false, true, true); -} - // -- cgit v1.2.3