← Back to team overview

ayatana-commits team mailing list archive

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

 

Conor Curran has proposed merging lp:~cjcurran/indicator-sound/service-crash-unresponsive-dbus-client into lp:indicator-sound.

Requested reviews:
  Indicator Applet Developers (indicator-applet-developers)


- 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. 
-- 
https://code.launchpad.net/~cjcurran/indicator-sound/service-crash-unresponsive-dbus-client/+merge/35441
Your team ayatana-commits is subscribed to branch lp:indicator-sound.
=== modified file 'src/dbus-menu-manager.c'
--- src/dbus-menu-manager.c	2010-08-25 14:18:45 +0000
+++ src/dbus-menu-manager.c	2010-09-14 17:25:08 +0000
@@ -50,8 +50,11 @@
 
 static void set_global_mute_from_ui();
 static gboolean idle_routine (gpointer data);
-static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service);
+static void rebuild_sound_menu(DbusmenuMenuitem *root,
+                               SoundServiceDbus *service);
 static void refresh_menu();
+static void remove_previous_children(gpointer obj, gpointer user_data);
+
 
 /*-------------------------------------------------------------------------*/
 //                          Public Methods
@@ -71,10 +74,22 @@
 
   DbusmenuServer *server = dbusmenu_server_new(INDICATOR_SOUND_DBUS_OBJECT);
   dbusmenu_server_set_root(server, root_menuitem);
+
+  /*GList* previous_children = dbusmenu_menuitem_get_children(root_menuitem);
+  if(previous_children != NULL){
+    g_list_foreach(previous_children, remove_previous_children, NULL);
+  }*/
   establish_pulse_activities(dbus_interface);
   return root_menuitem;
 }
 
+/*static void remove_previous_children(gpointer obj, gpointer user_data)
+{  
+  DbusmenuMenuitem *child = (DbusmenuMenuitem*)obj;
+  if(child != NULL){
+    dbusmenu_menuitem_child_delete(root_menuitem, child);
+  }
+}*/
 
 void dbus_menu_manager_update_volume(gdouble  volume)
 {
@@ -213,7 +228,7 @@
   // Sound preferences dialog
   DbusmenuMenuitem *settings_mi = dbusmenu_menuitem_new();
   dbusmenu_menuitem_property_set(settings_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Sound Preferences..."));
-//_("Sound Preferences..."));
+  //_("Sound Preferences..."));
   dbusmenu_menuitem_child_append(root, settings_mi);
   g_signal_connect(G_OBJECT(settings_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
                    G_CALLBACK(show_sound_settings_dialog), NULL);

=== modified file 'src/indicator-sound.c'
--- src/indicator-sound.c	2010-09-13 12:35:28 +0000
+++ src/indicator-sound.c	2010-09-14 17:25:08 +0000
@@ -156,7 +156,9 @@
 	IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self);
 	priv->volume_widget = NULL;
 
-	g_signal_connect(G_OBJECT(self->service), INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, G_CALLBACK(connection_changed), self);
+	g_signal_connect(G_OBJECT(self->service),
+                   INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE,
+                   G_CALLBACK(connection_changed), self);
   return;
 }
 
@@ -307,7 +309,7 @@
   volume_widget = volume_widget_new (newitem);	
 	io = g_object_get_data (G_OBJECT (client), "indicator");
 	IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io));
-	priv->volume_widget = volume_widget;
+  priv->volume_widget = volume_widget;
 
 	GtkWidget* ido_slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget));
 
@@ -321,47 +323,65 @@
 	dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client),
 	                                newitem,
 	                                menu_volume_item,
-	                                parent);
-	
-	fetch_mute_value_from_dbus();
-  fetch_sink_availability_from_dbus(INDICATOR_SOUND (io));
-	
+	                                parent);		
   return TRUE;	
 }
 
 
 static void
-connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer userdata)
+connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer user_data)
 {
   if (connected) {
-    if (sound_dbus_proxy == NULL) {
-      GError * error = NULL;
-
-      DBusGConnection * sbus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
-
-      sound_dbus_proxy = dbus_g_proxy_new_for_name_owner(sbus,
-                         INDICATOR_SOUND_DBUS_NAME,
-                         INDICATOR_SOUND_SERVICE_DBUS_OBJECT,
-                         INDICATOR_SOUND_SERVICE_DBUS_INTERFACE,
-                         &error);
-
-      if (error != NULL) {
-        g_warning("Unable to get status proxy: %s", error->message);
-        g_error_free(error);
-      }
-      g_debug("about to connect to the signals");
-      dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_TYPE_BOOLEAN, G_TYPE_INVALID);
-      dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_CALLBACK(catch_signal_sink_input_while_muted), NULL, NULL);
-      dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID);
-      dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_CALLBACK(catch_signal_sink_mute_update), userdata, NULL);
-      dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_AVAILABLE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID);
-      dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_AVAILABLE_UPDATE, G_CALLBACK(catch_signal_sink_availability_update), NULL, NULL);
-
-			g_return_if_fail(IS_INDICATOR_SOUND(userdata));
-			
-    }
+    gboolean service_restart = FALSE;
+    if (sound_dbus_proxy != NULL) {
+      g_object_unref (sound_dbus_proxy);
+      sound_dbus_proxy = NULL;
+      service_restart = TRUE;
+    }
+    GError * error = NULL;
+
+    DBusGConnection * sbus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
+
+    sound_dbus_proxy = dbus_g_proxy_new_for_name_owner(sbus,
+                       INDICATOR_SOUND_DBUS_NAME,
+                       INDICATOR_SOUND_SERVICE_DBUS_OBJECT,
+                       INDICATOR_SOUND_SERVICE_DBUS_INTERFACE,
+                       &error);
+
+    if (error != NULL) {
+      g_warning("Unable to get status proxy: %s", error->message);
+      g_error_free(error);
+    }
+    g_debug("about to connect to the signals");
+    dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_TYPE_BOOLEAN, G_TYPE_INVALID);
+    dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_CALLBACK(catch_signal_sink_input_while_muted), NULL, NULL);
+    dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID);
+    dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_CALLBACK(catch_signal_sink_mute_update), user_data, NULL);
+    dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_AVAILABLE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID);
+    dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_AVAILABLE_UPDATE, G_CALLBACK(catch_signal_sink_availability_update), NULL, NULL);	
+    if( service_restart == TRUE){
+      fetch_mute_value_from_dbus();
+      // Ensure UI is in sync with service again.
+      IndicatorSound* indicator = INDICATOR_SOUND(user_data);
+      fetch_sink_availability_from_dbus(indicator);    
+  	  IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator);
+      determine_state_from_volume (volume_widget_get_current_volume(priv->volume_widget));
+    }
+  }  
+  else{
+    g_warning("Indicator has been disconnected from the service -> SHOCK HORROR");
+    IndicatorSound* indicator = INDICATOR_SOUND(user_data);
+	  IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator);
+    
+    if(priv->volume_widget != NULL){
+      g_warning("indicator still has a slider, service must have crashed");
+      volume_widget_tidy_up(priv->volume_widget);
+      g_object_unref(G_OBJECT(priv->volume_widget));
+      priv->volume_widget = NULL;
+    }  
+    device_available = FALSE;
+    update_state(STATE_SINKS_NONE);
   }
-  return;
 }
 
 /*

=== modified file 'src/mpris2-controller.vala'
--- src/mpris2-controller.vala	2010-09-13 11:49:01 +0000
+++ src/mpris2-controller.vala	2010-09-14 17:25:08 +0000
@@ -28,8 +28,8 @@
 	public abstract string Identity{owned get; set;}
 	public abstract string DesktopEntry{owned get; set;}	
 	// methods
-	public abstract void Quit() throws DBus.Error;
-	public abstract void Raise() throws DBus.Error;
+	public abstract async void Quit() throws DBus.Error;
+	public abstract async void Raise() throws DBus.Error;
 }
 
 [DBus (name = "org.mpris.MediaPlayer2.Player")]
@@ -40,11 +40,9 @@
 	public abstract int32 Position{owned get; set;}
 	public abstract string PlaybackStatus{owned get; set;}	
 	// methods
-	public abstract void SetPosition(DBus.ObjectPath path, int64 pos) throws DBus.Error;
-	public abstract void PlayPause() throws DBus.Error;
-	public abstract void Pause() throws DBus.Error;
-	public abstract void Next() throws DBus.Error;
-	public abstract void Previous() throws DBus.Error;
+	public abstract async void PlayPause() throws DBus.Error;
+	public abstract async void Next() throws DBus.Error;
+	public abstract async void Previous() throws DBus.Error;
 	// signals
 	public signal void Seeked(int64 new_position);
 }
@@ -176,7 +174,7 @@
 		if(command == TransportMenuitem.action.PLAY_PAUSE){
 			debug("transport_event PLAY_PAUSE");
 			try{
-				this.player.PlayPause();							
+				this.player.PlayPause.begin();							
 			}
 			catch(DBus.Error error){
 				warning("DBus Error calling the player objects PlayPause method %s",
@@ -185,7 +183,7 @@
 		}
 		else if(command == TransportMenuitem.action.PREVIOUS){
 			try{
-				this.player.Previous();
+				this.player.Previous.begin();
 			}
 			catch(DBus.Error error){
 				warning("DBus Error calling the player objects Previous method %s",
@@ -194,7 +192,7 @@
 		}
 		else if(command == TransportMenuitem.action.NEXT){
 			try{
-				this.player.Next();
+				this.player.Next.begin();
 			}
 			catch(DBus.Error error){
 				warning("DBus Error calling the player objects Next method %s",
@@ -215,12 +213,12 @@
 		}
 		return true;
 	}
-
+  
 	public void expose()
 	{
 		if(this.connected() == true){
 			try{
-				this.mpris2_root.Raise();
+				this.mpris2_root.Raise.begin();
 			}
 			catch(DBus.Error e){
 				error("Exception thrown while calling function Raise - %s", e.message);

=== modified file 'src/pulse-manager.c'
--- src/pulse-manager.c	2010-08-02 18:13:58 +0000
+++ src/pulse-manager.c	2010-09-14 17:25:08 +0000
@@ -50,8 +50,8 @@
 
 /**
 Future Refactoring notes
- - Push all UI updates out through update PA state in the service.
- - Collapse 3 update_sink_info into one. The essentially do the same thing from different contexts.
+ - rewrite in vala.
+ - make sure all state is kept in the service for volume icon switching.
 **/
 
 /**
@@ -147,7 +147,7 @@
   // Firstly check to see if we have any sinks
   // if not get the hell out of here !
   if (g_hash_table_size(sink_hash) < 1) {
-    /*        g_debug("Sink_available returning false because sinks_hash is empty !!!");    */
+    g_debug("Sink_available returning false because sinks_hash is empty !!!");   
     DEFAULT_SINK_INDEX = -1;
     return FALSE;
   }
