Merge lp:~xavi-garcia-mena/indicator-sound/next-play-prev-buttons-bug-1373313 into lp:indicator-sound/15.10

Proposed by Xavi Garcia
Status: Merged
Approved by: Charles Kerr
Approved revision: 506
Merged at revision: 506
Proposed branch: lp:~xavi-garcia-mena/indicator-sound/next-play-prev-buttons-bug-1373313
Merge into: lp:indicator-sound/15.10
Diff against target: 538 lines (+275/-91)
7 files modified
debian/changelog (+24/-6)
src/media-player-mpris.vala (+22/-0)
src/media-player.vala (+4/-0)
src/mpris2-interfaces.vala (+4/-1)
src/sound-menu.vala (+61/-6)
tests/media-player-mock.vala (+6/-0)
tests/sound-menu.cc (+154/-78)
To merge this branch: bzr merge lp:~xavi-garcia-mena/indicator-sound/next-play-prev-buttons-bug-1373313
Reviewer Review Type Date Requested Status
Charles Kerr (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+271114@code.launchpad.net

Commit message

Synchronize the state of the Previous/Play/Next buttons with the state obtained from MPRIS.

The state is updated every time the properties are modified.

Description of the change

Synchronize the state of the Previous/Play/Next buttons with the state obtained from MPRIS.

The state is updated every time the properties are modified.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Charles Kerr (charlesk) wrote :

Mostly looks good. A couple of questions inline below.

review: Needs Information
505. By Xavi Garcia

Unit tests refactored

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
506. By Xavi Garcia

merged with trunk

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Charles Kerr (charlesk) wrote :

Thanks for the test changes, Xavi. LGTM.

review: Approve
507. By Xavi Garcia

Fixed property name when checking if CanGoPrevious changed

508. By Xavi Garcia

Fixed version in changelog

509. By Xavi Garcia

Updating MPRIS control in the menu not only when next and previous are updated

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2015-09-15 08:19:51 +0000
3+++ debian/changelog 2015-10-14 14:58:07 +0000
4@@ -1,4 +1,11 @@
5-indicator-sound (12.10.2+15.10.20150915-0ubuntu1) wily; urgency=medium
6+indicator-sound (12.10.2+15.04.20150917-0ubuntu1) vivid; urgency=medium
7+
8+ [ Xavi Garcia Mena ]
9+ * Merged lp:~xavi-garcia-mena/indicator-sound/icon-volume-zero
10+
11+ -- Sebastien Bacher <seb128@ubuntu.com> Tue, 15 Sep 2015 08:19:51 +0000
12+
13+indicator-sound (12.10.2+15.04.20150915-0ubuntu1) vivid; urgency=medium
14
15 [ Sebastien Bacher ]
16 * under unity8 start system-settings instead unity-control-center (LP:
17@@ -9,7 +16,7 @@
18
19 -- Sebastien Bacher <seb128@ubuntu.com> Tue, 15 Sep 2015 08:19:51 +0000
20
21-indicator-sound (12.10.2+15.10.20150812.3-0ubuntu1) wily; urgency=medium
22+indicator-sound (12.10.2+15.04.20150812.3-0ubuntu1) vivid; urgency=medium
23
24 [ CI Train Bot ]
25 * New rebuild forced.
26@@ -20,7 +27,7 @@
27
28 -- CI Train Bot <ci-train-bot@canonical.com> Wed, 12 Aug 2015 20:55:05 +0000
29
30-indicator-sound (12.10.2+15.10.20150807.6-0ubuntu1) wily; urgency=medium
31+indicator-sound (12.10.2+15.04.20150807.6-0ubuntu1) vivid; urgency=medium
32
33 [ CI Train Bot ]
34 * New rebuild forced.
35@@ -31,19 +38,19 @@
36
37 -- CI Train Bot <ci-train-bot@canonical.com> Fri, 07 Aug 2015 22:35:58 +0000
38
39-indicator-sound (12.10.2+15.10.20150605-0ubuntu1) wily; urgency=medium
40+indicator-sound (12.10.2+15.04.20150605-0ubuntu1) vivid; urgency=medium
41
42 *
43
44 -- CI Train Bot <ci-train-bot@canonical.com> Fri, 05 Jun 2015 19:50:06 +0000
45
46-indicator-sound (12.10.2+15.10.20150507+eventually4-0ubuntu1) wily; urgency=medium
47+indicator-sound (12.10.2+15.04.20150507+eventually4-0ubuntu1) vivid; urgency=medium
48
49 * Using eventually to avoid arbitrary timeouts in tests
50
51 -- Ted Gould <ted@ubuntu.com> Wed, 27 May 2015 11:11:19 -0500
52
53-indicator-sound (12.10.2+15.10.20150507-0ubuntu1) wily; urgency=medium
54+indicator-sound (12.10.2+15.04.20150507-0ubuntu1) vivid; urgency=medium
55
56 [ Charles Kerr ]
57 * Use the BusWatcher to look for org.freedesktop.Notifications
58@@ -51,6 +58,17 @@
59
60 -- CI Train Bot <ci-train-bot@canonical.com> Thu, 07 May 2015 15:27:00 +0000
61
62+indicator-sound (12.10.2+15.04.20150508-0ubuntu1) vivid; urgency=medium
63+
64+ [ CI Train Bot ]
65+ * New rebuild forced.
66+
67+ [ Charles Kerr ]
68+ * Use the BusWatcher to look for org.freedesktop.Notifications
69+ ownership changes on the bus. (LP: #1432446)
70+
71+ -- CI Train Bot <ci-train-bot@canonical.com> Fri, 08 May 2015 12:20:07 +0000
72+
73 indicator-sound (12.10.2+15.04.20150421-0ubuntu1) vivid; urgency=medium
74
75 [ Ted Gould ]
76
77=== modified file 'src/media-player-mpris.vala'
78--- src/media-player-mpris.vala 2015-03-26 15:56:49 +0000
79+++ src/media-player-mpris.vala 2015-10-14 14:58:07 +0000
80@@ -79,6 +79,24 @@
81 }
82 }
83
84+ public override bool can_do_play {
85+ get {
86+ return this.proxy.CanPlay;
87+ }
88+ }
89+
90+ public override bool can_do_prev {
91+ get {
92+ return this.proxy.CanGoPrevious;
93+ }
94+ }
95+
96+ public override bool can_do_next {
97+ get {
98+ return this.proxy.CanGoNext;
99+ }
100+ }
101+
102 /**
103 * Attach this object to a process of the associated media player. The player must own @dbus_name and
104 * implement the org.mpris.MediaPlayer2.Player interface.
105@@ -272,6 +290,10 @@
106 if (changed_properties.lookup ("PlaybackStatus", "s", null)) {
107 this.state = this.proxy.PlaybackStatus != null ? this.proxy.PlaybackStatus : "Unknown";
108 }
109+ if (changed_properties.lookup ("CanGoNext", "b", null) || changed_properties.lookup ("CanGoPrevious", "b", null) ||
110+ changed_properties.lookup ("CanPlay", "b", null) || changed_properties.lookup ("CanPause", "b", null)) {
111+ this.playbackstatus_changed ();
112+ }
113
114 var metadata = changed_properties.lookup_value ("Metadata", new VariantType ("a{sv}"));
115 if (metadata != null)
116
117=== modified file 'src/media-player.vala'
118--- src/media-player.vala 2014-02-12 16:21:32 +0000
119+++ src/media-player.vala 2015-10-14 14:58:07 +0000
120@@ -26,6 +26,9 @@
121
122 public virtual bool is_running { get { not_implemented(); return false; } }
123 public virtual bool can_raise { get { not_implemented(); return false; } }
124+ public virtual bool can_do_next { get { not_implemented(); return false; } }
125+ public virtual bool can_do_prev { get { not_implemented(); return false; } }
126+ public virtual bool can_do_play { get { not_implemented(); return false; } }
127
128 public class Track : Object {
129 public string artist { get; construct; }
130@@ -44,6 +47,7 @@
131 }
132
133 public signal void playlists_changed ();
134+ public signal void playbackstatus_changed ();
135
136 public abstract void activate ();
137 public abstract void play_pause ();
138
139=== modified file 'src/mpris2-interfaces.vala'
140--- src/mpris2-interfaces.vala 2015-03-26 15:56:49 +0000
141+++ src/mpris2-interfaces.vala 2015-10-14 14:58:07 +0000
142@@ -37,7 +37,10 @@
143 // properties
144 public abstract HashTable<string, Variant?> Metadata{owned get; set;}
145 public abstract int32 Position{owned get; set;}
146- public abstract string? PlaybackStatus{owned get; set;}
147+ public abstract string? PlaybackStatus{owned get; set;}
148+ public abstract bool CanPlay{owned get; set;}
149+ public abstract bool CanGoNext{owned get; set;}
150+ public abstract bool CanGoPrevious{owned get; set;}
151 // methods
152 public abstract async void PlayPause() throws IOError;
153 public abstract async void Next() throws IOError;
154
155=== modified file 'src/sound-menu.vala'
156--- src/sound-menu.vala 2015-02-12 00:44:34 +0000
157+++ src/sound-menu.vala 2015-10-14 14:58:07 +0000
158@@ -157,18 +157,26 @@
159 this.update_playlists (player);
160
161 var handler_id = player.notify["is-running"].connect ( () => {
162- if (player.is_running)
163- if (this.find_player_section(player) == -1)
164+ if (player.is_running) {
165+ int index = this.find_player_section(player);
166+ if (index == -1) {
167 this.insert_player_section (player);
168- else
169+ }
170+ else {
171+ update_player_section (player, index);
172+ }
173+ }
174+ else {
175 if (this.hide_inactive)
176 this.remove_player_section (player);
177+ }
178
179 this.update_playlists (player);
180 });
181 this.notify_handlers.insert (player, handler_id);
182
183 player.playlists_changed.connect (this.update_playlists);
184+ player.playbackstatus_changed.connect (this.update_playbackstatus);
185 }
186
187 public void remove_player (MediaPlayer player) {
188@@ -215,6 +223,23 @@
189 return -1;
190 }
191
192+ MenuItem create_playback_menu_item (MediaPlayer player) {
193+ var playback_item = new MenuItem (null, null);
194+ playback_item.set_attribute ("x-canonical-type", "s", "com.canonical.unity.playback-item");
195+ if (player.is_running) {
196+ if (player.can_do_play) {
197+ playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id);
198+ }
199+ if (player.can_do_next) {
200+ playback_item.set_attribute ("x-canonical-next-action", "s", "indicator.next." + player.id);
201+ }
202+ if (player.can_do_prev) {
203+ playback_item.set_attribute ("x-canonical-previous-action", "s", "indicator.previous." + player.id);
204+ }
205+ }
206+ return playback_item;
207+ }
208+
209 void insert_player_section (MediaPlayer player) {
210 if (this.hide_players)
211 return;
212@@ -240,9 +265,21 @@
213
214 var playback_item = new MenuItem (null, null);
215 playback_item.set_attribute ("x-canonical-type", "s", "com.canonical.unity.playback-item");
216- playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id);
217- playback_item.set_attribute ("x-canonical-next-action", "s", "indicator.next." + player.id);
218- playback_item.set_attribute ("x-canonical-previous-action", "s", "indicator.previous." + player.id);
219+ playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id + ".disabled");
220+ playback_item.set_attribute ("x-canonical-next-action", "s", "indicator.next." + player.id + ".disabled");
221+ playback_item.set_attribute ("x-canonical-previous-action", "s", "indicator.previous." + player.id + ".disabled");
222+
223+ if (player.is_running) {
224+ if (player.can_do_play) {
225+ playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id);
226+ }
227+ if (player.can_do_next) {
228+ playback_item.set_attribute ("x-canonical-next-action", "s", "indicator.next." + player.id);
229+ }
230+ if (player.can_do_prev) {
231+ playback_item.set_attribute ("x-canonical-previous-action", "s", "indicator.previous." + player.id);
232+ }
233+ }
234 section.append_item (playback_item);
235
236 /* Add new players to the end of the player sections, just before the settings */
237@@ -262,6 +299,17 @@
238 this.menu.remove (index);
239 }
240
241+ void update_player_section (MediaPlayer player, int index) {
242+ var player_section = this.menu.get_item_link(index, Menu.LINK_SECTION) as Menu;
243+ if (player_section.get_n_items () == 2) {
244+ // we have 2 items, the second one is the playback item
245+ // remove it first
246+ player_section.remove (1);
247+ MenuItem playback_item = create_playback_menu_item (player);
248+ player_section.append_item (playback_item);
249+ }
250+ }
251+
252 void update_playlists (MediaPlayer player) {
253 int index = find_player_section (player);
254 if (index < 0)
255@@ -292,6 +340,13 @@
256 submenu.append_section (null, playlists_section);
257 player_section.append_submenu (_("Choose Playlist"), submenu);
258 }
259+
260+ void update_playbackstatus (MediaPlayer player) {
261+ int index = find_player_section (player);
262+ if (index != -1) {
263+ update_player_section (player, index);
264+ }
265+ }
266
267 MenuItem create_slider_menu_item (string label, string action, double min, double max, double step, string min_icon_name, string max_icon_name) {
268 var min_icon = new ThemedIcon.with_default_fallbacks (min_icon_name);
269
270=== modified file 'tests/media-player-mock.vala'
271--- tests/media-player-mock.vala 2014-02-12 19:54:59 +0000
272+++ tests/media-player-mock.vala 2015-10-14 14:58:07 +0000
273@@ -28,6 +28,9 @@
274
275 public override bool is_running { get { return mock_is_running; } }
276 public override bool can_raise { get { return mock_can_raise; } }
277+ public override bool can_do_next { get { return mock_can_do_next; } }
278+ public override bool can_do_prev { get { return mock_can_do_prev; } }
279+ public override bool can_do_play { get { return mock_can_do_play; } }
280
281 public override MediaPlayer.Track? current_track { get { return mock_current_track; } set { this.mock_current_track = value; } }
282
283@@ -40,6 +43,9 @@
284
285 public bool mock_is_running { get; set; }
286 public bool mock_can_raise { get; set; }
287+ public bool mock_can_do_next { get; set; }
288+ public bool mock_can_do_prev { get; set; }
289+ public bool mock_can_do_play { get; set; }
290
291 public MediaPlayer.Track? mock_current_track { get; set; }
292
293
294=== modified file 'tests/sound-menu.cc'
295--- tests/sound-menu.cc 2014-03-03 21:38:38 +0000
296+++ tests/sound-menu.cc 2015-10-14 14:58:07 +0000
297@@ -27,87 +27,163 @@
298
299 class SoundMenuTest : public ::testing::Test
300 {
301- protected:
302- GTestDBus * bus = nullptr;
303-
304- virtual void SetUp() {
305- bus = g_test_dbus_new(G_TEST_DBUS_NONE);
306- g_test_dbus_up(bus);
307- }
308-
309- virtual void TearDown() {
310- g_test_dbus_down(bus);
311- g_clear_object(&bus);
312- }
313-
314- void verify_item_attribute (GMenuModel * mm, guint index, const gchar * name, GVariant * value) {
315- g_variant_ref_sink(value);
316-
317- gchar * variantstr = g_variant_print(value, TRUE);
318- g_debug("Expecting item %d to have a '%s' attribute: %s", index, name, variantstr);
319-
320- const GVariantType * type = g_variant_get_type(value);
321- GVariant * itemval = g_menu_model_get_item_attribute_value(mm, index, name, type);
322-
323- ASSERT_NE(nullptr, itemval);
324- EXPECT_TRUE(g_variant_equal(itemval, value));
325-
326- g_variant_unref(value);
327- }
328+ protected:
329+ GTestDBus * bus = nullptr;
330+
331+ virtual void SetUp() {
332+ bus = g_test_dbus_new(G_TEST_DBUS_NONE);
333+ g_test_dbus_up(bus);
334+ }
335+
336+ virtual void TearDown() {
337+ g_test_dbus_down(bus);
338+ g_clear_object(&bus);
339+ }
340+
341+ void verify_item_attribute (GMenuModel * mm, guint index, const gchar * name, GVariant * value) {
342+ g_variant_ref_sink(value);
343+
344+ gchar * variantstr = g_variant_print(value, TRUE);
345+ g_debug("Expecting item %d to have a '%s' attribute: %s", index, name, variantstr);
346+
347+ const GVariantType * type = g_variant_get_type(value);
348+ GVariant * itemval = g_menu_model_get_item_attribute_value(mm, index, name, type);
349+
350+ ASSERT_NE(nullptr, itemval);
351+ EXPECT_TRUE(g_variant_equal(itemval, value));
352+
353+ g_variant_unref(value);
354+ }
355+
356+ void verify_item_attribute_is_not_set(GMenuModel * mm, guint index, const gchar * name, const GVariantType * type) {
357+ GVariant * itemval = g_menu_model_get_item_attribute_value(mm, index, name, type);
358+ EXPECT_EQ(itemval, nullptr);
359+ }
360+
361+ void check_player_control_buttons(bool canPlay, bool canNext, bool canPrev)
362+ {
363+ SoundMenu * menu = sound_menu_new (nullptr, SOUND_MENU_DISPLAY_FLAGS_NONE);
364+
365+ MediaPlayerTrack * track = media_player_track_new("Artist", "Title", "Album", "http://art.url");
366+
367+ MediaPlayerMock * media = MEDIA_PLAYER_MOCK(
368+ g_object_new(TYPE_MEDIA_PLAYER_MOCK,
369+ "mock-id", "player-id",
370+ "mock-name", "Test Player",
371+ "mock-state", "Playing",
372+ "mock-is-running", TRUE,
373+ "mock-can-raise", FALSE,
374+ "mock-current-track", track,
375+ "mock-can-do-play", canPlay,
376+ "mock-can-do-next", canNext,
377+ "mock-can-do-prev", canPrev,
378+ NULL)
379+ );
380+ g_clear_object(&track);
381+
382+ sound_menu_add_player(menu, MEDIA_PLAYER(media));
383+
384+ ASSERT_NE(nullptr, menu->menu);
385+ EXPECT_EQ(2, g_menu_model_get_n_items(G_MENU_MODEL(menu->menu)));
386+
387+ GMenuModel * section = g_menu_model_get_item_link(G_MENU_MODEL(menu->menu), 1, G_MENU_LINK_SECTION);
388+ ASSERT_NE(nullptr, section);
389+ EXPECT_EQ(2, g_menu_model_get_n_items(section)); /* No playlists, so two items */
390+
391+ /* Player display */
392+ verify_item_attribute(section, 0, "action", g_variant_new_string("indicator.player-id"));
393+ verify_item_attribute(section, 0, "x-canonical-type", g_variant_new_string("com.canonical.unity.media-player"));
394+
395+ /* Player control */
396+ verify_item_attribute(section, 1, "x-canonical-type", g_variant_new_string("com.canonical.unity.playback-item"));
397+ verify_item_attribute(section, 1, "x-canonical-play-action", g_variant_new_string(canPlay ? "indicator.play.player-id" : "indicator.play.player-id.disabled"));
398+ verify_item_attribute(section, 1, "x-canonical-next-action", g_variant_new_string(canNext ? "indicator.next.player-id" : "indicator.next.player-id.disabled"));
399+ verify_item_attribute(section, 1, "x-canonical-previous-action", g_variant_new_string(canPrev ? "indicator.previous.player-id" : "indicator.previous.player-id.disabled"));
400+
401+ g_clear_object(&section);
402+
403+ sound_menu_remove_player(menu, MEDIA_PLAYER(media));
404+
405+ EXPECT_EQ(1, g_menu_model_get_n_items(G_MENU_MODEL(menu->menu)));
406+
407+ g_clear_object(&media);
408+ g_clear_object(&menu);
409+ }
410 };
411
412 TEST_F(SoundMenuTest, BasicObject) {
413- SoundMenu * menu = sound_menu_new (nullptr, SOUND_MENU_DISPLAY_FLAGS_NONE);
414-
415- ASSERT_NE(nullptr, menu);
416-
417- g_clear_object(&menu);
418- return;
419+ SoundMenu * menu = sound_menu_new (nullptr, SOUND_MENU_DISPLAY_FLAGS_NONE);
420+
421+ ASSERT_NE(nullptr, menu);
422+
423+ g_clear_object(&menu);
424+ return;
425 }
426
427 TEST_F(SoundMenuTest, AddRemovePlayer) {
428- SoundMenu * menu = sound_menu_new (nullptr, SOUND_MENU_DISPLAY_FLAGS_NONE);
429-
430- MediaPlayerTrack * track = media_player_track_new("Artist", "Title", "Album", "http://art.url");
431-
432- MediaPlayerMock * media = MEDIA_PLAYER_MOCK(
433- g_object_new(TYPE_MEDIA_PLAYER_MOCK,
434- "mock-id", "player-id",
435- "mock-name", "Test Player",
436- "mock-state", "Playing",
437- "mock-is-running", TRUE,
438- "mock-can-raise", FALSE,
439- "mock-current-track", track,
440- NULL)
441- );
442- g_clear_object(&track);
443-
444- sound_menu_add_player(menu, MEDIA_PLAYER(media));
445-
446- ASSERT_NE(nullptr, menu->menu);
447- EXPECT_EQ(2, g_menu_model_get_n_items(G_MENU_MODEL(menu->menu)));
448-
449- GMenuModel * section = g_menu_model_get_item_link(G_MENU_MODEL(menu->menu), 1, G_MENU_LINK_SECTION);
450- ASSERT_NE(nullptr, section);
451- EXPECT_EQ(2, g_menu_model_get_n_items(section)); /* No playlists, so two items */
452-
453- /* Player display */
454- verify_item_attribute(section, 0, "action", g_variant_new_string("indicator.player-id"));
455- verify_item_attribute(section, 0, "x-canonical-type", g_variant_new_string("com.canonical.unity.media-player"));
456-
457- /* Player control */
458- verify_item_attribute(section, 1, "x-canonical-type", g_variant_new_string("com.canonical.unity.playback-item"));
459- verify_item_attribute(section, 1, "x-canonical-play-action", g_variant_new_string("indicator.play.player-id"));
460- verify_item_attribute(section, 1, "x-canonical-next-action", g_variant_new_string("indicator.next.player-id"));
461- verify_item_attribute(section, 1, "x-canonical-previous-action", g_variant_new_string("indicator.previous.player-id"));
462-
463- g_clear_object(&section);
464-
465- sound_menu_remove_player(menu, MEDIA_PLAYER(media));
466-
467- EXPECT_EQ(1, g_menu_model_get_n_items(G_MENU_MODEL(menu->menu)));
468-
469- g_clear_object(&media);
470- g_clear_object(&menu);
471- return;
472-}
473+ SoundMenu * menu = sound_menu_new (nullptr, SOUND_MENU_DISPLAY_FLAGS_NONE);
474+
475+ MediaPlayerTrack * track = media_player_track_new("Artist", "Title", "Album", "http://art.url");
476+
477+ MediaPlayerMock * media = MEDIA_PLAYER_MOCK(
478+ g_object_new(TYPE_MEDIA_PLAYER_MOCK,
479+ "mock-id", "player-id",
480+ "mock-name", "Test Player",
481+ "mock-state", "Playing",
482+ "mock-is-running", TRUE,
483+ "mock-can-raise", FALSE,
484+ "mock-current-track", track,
485+ "mock-can-do-play", TRUE,
486+ "mock-can-do-next", TRUE,
487+ "mock-can-do-prev", TRUE,
488+ NULL)
489+ );
490+ g_clear_object(&track);
491+
492+ sound_menu_add_player(menu, MEDIA_PLAYER(media));
493+
494+ ASSERT_NE(nullptr, menu->menu);
495+ EXPECT_EQ(2, g_menu_model_get_n_items(G_MENU_MODEL(menu->menu)));
496+
497+ GMenuModel * section = g_menu_model_get_item_link(G_MENU_MODEL(menu->menu), 1, G_MENU_LINK_SECTION);
498+ ASSERT_NE(nullptr, section);
499+ EXPECT_EQ(2, g_menu_model_get_n_items(section)); /* No playlists, so two items */
500+
501+ /* Player display */
502+ verify_item_attribute(section, 0, "action", g_variant_new_string("indicator.player-id"));
503+ verify_item_attribute(section, 0, "x-canonical-type", g_variant_new_string("com.canonical.unity.media-player"));
504+
505+ /* Player control */
506+ verify_item_attribute(section, 1, "x-canonical-type", g_variant_new_string("com.canonical.unity.playback-item"));
507+ verify_item_attribute(section, 1, "x-canonical-play-action", g_variant_new_string("indicator.play.player-id"));
508+ verify_item_attribute(section, 1, "x-canonical-next-action", g_variant_new_string("indicator.next.player-id"));
509+ verify_item_attribute(section, 1, "x-canonical-previous-action", g_variant_new_string("indicator.previous.player-id"));
510+
511+ g_clear_object(&section);
512+
513+ sound_menu_remove_player(menu, MEDIA_PLAYER(media));
514+
515+ EXPECT_EQ(1, g_menu_model_get_n_items(G_MENU_MODEL(menu->menu)));
516+
517+ g_clear_object(&media);
518+ g_clear_object(&menu);
519+ return;
520+}
521+
522+TEST_F(SoundMenuTest, AddRemovePlayerNoPlayNextPrev) {
523+ check_player_control_buttons(false, false, false);
524+}
525+
526+TEST_F(SoundMenuTest, AddRemovePlayerNoNext) {
527+ check_player_control_buttons(true, false, true);
528+}
529+
530+TEST_F(SoundMenuTest, AddRemovePlayerNoPrev) {
531+ check_player_control_buttons(true, true, false);
532+}
533+
534+TEST_F(SoundMenuTest, AddRemovePlayerNoPlay) {
535+ check_player_control_buttons(false, true, true);
536+}
537+
538+//

Subscribers

People subscribed via source and target branches