Merge lp:~cjcurran/indicator-sound/blacklist-dbus-access into lp:~indicator-applet-developers/indicator-sound/trunk_3

Proposed by Conor Curran
Status: Merged
Merged at revision: 122
Proposed branch: lp:~cjcurran/indicator-sound/blacklist-dbus-access
Merge into: lp:~indicator-applet-developers/indicator-sound/trunk_3
Diff against target: 265 lines (+141/-12)
7 files modified
src/mpris2-watcher.vala (+1/-1)
src/music-player-bridge.vala (+11/-0)
src/player-controller.vala (+9/-5)
src/playlists-menu-item.vala (+1/-1)
src/settings-manager.vala (+21/-2)
src/sound-service-dbus.c (+95/-1)
src/sound-service.xml (+3/-2)
To merge this branch: bzr merge lp:~cjcurran/indicator-sound/blacklist-dbus-access
Reviewer Review Type Date Requested Status
Mikkel Kamstrup Erlandsen (community) Needs Fixing
Ted Gould Pending
Review via email: mp+48124@code.launchpad.net

This proposal supersedes a proposal from 2011-01-31.

Description of the change

Fixes the 'bug' attached. Now addition or removal of players from the menu can be achieved through dbus.
Any change to the gsettings is also automatically reflected in the menu.

To post a comment you must log in.
Revision history for this message
Ted Gould (ted) wrote : Posted in a previous version of this proposal

+ g_variant_get (the_black_list, "as", &iter);

I don't think you can do this to the iterator like that. You need to do a g_variant_iter_init();

I'm pretty sure you need to reinitialize the iterator before using it in a second loop.

You can allocate the builder on the stack, which would make the code slightly faster. Something like:

  GVariantBuilder builder;
  g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);

When you find that it's already in the black list you still need to clean up the builder. (note: even if it's on the stack it needs an _end()

review: Needs Fixing
Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote : Posted in a previous version of this proposal
Download full text (3.6 KiB)

 review needsfixing

