Merge lp:~cjcurran/indicator-sound/tests_branch into lp:indicator-sound/0.1

Proposed by Conor Curran
Status: Merged
Merged at revision: not available
Proposed branch: lp:~cjcurran/indicator-sound/tests_branch
Merge into: lp:indicator-sound/0.1
Diff against target: 1525 lines (+959/-200) (has conflicts)
18 files modified
Makefile.am (+1/-0)
configure.ac (+2/-1)
src/Makefile.am (+3/-0)
src/dbus-menu-manager.c (+229/-0)
src/dbus-menu-manager.h (+31/-0)
src/indicator-sound.c (+178/-154)
src/indicator-sound.h (+35/-0)
src/pulse-manager.c (+43/-7)
src/pulse-manager.h (+3/-1)
src/sound-service-dbus.c (+5/-9)
src/sound-service.c (+25/-18)
src/sound-service.h (+1/-10)
tests/Makefile.am (+95/-0)
tests/run-xvfb.sh (+8/-0)
tests/test-defines.h (+24/-0)
tests/test-indicator-sound-dbus-client.c (+112/-0)
tests/test-indicator-sound-dbus-server.c (+63/-0)
tests/test-indicator-sound.c (+101/-0)
Text conflict in src/pulse-manager.c
Text conflict in src/sound-service.c
To merge this branch: bzr merge lp:~cjcurran/indicator-sound/tests_branch
Reviewer Review Type Date Requested Status
Cody Russell (community) Approve
Review via email: mp+20642@code.launchpad.net

Description of the change

This branch contains a big refactor necessary for proper testing. It introduces the need for a dbus_menu_manager c and header living the sound-service.c just containing the main and exit functions
It also contains the start of the testing framework with tests in place for the indicator-sound and sound-service-dbus using dbus-test-runner.

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