@@ -163,7 +163,7 @@
 
   // Thirdly ensure the default sink index does not have the name "auto_null"
   sink_info* s = g_hash_table_lookup(sink_hash, GINT_TO_POINTER(DEFAULT_SINK_INDEX));
-  // Up until now the most rebust method to test this is to manually remove the available sink device
+  // Up until now the most robust method to test this is to manually remove the available sink device
   // kernel module and then reload (rmmod & modprobe).
   // TODO: Edge case of dynamic loading and unloading of sinks should be handled also.
   /*    g_debug("About to test for to see if the available sink is null - s->name = %s", s->name);*/
@@ -211,7 +211,6 @@
   if (GPOINTER_TO_INT(user_data) == 1) {
     sound_service_dbus_update_sink_mute(dbus_service, TRUE);
   } else {
-    //sound_service_dbus_update_sink_volume(dbus_service, get_default_sink_volume());
 		dbus_menu_manager_update_volume(get_default_sink_volume());
   }
 
@@ -411,7 +410,6 @@
           pa_volume_t vol = pa_cvolume_max(&s->volume);
           gdouble volume_percent = ((gdouble) vol * 100) / PA_VOLUME_NORM;
           /*                    g_debug("Updating volume from PA manager with volume = %f", volume_percent);*/
-          //sound_service_dbus_update_sink_volume(dbus_service, volume_percent);
 	        dbus_menu_manager_update_volume(volume_percent);
         }
       }

=== modified file 'src/slider-menu-item.c'
--- src/slider-menu-item.c	2010-08-06 12:20:03 +0000
+++ src/slider-menu-item.c	2010-09-14 17:25:08 +0000
@@ -88,8 +88,7 @@
 
 
 SliderMenuItem* slider_menu_item_new(gboolean sinks_available, gdouble start_volume)
-{
-	
+{	
   SliderMenuItem *self = g_object_new(SLIDER_MENU_ITEM_TYPE, NULL);
   dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_VOLUME_MENUITEM_TYPE);
 

=== modified file 'src/volume-widget.c'
--- src/volume-widget.c	2010-08-31 11:08:03 +0000
+++ src/volume-widget.c	2010-09-14 17:25:08 +0000
@@ -61,6 +61,7 @@
 
 G_DEFINE_TYPE (VolumeWidget, volume_widget, G_TYPE_OBJECT);
 
+
 static void
 volume_widget_class_init (VolumeWidgetClass *klass)
 {
@@ -201,8 +202,6 @@
   dbusmenu_menuitem_handle_event (priv->twin_item, "update", &value, 0);
 }
 
-
-
 GtkWidget*
 volume_widget_get_ido_slider(VolumeWidget* self)
 {
@@ -234,6 +233,24 @@
 	priv->grabbed = FALSE;
 }
 
+void
+volume_widget_tidy_up (GtkWidget *widget)
+{
+  VolumeWidget* mitem = VOLUME_WIDGET(widget);
+	VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem);
+  gtk_widget_destroy (priv->ido_volume_slider);
+}
+
+gdouble
+volume_widget_get_current_volume ( GtkWidget *widget )
+{
+  VolumeWidget* mitem = VOLUME_WIDGET(widget);
+	VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem);
+  gdouble vol = g_value_get_double (  dbusmenu_menuitem_property_get_value( priv->twin_item,
+	                                                                          DBUSMENU_VOLUME_MENUITEM_LEVEL));  
+  return vol;
+}
+
 /**
  * volume_widget_new:
  * @returns: a new #VolumeWidget.

=== modified file 'src/volume-widget.h'
--- src/volume-widget.h	2010-08-06 12:20:03 +0000
+++ src/volume-widget.h	2010-09-14 17:25:08 +0000
@@ -47,6 +47,8 @@
 GtkWidget* volume_widget_new(DbusmenuMenuitem* twin_item);
 GtkWidget* volume_widget_get_ido_slider(VolumeWidget* self);
 void volume_widget_update(VolumeWidget* self, gdouble update);
+void volume_widget_tidy_up (GtkWidget *widget);
+gdouble volume_widget_get_current_volume ( GtkWidget *widget );
 
 G_END_DECLS
 


Follow ups