> === modified file 'src/sound-service-dbus.c'
...
> +static gboolean sound_service_dbus_blacklist_player (SoundServiceDbus* self,
> +                                                     gchar* player_name,
> +                                                     gboolean blacklist)
> +{
> +  gboolean result = FALSE;
> +  GSettings* our_settings = NULL;
> +  our_settings  = g_settings_new ("com.canonical.indicators.sound");
> +  GVariant* the_black_list = g_settings_get_value (our_settings,
> +                                                   "blacklisted-media-players");
> +  GVariantIter iter;
> +  gchar *str;
> +  // Firstly prep new array which will be set on the key.
> +  GVariantBuilder builder;
> +
> +  g_variant_iter_init (&iter, the_black_list);
> +  g_variant_builder_init(&builder, G_VARIANT_TYPE_STRING_ARRAY);
> +
> +  while (g_variant_iter_loop (&iter, "s", &str)){
> +    g_variant_builder_add (&builder, "s", str);
> +  }
> +  g_variant_iter_init (&iter, the_black_list);
> +
> +  if (blacklist == TRUE){
> +    while (g_variant_iter_loop (&iter, "s", &str)){
> +      g_print ("first pass to check if %s is present\n", str);
> +      if (g_strcmp0 (player_name, str) == 0){
> +        // Return if its already there
> +        g_debug ("we have this already blacklisted, no need to do anything");
> +        g_variant_builder_end (&builder);
> +        g_object_unref (our_settings);
> +        return result;

Here you'll leak the result from g_variant_builder_end() and
the_black_list. It's probably simplest to use g_variant_iter_clear()
instead of _end() (an then unref the_black_list of course).

> +      }
> +    }
> +    // Otherwise blacklist it !
> +    g_debug ("about to blacklist %s", player_name);
> +    g_variant_builder_add (&builder, "s", player_name);
> +  }
> +  else{
> +    gboolean present = FALSE;
> +    g_variant_iter_init (&iter, the_black_list);
> +    g_debug ("attempting to UN-blacklist %s", player_name);
> +
> +    while (g_variant_iter_loop (&iter, "s", &str)){
> +      if (g_strcmp0 (player_name, str) == 0){
> +        present = TRUE;
> +      }
> +    }
> +    // It was not there anyway, return false
> +    if (present == FALSE){
> +      g_debug ("it was not blacklisted ?, no need to do anything");
> +      g_variant_builder_end (&builder);
> +      g_object_unref (our_settings);
> +      return result;

Same as return statement above.

> +    }
> +
> +    // Otherwise free the builder and reconstruct ensuring no duplicates.
> +    g_variant_builder_end (&builder);

_clear() as before

> +    g_variant_builder_init (&builder, G_VARIANT_TYPE_STRING_ARRAY);
> +
> +    g_variant_iter_init (&iter, the_black_list);
> +
> +    while (g_variant_iter_loop (&iter, "s", &str)){
> +      if (g_strcmp0 (player_name, str) != 0){
> +        g_variant_builder_add (&builder, "s", str);
> +      }
> +    }
> +  }
> +  GVariant* value = g_variant_builder_end (&builder);
> +  g_variant_ref (value);
> +  result = g_settings_set_value (our_settings,
> +                                 "blacklisted-media-players",
> +                                 value);
> +
> +  g_variant_unref (value);

No need to ref/unref v...

Read more...

review: Needs Fixing
Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote : Posted in a previous version of this proposal

Just a clarification. Conor's original code is perfectly valid:

GVariantIter *iter;
g_variant_get (val, "as", &iter);
// do stuff
g_variant_iter_free(iter);

although it does seem like there was missing a call to free the iter? Please see http://library.gnome.org/devel/glib/unstable/gvariant-format-strings.html#gvariant-format-strings-arrays

And for cleaning up a stack allocated builder when you find you don't need it, use g_variant_builder_clear() not _end() as the latter call will return a ref to a newly allocated variant that you'd also have to free.

Revision history for this message
Conor Curran (cjcurran) wrote : Posted in a previous version of this proposal

> There is generally something about this
> sound_service_dbus_blacklist_player() method that nags me - it seems
> overly complex in it's logical structure for doing what is really just
> updating a set of strings. You might wanna consider if there is a
> simpler way to do this.

Yes it's too long-winded. But it does need to handle the four cases. I plan to do more refactoring once outstanding issues are resolved. Hopefully get around to this refactor this week.

Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote :

 review needsfixing

> === modified file 'src/sound-service-dbus.c'
...
> +static gboolean sound_service_dbus_blacklist_player (SoundServiceDbus* self,
> +                                                     gchar* player_name,
> +                                                     gboolean blacklist)
> +{
> +  gboolean result = FALSE;
> +  GSettings* our_settings = NULL;
> +  our_settings  = g_settings_new ("com.canonical.indicators.sound");
> +  GVariant* the_black_list = g_settings_get_value (our_settings,
> +                                                   "blacklisted-media-players");
> +  GVariantIter iter;
> +  gchar *str;
> +  // Firstly prep new array which will be set on the key.
> +  GVariantBuilder builder;
> +
> +  g_variant_iter_init (&iter, the_black_list);
> +  g_variant_builder_init(&builder, G_VARIANT_TYPE_STRING_ARRAY);
> +
> +  while (g_variant_iter_loop (&iter, "s", &str)){
> +    g_variant_builder_add (&builder, "s", str);
> +  }
> +  g_variant_iter_init (&iter, the_black_list);
> +
> +  if (blacklist == TRUE){
> +    while (g_variant_iter_loop (&iter, "s", &str)){
> +      g_print ("first pass to check if %s is present\n", str);
> +      if (g_strcmp0 (player_name, str) == 0){
> +        // Return if its already there
> +        g_debug ("we have this already blacklisted, no need to do anything");
> +        g_variant_builder_clear (&builder);
> +        g_object_unref (our_settings);
> +        g_object_unref (the_black_list);
> +        return result;
> +      }
> +    }
> +    // Otherwise blacklist it !
> +    g_debug ("about to blacklist %s", player_name);
> +    g_variant_builder_add (&builder, "s", player_name);
> +  }
> +  else{
> +    gboolean present = FALSE;
> +    g_variant_iter_init (&iter, the_black_list);
> +    g_debug ("attempting to UN-blacklist %s", player_name);
> +
> +    while (g_variant_iter_loop (&iter, "s", &str)){
> +      if (g_strcmp0 (player_name, str) == 0){
> +        present = TRUE;
> +      }
> +    }
> +    // It was not there anyway, return false
> +    if (present == FALSE){
> +      g_debug ("it was not blacklisted ?, no need to do anything");
> +      g_variant_builder_clear (&builder);
> +      g_object_unref (our_settings);
> +      g_object_unref (the_black_list);
> +      return result;
> +    }
> +
> +    // Otherwise free the builder and reconstruct ensuring no duplicates.
> +    g_variant_builder_clear (&builder);
> +    g_variant_builder_init (&builder, G_VARIANT_TYPE_STRING_ARRAY);
> +
> +    g_variant_iter_init (&iter, the_black_list);
> +
> +    while (g_variant_iter_loop (&iter, "s", &str)){
> +      if (g_strcmp0 (player_name, str) != 0){
> +        g_variant_builder_add (&builder, "s", str);
> +      }
> +    }
> +  }
> +  GVariant* value = g_variant_builder_end (&builder);
> +  result = g_settings_set_value (our_settings,
> +                                 "blacklisted-media-players",
> +                                 value);
> +
> +  g_object_unref (our_settings);
> +  g_object_unref (the_black_list);
> +
> +  return result;
> +}

There are a bunch of g_object_unref()s here that should be
g_variant_unref() instead.

review: Needs Fixing

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/mpris2-watcher.vala'
2--- src/mpris2-watcher.vala 2011-01-09 15:05:33 +0000
3+++ src/mpris2-watcher.vala 2011-02-01 09:54:15 +0000
4@@ -50,7 +50,7 @@
5
6 // At startup check to see if there are clients up that we are interested in
7 // More relevant for development and daemon's like mpd.
8- private async void check_for_active_clients()
9+ public async void check_for_active_clients()
10 {
11 string[] interfaces;
12 try{
13
14=== modified file 'src/music-player-bridge.vala'
15--- src/music-player-bridge.vala 2011-01-27 23:08:08 +0000
16+++ src/music-player-bridge.vala 2011-02-01 09:54:15 +0000
17@@ -41,6 +41,17 @@
18 private void on_blacklist_update ( string[] blacklist )
19 {
20 debug("some blacklist update");
21+
22+ foreach(var s in blacklist){
23+ string key = this.determine_key (s);
24+ if (this.registered_clients.has_key (key)){
25+ debug ("Apparently %s is now blacklisted - remove thy self", key);
26+ this.registered_clients[key].remove_from_menu();
27+ this.registered_clients.unset (key);
28+ }
29+ }
30+ // double check present players to ensure dynamic removal/addition
31+ this.watcher.check_for_active_clients.begin();
32 }
33
34 private void try_to_add_inactive_familiar_clients()
35
36=== modified file 'src/player-controller.vala'
37--- src/player-controller.vala 2011-01-27 23:08:08 +0000
38+++ src/player-controller.vala 2011-02-01 09:54:15 +0000
39@@ -119,10 +119,14 @@
40 this.determine_state();
41 }
42
43- public void vanish()
44+ public void remove_from_menu()
45 {
46- foreach(Dbusmenu.Menuitem item in this.custom_items){
47- root_menu.child_delete(item);
48+ foreach(PlayerItem item in this.custom_items){
49+ this.root_menu.child_delete(item);
50+ }
51+ if (this.use_playlists == true){
52+ PlaylistsMenuitem playlists_menuitem = this.custom_items[widget_order.PLAYLISTS] as PlaylistsMenuitem;
53+ this.root_menu.child_delete (playlists_menuitem.root_item);
54 }
55 }
56
57@@ -180,7 +184,7 @@
58
59 foreach(PlayerItem item in this.custom_items){
60 if (this.custom_items.index_of(item) != 4) {
61- root_menu.child_add_position(item, this.menu_offset + this.custom_items.index_of(item));
62+ root_menu.child_add_position(item, this.menu_offset + this.custom_items.index_of(item));
63 }
64 else{
65 PlaylistsMenuitem playlists_menuitem = item as PlaylistsMenuitem;
66@@ -188,7 +192,7 @@
67 }
68 }
69 }
70-
71+
72 private void determine_state()
73 {
74 if(this.mpris_bridge.connected() == true){
75
76=== modified file 'src/playlists-menu-item.vala'
77--- src/playlists-menu-item.vala 2010-12-21 14:53:56 +0000
78+++ src/playlists-menu-item.vala 2011-02-01 09:54:15 +0000
79@@ -50,7 +50,7 @@
80 this.root_item.child_append( menuitem );
81 }
82 }
83-
84+
85 private bool already_observed (PlaylistDetails new_detail)
86 {
87 foreach ( PlaylistDetails detail in this.current_playlists.values ){
88
89=== modified file 'src/settings-manager.vala'
90--- src/settings-manager.vala 2011-01-10 12:57:35 +0000
91+++ src/settings-manager.vala 2011-02-01 09:54:15 +0000
92@@ -52,7 +52,7 @@
93 this.settings.reset("interested-media-players");
94 }
95
96- public void add_interested(string app_desktop_name)
97+ public void add_interested (string app_desktop_name)
98 {
99 var already_interested = this.settings.get_strv ("interested-media-players");
100 foreach (var s in already_interested){
101@@ -67,5 +67,24 @@
102 private void on_blacklist_event()
103 {
104 this.blacklist_updates(this.settings.get_strv ("blacklisted-media-players"));
105- }
106+ }
107+
108+ // Convenient debug method inorder to provide visability over
109+ // the contents of both interested and blacklisted containers in its gsettings
110+ private void reveal_contents()
111+ {
112+ var already_interested = this.settings.get_strv ("interested-media-players");
113+ foreach (var s in already_interested)
114+ {
115+ debug ("client %s is in interested array", s);
116+ }
117+ var blacklisted = this.settings.get_strv ("blacklisted-media-players");
118+ foreach (var s in blacklisted)
119+ {
120+ debug ("client %s is in blacklisted array", s);
121+ }
122+
123+ debug ("interested array size = %i", already_interested.length);
124+ debug ("blacklisted array size = %i", blacklisted.length);
125+ }
126 }
127
128=== modified file 'src/sound-service-dbus.c'
129--- src/sound-service-dbus.c 2011-01-27 22:10:48 +0000
130+++ src/sound-service-dbus.c 2011-02-01 09:54:15 +0000
131@@ -85,6 +85,10 @@
132 gboolean availability,
133 gboolean mute,
134 gdouble volume);
135+static gboolean sound_service_dbus_blacklist_player (SoundServiceDbus* self,
136+ gchar* player_name,
137+ gboolean blacklist);
138+
139
140 G_DEFINE_TYPE (SoundServiceDbus, sound_service_dbus, G_TYPE_OBJECT);
141
142@@ -400,12 +404,102 @@
143 g_debug("Get state - %i", priv->current_sound_state );
144 retval = g_variant_new ( "(i)", priv->current_sound_state);
145 }
146+ else if (g_strcmp0(method, "BlacklistMediaPlayer") == 0) {
147+ gboolean blacklist;
148+ gchar* player_name;
149+ g_variant_get (params, "(sb)", &player_name, &blacklist);
150+
151+ g_debug ("BlacklistMediaPlayer - bool %i", blacklist);
152+ g_debug ("BlacklistMediaPlayer - name %s", player_name);
153+ gboolean result = sound_service_dbus_blacklist_player (service,
154+ player_name,
155+ blacklist);
156+ retval = g_variant_new ("(b)", result);
157+ }
158 else {
159 g_warning("Calling method '%s' on the sound service but it's unknown", method);
160 }
161 g_dbus_method_invocation_return_value (invocation, retval);
162 }
163
164-
165+static gboolean sound_service_dbus_blacklist_player (SoundServiceDbus* self,
166+ gchar* player_name,
167+ gboolean blacklist)
168+{
169+ gboolean result = FALSE;
170+ GSettings* our_settings = NULL;
171+ our_settings = g_settings_new ("com.canonical.indicators.sound");
172+ GVariant* the_black_list = g_settings_get_value (our_settings,
173+ "blacklisted-media-players");
174+ GVariantIter iter;
175+ gchar *str;
176+ // Firstly prep new array which will be set on the key.
177+ GVariantBuilder builder;
178+
179+ g_variant_iter_init (&iter, the_black_list);
180+ g_variant_builder_init(&builder, G_VARIANT_TYPE_STRING_ARRAY);
181+
182+ while (g_variant_iter_loop (&iter, "s", &str)){
183+ g_variant_builder_add (&builder, "s", str);
184+ }
185+ g_variant_iter_init (&iter, the_black_list);
186+
187+ if (blacklist == TRUE){
188+ while (g_variant_iter_loop (&iter, "s", &str)){
189+ g_print ("first pass to check if %s is present\n", str);
190+ if (g_strcmp0 (player_name, str) == 0){
191+ // Return if its already there
192+ g_debug ("we have this already blacklisted, no need to do anything");
193+ g_variant_builder_clear (&builder);
194+ g_object_unref (our_settings);
195+ g_object_unref (the_black_list);
196+ return result;
197+ }
198+ }
199+ // Otherwise blacklist it !
200+ g_debug ("about to blacklist %s", player_name);
201+ g_variant_builder_add (&builder, "s", player_name);
202+ }
203+ else{
204+ gboolean present = FALSE;
205+ g_variant_iter_init (&iter, the_black_list);
206+ g_debug ("attempting to UN-blacklist %s", player_name);
207+
208+ while (g_variant_iter_loop (&iter, "s", &str)){
209+ if (g_strcmp0 (player_name, str) == 0){
210+ present = TRUE;
211+ }
212+ }
213+ // It was not there anyway, return false
214+ if (present == FALSE){
215+ g_debug ("it was not blacklisted ?, no need to do anything");
216+ g_variant_builder_clear (&builder);
217+ g_object_unref (our_settings);
218+ g_object_unref (the_black_list);
219+ return result;
220+ }
221+
222+ // Otherwise free the builder and reconstruct ensuring no duplicates.
223+ g_variant_builder_clear (&builder);
224+ g_variant_builder_init (&builder, G_VARIANT_TYPE_STRING_ARRAY);
225+
226+ g_variant_iter_init (&iter, the_black_list);
227+
228+ while (g_variant_iter_loop (&iter, "s", &str)){
229+ if (g_strcmp0 (player_name, str) != 0){
230+ g_variant_builder_add (&builder, "s", str);
231+ }
232+ }
233+ }
234+ GVariant* value = g_variant_builder_end (&builder);
235+ result = g_settings_set_value (our_settings,
236+ "blacklisted-media-players",
237+ value);
238+
239+ g_object_unref (our_settings);
240+ g_object_unref (the_black_list);
241+
242+ return result;
243+}
244
245
246
247=== modified file 'src/sound-service.xml'
248--- src/sound-service.xml 2011-01-27 22:10:48 +0000
249+++ src/sound-service.xml 2011-02-01 09:54:15 +0000
250@@ -2,12 +2,13 @@
251 <node name="/com/canonical/indicators/sound">
252 <interface name="com.canonical.indicators.sound">
253 <method name = "BlacklistMediaPlayer">
254- <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="sound_service_dbus_blacklist_media_player"/>
255+ <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
256 <arg type='s' name='player_desktop_name' direction="in"/>
257 <arg type='b' name='blacklist' direction="in"/>
258+ <arg type='b' name='result' direction="out"/>
259 </method>
260 <method name = "GetSoundState">
261- <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="sound_service_dbus_get_sink_state"/>
262+ <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
263 <arg type='i' name='current_state' direction="out"/>
264 </method>
265 <signal name="SoundStateUpdate">

Subscribers

People subscribed via source and target branches