Other than obvious merge conflicts, it seems fine.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile.am'
2--- Makefile.am 2010-02-11 20:47:53 +0000
3+++ Makefile.am 2010-03-04 12:22:15 +0000
4@@ -2,6 +2,7 @@
5 SUBDIRS = \
6 src \
7 data \
8+ tests \
9 po
10
11 EXTRA_DIST = autogen.sh
12
13=== modified file 'configure.ac'
14--- configure.ac 2010-03-04 10:56:49 +0000
15+++ configure.ac 2010-03-04 12:22:15 +0000
16@@ -1,5 +1,5 @@
17
18-AC_INIT(src/indicator-sound.c)
19+AC_INIT(indicator-sound, 0.1.2, conor.curran@canonical.com)
20
21 AC_PREREQ(2.53)
22
23@@ -127,6 +127,7 @@
24 Makefile
25 src/Makefile
26 data/Makefile
27+tests/Makefile
28 po/Makefile.in
29 ])
30
31
32=== modified file 'src/Makefile.am'
33--- src/Makefile.am 2010-02-04 06:02:41 +0000
34+++ src/Makefile.am 2010-03-04 12:22:15 +0000
35@@ -8,6 +8,7 @@
36 soundmenulib_LTLIBRARIES = libsoundmenu.la
37 libsoundmenu_la_SOURCES = \
38 common-defs.h \
39+ indicator-sound.h \
40 indicator-sound.c \
41 dbus-shared-names.h \
42 sound-service-client.h \
43@@ -47,6 +48,8 @@
44 common-defs.h \
45 sound-service.h \
46 sound-service.c \
47+ dbus-menu-manager.c \
48+ dbus-menu-manager.h \
49 pulse-manager.h \
50 pulse-manager.c \
51 sound-service-dbus.h \
52
53=== added file 'src/dbus-menu-manager.c'
54--- src/dbus-menu-manager.c 1970-01-01 00:00:00 +0000
55+++ src/dbus-menu-manager.c 2010-03-04 12:22:15 +0000
56@@ -0,0 +1,229 @@
57+/*
58+This service primarily controls PulseAudio and is driven by the sound indicator menu on the panel.
59+Copyright 2010 Canonical Ltd.
60+
61+Authors:
62+ Conor Curran <conor.curran@canonical.com>
63+
64+This program is free software: you can redistribute it and/or modify it
65+under the terms of the GNU General Public License version 3, as published
66+by the Free Software Foundation.
67+
68+This program is distributed in the hope that it will be useful, but
69+WITHOUT ANY WARRANTY; without even the implied warranties of
70+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
71+PURPOSE. See the GNU General Public License for more details.
72+
73+You should have received a copy of the GNU General Public License along
74+with this program. If not, see <http://www.gnu.org/licenses/>.
75+*/
76+
77+#include <dbus/dbus-glib.h>
78+#include <dbus/dbus-glib-bindings.h>
79+
80+#include <libdbusmenu-glib/server.h>
81+#include <libdbusmenu-glib/menuitem.h>
82+#include <libdbusmenu-glib/client.h>
83+
84+#include "dbus-menu-manager.h"
85+#include "sound-service-dbus.h"
86+#include "pulse-manager.h"
87+#include "slider-menu-item.h"
88+
89+#include "dbus-shared-names.h"
90+
91+// DBUS items
92+static DbusmenuMenuitem *root_menuitem = NULL;
93+static DbusmenuMenuitem *mute_all_menuitem = NULL;
94+static SliderMenuItem *volume_slider_menuitem = NULL;
95+static SoundServiceDbus *dbus_interface = NULL;
96+
97+// PULSEAUDIO
98+static gboolean b_sink_available = FALSE;
99+static gboolean b_all_muted = FALSE;
100+static gboolean b_pulse_ready = FALSE;
101+static gboolean b_startup = TRUE;
102+static gdouble volume_percent = 0.0;
103+
104+static void set_global_mute_from_ui();
105+static gboolean idle_routine (gpointer data);
106+static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service);
107+static void refresh_menu();
108+
109+/*-------------------------------------------------------------------------*/
110+// Public Methods
111+/*-------------------------------------------------------------------------*/
112+
113+/**
114+setup:
115+**/
116+void dbus_menu_manager_setup()
117+{
118+ root_menuitem = dbusmenu_menuitem_new();
119+ g_debug("Root ID: %d", dbusmenu_menuitem_get_id(root_menuitem));
120+
121+ g_idle_add(idle_routine, root_menuitem);
122+
123+ dbus_interface = g_object_new(SOUND_SERVICE_DBUS_TYPE, NULL);
124+
125+ DbusmenuServer *server = dbusmenu_server_new(INDICATOR_SOUND_DBUS_OBJECT);
126+ dbusmenu_server_set_root(server, root_menuitem);
127+ establish_pulse_activities(dbus_interface);
128+}
129+
130+/**
131+teardown:
132+**/
133+void dbus_menu_manager_teardown()
134+{
135+ //TODO tidy up dbus_interface and items!
136+}
137+
138+/**
139+update_pa_state:
140+**/
141+void dbus_menu_manager_update_pa_state(gboolean pa_state, gboolean sink_available, gboolean sink_muted, gdouble percent)
142+{
143+ b_sink_available = sink_available;
144+ b_all_muted = sink_muted;
145+ b_pulse_ready = pa_state;
146+ volume_percent = percent;
147+ g_debug("update pa state with state %i, availability of %i, mute value of %i and a volume percent is %f", pa_state, sink_available, sink_muted, volume_percent);
148+ // Only rebuild the menu on start up...
149+ if(b_startup == TRUE){
150+ rebuild_sound_menu(root_menuitem, dbus_interface);
151+ b_startup = FALSE;
152+ }
153+ else{
154+ refresh_menu();
155+ }
156+ // Emit the signals after the menus are setup/torn down
157+ sound_service_dbus_update_sink_volume(dbus_interface, percent);
158+ sound_service_dbus_update_sink_mute(dbus_interface, sink_muted);
159+ dbus_menu_manager_update_mute_ui(b_all_muted);
160+}
161+
162+/**
163+update_mute_ui:
164+'public' method allowing the pa manager to update the mute menu item.
165+**/
166+void dbus_menu_manager_update_mute_ui(gboolean incoming_mute_value)
167+{
168+ b_all_muted = incoming_mute_value;
169+ dbusmenu_menuitem_property_set(mute_all_menuitem,
170+ DBUSMENU_MENUITEM_PROP_LABEL,
171+ (b_all_muted == FALSE ? "Mute All" : "Unmute"));
172+}
173+
174+
175+/*-------------------------------------------------------------------------*/
176+// Private Methods
177+/*-------------------------------------------------------------------------*/
178+
179+static void refresh_menu()
180+{
181+ g_debug("in the refresh menu method");
182+ if(b_sink_available == FALSE || b_pulse_ready == FALSE)
183+ {
184+
185+ dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem),
186+ DBUSMENU_MENUITEM_PROP_ENABLED,
187+ FALSE);
188+ dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem),
189+ DBUSMENU_MENUITEM_PROP_VISIBLE,
190+ FALSE);
191+ dbusmenu_menuitem_property_set_bool(mute_all_menuitem,
192+ DBUSMENU_MENUITEM_PROP_ENABLED,
193+ FALSE);
194+
195+ }
196+ else if(b_sink_available == TRUE && b_pulse_ready == TRUE){
197+
198+ dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem),
199+ DBUSMENU_MENUITEM_PROP_ENABLED,
200+ TRUE);
201+ dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem),
202+ DBUSMENU_MENUITEM_PROP_VISIBLE,
203+ TRUE);
204+ dbusmenu_menuitem_property_set_bool(mute_all_menuitem,
205+ DBUSMENU_MENUITEM_PROP_ENABLED,
206+ TRUE);
207+ }
208+}
209+
210+
211+
212+/**
213+
214+**/
215+static gboolean idle_routine (gpointer data)
216+{
217+ return FALSE;
218+}
219+
220+
221+
222+/**
223+show_sound_settings_dialog:
224+Bring up the gnome volume preferences dialog
225+**/
226+static void show_sound_settings_dialog (DbusmenuMenuitem *mi, gpointer user_data)
227+{
228+ GError * error = NULL;
229+ if (!g_spawn_command_line_async("gnome-volume-control", &error))
230+ {
231+ g_warning("Unable to show dialog: %s", error->message);
232+ g_error_free(error);
233+ }
234+}
235+
236+/**
237+rebuild_sound_menu:
238+Build the DBus menu items, mute/unmute, slider, separator and sound preferences 'link'
239+**/
240+static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service)
241+{
242+ // Mute button
243+ mute_all_menuitem = dbusmenu_menuitem_new();
244+ dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, (b_all_muted == FALSE ? "Mute All" : "Unmute"));
245+ g_signal_connect(G_OBJECT(mute_all_menuitem), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(set_global_mute_from_ui), NULL);
246+ dbusmenu_menuitem_property_set_bool(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_ENABLED, b_sink_available);
247+
248+ // Slider
249+ volume_slider_menuitem = slider_menu_item_new(b_sink_available, volume_percent);
250+ dbusmenu_menuitem_child_append(root, mute_all_menuitem);
251+ dbusmenu_menuitem_child_append(root, DBUSMENU_MENUITEM(volume_slider_menuitem));
252+ dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem),
253+ DBUSMENU_MENUITEM_PROP_ENABLED,
254+ b_sink_available);
255+ dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem),
256+ DBUSMENU_MENUITEM_PROP_VISIBLE,
257+ b_sink_available);
258+ // Separator
259+ DbusmenuMenuitem *separator = dbusmenu_menuitem_new();
260+ dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
261+ dbusmenu_menuitem_child_append(root, separator);
262+
263+ // Sound preferences dialog
264+ DbusmenuMenuitem *settings_mi = dbusmenu_menuitem_new();
265+ dbusmenu_menuitem_property_set(settings_mi, DBUSMENU_MENUITEM_PROP_LABEL,
266+ ("Sound Preferences..."));
267+ dbusmenu_menuitem_child_append(root, settings_mi);
268+ g_signal_connect(G_OBJECT(settings_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
269+ G_CALLBACK(show_sound_settings_dialog), NULL);
270+}
271+
272+/**
273+set_global_mute_from_ui:
274+Callback for the dbusmenuitem button
275+**/
276+static void set_global_mute_from_ui()
277+{
278+ b_all_muted = !b_all_muted;
279+ toggle_global_mute(b_all_muted);
280+ dbusmenu_menuitem_property_set(mute_all_menuitem,
281+ DBUSMENU_MENUITEM_PROP_LABEL,
282+ (b_all_muted == FALSE ? "Mute All" : "Unmute"));
283+}
284+
285+
286
287=== added file 'src/dbus-menu-manager.h'
288--- src/dbus-menu-manager.h 1970-01-01 00:00:00 +0000
289+++ src/dbus-menu-manager.h 2010-03-04 12:22:15 +0000
290@@ -0,0 +1,31 @@
291+#ifndef __INCLUDE_DBUS_MENU_MANAGER_H__
292+#define __INCLUDE_DBUS_MENU_MANAGER_H__
293+
294+/*
295+This handles the management of the dbusmeneu items.
296+Copyright 2010 Canonical Ltd.
297+
298+Authors:
299+ Conor Curran <conor.curran@canonical.com>
300+
301+This program is free software: you can redistribute it and/or modify it
302+under the terms of the GNU General Public License version 3, as published
303+by the Free Software Foundation.
304+
305+This program is distributed in the hope that it will be useful, but
306+WITHOUT ANY WARRANTY; without even the implied warranties of
307+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
308+PURPOSE. See the GNU General Public License for more details.
309+
310+You should have received a copy of the GNU General Public License along
311+with this program. If not, see <http://www.gnu.org/licenses/>.
312+*/
313+
314+void dbus_menu_manager_setup();
315+void dbus_menu_manager_teardown();
316+void dbus_menu_manager_update_pa_state(gboolean pa_state, gboolean sink_available, gboolean sink_muted, gdouble current_vol);
317+// TODO update pa_state should incorporate the method below !
318+void dbus_menu_manager_update_mute_ui(gboolean incoming_mute_value);
319+
320+#endif
321+
322
323=== modified file 'src/indicator-sound.c'
324--- src/indicator-sound.c 2010-03-03 17:33:28 +0000
325+++ src/indicator-sound.c 2010-03-04 12:22:15 +0000
326@@ -35,7 +35,7 @@
327 #include <libindicator/indicator-object.h>
328 #include <libindicator/indicator-service-manager.h>
329
330-
331+#include "indicator-sound.h"
332 #include "dbus-shared-names.h"
333 #include "sound-service-client.h"
334 #include "common-defs.h"
335@@ -90,23 +90,23 @@
336 // DBUS communication
337 static DBusGProxy *sound_dbus_proxy = NULL;
338 static void connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer userdata);
339-static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean value, gpointer userdata);
340+/*static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean value, gpointer userdata);*/
341 static void catch_signal_sink_volume_update(DBusGProxy * proxy, gdouble volume_percent, gpointer userdata);
342 static void catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value, gpointer userdata);
343 static void fetch_volume_percent_from_dbus();
344 static void fetch_mute_value_from_dbus();
345
346 /****Volume States 'members' ***/
347-static void prepare_state_machine();
348-static void determine_state_from_volume(gdouble volume_percent);
349 static void update_state(const gint state);
350+
351 static const gint STATE_MUTED = 0;
352 static const gint STATE_ZERO = 1;
353 static const gint STATE_LOW = 2;
354 static const gint STATE_MEDIUM = 3;
355 static const gint STATE_HIGH = 4;
356 static const gint STATE_MUTED_WHILE_INPUT = 5;
357-static const gint STATE_SINKS_NONE = 5;
358+static const gint STATE_SINKS_NONE = 6;
359+
360 static GHashTable *volume_states = NULL;
361 static GtkImage *speaker_image = NULL;
362 static GtkWidget* primary_image = NULL;
363@@ -115,6 +115,7 @@
364 static gdouble initial_volume_percent = 0;
365 static gboolean initial_mute = FALSE;
366
367+// Construction
368 static void
369 indicator_sound_class_init (IndicatorSoundClass *klass)
370 {
371@@ -128,11 +129,11 @@
372 io_class->get_image = get_icon;
373 io_class->get_menu = get_menu;
374
375- dbus_g_object_register_marshaller (_sound_service_marshal_VOID__INT_BOOLEAN,
376- G_TYPE_NONE,
377- G_TYPE_INT,
378- G_TYPE_BOOLEAN,
379- G_TYPE_INVALID);
380+/* dbus_g_object_register_marshaller (_sound_service_marshal_VOID__INT_BOOLEAN,*/
381+/* G_TYPE_NONE,*/
382+/* G_TYPE_INT,*/
383+/* G_TYPE_BOOLEAN,*/
384+/* G_TYPE_INVALID);*/
385 return;
386 }
387
388@@ -147,26 +148,97 @@
389 return;
390 }
391
392-
393-/*
394-Prepare states Array.
395-*/
396-static void prepare_state_machine()
397-{
398- // TODO we need three more images
399- volume_states = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
400- g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED), g_strdup("audio-volume-muted-panel"));
401- g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_ZERO), g_strdup("audio-volume-zero-panel"));
402- g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_LOW), g_strdup("audio-volume-low-panel"));
403- g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MEDIUM), g_strdup("audio-volume-medium-panel"));
404- g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_HIGH), g_strdup("audio-volume-high-panel"));
405- g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT), g_strdup("audio-volume-muted-blocking-panel"));
406- g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_SINKS_NONE), g_strdup("audio-output-none-panel"));
407+static void
408+indicator_sound_dispose (GObject *object)
409+{
410+ IndicatorSound * self = INDICATOR_SOUND(object);
411+
412+ if (self->service != NULL) {
413+ g_object_unref(G_OBJECT(self->service));
414+ self->service = NULL;
415+ }
416+ g_hash_table_destroy(volume_states);
417+ G_OBJECT_CLASS (indicator_sound_parent_class)->dispose (object);
418+ return;
419+}
420+
421+static void
422+indicator_sound_finalize (GObject *object)
423+{
424+ G_OBJECT_CLASS (indicator_sound_parent_class)->finalize (object);
425+ return;
426+}
427+
428+static GtkLabel *
429+get_label (IndicatorObject * io)
430+{
431+ return NULL;
432+}
433+
434+static GtkImage *
435+get_icon (IndicatorObject * io)
436+{
437+ gchar* current_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state));
438+ //g_debug("At start-up attempting to set the image to %s", current_name);
439+ speaker_image = GTK_IMAGE(gtk_image_new_from_icon_name(current_name, GTK_ICON_SIZE_MENU));
440+ gtk_widget_show(GTK_WIDGET(speaker_image));
441+ return speaker_image;
442+}
443+
444+/* Indicator based function to get the menu for the whole
445+ applet. This starts up asking for the parts of the menu
446+ from the various services. */
447+static GtkMenu *
448+get_menu (IndicatorObject * io)
449+{
450+ DbusmenuGtkMenu *menu = dbusmenu_gtkmenu_new(INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_DBUS_OBJECT);
451+ DbusmenuGtkClient *client = dbusmenu_gtkmenu_get_client(menu);
452+ dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_SLIDER_MENUITEM_TYPE, new_slider_item);
453+
454+ // register Key-press listening on the menu widget as the slider does not allow this.
455+ g_signal_connect(menu, "key-press-event", G_CALLBACK(key_press_cb), NULL);
456+
457+ return GTK_MENU(menu);
458+}
459+
460+/**
461+new_slider_item:
462+Create a new dBusMenu Slider item.
463+**/
464+static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
465+{
466+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
467+ g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
468+
469+ volume_slider = ido_scale_menu_item_new_with_range ("Volume", initial_volume_percent, 0, 100, 0.5);
470+ g_object_set(volume_slider, "reverse-scroll-events", TRUE, NULL);
471+
472+ GtkMenuItem *menu_volume_slider = GTK_MENU_ITEM(volume_slider);
473+
474+ dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_volume_slider, parent);
475+ g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(slider_prop_change_cb), volume_slider);
476+
477+ // register slider changes listening on the range
478+ GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider);
479+ g_signal_connect(slider, "value-changed", G_CALLBACK(value_changed_event_cb), newitem);
480+ // alternative callback mechanism which i could use again at some point.
481+/* g_signal_connect(slider, "change-value", G_CALLBACK(user_change_value_event_cb), newitem); */
482+
483+ // Set images on the ido
484+ primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)volume_slider);
485+ gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), GTK_ICON_SIZE_MENU);
486+ GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)volume_slider);
487+ gtk_image_set_from_icon_name(GTK_IMAGE(secondary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)), GTK_ICON_SIZE_MENU);
488+
489+ gtk_widget_show_all(volume_slider);
490+
491+ return TRUE;
492 }
493
494 static void
495 connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer userdata)
496 {
497+ // TODO: This could be safer.
498 if (connected) {
499 if (sound_dbus_proxy == NULL) {
500 GError * error = NULL;
501@@ -186,7 +258,7 @@
502 g_debug("about to connect to the signals");
503 dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_TYPE_BOOLEAN, G_TYPE_INVALID);
504
505- dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_CALLBACK(catch_signal_sink_input_while_muted), NULL, NULL);
506+/* dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_CALLBACK(catch_signal_sink_input_while_muted), NULL, NULL);*/
507 dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_VOLUME_UPDATE, G_TYPE_DOUBLE, G_TYPE_INVALID);
508 dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_VOLUME_UPDATE, G_CALLBACK(catch_signal_sink_volume_update), NULL, NULL);
509 dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID);
510@@ -205,6 +277,82 @@
511 return;
512 }
513
514+
515+
516+
517+/*
518+Prepare states Array.
519+*/
520+void prepare_state_machine()
521+{
522+ // TODO we need three more images
523+ volume_states = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
524+ g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED), g_strdup("audio-volume-muted-panel"));
525+ g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_ZERO), g_strdup("audio-volume-low-zero-panel"));
526+ g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_LOW), g_strdup("audio-volume-low-panel"));
527+ g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MEDIUM), g_strdup("audio-volume-medium-panel"));
528+ g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_HIGH), g_strdup("audio-volume-high-panel"));
529+ g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT), g_strdup("audio-volume-muted-blocking-panel"));
530+ g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_SINKS_NONE), g_strdup("audio-output-none-panel"));
531+}
532+
533+gint get_state()
534+{
535+ return current_state;
536+}
537+
538+gchar* get_state_image_name(gint state)
539+{
540+ return g_hash_table_lookup(volume_states, GINT_TO_POINTER(state));
541+}
542+
543+void prepare_for_tests(IndicatorObject *io)
544+{
545+ prepare_state_machine();
546+ get_icon(io);
547+}
548+
549+void tidy_up_hash()
550+{
551+ g_hash_table_destroy(volume_states);
552+}
553+
554+static void update_state(const gint state)
555+{
556+/* g_debug("update state beginning - previous_state = %i", previous_state);*/
557+
558+ previous_state = current_state;
559+
560+/* g_debug("update state 3rd line - previous_state = %i", previous_state);*/
561+
562+ current_state = state;
563+ gchar* image_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state));
564+ gtk_image_set_from_icon_name(speaker_image, image_name, GTK_ICON_SIZE_MENU);
565+}
566+
567+
568+void determine_state_from_volume(gdouble volume_percent)
569+{
570+/* g_debug("determine_state_from_volume - previous_state = %i", previous_state);*/
571+
572+ gint state = previous_state;
573+ if (volume_percent < 30.0 && volume_percent > 0){
574+ state = STATE_LOW;
575+ }
576+ else if(volume_percent < 70.0 && volume_percent >= 30.0){
577+ state = STATE_MEDIUM;
578+ }
579+ else if(volume_percent >= 70.0){
580+ state = STATE_HIGH;
581+ }
582+ else if(volume_percent == 0.0){
583+ state = STATE_ZERO;
584+ }
585+ update_state(state);
586+}
587+
588+
589+
590 static void fetch_volume_percent_from_dbus()
591 {
592 GError * error = NULL;
593@@ -242,10 +390,10 @@
594 g_debug("at the indicator start up and the MUTE returned from dbus method is %i", initial_mute);
595 }
596
597-static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean block_value, gpointer userdata)
598-{
599- g_debug("signal caught - sink input while muted with value %i", block_value);
600-}
601+/*static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean block_value, gpointer userdata)*/
602+/*{*/
603+/* g_debug("signal caught - sink input while muted with value %i", block_value);*/
604+/*}*/
605
606 static void catch_signal_sink_volume_update(DBusGProxy *proxy, gdouble volume_percent, gpointer userdata)
607 {
608@@ -270,130 +418,6 @@
609 g_debug("signal caught - sink mute update with mute value: %i", mute_value);
610 gtk_widget_set_sensitive(volume_slider, !mute_value);
611 }
612-
613-
614-static void
615-indicator_sound_dispose (GObject *object)
616-{
617- IndicatorSound * self = INDICATOR_SOUND(object);
618-
619- if (self->service != NULL) {
620- g_object_unref(G_OBJECT(self->service));
621- self->service = NULL;
622- }
623- g_hash_table_destroy(volume_states);
624- G_OBJECT_CLASS (indicator_sound_parent_class)->dispose (object);
625- return;
626-}
627-
628-static void
629-indicator_sound_finalize (GObject *object)
630-{
631- G_OBJECT_CLASS (indicator_sound_parent_class)->finalize (object);
632- return;
633-}
634-
635-static GtkLabel *
636-get_label (IndicatorObject * io)
637-{
638- return NULL;
639-}
640-
641-static GtkImage *
642-get_icon (IndicatorObject * io)
643-{
644- gchar* current_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state));
645- g_debug("At start-up attempting to set the image to %s", current_name);
646- speaker_image = GTK_IMAGE(gtk_image_new_from_icon_name(current_name, GTK_ICON_SIZE_MENU));
647- gtk_widget_show(GTK_WIDGET(speaker_image));
648- return speaker_image;
649-}
650-
651-static void update_state(const gint state)
652-{
653-/* g_debug("update state beginning - previous_state = %i", previous_state);*/
654-
655- previous_state = current_state;
656-
657-/* g_debug("update state 3rd line - previous_state = %i", previous_state);*/
658-
659- current_state = state;
660- gchar* image_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state));
661- gtk_image_set_from_icon_name(speaker_image, image_name, GTK_ICON_SIZE_MENU);
662-}
663-
664-
665-static void determine_state_from_volume(gdouble volume_percent)
666-{
667-/* g_debug("determine_state_from_volume - previous_state = %i", previous_state);*/
668-
669- gint state = previous_state;
670- if (volume_percent < 30.0 && volume_percent > 0){
671- state = STATE_LOW;
672- }
673- else if(volume_percent < 70.0 && volume_percent > 30.0){
674- state = STATE_MEDIUM;
675- }
676- else if(volume_percent > 70.0){
677- state = STATE_HIGH;
678- }
679- else if(volume_percent == 0.0){
680- state = STATE_ZERO;
681- }
682- update_state(state);
683-}
684-
685-
686-/* Indicator based function to get the menu for the whole
687- applet. This starts up asking for the parts of the menu
688- from the various services. */
689-static GtkMenu *
690-get_menu (IndicatorObject * io)
691-{
692- DbusmenuGtkMenu *menu = dbusmenu_gtkmenu_new(INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_DBUS_OBJECT);
693- DbusmenuGtkClient *client = dbusmenu_gtkmenu_get_client(menu);
694- dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_SLIDER_MENUITEM_TYPE, new_slider_item);
695-
696- // register Key-press listening on the menu widget as the slider does not allow this.
697- g_signal_connect(menu, "key-press-event", G_CALLBACK(key_press_cb), NULL);
698-
699- return GTK_MENU(menu);
700-}
701-
702-/**
703-new_slider_item:
704-Create a new dBusMenu Slider item, register the
705-**/
706-static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
707-{
708- g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
709- g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
710-
711- volume_slider = ido_scale_menu_item_new_with_range ("Volume", initial_volume_percent, 0, 100, 0.5);
712- g_object_set(volume_slider, "reverse-scroll-events", TRUE, NULL);
713-
714- GtkMenuItem *menu_volume_slider = GTK_MENU_ITEM(volume_slider);
715-
716- dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_volume_slider, parent);
717- g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(slider_prop_change_cb), volume_slider);
718-
719- // register slider changes listening on the range
720- GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider);
721- g_signal_connect(slider, "value-changed", G_CALLBACK(value_changed_event_cb), newitem);
722- // alternative callback mechanism which i could use again at some point.
723-/* g_signal_connect(slider, "change-value", G_CALLBACK(user_change_value_event_cb), newitem); */
724-
725- // Set images on the ido
726- primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)volume_slider);
727- gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), GTK_ICON_SIZE_MENU);
728- GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)volume_slider);
729- gtk_image_set_from_icon_name(GTK_IMAGE(secondary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)), GTK_ICON_SIZE_MENU);
730-
731- gtk_widget_show_all(volume_slider);
732-
733- return TRUE;
734-}
735-
736 /**
737 slider_prop_change_cb:
738 Whenever we have a property change on a DbusmenuMenuitem this will be called.
739
740=== added file 'src/indicator-sound.h'
741--- src/indicator-sound.h 1970-01-01 00:00:00 +0000
742+++ src/indicator-sound.h 2010-03-04 12:22:15 +0000
743@@ -0,0 +1,35 @@
744+#ifndef __INCLUDE_INDICATOR_SOUND_H__
745+#define __INCLUDE_INDICATOR_SOUND_H__
746+
747+/*
748+A small wrapper utility to load indicators and put them as menu items
749+into the gnome-panel using it's applet interface.
750+
751+Copyright 2010 Canonical Ltd.
752+
753+Authors:
754+ Conor Curran <conor.curra@canonical.com>
755+ Ted Gould <ted@canonical.com>
756+
757+This program is free software: you can redistribute it and/or modify it
758+under the terms of the GNU General Public License version 3, as published
759+by the Free Software Foundation.
760+
761+This program is distributed in the hope that it will be useful, but
762+WITHOUT ANY WARRANTY; without even the implied warranties of
763+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
764+PURPOSE. See the GNU General Public License for more details.
765+
766+You should have received a copy of the GNU General Public License along
767+with this program. If not, see <http://www.gnu.org/licenses/>.
768+*/
769+
770+// Essentially these are all exported to faciltiate testing
771+void prepare_state_machine();
772+void determine_state_from_volume(gdouble volume_percent);
773+gint get_state();
774+gchar* get_state_image_name(gint state);
775+void prepare_for_tests(IndicatorObject * io);
776+void tidy_up_hash();
777+
778+#endif
779
780=== modified file 'src/pulse-manager.c'
781--- src/pulse-manager.c 2010-02-26 14:40:28 +0000
782+++ src/pulse-manager.c 2010-03-04 12:22:15 +0000
783@@ -26,8 +26,7 @@
784 #include <pulse/gccmacro.h>
785
786 #include "pulse-manager.h"
787-#include "sound-service.h"
788-
789+#include "dbus-menu-manager.h"
790
791 static GHashTable *sink_hash = NULL;
792 static SoundServiceDbus *dbus_service = NULL;
793@@ -68,10 +67,17 @@
794
795 // Establish event callback registration
796 pa_context_set_state_callback(pulse_context, context_state_callback, NULL);
797+<<<<<<< TREE
798 // BUILD MENU ANYWHO - it will be updated
799 update_pa_state(FALSE, FALSE, FALSE, 0);
800
801 pa_context_connect(pulse_context, NULL, PA_CONTEXT_NOFAIL, NULL);
802+=======
803+ // BUILD MENU ANYWHO - it will be updated
804+ dbus_menu_manager_update_pa_state(FALSE, FALSE, FALSE, 0);
805+
806+ pa_context_connect(pulse_context, NULL, PA_CONTEXT_NOFAIL, NULL);
807+>>>>>>> MERGE-SOURCE
808 }
809
810 void close_pulse_activites()
811@@ -87,6 +93,7 @@
812 g_debug("I just closed communication with Pulse");
813 }
814
815+<<<<<<< TREE
816 /**
817 reconnect_to_pulse()
818 In the event of Pulseaudio flapping in the wind handle gracefully without
819@@ -111,6 +118,32 @@
820 update_pa_state(FALSE, FALSE, FALSE, 0);
821 pa_context_connect(pulse_context, NULL, PA_CONTEXT_NOFAIL, NULL);
822 }
823+=======
824+/**
825+reconnect_to_pulse()
826+In the event of Pulseaudio flapping in the wind handle gracefully without
827+memory leaks !
828+*/
829+static void reconnect_to_pulse()
830+{
831+ // reset
832+ if (pulse_context != NULL){
833+ g_debug("freeing the pulse context");
834+ pa_context_unref(pulse_context);
835+ pulse_context = NULL;
836+ }
837+ g_hash_table_destroy(sink_hash);
838+
839+ // reconnect
840+ pulse_context = pa_context_new(pa_glib_mainloop_get_api(pa_main_loop), "ayatana.indicator.sound");
841+ g_assert(pulse_context);
842+ sink_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, destroy_sink_info);
843+ // Establish event callback registration
844+ pa_context_set_state_callback(pulse_context, context_state_callback, NULL);
845+ dbus_menu_manager_update_pa_state(FALSE, FALSE, FALSE, 0);
846+ pa_context_connect(pulse_context, NULL, PA_CONTEXT_NOFAIL, NULL);
847+}
848+>>>>>>> MERGE-SOURCE
849
850 static void destroy_sink_info(void *value)
851 {
852@@ -276,12 +309,15 @@
853 gboolean device_available = determine_sink_availability();
854 if(device_available == TRUE)
855 {
856- update_pa_state(TRUE, device_available, default_sink_is_muted(), get_default_sink_volume());
857+ dbus_menu_manager_update_pa_state(TRUE,
858+ device_available,
859+ default_sink_is_muted(),
860+ get_default_sink_volume());
861 }
862 else{
863 //Update the indicator to show PA either is not ready or has no available sink
864 g_warning("Cannot find a suitable default sink ...");
865- update_pa_state(FALSE, device_available, TRUE, 0);
866+ dbus_menu_manager_update_pa_state(FALSE, device_available, TRUE, 0);
867 }
868 }
869 else{
870@@ -322,7 +358,7 @@
871 }
872 else
873 {
874- update_pa_state(TRUE, determine_sink_availability(), default_sink_is_muted(), get_default_sink_volume());
875+ dbus_menu_manager_update_pa_state(TRUE, determine_sink_availability(), default_sink_is_muted(), get_default_sink_volume());
876 }
877 }
878 }
879@@ -385,7 +421,7 @@
880 {
881 g_debug("Updating Mute from PA manager with mute = %i", s->mute);
882 sound_service_dbus_update_sink_mute(dbus_service, s->mute);
883- update_mute_ui(s->mute);
884+ dbus_menu_manager_update_mute_ui(s->mute);
885 if(s->mute == FALSE){
886 pa_volume_t vol = pa_cvolume_avg(&s->volume);
887 gdouble volume_percent = ((gdouble) vol * 100) / PA_VOLUME_NORM;
888@@ -421,7 +457,7 @@
889 if (info == NULL)
890 {
891 g_warning("No server - get the hell out of here");
892- update_pa_state(FALSE, FALSE, TRUE, 0);
893+ dbus_menu_manager_update_pa_state(FALSE, FALSE, TRUE, 0);
894 pa_server_available = FALSE;
895 return;
896 }
897
898=== modified file 'src/pulse-manager.h'
899--- src/pulse-manager.h 2010-02-11 15:19:22 +0000
900+++ src/pulse-manager.h 2010-03-04 12:22:15 +0000
901@@ -1,3 +1,5 @@
902+#ifndef __INCLUDE_PULSE_MANAGER_H__
903+#define __INCLUDE_PULSE_MANAGER_H__
904 /*
905 A small wrapper utility to load indicators and put them as menu items
906 into the gnome-panel using it's applet interface.
907@@ -21,7 +23,6 @@
908 */
909
910
911-
912 #include <pulse/pulseaudio.h>
913 #include <glib.h>
914 #include "sound-service-dbus.h"
915@@ -47,4 +48,5 @@
916 void toggle_global_mute(gboolean mute_value);
917 void close_pulse_activites();
918
919+#endif
920
921
922=== modified file 'src/sound-service-dbus.c'
923--- src/sound-service-dbus.c 2010-02-16 16:37:27 +0000
924+++ src/sound-service-dbus.c 2010-03-04 12:22:15 +0000
925@@ -29,8 +29,7 @@
926 #include "sound-service-marshal.h"
927 #include "pulse-manager.h"
928
929-// DBUS methods -
930-// TODO - other should be static and moved from the header to here
931+// DBUS methods
932 static gboolean sound_service_dbus_get_sink_volume(SoundServiceDbus* service, gdouble* volume_percent_input, GError** gerror);
933 static gboolean sound_service_dbus_get_sink_mute(SoundServiceDbus* service, gboolean* mute_input, GError** gerror);
934 static void sound_service_dbus_set_sink_volume(SoundServiceDbus* service, const guint volume_percent, GError** gerror);
935@@ -41,7 +40,6 @@
936
937 struct _SoundServiceDbusPrivate
938 {
939- DBusGConnection *system_bus;
940 DBusGConnection *connection;
941 gdouble volume_percent;
942 gboolean mute;
943@@ -50,7 +48,7 @@
944
945 /* Signals */
946 enum {
947- SINK_INPUT_WHILE_MUTED,
948+ SINK_INPUT_WHILE_MUTED,
949 SINK_VOLUME_UPDATE,
950 SINK_MUTE_UPDATE,
951 LAST_SIGNAL
952@@ -116,20 +114,18 @@
953 GError *error = NULL;
954 SoundServiceDbusPrivate * priv = SOUND_SERVICE_DBUS_GET_PRIVATE(self);
955
956- priv->system_bus = NULL;
957 priv->connection = NULL;
958 priv->volume_percent = 0;
959
960- /* Get the system bus */
961- priv->system_bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
962- /* Put the object on DBus */
963+ /* Fetch the session bus */
964 priv->connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
965
966 if (error != NULL) {
967- g_error("Unable to connect to the session bus when creating application indicator: %s", error->message);
968+ g_error("sound-service-dbus:Unable to connect to the session bus when creating indicator sound service : %s", error->message);
969 g_error_free(error);
970 return;
971 }
972+ /* register the service on it */
973 dbus_g_connection_register_g_object(priv->connection,
974 "/org/ayatana/indicator/sound/service",
975 G_OBJECT(self));
976
977=== modified file 'src/sound-service.c'
978--- src/sound-service.c 2010-03-03 17:40:55 +0000
979+++ src/sound-service.c 2010-03-04 12:22:15 +0000
980@@ -19,15 +19,13 @@
981 You should have received a copy of the GNU General Public License along
982 with this program. If not, see <http://www.gnu.org/licenses/>.
983 */
984+
985 #include "sound-service.h"
986-#include "sound-service-dbus.h"
987+#include "dbus-menu-manager.h"
988 #include "pulse-manager.h"
989-#include "slider-menu-item.h"
990-#include "common-defs.h"
991-
992-
993-// GTK + DBUS
994+
995 static GMainLoop *mainloop = NULL;
996+<<<<<<< TREE
997 static DbusmenuMenuitem *root_menuitem = NULL;
998 static DbusmenuMenuitem *mute_all_menuitem = NULL;
999 static SliderMenuItem *volume_slider_menuitem = NULL;
1000@@ -130,6 +128,18 @@
1001 /* When the service interface starts to shutdown, we
1002 should follow it. -
1003 */
1004+=======
1005+
1006+/**********************************************************************************************************************/
1007+// Init and exit functions
1008+/**********************************************************************************************************************/
1009+
1010+/**
1011+service_shutdown:
1012+When the service interface starts to shutdown, we
1013+should follow it.
1014+**/
1015+>>>>>>> MERGE-SOURCE
1016 void
1017 service_shutdown (IndicatorService *service, gpointer user_data)
1018 {
1019@@ -137,12 +147,13 @@
1020 if (mainloop != NULL) {
1021 g_debug("Service shutdown !");
1022 // TODO: uncomment for release !!
1023- close_pulse_activites();
1024- g_main_loop_quit(mainloop);
1025+/* close_pulse_activites();*/
1026+/* g_main_loop_quit(mainloop);*/
1027 }
1028 return;
1029 }
1030
1031+<<<<<<< TREE
1032 void update_pa_state(gboolean pa_state, gboolean sink_available, gboolean sink_muted, gdouble percent)
1033 {
1034 b_sink_available = sink_available;
1035@@ -198,6 +209,11 @@
1036
1037 /* Main, is well, main. It brings everything up and throws
1038 us into the mainloop of no return. Some refactoring needed.*/
1039+=======
1040+/**
1041+main:
1042+**/
1043+>>>>>>> MERGE-SOURCE
1044 int
1045 main (int argc, char ** argv)
1046 {
1047@@ -213,16 +229,7 @@
1048 INDICATOR_SERVICE_SIGNAL_SHUTDOWN,
1049 G_CALLBACK(service_shutdown), NULL);
1050
1051- root_menuitem = dbusmenu_menuitem_new();
1052- g_debug("Root ID: %d", dbusmenu_menuitem_get_id(root_menuitem));
1053-
1054- g_idle_add(idle_routine, root_menuitem);
1055-
1056- dbus_interface = g_object_new(SOUND_SERVICE_DBUS_TYPE, NULL);
1057-
1058- DbusmenuServer *server = dbusmenu_server_new(INDICATOR_SOUND_DBUS_OBJECT);
1059- dbusmenu_server_set_root(server, root_menuitem);
1060- establish_pulse_activities(dbus_interface);
1061+ dbus_menu_manager_setup();
1062
1063 // Run the loop
1064 mainloop = g_main_loop_new(NULL, FALSE);
1065
1066=== modified file 'src/sound-service.h'
1067--- src/sound-service.h 2010-02-08 19:19:07 +0000
1068+++ src/sound-service.h 2010-03-04 12:22:15 +0000
1069@@ -27,13 +27,6 @@
1070 #include <unistd.h>
1071 #include <glib/gi18n.h>
1072
1073-#include <dbus/dbus-glib.h>
1074-#include <dbus/dbus-glib-bindings.h>
1075-
1076-#include <libdbusmenu-glib/server.h>
1077-#include <libdbusmenu-glib/menuitem.h>
1078-#include <libdbusmenu-glib/client.h>
1079-
1080 #include <libindicator/indicator-service.h>
1081
1082 #include "dbus-shared-names.h"
1083@@ -41,7 +34,5 @@
1084 // ENTRY AND EXIT POINTS
1085 void service_shutdown(IndicatorService * service, gpointer user_data);
1086 int main (int argc, char ** argv);
1087-void update_pa_state(gboolean pa_state, gboolean sink_available, gboolean sink_muted, gdouble current_vol);
1088-void update_mute_ui(gboolean incoming_mute_value);
1089+
1090 #endif
1091-
1092
1093=== added directory 'tests'
1094=== added file 'tests/Makefile.am'
1095--- tests/Makefile.am 1970-01-01 00:00:00 +0000
1096+++ tests/Makefile.am 2010-03-04 12:22:15 +0000
1097@@ -0,0 +1,95 @@
1098+
1099+check_PROGRAMS = \
1100+ test-indicator-sound \
1101+ test-indicator-sound-dbus-client \
1102+ test-indicator-sound-dbus-server
1103+
1104+TESTS =
1105+DISTCLEANFILES = $(TESTS)
1106+
1107+#########################################
1108+## test-indicator-sound
1109+#########################################
1110+test_indicator_sound_SOURCES = \
1111+ test-indicator-sound.c \
1112+ $(top_builddir)/src/indicator-sound.c
1113+
1114+test_indicator_sound_CFLAGS = \
1115+ $(APPLET_CFLAGS) \
1116+ -Wall -Werror \
1117+ -I$(srcdir) \
1118+ -DTOP_BUILD_DIR="\"${abs_top_builddir}\""
1119+
1120+test_indicator_sound_LDADD = \
1121+ $(APPLET_LIBS)
1122+
1123+
1124+#########################################
1125+## test-indicator-sound-dbus-client
1126+#########################################
1127+test_indicator_sound_dbus_client_SOURCES = \
1128+ test-defines.h \
1129+ test-indicator-sound-dbus-client.c
1130+
1131+test_indicator_sound_dbus_client_CFLAGS = \
1132+ $(SOUNDSERVICE_CFLAGS) \
1133+ -Wall -Werror \
1134+ -I$(srcdir)
1135+
1136+test_indicator_sound_dbus_client_LDADD = \
1137+ $(SOUNDSERVICE_LIBS)
1138+
1139+########################################
1140+# test-indicator-sound-dbus-server
1141+########################################
1142+test_indicator_sound_dbus_server_SOURCES = \
1143+ test-defines.h \
1144+ test-indicator-sound-dbus-server.c \
1145+ $(top_builddir)/src/sound-service-dbus.c \
1146+ $(top_builddir)/src/pulse-manager.c \
1147+ $(top_builddir)/src/slider-menu-item.c \
1148+ $(top_builddir)/src/dbus-menu-manager.c
1149+
1150+test_indicator_sound_dbus_server_CFLAGS = \
1151+ $(SOUNDSERVICE_CFLAGS) \
1152+ -Wall -Werror \
1153+ -I$(srcdir)
1154+
1155+test_indicator_sound_dbus_server_LDADD = \
1156+ $(SOUNDSERVICE_LIBS)
1157+
1158+
1159+#########################################
1160+## Actual tests
1161+#########################################
1162+
1163+XML_REPORT = indicator-sound-check-results.xml
1164+HTML_REPORT = indicator-sound-check-results.html
1165+
1166+indicator-sound-tests: indicator-sound-tests-gtester Makefile.am
1167+ @echo "#!/bin/sh" > $@
1168+ @echo $(DBUS_RUNNER) --task ./indicator-sound-tests-gtester >> $@
1169+ @chmod +x $@
1170+
1171+indicator-sound-tests-gtester: test-indicator-sound Makefile.am
1172+ @echo "#!/bin/sh" > $@
1173+ @echo gtester -k --verbose -o=$(XML_REPORT) ./test-indicator-sound >> $@
1174+ @chmod +x $@
1175+
1176+TESTS += indicator-sound-tests
1177+
1178+DISTCLEANFILES += $(XML_REPORT) $(HTML_REPORT) indicator-sound-tests-gtester
1179+
1180+DBUS_RUNNER=dbus-test-runner --dbus-config /usr/share/dbus-test-runner/session.conf
1181+
1182+test-indicator-sound-dbus: test-indicator-sound-dbus-client test-indicator-sound-dbus-server Makefile.am
1183+ @echo "#!/bin/sh" > test-indicator-sound-dbus
1184+ @echo $(DBUS_RUNNER) --task ./test-indicator-sound-dbus-client --task-name Client --task ./test-indicator-sound-dbus-server --task-name Server --ignore-return >> test-indicator-sound-dbus
1185+ @chmod +x test-indicator-sound-dbus
1186+
1187+TESTS += test-indicator-sound-dbus
1188+
1189+
1190+
1191+
1192+
1193
1194=== added file 'tests/run-xvfb.sh'
1195--- tests/run-xvfb.sh 1970-01-01 00:00:00 +0000
1196+++ tests/run-xvfb.sh 2010-03-04 12:22:15 +0000
1197@@ -0,0 +1,8 @@
1198+if [ "$DISPLAY" == "" ]; then
1199+Xvfb -ac -noreset -screen 0 800x600x16 -help 2>/dev/null 1>&2
1200+XID=`for id in 101 102 103 104 105 106 107 197 199 211 223 227 293 307 308 309 310 311 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 4703 4721 4723 4729 4733 4751 9973 9974 9975 9976 9977 9978 9979 9980 9981 9982 9983 9984 9985 9986 9987 9988 9989 9990 9991 9992 9993 9994 9995 9996 9997 9998 9999 ; do test -e /tmp/.X$id-lock || { echo $id; exit 0; }; done; exit 1`
1201+{ Xvfb -ac -noreset -screen 0 800x600x16 :$XID -screen 0 800x600x16 -nolisten tcp -auth /dev/null >/dev/null 2>&1 & trap "kill -15 $! " 0 HUP INT QUIT TRAP USR1 PIPE TERM ; } || { echo "Gtk+Tests:ERROR: Failed to start Xvfb environment for X11 target tests."; exit 1; }
1202+DISPLAY=:$XID
1203+export DISPLAY
1204+echo Setting display: $DISPLAY
1205+fi
1206
1207=== added file 'tests/test-defines.h'
1208--- tests/test-defines.h 1970-01-01 00:00:00 +0000
1209+++ tests/test-defines.h 2010-03-04 12:22:15 +0000
1210@@ -0,0 +1,24 @@
1211+/*
1212+Testing defines to be shared between various tests.
1213+
1214+Copyright 2010 Canonical Ltd.
1215+
1216+Authors:
1217+ Conor Curran <conor.curran@canonical.com>
1218+ Ted Gould <ted@canonical.com>
1219+
1220+This program is free software: you can redistribute it and/or modify it
1221+under the terms of the GNU General Public License version 3, as published
1222+by the Free Software Foundation.
1223+
1224+This program is distributed in the hope that it will be useful, but
1225+WITHOUT ANY WARRANTY; without even the implied warranties of
1226+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1227+PURPOSE. See the GNU General Public License for more details.
1228+
1229+You should have received a copy of the GNU General Public License along
1230+with this program. If not, see <http://www.gnu.org/licenses/>.
1231+*/
1232+
1233+#define TEST_MUTE FALSE
1234+
1235
1236=== added file 'tests/test-indicator-sound-dbus-client.c'
1237--- tests/test-indicator-sound-dbus-client.c 1970-01-01 00:00:00 +0000
1238+++ tests/test-indicator-sound-dbus-client.c 2010-03-04 12:22:15 +0000
1239@@ -0,0 +1,112 @@
1240+/*
1241+Tests for the libappindicator library that are over DBus. This is
1242+the client side of those tests.
1243+
1244+Copyright 2010 Canonical Ltd.
1245+
1246+Authors:
1247+ Conor Curran <conor.curran@canonical.com>
1248+ Ted Gould <ted@canonical.com>
1249+
1250+This program is free software: you can redistribute it and/or modify it
1251+under the terms of the GNU General Public License version 3, as published
1252+by the Free Software Foundation.
1253+
1254+This program is distributed in the hope that it will be useful, but
1255+WITHOUT ANY WARRANTY; without even the implied warranties of
1256+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1257+PURPOSE. See the GNU General Public License for more details.
1258+
1259+You should have received a copy of the GNU General Public License along
1260+with this program. If not, see <http://www.gnu.org/licenses/>.
1261+*/
1262+
1263+
1264+#include <glib.h>
1265+#include <dbus/dbus-glib.h>
1266+#include "../src/dbus-shared-names.h"
1267+#include "test-defines.h"
1268+
1269+static GMainLoop * mainloop = NULL;
1270+static gboolean passed = TRUE;
1271+
1272+static void
1273+fetch_mute_cb (DBusGProxy * proxy, DBusGProxyCall * call, void * data)
1274+{
1275+ GError * error = NULL;
1276+ GValue value = {0};
1277+
1278+ if (!dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_VALUE, &value, G_TYPE_INVALID)) {
1279+ g_warning("Getting mute failed: %s", error->message);
1280+ g_error_free(error);
1281+ passed = FALSE;
1282+ return;
1283+ }
1284+
1285+ if (TEST_MUTE != g_value_get_boolean(&value)) {
1286+ g_debug("Mute vale Returned: FAILED");
1287+ passed = FALSE;
1288+ } else {
1289+ g_debug("Property ID Returned: PASSED");
1290+ }
1291+ return;
1292+}
1293+
1294+
1295+gboolean
1296+kill_func (gpointer userdata)
1297+{
1298+ g_main_loop_quit(mainloop);
1299+ g_warning("Forced to Kill");
1300+ passed = FALSE;
1301+ return FALSE;
1302+}
1303+
1304+gint
1305+main (gint argc, gchar * argv[])
1306+{
1307+ g_type_init();
1308+
1309+ g_usleep(500000);
1310+
1311+ GError * error = NULL;
1312+ DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
1313+ if (error != NULL) {
1314+ g_error("Unable to get session bus: %s", error->message);
1315+ return 1;
1316+ }
1317+
1318+ DBusGProxy * props = dbus_g_proxy_new_for_name_owner(session_bus,
1319+ INDICATOR_SOUND_DBUS_NAME,
1320+ INDICATOR_SOUND_SERVICE_DBUS_OBJECT,
1321+ INDICATOR_SOUND_SERVICE_DBUS_INTERFACE,
1322+ &error);
1323+/* ":1.0",*/
1324+/* "/need/a/path",*/
1325+/* DBUS_INTERFACE_PROPERTIES,*/
1326+/* &error);*/
1327+ if (error != NULL) {
1328+ g_error("Unable to get property proxy: %s", error->message);
1329+ return 1;
1330+ }
1331+
1332+ dbus_g_proxy_begin_call (props,
1333+ "GetSinkMute",
1334+ fetch_mute_cb,
1335+ NULL, NULL,
1336+ G_TYPE_INVALID);
1337+
1338+ g_timeout_add_seconds(2, kill_func, NULL);
1339+
1340+ mainloop = g_main_loop_new(NULL, FALSE);
1341+ g_main_loop_run(mainloop);
1342+
1343+ if (passed) {
1344+ g_debug("Quiting");
1345+ return 0;
1346+ } else {
1347+ g_debug("Quiting as we're a failure");
1348+ return 1;
1349+ }
1350+ return 0;
1351+}
1352
1353=== added file 'tests/test-indicator-sound-dbus-server.c'
1354--- tests/test-indicator-sound-dbus-server.c 1970-01-01 00:00:00 +0000
1355+++ tests/test-indicator-sound-dbus-server.c 2010-03-04 12:22:15 +0000
1356@@ -0,0 +1,63 @@
1357+/*
1358+Tests for the libappindicator library that are over DBus. This is
1359+the server side of those tests.
1360+
1361+Copyright 2009 Canonical Ltd.
1362+
1363+Authors:
1364+ Conor Curran <conor.curran@canonical.com>
1365+ Ted Gould <ted@canonical.com>
1366+
1367+This program is free software: you can redistribute it and/or modify it
1368+under the terms of the GNU General Public License version 3, as published
1369+by the Free Software Foundation.
1370+
1371+This program is distributed in the hope that it will be useful, but
1372+WITHOUT ANY WARRANTY; without even the implied warranties of
1373+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1374+PURPOSE. See the GNU General Public License for more details.
1375+
1376+You should have received a copy of the GNU General Public License along
1377+with this program. If not, see <http://www.gnu.org/licenses/>.
1378+*/
1379+
1380+
1381+#include <dbus/dbus-glib.h>
1382+#include <dbus/dbus-glib-lowlevel.h>
1383+#include <glib.h>
1384+#include "../src/sound-service-dbus.h"
1385+#include "test-defines.h"
1386+
1387+static GMainLoop * mainloop = NULL;
1388+static SoundServiceDbus *dbus_interface = NULL;
1389+
1390+gboolean
1391+kill_func (gpointer userdata)
1392+{
1393+ g_main_loop_quit(mainloop);
1394+ // TODO free the dbus interface !!
1395+ return FALSE;
1396+}
1397+
1398+gint
1399+main (gint argc, gchar * argv[])
1400+{
1401+ g_type_init();
1402+ g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL))));
1403+
1404+ dbus_interface = g_object_new(SOUND_SERVICE_DBUS_TYPE, NULL);
1405+
1406+ // Set the mute value
1407+ sound_service_dbus_update_sink_mute(dbus_interface, TEST_MUTE);
1408+ g_timeout_add_seconds(2, kill_func, NULL);
1409+
1410+ // Run the loop
1411+ mainloop = g_main_loop_new(NULL, FALSE);
1412+ g_main_loop_run(mainloop);
1413+
1414+ g_debug("Quiting");
1415+
1416+ return 0;
1417+}
1418+
1419+
1420
1421=== added file 'tests/test-indicator-sound.c'
1422--- tests/test-indicator-sound.c 1970-01-01 00:00:00 +0000
1423+++ tests/test-indicator-sound.c 2010-03-04 12:22:15 +0000
1424@@ -0,0 +1,101 @@
1425+/*
1426+Copyright 2010 Canonical Ltd.
1427+
1428+Authors:
1429+ Conor Curran <conor.curran@canonical.com>
1430+
1431+This program is free software: you can redistribute it and/or modify it
1432+under the terms of the GNU General Public License version 3, as published
1433+by the Free Software Foundation.
1434+
1435+This program is distributed in the hope that it will be useful, but
1436+WITHOUT ANY WARRANTY; without even the implied warranties of
1437+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1438+PURPOSE. See the GNU General Public License for more details.
1439+
1440+You should have received a copy of the GNU General Public License along
1441+with this program. If not, see <http://www.gnu.org/licenses/>.
1442+*/
1443+
1444+#include <string.h>
1445+#include <gtk/gtk.h>
1446+#include <libindicator/indicator-object.h>
1447+#include "../src/indicator-sound.h"
1448+
1449+static const gint STATE_MUTED = 0;
1450+static const gint STATE_ZERO = 1;
1451+static const gint STATE_LOW = 2;
1452+static const gint STATE_MEDIUM = 3;
1453+static const gint STATE_HIGH = 4;
1454+static const gint STATE_MUTED_WHILE_INPUT = 5;
1455+static const gint STATE_SINKS_NONE = 6;
1456+
1457+void test_libindicator_sound_init()
1458+{
1459+ IndicatorObject * sound_menu = indicator_object_new_from_file(TOP_BUILD_DIR "/src/.libs/libsoundmenu.so");
1460+ g_assert(sound_menu != NULL);
1461+ g_object_unref(G_OBJECT(sound_menu));
1462+}
1463+
1464+void test_libindicator_determine_state()
1465+{
1466+ IndicatorObject * sound_menu = indicator_object_new_from_file(TOP_BUILD_DIR "/src/.libs/libsoundmenu.so");
1467+ prepare_for_tests(sound_menu);
1468+
1469+ determine_state_from_volume(40);
1470+ g_assert(get_state() == STATE_MEDIUM);
1471+
1472+ determine_state_from_volume(0);
1473+ g_assert(get_state() == STATE_ZERO);
1474+
1475+ determine_state_from_volume(15);
1476+ g_assert(get_state() == STATE_LOW);
1477+
1478+ determine_state_from_volume(70);
1479+ g_assert(get_state() == STATE_HIGH);
1480+
1481+ g_object_unref(G_OBJECT(sound_menu));
1482+}
1483+
1484+void test_libindicator_image_names()
1485+{
1486+ prepare_state_machine();
1487+
1488+ gchar* muted_name = get_state_image_name(STATE_MUTED);
1489+ g_assert(g_ascii_strncasecmp("audio-volume-muted-panel", muted_name, strlen("audio-volume-muted-panel")) == 0);
1490+
1491+ gchar* zero_name = get_state_image_name(STATE_ZERO);
1492+ g_assert(g_ascii_strncasecmp("audio-volume-low-zero-panel", zero_name, strlen("audio-volume-low-zero-panel")) == 0);
1493+
1494+ gchar* low_name = get_state_image_name(STATE_LOW);
1495+ g_assert(g_ascii_strncasecmp("audio-volume-low-panel", low_name, strlen("audio-volume-low-panel")) == 0);
1496+
1497+ gchar* medium_name = get_state_image_name(STATE_MEDIUM);
1498+ g_assert(g_ascii_strncasecmp("audio-volume-medium-panel", medium_name, strlen("audio-volume-medium-panel")) == 0);
1499+
1500+ gchar* high_name = get_state_image_name(STATE_HIGH);
1501+ g_assert(g_ascii_strncasecmp("audio-volume-high-panel", high_name, strlen("audio-volume-high-panel")) == 0);
1502+
1503+ gchar* blocked_name = get_state_image_name(STATE_MUTED_WHILE_INPUT);
1504+ g_assert(g_ascii_strncasecmp("audio-volume-muted-blocking-panel", blocked_name, strlen("audio-volume-muted-blocking-panel")) == 0);
1505+
1506+ gchar* none_name = get_state_image_name(STATE_SINKS_NONE);
1507+ g_assert(g_ascii_strncasecmp("audio-output-none-panel", none_name, strlen("audio-output-none-panel")) == 0);
1508+
1509+ tidy_up_hash();
1510+}
1511+
1512+
1513+
1514+gint main (gint argc, gchar * argv[])
1515+{
1516+ g_type_init();
1517+ g_test_init(&argc, &argv, NULL);
1518+
1519+ g_test_add_func("/indicator-sound/indicator-sound/init", test_libindicator_sound_init);
1520+ g_test_add_func("/indicator-sound/indicator-sound/state_machine", test_libindicator_determine_state);
1521+ g_test_add_func("/indicator-sound/indicator-sound/image_names", test_libindicator_image_names);
1522+
1523+ return g_test_run ();
1524+}
1525+

Subscribers

People subscribed via source and target branches