Merge lp:~cjcurran/indicator-sound/service-crash-unresponsive-dbus-client into lp:indicator-sound/sound-menu-v2

Proposed by Conor Curran
Status: Merged
Merged at revision: 135
Proposed branch: lp:~cjcurran/indicator-sound/service-crash-unresponsive-dbus-client
Merge into: lp:indicator-sound/sound-menu-v2
Diff against target: 349 lines (+95/-60)
7 files modified
src/dbus-menu-manager.c (+4/-3)
src/indicator-sound.c (+55/-35)
src/mpris2-controller.vala (+10/-12)
src/pulse-manager.c (+4/-6)
src/slider-menu-item.c (+1/-2)
src/volume-widget.c (+19/-2)
src/volume-widget.h (+2/-0)
To merge this branch: bzr merge lp:~cjcurran/indicator-sound/service-crash-unresponsive-dbus-client
Reviewer Review Type Date Requested Status
Cody Russell (community) Approve
Review via email: mp+35445@code.launchpad.net

This proposal supersedes a proposal from 2010-09-14.

Description of the change

- makes sure all mpris dbus method calls are async
- in the case of a service crash the indicator should reset itself properly and populate like normal from the restarted service.

To post a comment you must log in.
Revision history for this message
Cody Russell (bratsche) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/dbus-menu-manager.c'
2--- src/dbus-menu-manager.c 2010-08-25 14:18:45 +0000
3+++ src/dbus-menu-manager.c 2010-09-14 17:32:45 +0000
4@@ -50,9 +50,11 @@
5
6 static void set_global_mute_from_ui();
7 static gboolean idle_routine (gpointer data);
8-static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service);
9+static void rebuild_sound_menu(DbusmenuMenuitem *root,
10+ SoundServiceDbus *service);
11 static void refresh_menu();
12
13+
14 /*-------------------------------------------------------------------------*/
15 // Public Methods
16 /*-------------------------------------------------------------------------*/
17@@ -75,7 +77,6 @@
18 return root_menuitem;
19 }
20
21-
22 void dbus_menu_manager_update_volume(gdouble volume)
23 {
24 GValue value = {0};
25@@ -213,7 +214,7 @@
26 // Sound preferences dialog
27 DbusmenuMenuitem *settings_mi = dbusmenu_menuitem_new();
28 dbusmenu_menuitem_property_set(settings_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Sound Preferences..."));
29-//_("Sound Preferences..."));
30+ //_("Sound Preferences..."));
31 dbusmenu_menuitem_child_append(root, settings_mi);
32 g_signal_connect(G_OBJECT(settings_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
33 G_CALLBACK(show_sound_settings_dialog), NULL);
34
35=== modified file 'src/indicator-sound.c'
36--- src/indicator-sound.c 2010-09-13 12:35:28 +0000
37+++ src/indicator-sound.c 2010-09-14 17:32:45 +0000
38@@ -156,7 +156,9 @@
39 IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self);
40 priv->volume_widget = NULL;
41
42- g_signal_connect(G_OBJECT(self->service), INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, G_CALLBACK(connection_changed), self);
43+ g_signal_connect(G_OBJECT(self->service),
44+ INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE,
45+ G_CALLBACK(connection_changed), self);
46 return;
47 }
48
49@@ -307,7 +309,7 @@
50 volume_widget = volume_widget_new (newitem);
51 io = g_object_get_data (G_OBJECT (client), "indicator");
52 IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io));
53- priv->volume_widget = volume_widget;
54+ priv->volume_widget = volume_widget;
55
56 GtkWidget* ido_slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget));
57
58@@ -321,47 +323,65 @@
59 dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client),
60 newitem,
61 menu_volume_item,
62- parent);
63-
64- fetch_mute_value_from_dbus();
65- fetch_sink_availability_from_dbus(INDICATOR_SOUND (io));
66-
67+ parent);
68 return TRUE;
69 }
70
71
72 static void
73-connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer userdata)
74+connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer user_data)
75 {
76 if (connected) {
77- if (sound_dbus_proxy == NULL) {
78- GError * error = NULL;
79-
80- DBusGConnection * sbus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
81-
82- sound_dbus_proxy = dbus_g_proxy_new_for_name_owner(sbus,
83- INDICATOR_SOUND_DBUS_NAME,
84- INDICATOR_SOUND_SERVICE_DBUS_OBJECT,
85- INDICATOR_SOUND_SERVICE_DBUS_INTERFACE,
86- &error);
87-
88- if (error != NULL) {
89- g_warning("Unable to get status proxy: %s", error->message);
90- g_error_free(error);
91- }
92- g_debug("about to connect to the signals");
93- dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_TYPE_BOOLEAN, G_TYPE_INVALID);
94- dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_CALLBACK(catch_signal_sink_input_while_muted), NULL, NULL);
95- dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID);
96- dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_CALLBACK(catch_signal_sink_mute_update), userdata, NULL);
97- dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_AVAILABLE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID);
98- dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_AVAILABLE_UPDATE, G_CALLBACK(catch_signal_sink_availability_update), NULL, NULL);
99-
100- g_return_if_fail(IS_INDICATOR_SOUND(userdata));
101-
102- }
103+ gboolean service_restart = FALSE;
104+ if (sound_dbus_proxy != NULL) {
105+ g_object_unref (sound_dbus_proxy);
106+ sound_dbus_proxy = NULL;
107+ service_restart = TRUE;
108+ }
109+ GError * error = NULL;
110+
111+ DBusGConnection * sbus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
112+
113+ sound_dbus_proxy = dbus_g_proxy_new_for_name_owner(sbus,
114+ INDICATOR_SOUND_DBUS_NAME,
115+ INDICATOR_SOUND_SERVICE_DBUS_OBJECT,
116+ INDICATOR_SOUND_SERVICE_DBUS_INTERFACE,
117+ &error);
118+
119+ if (error != NULL) {
120+ g_warning("Unable to get status proxy: %s", error->message);
121+ g_error_free(error);
122+ }
123+ g_debug("about to connect to the signals");
124+ dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_TYPE_BOOLEAN, G_TYPE_INVALID);
125+ dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_CALLBACK(catch_signal_sink_input_while_muted), NULL, NULL);
126+ dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID);
127+ dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_CALLBACK(catch_signal_sink_mute_update), user_data, NULL);
128+ dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_AVAILABLE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID);
129+ dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_AVAILABLE_UPDATE, G_CALLBACK(catch_signal_sink_availability_update), NULL, NULL);
130+ if( service_restart == TRUE){
131+ fetch_mute_value_from_dbus();
132+ // Ensure UI is in sync with service again.
133+ IndicatorSound* indicator = INDICATOR_SOUND(user_data);
134+ fetch_sink_availability_from_dbus(indicator);
135+ IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator);
136+ determine_state_from_volume (volume_widget_get_current_volume(priv->volume_widget));
137+ }
138+ }
139+ else{
140+ g_warning("Indicator has been disconnected from the service -> SHOCK HORROR");
141+ IndicatorSound* indicator = INDICATOR_SOUND(user_data);
142+ IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator);
143+
144+ if(priv->volume_widget != NULL){
145+ g_warning("indicator still has a slider, service must have crashed");
146+ volume_widget_tidy_up(priv->volume_widget);
147+ g_object_unref(G_OBJECT(priv->volume_widget));
148+ priv->volume_widget = NULL;
149+ }
150+ device_available = FALSE;
151+ update_state(STATE_SINKS_NONE);
152 }
153- return;
154 }
155
156 /*
157
158=== modified file 'src/mpris2-controller.vala'
159--- src/mpris2-controller.vala 2010-09-13 11:49:01 +0000
160+++ src/mpris2-controller.vala 2010-09-14 17:32:45 +0000
161@@ -28,8 +28,8 @@
162 public abstract string Identity{owned get; set;}
163 public abstract string DesktopEntry{owned get; set;}
164 // methods
165- public abstract void Quit() throws DBus.Error;
166- public abstract void Raise() throws DBus.Error;
167+ public abstract async void Quit() throws DBus.Error;
168+ public abstract async void Raise() throws DBus.Error;
169 }
170
171 [DBus (name = "org.mpris.MediaPlayer2.Player")]
172@@ -40,11 +40,9 @@
173 public abstract int32 Position{owned get; set;}
174 public abstract string PlaybackStatus{owned get; set;}
175 // methods
176- public abstract void SetPosition(DBus.ObjectPath path, int64 pos) throws DBus.Error;
177- public abstract void PlayPause() throws DBus.Error;
178- public abstract void Pause() throws DBus.Error;
179- public abstract void Next() throws DBus.Error;
180- public abstract void Previous() throws DBus.Error;
181+ public abstract async void PlayPause() throws DBus.Error;
182+ public abstract async void Next() throws DBus.Error;
183+ public abstract async void Previous() throws DBus.Error;
184 // signals
185 public signal void Seeked(int64 new_position);
186 }
187@@ -176,7 +174,7 @@
188 if(command == TransportMenuitem.action.PLAY_PAUSE){
189 debug("transport_event PLAY_PAUSE");
190 try{
191- this.player.PlayPause();
192+ this.player.PlayPause.begin();
193 }
194 catch(DBus.Error error){
195 warning("DBus Error calling the player objects PlayPause method %s",
196@@ -185,7 +183,7 @@
197 }
198 else if(command == TransportMenuitem.action.PREVIOUS){
199 try{
200- this.player.Previous();
201+ this.player.Previous.begin();
202 }
203 catch(DBus.Error error){
204 warning("DBus Error calling the player objects Previous method %s",
205@@ -194,7 +192,7 @@
206 }
207 else if(command == TransportMenuitem.action.NEXT){
208 try{
209- this.player.Next();
210+ this.player.Next.begin();
211 }
212 catch(DBus.Error error){
213 warning("DBus Error calling the player objects Next method %s",
214@@ -215,12 +213,12 @@
215 }
216 return true;
217 }
218-
219+
220 public void expose()
221 {
222 if(this.connected() == true){
223 try{
224- this.mpris2_root.Raise();
225+ this.mpris2_root.Raise.begin();
226 }
227 catch(DBus.Error e){
228 error("Exception thrown while calling function Raise - %s", e.message);
229
230=== modified file 'src/pulse-manager.c'
231--- src/pulse-manager.c 2010-08-02 18:13:58 +0000
232+++ src/pulse-manager.c 2010-09-14 17:32:45 +0000
233@@ -50,8 +50,8 @@
234
235 /**
236 Future Refactoring notes
237- - Push all UI updates out through update PA state in the service.
238- - Collapse 3 update_sink_info into one. The essentially do the same thing from different contexts.
239+ - rewrite in vala.
240+ - make sure all state is kept in the service for volume icon switching.
241 **/
242
243 /**
244@@ -147,7 +147,7 @@
245 // Firstly check to see if we have any sinks
246 // if not get the hell out of here !
247 if (g_hash_table_size(sink_hash) < 1) {
248- /* g_debug("Sink_available returning false because sinks_hash is empty !!!"); */
249+ g_debug("Sink_available returning false because sinks_hash is empty !!!");
250 DEFAULT_SINK_INDEX = -1;
251 return FALSE;
252 }
253@@ -163,7 +163,7 @@
254
255 // Thirdly ensure the default sink index does not have the name "auto_null"
256 sink_info* s = g_hash_table_lookup(sink_hash, GINT_TO_POINTER(DEFAULT_SINK_INDEX));
257- // Up until now the most rebust method to test this is to manually remove the available sink device
258+ // Up until now the most robust method to test this is to manually remove the available sink device
259 // kernel module and then reload (rmmod & modprobe).
260 // TODO: Edge case of dynamic loading and unloading of sinks should be handled also.
261 /* g_debug("About to test for to see if the available sink is null - s->name = %s", s->name);*/
262@@ -211,7 +211,6 @@
263 if (GPOINTER_TO_INT(user_data) == 1) {
264 sound_service_dbus_update_sink_mute(dbus_service, TRUE);
265 } else {
266- //sound_service_dbus_update_sink_volume(dbus_service, get_default_sink_volume());
267 dbus_menu_manager_update_volume(get_default_sink_volume());
268 }
269
270@@ -411,7 +410,6 @@
271 pa_volume_t vol = pa_cvolume_max(&s->volume);
272 gdouble volume_percent = ((gdouble) vol * 100) / PA_VOLUME_NORM;
273 /* g_debug("Updating volume from PA manager with volume = %f", volume_percent);*/
274- //sound_service_dbus_update_sink_volume(dbus_service, volume_percent);
275 dbus_menu_manager_update_volume(volume_percent);
276 }
277 }
278
279=== modified file 'src/slider-menu-item.c'
280--- src/slider-menu-item.c 2010-08-06 12:20:03 +0000
281+++ src/slider-menu-item.c 2010-09-14 17:32:45 +0000
282@@ -88,8 +88,7 @@
283
284
285 SliderMenuItem* slider_menu_item_new(gboolean sinks_available, gdouble start_volume)
286-{
287-
288+{
289 SliderMenuItem *self = g_object_new(SLIDER_MENU_ITEM_TYPE, NULL);
290 dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_VOLUME_MENUITEM_TYPE);
291
292
293=== modified file 'src/volume-widget.c'
294--- src/volume-widget.c 2010-08-31 11:08:03 +0000
295+++ src/volume-widget.c 2010-09-14 17:32:45 +0000
296@@ -61,6 +61,7 @@
297
298 G_DEFINE_TYPE (VolumeWidget, volume_widget, G_TYPE_OBJECT);
299
300+
301 static void
302 volume_widget_class_init (VolumeWidgetClass *klass)
303 {
304@@ -201,8 +202,6 @@
305 dbusmenu_menuitem_handle_event (priv->twin_item, "update", &value, 0);
306 }
307
308-
309-
310 GtkWidget*
311 volume_widget_get_ido_slider(VolumeWidget* self)
312 {
313@@ -234,6 +233,24 @@
314 priv->grabbed = FALSE;
315 }
316
317+void
318+volume_widget_tidy_up (GtkWidget *widget)
319+{
320+ VolumeWidget* mitem = VOLUME_WIDGET(widget);
321+ VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem);
322+ gtk_widget_destroy (priv->ido_volume_slider);
323+}
324+
325+gdouble
326+volume_widget_get_current_volume ( GtkWidget *widget )
327+{
328+ VolumeWidget* mitem = VOLUME_WIDGET(widget);
329+ VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem);
330+ gdouble vol = g_value_get_double ( dbusmenu_menuitem_property_get_value( priv->twin_item,
331+ DBUSMENU_VOLUME_MENUITEM_LEVEL));
332+ return vol;
333+}
334+
335 /**
336 * volume_widget_new:
337 * @returns: a new #VolumeWidget.
338
339=== modified file 'src/volume-widget.h'
340--- src/volume-widget.h 2010-08-06 12:20:03 +0000
341+++ src/volume-widget.h 2010-09-14 17:32:45 +0000
342@@ -47,6 +47,8 @@
343 GtkWidget* volume_widget_new(DbusmenuMenuitem* twin_item);
344 GtkWidget* volume_widget_get_ido_slider(VolumeWidget* self);
345 void volume_widget_update(VolumeWidget* self, gdouble update);
346+void volume_widget_tidy_up (GtkWidget *widget);
347+gdouble volume_widget_get_current_volume ( GtkWidget *widget );
348
349 G_END_DECLS
350

Subscribers

People subscribed via source and target branches

to all changes: