From de077cfdb0a73fc61218ee9f769a60e73499ebb9 Mon Sep 17 00:00:00 2001 From: CI Train Bot Date: Fri, 7 Aug 2015 22:35:58 +0000 Subject: Releasing 12.10.2+15.10.20150807.6-0ubuntu1 --- debian/changelog | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/debian/changelog b/debian/changelog index 79a15aa..ad4ba93 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,14 @@ +indicator-sound (12.10.2+15.10.20150807.6-0ubuntu1) wily; urgency=medium + + [ CI Train Bot ] + * New rebuild forced. + + [ Charles Kerr ] + * Revised UI volume warnings to comply with EU requirements. (LP: + #1481913) + + -- CI Train Bot Fri, 07 Aug 2015 22:35:58 +0000 + indicator-sound (12.10.2+15.10.20150605-0ubuntu1) wily; urgency=medium * -- cgit v1.2.3 From 20f6bd10f17dfeecea93d03873e3b74ecef54782 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 10 Aug 2015 23:48:37 -0500 Subject: huge pile of diff that consolidates pulse-specific audio work into volume-control-pulse. Work in progress. Promising but currently ugly. --- data/com.canonical.indicator.sound.gschema.xml | 68 ++++++---- src/service.vala | 108 +++++---------- src/volume-control-pulse.vala | 173 ++++++++++++++++++++++--- src/volume-control.vala | 13 +- tests/volume-control-mock.vala | 4 +- 5 files changed, 249 insertions(+), 117 deletions(-) diff --git a/data/com.canonical.indicator.sound.gschema.xml b/data/com.canonical.indicator.sound.gschema.xml index ff4816e..c0e4dc1 100644 --- a/data/com.canonical.indicator.sound.gschema.xml +++ b/data/com.canonical.indicator.sound.gschema.xml @@ -42,41 +42,65 @@ - + true - Whether or not to show the a volume warning. + Whether or not to show high volume warnings. - Whether or not to show the a volume warning when the volume exceeds some level while headphones are plugged in. + If enabled on a device, a confirmation dialog will be presented to the user if + (a) something is plugged into the headphone jack (ie, no warnings for speaker volumes) AND + (b) media is playing (ie, no warnings for ringtone volumes) AND + (c) the user attempts to set the volume higher than warning-volume-dB AND + (d) the user has not indicated approval in the last warning-volume-approval-ttl seconds. - - 1200 - How often, in hours, a user's high volume confirmation should be remembered. + + 72000 + How many seconds a user's warning-volume approval should be remembered. - After a user confirms that they want to listen at a higher volume, subsequent volume - changes do not need to re-trigger a warning until this interval has passed. - For example, EU standard EN 60950-1/Al2 cites "The acknowledgement does not need to - be repeated more than once every 20 h of cumulative listening time." + How long to remember a user's approval of the confirmation dialog discussed in the + description of 'warning-volume-enabled'. + + The default value (72,000 seconds) corresponds to the 20 hours suggested by + EU standard EN 60950-1/Al2: “The acknowledgement does not need to be repeated + more than once every 20 h of cumulative listening time.” - - 0.75 - Volume level that triggers a high volume warning. [0.0..1.0] + + -8.0 + Volume level that triggers a high volume warning. - When high volume warnings are enabled, a warning will be shown when - the volume level is raised past this level. + Volume level that triggers a high volume warning. + See warning-volume-enabled for details. - diff --git a/src/service.vala b/src/service.vala index 73a331a..c7341f2 100644 --- a/src/service.vala +++ b/src/service.vala @@ -34,12 +34,9 @@ public class IndicatorSound.Service: Object { warn_notification.set_hint ("x-canonical-snap-decisions", "true"); warn_notification.set_hint ("x-canonical-private-affirmative-tint", "true"); warn_notification.add_action ("ok", _("OK"), (n, a) => { - this.loudness_approved_timestamp = GLib.get_monotonic_time (); - }); - warn_notification.add_action ("cancel", _("Cancel"), (n, a) => { - /* user rejected loud volume; re-clamp to just below the warning level */ - set_clamped_volume (settings.get_double("high-volume-level") * 0.9, VolumeControl.VolumeReasons.USER_KEYPRESS); + this.volume_control.approve_high_volume (); }); + warn_notification.add_action ("cancel", _("Cancel"), (n, a) => {}); BusWatcher.watch_namespace (GLib.BusType.SESSION, "org.freedesktop.Notifications", @@ -47,7 +44,6 @@ public class IndicatorSound.Service: Object { () => { debug("Notifications name vanshed"); notify_server_caps_checked = false; }); this.settings = new Settings ("com.canonical.indicator.sound"); - this.sharedsettings = new Settings ("com.ubuntu.sound"); this.settings.bind ("visible", this, "visible", SettingsBindFlags.GET); this.notify["visible"].connect ( () => this.update_root_icon () ); @@ -96,8 +92,6 @@ public class IndicatorSound.Service: Object { this.sync_preferred_players (); }); - sharedsettings.bind ("allow-amplified-volume", this, "allow-amplified-volume", SettingsBindFlags.GET); - /* Hide the notification when the menu is shown */ var shown_action = actions.lookup_action ("indicator-shown") as SimpleAction; shown_action.change_state.connect ((state) => { @@ -174,28 +168,6 @@ public class IndicatorSound.Service: Object { public bool visible { get; set; } - public bool allow_amplified_volume { - get { - return this.max_volume > 1.0; - } - - set { - if (this.allow_amplified_volume == value) - return; - - if (value) { - /* from pulse/volume.h: #define PA_VOLUME_UI_MAX (pa_sw_volume_from_dB(+11.0)) */ - this.max_volume = (double)PulseAudio.Volume.sw_from_dB(11.0) / PulseAudio.Volume.NORM; - } - else { - this.max_volume = 1.0; - } - - /* Normalize volume, because the volume action's state is [0.0, 1.0], see create_volume_action() */ - this.actions.change_action_state ("volume", this.volume_control.volume.volume / this.max_volume); - } - } - const ActionEntry[] action_entries = { { "root", null, null, "@a{sv} {}", null }, { "scroll", activate_scroll_action, "i", null, null }, @@ -207,7 +179,6 @@ public class IndicatorSound.Service: Object { SimpleActionGroup actions; HashTable menus; Settings settings; - Settings sharedsettings; VolumeControl volume_control; MediaPlayerList players; uint player_action_update_id; @@ -219,24 +190,12 @@ public class IndicatorSound.Service: Object { private Notify.Notification info_notification; private Notify.Notification warn_notification; - /* Maximum volume as a scaling factor between the volume action's state and the value in - * this.volume_control. See create_volume_action(). - */ - double max_volume = 1.0; - const double volume_step_percentage = 0.06; - void set_clamped_volume (double unclamped, VolumeControl.VolumeReasons reason) { - var vol = new VolumeControl.Volume(); - vol.volume = unclamped.clamp (0.0, this.max_volume); - vol.reason = reason; - this.volume_control.volume = vol; - } - void activate_scroll_action (SimpleAction action, Variant? param) { int delta = param.get_int32(); /* positive for up, negative for down */ - double v = this.volume_control.volume.volume + volume_step_percentage * delta; - set_clamped_volume (v, VolumeControl.VolumeReasons.USER_KEYPRESS); + double v = volume_control.volume.volume + volume_step_percentage * delta; + volume_control.set_volume_clamp (v, VolumeControl.VolumeReasons.USER_KEYPRESS); } void activate_desktop_settings (SimpleAction action, Variant? param) { @@ -312,15 +271,6 @@ public class IndicatorSound.Service: Object { private bool notify_server_supports_actions = false; private bool notify_server_supports_sync = false; private bool block_info_notifications = false; - private int64 loudness_approved_timestamp = 0; - - private bool user_recently_approved_loudness() { - int64 ttl_sec = this.settings.get_int("high-volume-acknowledgment-ttl"); - int64 ttl_usec = ttl_sec * 1000000; - int64 now = GLib.get_monotonic_time(); - return (this.loudness_approved_timestamp != 0) - && (this.loudness_approved_timestamp + ttl_usec >= now); - } void update_notification () { @@ -334,13 +284,14 @@ public class IndicatorSound.Service: Object { var loud = volume_control.high_volume; var warn = loud && this.notify_server_supports_actions - && this.settings.get_boolean("high-volume-warning-enabled") - && !this.user_recently_approved_loudness(); + && !this.volume_control.high_volume_approved; if (warn) { close_notification(info_notification); + message("showing warning"); show_notification(warn_notification); } else { + message("closing warning"); close_notification(warn_notification); if (notify_server_supports_sync && !block_info_notifications) { @@ -371,7 +322,7 @@ public class IndicatorSound.Service: Object { n.set_hint ("x-canonical-non-shaped-icon", "true"); n.set_hint ("x-canonical-private-synchronous", "true"); n.set_hint ("x-canonical-value-bar-tint", loud ? "true" : "false"); - n.set_hint ("value", (int32)Math.round(volume_control.volume.volume / this.max_volume * 100.0)); + n.set_hint ("value", (int32)Math.round(get_volume_percent() * 100.0)); show_notification(n); } } @@ -453,34 +404,41 @@ public class IndicatorSound.Service: Object { return mute_action; } - SimpleAction volume_action; - Action create_volume_action () { - /* The action's state is between be in [0.0, 1.0] instead of [0.0, - * max_volume], so that we don't need to update the slider menu item - * every time allow-amplified-volume is changed. Convert between the - * two here, so that we always pass the full range into - * volume_control.set_volume(). - */ + /* return the current volume in the range of [0.0, 1.0] */ + private double get_volume_percent() { + return volume_control.volume.volume / this.volume_control.max_volume; + } - double volume = this.volume_control.volume.volume / this.max_volume; + /* volume control's range can vary depending on its max_volume property, + * but the action always needs to be in [0.0, 1.0]... */ + private Variant create_volume_action_state() { + return new Variant.double (get_volume_percent()); + } - volume_action = new SimpleAction.stateful ("volume", VariantType.INT32, new Variant.double (volume)); + private void update_volume_action_state() { + volume_action.set_state(create_volume_action_state()); + } + + + SimpleAction volume_action; + Action create_volume_action () { + volume_action = new SimpleAction.stateful ("volume", VariantType.INT32, create_volume_action_state()); volume_action.change_state.connect ( (action, val) => { - double v = val.get_double () * this.max_volume; - set_clamped_volume (v, VolumeControl.VolumeReasons.USER_KEYPRESS); + double v = val.get_double () * this.volume_control.max_volume; + volume_control.set_volume_clamp (v, VolumeControl.VolumeReasons.USER_KEYPRESS); }); /* activating this action changes the volume by the amount given in the parameter */ - volume_action.activate.connect ( (action, param) => { - int delta = param.get_int32 (); - double v = volume_control.volume.volume + volume_step_percentage * delta; - set_clamped_volume (v, VolumeControl.VolumeReasons.USER_KEYPRESS); + volume_action.activate.connect ((action, param) => activate_scroll_action); + + this.volume_control.notify["max-volume"].connect(() => { + message("max-volume changed to %f", volume_control.max_volume); + update_volume_action_state(); }); this.volume_control.notify["volume"].connect (() => { - /* Normalize volume, because the volume action's state is [0.0, 1.0], see create_volume_action() */ - volume_action.set_state (new Variant.double (this.volume_control.volume.volume / this.max_volume)); + update_volume_action_state(); this.update_root_icon (); diff --git a/src/volume-control-pulse.vala b/src/volume-control-pulse.vala index d3e93c5..a2605c6 100644 --- a/src/volume-control-pulse.vala +++ b/src/volume-control-pulse.vala @@ -45,6 +45,7 @@ public class VolumeControlPulse : VolumeControl private VolumeControl.Volume _volume = new VolumeControl.Volume(); private double _mic_volume = 0.0; private Settings _settings = new Settings ("com.canonical.indicator.sound"); + private Settings _shared_settings = new Settings ("com.ubuntu.sound"); /* Used by the pulseaudio stream restore extension */ private DBusConnection _pconn; @@ -93,20 +94,6 @@ public class VolumeControlPulse : VolumeControl /** true when a microphone is active **/ public override bool active_mic { get; private set; default = false; } - /** true when high volume warnings should be shown */ - public override bool high_volume { - get { - if (!_active_port_headphone) { - return false; - } - if (stream != "multimedia") { - return false; - } - var high_volume_level = this._settings.get_double("high-volume-level"); - return this._volume.volume > high_volume_level; - } - } - public VolumeControlPulse () { _volume.volume = 0.0; @@ -118,6 +105,10 @@ public class VolumeControlPulse : VolumeControl _mute_cancellable = new Cancellable (); _volume_cancellable = new Cancellable (); + init_max_volume(); + init_high_volume(); + init_high_volume_approved(); + setup_accountsservice.begin (); this.reconnect_to_pulse (); @@ -131,6 +122,7 @@ public class VolumeControlPulse : VolumeControl } stop_local_volume_timer(); stop_account_service_volume_timer(); + stop_high_volume_approved_timer(); } /* PulseAudio logic*/ @@ -624,10 +616,19 @@ public class VolumeControlPulse : VolumeControl return _volume; } set { + + if ((value.reason == VolumeReasons.USER_KEYPRESS) + && !_high_volume_approved + && calculate_high_volume_from_volume(value.volume)) + { + var clamped = value.volume.clamp(0, _warning_volume_norms); + message("User is trying to raise volume past warning... clamping from %f down to %f", value.volume, clamped); + value.volume = clamped; + } + var volume_changed = (value.volume != _volume.volume); debug("Setting volume to %f for profile %d because %d", value.volume, _active_sink_input, value.reason); - var old_high_volume = this.high_volume; _volume = value; /* Make sure we're connected to Pulse and pulse didn't give us the change */ @@ -639,15 +640,153 @@ public class VolumeControlPulse : VolumeControl else context.get_server_info (server_info_cb_for_set_volume); - if (this.high_volume != old_high_volume) - this.notify_property("high-volume"); if (volume.reason != VolumeControl.VolumeReasons.ACCOUNTS_SERVICE_SET && volume_changed) { start_local_volume_timer(); } + + update_high_volume(); + } + } + + /** MAX VOLUME PROPERTY **/ + + private void init_max_volume() { + message("woo"); + _settings.changed["normal-volume-decibels"].connect(() => update_max_volume()); + _settings.changed["amplified-volume-decibels"].connect(() => update_max_volume()); + _shared_settings.changed["allow-amplified-volume"].connect(() => update_max_volume()); + update_max_volume(); + } + private void update_max_volume () { + var new_max_volume = calculate_max_volume(); + message ("old_max_volume %f new_max_volume %f", max_volume, new_max_volume); + if (max_volume != new_max_volume) { + message("changing max_volume from %f to %f", this.max_volume, new_max_volume); + max_volume = calculate_max_volume(); + } + } + private double calculate_max_volume () { + string decibel_key; + if (_shared_settings.get_boolean("allow-amplified-volume")) + decibel_key = "amplified-volume-decibels"; + else + decibel_key = "normal-volume-decibels"; + + var volume_dB = _settings.get_double(decibel_key); + var volume_sw = PulseAudio.Volume.sw_from_dB (volume_dB); + return volume_to_double (volume_sw); + } + + /** HIGH VOLUME PROPERTY **/ + + private bool _warning_volume_enabled; + private double _warning_volume_norms; + private bool _high_volume = false; + public override bool high_volume { + get { return this._high_volume; } + private set { this._high_volume = value; } + } + private void init_high_volume() { + _settings.changed["warning-volume-enabled"].connect(() => update_high_volume_cache()); + _settings.changed["warning-volume-decibels"].connect(() => update_high_volume_cache()); + update_high_volume_cache(); + } + private void update_high_volume_cache() { + _warning_volume_enabled = _settings.get_boolean("warning-volume-enabled"); + + var volume_dB = _settings.get_double ("warning-volume-decibels"); + var volume_sw = PulseAudio.Volume.sw_from_dB (volume_dB); + var volume_norms = volume_to_double (volume_sw); + _warning_volume_norms = volume_norms; + + message("updating high volume cache... enabled %d dB %f sw %lu norm %f", (int)_warning_volume_enabled, volume_dB, volume_sw, volume_norms); + update_high_volume(); + } + private void update_high_volume() { + var new_high_volume = calculate_high_volume(); + if (high_volume != new_high_volume) { + message("changing high_volume from %d to %d", (int)high_volume, (int)new_high_volume); + high_volume = new_high_volume; + } + } + private bool calculate_high_volume() { + return calculate_high_volume_from_volume(_volume.volume); + } + private bool calculate_high_volume_from_volume(double volume) { + message ("headphones %d warning enabled %d (vol %f > loud %f) multimedia %d", (int)_active_port_headphone, (int)_warning_volume_enabled, (double)volume, (double)_warning_volume_norms, (int)(stream == "multimedia")); + return _active_port_headphone + && _warning_volume_enabled + && volume >= _warning_volume_norms + && (stream == "multimedia"); + } + + /** HIGH VOLUME APPROVED PROPERTY **/ + + private bool _high_volume_approved = false; + private int64 _high_volume_approved_at = 0; + private int64 _high_volume_approved_ttl_usec = 0; + private uint _high_volume_approved_timer = 0; + public override bool high_volume_approved { + get { return this._high_volume_approved; } + private set { this._high_volume_approved = value; } + } + private void init_high_volume_approved() { + _settings.changed["warning-volume-confirmation-ttl"].connect(() => update_high_volume_approved_cache()); + update_high_volume_approved_cache(); + } + private void update_high_volume_approved_cache() { + _high_volume_approved_ttl_usec = _settings.get_int("warning-volume-confirmation-ttl"); + _high_volume_approved_ttl_usec *= 1000000; + + update_high_volume_approved(); + update_high_volume_approved_timer(); + } + private void update_high_volume_approved_timer() { + stop_high_volume_approved_timer(); + if (_high_volume_approved_at != 0) { + int64 expires_at = _high_volume_approved_at + _high_volume_approved_ttl_usec; + int64 now = GLib.get_monotonic_time(); + if (expires_at > now) { + var seconds_left = (now - expires_at) / 1000000; + _high_volume_approved_timer = Timeout.add_seconds((uint)seconds_left, on_high_volume_timer); + } + } + } + private void stop_high_volume_approved_timer() { + if (_high_volume_approved_timer != 0) { + Source.remove (_high_volume_approved_timer); + _high_volume_approved_timer = 0; + } + } + private bool on_high_volume_timer() { + _high_volume_approved_timer = 0; + update_high_volume_approved(); + return false; /* Source.REMOVE */ + } + private void update_high_volume_approved() { + var new_high_volume_approved = calculate_high_volume_approved(); + if (high_volume_approved != new_high_volume_approved) { + message("changing high_volume_approved from %d to %d", (int)high_volume_approved, (int)new_high_volume_approved); + high_volume_approved = new_high_volume_approved; } } + private bool calculate_high_volume_approved() { + int64 now = GLib.get_monotonic_time(); + var foo = (_high_volume_approved_at != 0) + && (_high_volume_approved_at + _high_volume_approved_ttl_usec >= now); + message("approved: %d", (int)foo); + return foo; + } + public override void approve_high_volume() { + _high_volume_approved_at = GLib.get_monotonic_time(); + update_high_volume_approved_timer(); + update_high_volume_approved(); + } + + + /** MIC VOLUME PROPERTY */ public override double mic_volume { get { diff --git a/src/volume-control.vala b/src/volume-control.vala index 3f1c799..36d7083 100644 --- a/src/volume-control.vala +++ b/src/volume-control.vala @@ -36,12 +36,23 @@ public abstract class VolumeControl : Object public virtual string stream { get { return ""; } } public virtual bool ready { get { return false; } set { } } public virtual bool active_mic { get { return false; } set { } } - public virtual bool high_volume { get { return false; } } + public virtual bool high_volume { get { return false; } protected set { } } public virtual bool mute { get { return false; } } public virtual bool is_playing { get { return false; } } private Volume _volume; public virtual Volume volume { get { return _volume; } set { } } public virtual double mic_volume { get { return 0.0; } set { } } + public virtual double max_volume { get; set; } + + public virtual bool high_volume_approved { get { return false; } protected set { } } + public virtual void approve_high_volume() { } public abstract void set_mute (bool mute); + + public void set_volume_clamp (double unclamped, VolumeControl.VolumeReasons reason) { + var v = new VolumeControl.Volume(); + v.volume = unclamped.clamp (0.0, this.max_volume); + v.reason = reason; + this.volume = v; + } } diff --git a/tests/volume-control-mock.vala b/tests/volume-control-mock.vala index 4c96518..5902037 100644 --- a/tests/volume-control-mock.vala +++ b/tests/volume-control-mock.vala @@ -24,8 +24,8 @@ public class VolumeControlMock : VolumeControl public override string stream { get { return mock_stream; } } public override bool ready { get; set; } public override bool active_mic { get; set; } - public bool mock_high_volume { get; set; } - public override bool high_volume { get { return mock_high_volume; } } + public bool mock_high_volume { get { return high_volume; } set { high_volume = value; } } + public override bool high_volume { get; private set; } public bool mock_mute { get; set; } public override bool mute { get { return mock_mute; } } public bool mock_is_playing { get; set; } -- cgit v1.2.3 From 4570ce15a7769a4a1ce3b5ce4ac5d578c77eb267 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 11 Aug 2015 10:01:05 -0500 Subject: fix volume_action -> scroll action signal connection regression found by xavi --- src/service.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/service.vala b/src/service.vala index c7341f2..57c9d4a 100644 --- a/src/service.vala +++ b/src/service.vala @@ -430,7 +430,7 @@ public class IndicatorSound.Service: Object { }); /* activating this action changes the volume by the amount given in the parameter */ - volume_action.activate.connect ((action, param) => activate_scroll_action); + volume_action.activate.connect ((action, param) => activate_scroll_action()); this.volume_control.notify["max-volume"].connect(() => { message("max-volume changed to %f", volume_control.max_volume); -- cgit v1.2.3 From 37f663ff9c5b6c77ec0d128d70d7ab213d865477 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 11 Aug 2015 10:01:36 -0500 Subject: ensure the high volume timer is always at least 1 sec --- src/volume-control-pulse.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/volume-control-pulse.vala b/src/volume-control-pulse.vala index a2605c6..7f0edcb 100644 --- a/src/volume-control-pulse.vala +++ b/src/volume-control-pulse.vala @@ -749,7 +749,7 @@ public class VolumeControlPulse : VolumeControl int64 expires_at = _high_volume_approved_at + _high_volume_approved_ttl_usec; int64 now = GLib.get_monotonic_time(); if (expires_at > now) { - var seconds_left = (now - expires_at) / 1000000; + var seconds_left = 1 + ((now - expires_at) / 1000000); _high_volume_approved_timer = Timeout.add_seconds((uint)seconds_left, on_high_volume_timer); } } -- cgit v1.2.3 From 928b62bedbf3787dfd749df2e64714a589bd06ce Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 11 Aug 2015 12:33:34 -0500 Subject: fix typo in gschema description text --- data/com.canonical.indicator.sound.gschema.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/com.canonical.indicator.sound.gschema.xml b/data/com.canonical.indicator.sound.gschema.xml index c0e4dc1..b2ee856 100644 --- a/data/com.canonical.indicator.sound.gschema.xml +++ b/data/com.canonical.indicator.sound.gschema.xml @@ -49,7 +49,7 @@ If enabled on a device, a confirmation dialog will be presented to the user if (a) something is plugged into the headphone jack (ie, no warnings for speaker volumes) AND (b) media is playing (ie, no warnings for ringtone volumes) AND - (c) the user attempts to set the volume higher than warning-volume-dB AND + (c) the user attempts to set the volume higher than warning-volume-decibels AND (d) the user has not indicated approval in the last warning-volume-approval-ttl seconds. -- cgit v1.2.3 From 8e7aa6d1ba5f62c4525c7d20e674ce8ef579040b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 11 Aug 2015 12:38:58 -0500 Subject: fix invocation to activate_scroll_action --- src/service.vala | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/service.vala b/src/service.vala index 57c9d4a..994de30 100644 --- a/src/service.vala +++ b/src/service.vala @@ -192,7 +192,7 @@ public class IndicatorSound.Service: Object { const double volume_step_percentage = 0.06; - void activate_scroll_action (SimpleAction action, Variant? param) { + private void activate_scroll_action (SimpleAction action, Variant? param) { int delta = param.get_int32(); /* positive for up, negative for down */ double v = volume_control.volume.volume + volume_step_percentage * delta; volume_control.set_volume_clamp (v, VolumeControl.VolumeReasons.USER_KEYPRESS); @@ -272,7 +272,7 @@ public class IndicatorSound.Service: Object { private bool notify_server_supports_sync = false; private bool block_info_notifications = false; - void update_notification () { + private void update_notification () { if (!notify_server_caps_checked) { List caps = Notify.get_server_caps (); @@ -419,9 +419,8 @@ public class IndicatorSound.Service: Object { volume_action.set_state(create_volume_action_state()); } - - SimpleAction volume_action; - Action create_volume_action () { + private SimpleAction volume_action; + private Action create_volume_action () { volume_action = new SimpleAction.stateful ("volume", VariantType.INT32, create_volume_action_state()); volume_action.change_state.connect ( (action, val) => { @@ -430,7 +429,7 @@ public class IndicatorSound.Service: Object { }); /* activating this action changes the volume by the amount given in the parameter */ - volume_action.activate.connect ((action, param) => activate_scroll_action()); + volume_action.activate.connect ((a,p) => activate_scroll_action(a,p)); this.volume_control.notify["max-volume"].connect(() => { message("max-volume changed to %f", volume_control.max_volume); -- cgit v1.2.3 From f52fe2483aae720b92878272f052b8fc6605dcd9 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 11 Aug 2015 15:10:56 -0500 Subject: clamp the volume whenever the 'high volume' confirmation notification is open. --- src/service.vala | 34 +++++++++++++++++++++++++++++++++- src/volume-control-pulse.vala | 23 +++++++++++++---------- src/volume-control.vala | 1 + 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/service.vala b/src/service.vala index 994de30..c8382a5 100644 --- a/src/service.vala +++ b/src/service.vala @@ -139,6 +139,8 @@ public class IndicatorSound.Service: Object { clear_acts_player(); + stop_clamp_volume_timeout(); + if (this.player_action_update_id > 0) { Source.remove (this.player_action_update_id); this.player_action_update_id = 0; @@ -416,7 +418,9 @@ public class IndicatorSound.Service: Object { } private void update_volume_action_state() { - volume_action.set_state(create_volume_action_state()); + var state = create_volume_action_state(); + message("updating volume_action state to %s", state.print(true)); + volume_action.set_state(state); } private SimpleAction volume_action; @@ -445,6 +449,11 @@ public class IndicatorSound.Service: Object { if (reason == VolumeControl.VolumeReasons.USER_KEYPRESS || reason == VolumeControl.VolumeReasons.DEVICE_OUTPUT_CHANGE) this.update_notification (); + + /* if the volume changes while the "high volume" + * warning dialog is up, clamp to high-volume */ + if (this.warn_notification.id != 0) + this.clamp_volume_soon(); }); this.volume_control.bind_property ("ready", volume_action, "enabled", BindingFlags.SYNC_CREATE); @@ -598,4 +607,27 @@ public class IndicatorSound.Service: Object { this.update_preferred_players (); } + + /** VOLUME CLAMPING **/ + + private uint _clamp_volume_timeout = 0; + + private void stop_clamp_volume_timeout() { + if (_clamp_volume_timeout != 0) { + Source.remove(_clamp_volume_timeout); + _clamp_volume_timeout = 0; + } + } + + private void clamp_volume_soon() { + const uint interval_msec = 200; /* arbitrary, but works */ + if (_clamp_volume_timeout == 0) + _clamp_volume_timeout = Timeout.add(interval_msec, clamp_volume_idle); + } + + private bool clamp_volume_idle() { + _clamp_volume_timeout = 0; + volume_control.clamp_to_high_volume(); + return false; // Source.REMOVE; + } } diff --git a/src/volume-control-pulse.vala b/src/volume-control-pulse.vala index 7f0edcb..edbfd23 100644 --- a/src/volume-control-pulse.vala +++ b/src/volume-control-pulse.vala @@ -616,16 +616,6 @@ public class VolumeControlPulse : VolumeControl return _volume; } set { - - if ((value.reason == VolumeReasons.USER_KEYPRESS) - && !_high_volume_approved - && calculate_high_volume_from_volume(value.volume)) - { - var clamped = value.volume.clamp(0, _warning_volume_norms); - message("User is trying to raise volume past warning... clamping from %f down to %f", value.volume, clamped); - value.volume = clamped; - } - var volume_changed = (value.volume != _volume.volume); debug("Setting volume to %f for profile %d because %d", value.volume, _active_sink_input, value.reason); @@ -722,6 +712,19 @@ public class VolumeControlPulse : VolumeControl && (stream == "multimedia"); } + public override void clamp_to_high_volume() { + if (_high_volume) { + message("_volume.volume(%f) _warning_volume_norms(%f)", _volume.volume, _warning_volume_norms); + if (_volume.volume > _warning_volume_norms) { + var vol = new VolumeControl.Volume(); + vol.volume = _volume.volume.clamp(0, _warning_volume_norms); + vol.reason = _volume.reason; + message("Clamping from %f down to %f", _volume.volume, vol.volume); + volume = vol; + } + } + } + /** HIGH VOLUME APPROVED PROPERTY **/ private bool _high_volume_approved = false; diff --git a/src/volume-control.vala b/src/volume-control.vala index 36d7083..a30a373 100644 --- a/src/volume-control.vala +++ b/src/volume-control.vala @@ -46,6 +46,7 @@ public abstract class VolumeControl : Object public virtual bool high_volume_approved { get { return false; } protected set { } } public virtual void approve_high_volume() { } + public virtual void clamp_to_high_volume() { } public abstract void set_mute (bool mute); -- cgit v1.2.3 From dbefa016baa5cb14c5a605e30dc0d0a808ea4e21 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 11 Aug 2015 15:50:11 -0500 Subject: before the service pops up a 'high volume' warning and clamps the volume, remember the previous volume. If the user hits 'OK', restore that volume. --- src/service.vala | 54 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/src/service.vala b/src/service.vala index c8382a5..b164877 100644 --- a/src/service.vala +++ b/src/service.vala @@ -20,6 +20,13 @@ public class IndicatorSound.Service: Object { DBusConnection bus; + /** + * A copy of volume_control.volume made before just warn_notification + * is shown. Since the volume is clamped during the warning, we cache + * the previous volume to use iff the user hits "OK". + */ + VolumeControl.Volume _pre_warn_volume = null; + public Service (MediaPlayerList playerlist, VolumeControl volume, AccountsServiceUser? accounts) { try { bus = Bus.get_sync(GLib.BusType.SESSION); @@ -34,9 +41,18 @@ public class IndicatorSound.Service: Object { warn_notification.set_hint ("x-canonical-snap-decisions", "true"); warn_notification.set_hint ("x-canonical-private-affirmative-tint", "true"); warn_notification.add_action ("ok", _("OK"), (n, a) => { - this.volume_control.approve_high_volume (); + stop_clamp_to_high_timeout(); + volume_control.approve_high_volume (); + if (_pre_warn_volume != null) { + var tmp = _pre_warn_volume; + _pre_warn_volume = null; + volume_control.volume = tmp; + } + }); + warn_notification.add_action ("cancel", _("Cancel"), (n, a) => { + _pre_warn_volume = null; }); - warn_notification.add_action ("cancel", _("Cancel"), (n, a) => {}); + BusWatcher.watch_namespace (GLib.BusType.SESSION, "org.freedesktop.Notifications", @@ -139,7 +155,7 @@ public class IndicatorSound.Service: Object { clear_acts_player(); - stop_clamp_volume_timeout(); + stop_clamp_to_high_timeout(); if (this.player_action_update_id > 0) { Source.remove (this.player_action_update_id); @@ -290,7 +306,11 @@ public class IndicatorSound.Service: Object { if (warn) { close_notification(info_notification); - message("showing warning"); + if (_pre_warn_volume == null) { + _pre_warn_volume = new VolumeControl.Volume(); + _pre_warn_volume.volume = volume_control.volume.volume; + _pre_warn_volume.reason = volume_control.volume.reason; + } show_notification(warn_notification); } else { message("closing warning"); @@ -450,10 +470,8 @@ public class IndicatorSound.Service: Object { reason == VolumeControl.VolumeReasons.DEVICE_OUTPUT_CHANGE) this.update_notification (); - /* if the volume changes while the "high volume" - * warning dialog is up, clamp to high-volume */ - if (this.warn_notification.id != 0) - this.clamp_volume_soon(); + if ((warn_notification.id != 0) && (_pre_warn_volume != null)) + clamp_to_high_soon(); }); this.volume_control.bind_property ("ready", volume_action, "enabled", BindingFlags.SYNC_CREATE); @@ -610,23 +628,23 @@ public class IndicatorSound.Service: Object { /** VOLUME CLAMPING **/ - private uint _clamp_volume_timeout = 0; + private uint _clamp_to_high_timeout = 0; - private void stop_clamp_volume_timeout() { - if (_clamp_volume_timeout != 0) { - Source.remove(_clamp_volume_timeout); - _clamp_volume_timeout = 0; + private void stop_clamp_to_high_timeout() { + if (_clamp_to_high_timeout != 0) { + Source.remove(_clamp_to_high_timeout); + _clamp_to_high_timeout = 0; } } - private void clamp_volume_soon() { + private void clamp_to_high_soon() { const uint interval_msec = 200; /* arbitrary, but works */ - if (_clamp_volume_timeout == 0) - _clamp_volume_timeout = Timeout.add(interval_msec, clamp_volume_idle); + if (_clamp_to_high_timeout == 0) + _clamp_to_high_timeout = Timeout.add(interval_msec, clamp_to_high_idle); } - private bool clamp_volume_idle() { - _clamp_volume_timeout = 0; + private bool clamp_to_high_idle() { + _clamp_to_high_timeout = 0; volume_control.clamp_to_high_volume(); return false; // Source.REMOVE; } -- cgit v1.2.3 From e52f77bc9f85db4ac02b05bfb96a1e092fed698b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 11 Aug 2015 16:00:18 -0500 Subject: take the g_message() tracers and remove or demote to g_debug() as appropriate --- src/service.vala | 6 +----- src/volume-control-pulse.vala | 34 ++++++++++++---------------------- 2 files changed, 13 insertions(+), 27 deletions(-) diff --git a/src/service.vala b/src/service.vala index b164877..777070a 100644 --- a/src/service.vala +++ b/src/service.vala @@ -313,7 +313,6 @@ public class IndicatorSound.Service: Object { } show_notification(warn_notification); } else { - message("closing warning"); close_notification(warn_notification); if (notify_server_supports_sync && !block_info_notifications) { @@ -438,9 +437,7 @@ public class IndicatorSound.Service: Object { } private void update_volume_action_state() { - var state = create_volume_action_state(); - message("updating volume_action state to %s", state.print(true)); - volume_action.set_state(state); + volume_action.set_state(create_volume_action_state()); } private SimpleAction volume_action; @@ -456,7 +453,6 @@ public class IndicatorSound.Service: Object { volume_action.activate.connect ((a,p) => activate_scroll_action(a,p)); this.volume_control.notify["max-volume"].connect(() => { - message("max-volume changed to %f", volume_control.max_volume); update_volume_action_state(); }); diff --git a/src/volume-control-pulse.vala b/src/volume-control-pulse.vala index edbfd23..874a6ca 100644 --- a/src/volume-control-pulse.vala +++ b/src/volume-control-pulse.vala @@ -643,7 +643,6 @@ public class VolumeControlPulse : VolumeControl /** MAX VOLUME PROPERTY **/ private void init_max_volume() { - message("woo"); _settings.changed["normal-volume-decibels"].connect(() => update_max_volume()); _settings.changed["amplified-volume-decibels"].connect(() => update_max_volume()); _shared_settings.changed["allow-amplified-volume"].connect(() => update_max_volume()); @@ -651,9 +650,8 @@ public class VolumeControlPulse : VolumeControl } private void update_max_volume () { var new_max_volume = calculate_max_volume(); - message ("old_max_volume %f new_max_volume %f", max_volume, new_max_volume); if (max_volume != new_max_volume) { - message("changing max_volume from %f to %f", this.max_volume, new_max_volume); + debug("changing max_volume from %f to %f", this.max_volume, new_max_volume); max_volume = calculate_max_volume(); } } @@ -684,20 +682,18 @@ public class VolumeControlPulse : VolumeControl update_high_volume_cache(); } private void update_high_volume_cache() { - _warning_volume_enabled = _settings.get_boolean("warning-volume-enabled"); - var volume_dB = _settings.get_double ("warning-volume-decibels"); var volume_sw = PulseAudio.Volume.sw_from_dB (volume_dB); var volume_norms = volume_to_double (volume_sw); _warning_volume_norms = volume_norms; - - message("updating high volume cache... enabled %d dB %f sw %lu norm %f", (int)_warning_volume_enabled, volume_dB, volume_sw, volume_norms); + _warning_volume_enabled = _settings.get_boolean("warning-volume-enabled"); + debug("updating high volume cache... enabled %d dB %f sw %lu norm %f", (int)_warning_volume_enabled, volume_dB, volume_sw, volume_norms); update_high_volume(); } private void update_high_volume() { var new_high_volume = calculate_high_volume(); if (high_volume != new_high_volume) { - message("changing high_volume from %d to %d", (int)high_volume, (int)new_high_volume); + debug("changing high_volume from %d to %d", (int)high_volume, (int)new_high_volume); high_volume = new_high_volume; } } @@ -705,7 +701,6 @@ public class VolumeControlPulse : VolumeControl return calculate_high_volume_from_volume(_volume.volume); } private bool calculate_high_volume_from_volume(double volume) { - message ("headphones %d warning enabled %d (vol %f > loud %f) multimedia %d", (int)_active_port_headphone, (int)_warning_volume_enabled, (double)volume, (double)_warning_volume_norms, (int)(stream == "multimedia")); return _active_port_headphone && _warning_volume_enabled && volume >= _warning_volume_norms @@ -713,15 +708,12 @@ public class VolumeControlPulse : VolumeControl } public override void clamp_to_high_volume() { - if (_high_volume) { - message("_volume.volume(%f) _warning_volume_norms(%f)", _volume.volume, _warning_volume_norms); - if (_volume.volume > _warning_volume_norms) { - var vol = new VolumeControl.Volume(); - vol.volume = _volume.volume.clamp(0, _warning_volume_norms); - vol.reason = _volume.reason; - message("Clamping from %f down to %f", _volume.volume, vol.volume); - volume = vol; - } + if (_high_volume && (_volume.volume > _warning_volume_norms)) { + var vol = new VolumeControl.Volume(); + vol.volume = _volume.volume.clamp(0, _warning_volume_norms); + vol.reason = _volume.reason; + debug("Clamping from %f down to %f", _volume.volume, vol.volume); + volume = vol; } } @@ -771,16 +763,14 @@ public class VolumeControlPulse : VolumeControl private void update_high_volume_approved() { var new_high_volume_approved = calculate_high_volume_approved(); if (high_volume_approved != new_high_volume_approved) { - message("changing high_volume_approved from %d to %d", (int)high_volume_approved, (int)new_high_volume_approved); + debug("changing high_volume_approved from %d to %d", (int)high_volume_approved, (int)new_high_volume_approved); high_volume_approved = new_high_volume_approved; } } private bool calculate_high_volume_approved() { int64 now = GLib.get_monotonic_time(); - var foo = (_high_volume_approved_at != 0) + return (_high_volume_approved_at != 0) && (_high_volume_approved_at + _high_volume_approved_ttl_usec >= now); - message("approved: %d", (int)foo); - return foo; } public override void approve_high_volume() { _high_volume_approved_at = GLib.get_monotonic_time(); -- cgit v1.2.3 From 8118ed6a926ebfafdae84899e0b0dd1de23a479b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 11 Aug 2015 16:42:20 -0500 Subject: re-enable notifications tests (currently failing) --- tests/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3c2e76f..2bbd8c5 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -195,7 +195,6 @@ add_test(sound-menu-test sound-menu-test) # Notification Test ########################### -#[[ include_directories(${CMAKE_SOURCE_DIR}/src) add_executable (notifications-test notifications-test.cc) target_link_libraries ( @@ -209,7 +208,6 @@ target_link_libraries ( ) add_test(notifications-test notifications-test) -]] ########################### # Accounts Service User -- cgit v1.2.3 From 93ed4338dc83fcae4a7c743452cf275d19d1d16c Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 11 Aug 2015 16:42:58 -0500 Subject: set the default value of max-volume to 1.0 so that tests behave nicely without explicitly having to set this value. --- src/volume-control.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/volume-control.vala b/src/volume-control.vala index a30a373..4efa85f 100644 --- a/src/volume-control.vala +++ b/src/volume-control.vala @@ -42,7 +42,7 @@ public abstract class VolumeControl : Object private Volume _volume; public virtual Volume volume { get { return _volume; } set { } } public virtual double mic_volume { get { return 0.0; } set { } } - public virtual double max_volume { get; set; } + public virtual double max_volume { get { return 1.0; } protected set { } } public virtual bool high_volume_approved { get { return false; } protected set { } } public virtual void approve_high_volume() { } -- cgit v1.2.3 From 8301d866b4a4aa7ef9f9235ebcb56c121b71b495 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 11 Aug 2015 17:17:57 -0500 Subject: fix circular reference loop that prevented Service from being destructed properly --- src/service.vala | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/service.vala b/src/service.vala index 777070a..a8e11fd 100644 --- a/src/service.vala +++ b/src/service.vala @@ -40,20 +40,7 @@ public class IndicatorSound.Service: Object { warn_notification.set_hint ("x-canonical-non-shaped-icon", "true"); warn_notification.set_hint ("x-canonical-snap-decisions", "true"); warn_notification.set_hint ("x-canonical-private-affirmative-tint", "true"); - warn_notification.add_action ("ok", _("OK"), (n, a) => { - stop_clamp_to_high_timeout(); - volume_control.approve_high_volume (); - if (_pre_warn_volume != null) { - var tmp = _pre_warn_volume; - _pre_warn_volume = null; - volume_control.volume = tmp; - } - }); - warn_notification.add_action ("cancel", _("Cancel"), (n, a) => { - _pre_warn_volume = null; - }); - - + warn_notification.closed.connect((n) => { n.clear_actions(); }); BusWatcher.watch_namespace (GLib.BusType.SESSION, "org.freedesktop.Notifications", () => { debug("Notifications name appeared"); notify_server_caps_checked = false; }, @@ -131,7 +118,8 @@ public class IndicatorSound.Service: Object { } private void close_notification(Notify.Notification? n) { - if ((n != null) && (n.id != 0)) { + return_if_fail (n != null); + if (n.id != 0) { try { n.close(); } catch (GLib.Error e) { @@ -141,12 +129,11 @@ public class IndicatorSound.Service: Object { } private void show_notification(Notify.Notification? n) { - if (n != null) { - try { - n.show (); - } catch (GLib.Error e) { - warning ("Unable to show notification: %s", e.message); - } + return_if_fail (n != null); + try { + n.show (); + } catch (GLib.Error e) { + warning ("Unable to show notification: %s", e.message); } } @@ -311,6 +298,19 @@ public class IndicatorSound.Service: Object { _pre_warn_volume.volume = volume_control.volume.volume; _pre_warn_volume.reason = volume_control.volume.reason; } + warn_notification.clear_actions(); + warn_notification.add_action ("ok", _("OK"), (n, a) => { + stop_clamp_to_high_timeout(); + volume_control.approve_high_volume (); + if (_pre_warn_volume != null) { + var tmp = _pre_warn_volume; + _pre_warn_volume = null; + volume_control.volume = tmp; + } + }); + warn_notification.add_action ("cancel", _("Cancel"), (n, a) => { + _pre_warn_volume = null; + }); show_notification(warn_notification); } else { close_notification(warn_notification); -- cgit v1.2.3 From 6cba78cd762fde9978d6eac65ae83fcde13eed83 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 11 Aug 2015 17:19:05 -0500 Subject: in tests/volume-control-mock, add a public method for setting max-volume so that we can re-enable those tests in notifications-test --- tests/volume-control-mock.vala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/volume-control-mock.vala b/tests/volume-control-mock.vala index 5902037..dc11fba 100644 --- a/tests/volume-control-mock.vala +++ b/tests/volume-control-mock.vala @@ -20,12 +20,14 @@ public class VolumeControlMock : VolumeControl { + private bool _high_volume = false; + public override bool high_volume { get { return _high_volume; } protected set { _high_volume = value; } } + public void set_high_volume(bool b) { high_volume = b; } + public string mock_stream { get; set; default = "multimedia"; } public override string stream { get { return mock_stream; } } public override bool ready { get; set; } public override bool active_mic { get; set; } - public bool mock_high_volume { get { return high_volume; } set { high_volume = value; } } - public override bool high_volume { get; private set; } public bool mock_mute { get; set; } public override bool mute { get { return mock_mute; } } public bool mock_is_playing { get; set; } -- cgit v1.2.3 From 2383bfa87a15534d94241ca6aa4332aa3e16d8aa Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 11 Aug 2015 17:19:36 -0500 Subject: in tests/notification-tests, re-enable the max-volume tests --- tests/notifications-test.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/notifications-test.cc b/tests/notifications-test.cc index 1f7e178..8d5617d 100644 --- a/tests/notifications-test.cc +++ b/tests/notifications-test.cc @@ -350,29 +350,29 @@ TEST_F(NotificationsTest, HighVolume) { /* Set high volume with volume change */ notifications->clearNotifications(); - volume_control_mock_set_mock_high_volume(VOLUME_CONTROL_MOCK(volumeControl.get()), TRUE); + volume_control_mock_set_high_volume(VOLUME_CONTROL_MOCK(volumeControl.get()), true); setMockVolume(volumeControl, 0.90); loop(50); notev = notifications->getNotifications(); ASSERT_LT(0, notev.size()); /* This passes with one or two since it would just be an update to the first if a second was sent */ EXPECT_EQ("Volume", notev[0].summary); - EXPECT_EQ("High volume", notev[0].body); + EXPECT_EQ("High volume can damage your hearing.", notev[0].body); EXPECT_GVARIANT_EQ("@s 'true'", notev[0].hints["x-canonical-value-bar-tint"]); /* Move it back */ - volume_control_mock_set_mock_high_volume(VOLUME_CONTROL_MOCK(volumeControl.get()), FALSE); + volume_control_mock_set_high_volume(VOLUME_CONTROL_MOCK(volumeControl.get()), false); setMockVolume(volumeControl, 0.50); loop(50); /* Set high volume without level change */ /* NOTE: This can happen if headphones are plugged in */ notifications->clearNotifications(); - volume_control_mock_set_mock_high_volume(VOLUME_CONTROL_MOCK(volumeControl.get()), TRUE); + volume_control_mock_set_high_volume(VOLUME_CONTROL_MOCK(volumeControl.get()), TRUE); loop(50); notev = notifications->getNotifications(); ASSERT_EQ(1, notev.size()); EXPECT_EQ("Volume", notev[0].summary); - EXPECT_EQ("High volume", notev[0].body); + EXPECT_EQ("High volume can damage your hearing.", notev[0].body); EXPECT_GVARIANT_EQ("@s 'true'", notev[0].hints["x-canonical-value-bar-tint"]); } @@ -406,7 +406,7 @@ TEST_F(NotificationsTest, MenuHide) { EXPECT_EQ(1, notev.size()); } -TEST_F(NotificationsTest, ExtendendVolumeNotification) { +TEST_F(NotificationsTest, DISABLED_ExtendendVolumeNotification) { auto volumeControl = volumeControlMock(); auto soundService = standardService(volumeControl, playerListMock()); @@ -424,7 +424,7 @@ TEST_F(NotificationsTest, ExtendendVolumeNotification) { /* Allow an amplified volume */ notifications->clearNotifications(); - indicator_sound_service_set_allow_amplified_volume(soundService.get(), TRUE); + //indicator_sound_service_set_allow_amplified_volume(soundService.get(), TRUE); loop(50); notev = notifications->getNotifications(); ASSERT_EQ(1, notev.size()); @@ -440,7 +440,7 @@ TEST_F(NotificationsTest, ExtendendVolumeNotification) { /* Put back */ notifications->clearNotifications(); - indicator_sound_service_set_allow_amplified_volume(soundService.get(), FALSE); + //indicator_sound_service_set_allow_amplified_volume(soundService.get(), FALSE); loop(50); notev = notifications->getNotifications(); ASSERT_EQ(1, notev.size()); -- cgit v1.2.3 From 156b8fd79ae38aeb3bdaaaa87257a4376a62dd41 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 11 Aug 2015 17:20:59 -0500 Subject: in tests/media-player-user, re-enable the DataSet and TimeoutTests --- tests/media-player-user.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/media-player-user.cc b/tests/media-player-user.cc index 876bce2..ca20b5f 100644 --- a/tests/media-player-user.cc +++ b/tests/media-player-user.cc @@ -239,7 +239,7 @@ running_update (GObject * obj, GParamSpec * pspec, bool * running) { *running = media_player_get_is_running(MEDIA_PLAYER(obj)) == TRUE; }; -TEST_F(MediaPlayerUserTest, DISABLED_DataSet) { +TEST_F(MediaPlayerUserTest, DataSet) { /* Put data into Acts */ set_property("Timestamp", g_variant_new_uint64(g_get_monotonic_time())); set_property("PlayerName", g_variant_new_string("The Player Formerly Known as Prince")); @@ -282,7 +282,7 @@ TEST_F(MediaPlayerUserTest, DISABLED_DataSet) { g_clear_object(&player); } -TEST_F(MediaPlayerUserTest, DISABLED_TimeoutTest) { +TEST_F(MediaPlayerUserTest, TimeoutTest) { /* Put data into Acts -- but 15 minutes ago */ set_property("Timestamp", g_variant_new_uint64(g_get_monotonic_time() - 15 * 60 * 1000 * 1000)); set_property("PlayerName", g_variant_new_string("The Player Formerly Known as Prince")); -- cgit v1.2.3 From 316be08822afec241a5ed1acca16612b87abfcdf Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 11 Aug 2015 18:37:34 -0500 Subject: in volume-control-pulse's update_high_volume_approved_timer(), fix timer interval --- src/volume-control-pulse.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/volume-control-pulse.vala b/src/volume-control-pulse.vala index 874a6ca..bc0fa40 100644 --- a/src/volume-control-pulse.vala +++ b/src/volume-control-pulse.vala @@ -744,7 +744,7 @@ public class VolumeControlPulse : VolumeControl int64 expires_at = _high_volume_approved_at + _high_volume_approved_ttl_usec; int64 now = GLib.get_monotonic_time(); if (expires_at > now) { - var seconds_left = 1 + ((now - expires_at) / 1000000); + var seconds_left = 1 + ((expires_at - now) / 1000000); _high_volume_approved_timer = Timeout.add_seconds((uint)seconds_left, on_high_volume_timer); } } -- cgit v1.2.3 From 6bfef752b163253821d6c967fabb8ca04c542fec Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 11 Aug 2015 19:13:59 -0500 Subject: in tests/media-player-user, re-disable the DataSet and TimeoutTests. This failure is not related to the new code and should be handled separately. --- tests/media-player-user.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/media-player-user.cc b/tests/media-player-user.cc index ca20b5f..876bce2 100644 --- a/tests/media-player-user.cc +++ b/tests/media-player-user.cc @@ -239,7 +239,7 @@ running_update (GObject * obj, GParamSpec * pspec, bool * running) { *running = media_player_get_is_running(MEDIA_PLAYER(obj)) == TRUE; }; -TEST_F(MediaPlayerUserTest, DataSet) { +TEST_F(MediaPlayerUserTest, DISABLED_DataSet) { /* Put data into Acts */ set_property("Timestamp", g_variant_new_uint64(g_get_monotonic_time())); set_property("PlayerName", g_variant_new_string("The Player Formerly Known as Prince")); @@ -282,7 +282,7 @@ TEST_F(MediaPlayerUserTest, DataSet) { g_clear_object(&player); } -TEST_F(MediaPlayerUserTest, TimeoutTest) { +TEST_F(MediaPlayerUserTest, DISABLED_TimeoutTest) { /* Put data into Acts -- but 15 minutes ago */ set_property("Timestamp", g_variant_new_uint64(g_get_monotonic_time() - 15 * 60 * 1000 * 1000)); set_property("PlayerName", g_variant_new_string("The Player Formerly Known as Prince")); -- cgit v1.2.3 From a78a8c0394bf2d4050b3748e8e753a8935849879 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 12 Aug 2015 09:00:56 -0500 Subject: copyediting: make tabs use in the new code consistent with existing codebase --- src/service.vala | 38 +++++++++++++++++++------------------- src/volume-control-pulse.vala | 12 ++++++------ src/volume-control.vala | 14 +++++++------- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/service.vala b/src/service.vala index a8e11fd..8da44da 100644 --- a/src/service.vala +++ b/src/service.vala @@ -142,7 +142,7 @@ public class IndicatorSound.Service: Object { clear_acts_player(); - stop_clamp_to_high_timeout(); + stop_clamp_to_high_timeout(); if (this.player_action_update_id > 0) { Source.remove (this.player_action_update_id); @@ -242,7 +242,7 @@ public class IndicatorSound.Service: Object { if (this.volume_control.mute) icon = this.mute_blocks_sound ? "audio-volume-muted-blocking-panel" : "audio-volume-muted-panel"; else if (this.accounts_service != null && this.accounts_service.silentMode) - icon = "audio-volume-muted-panel"; + icon = "audio-volume-muted-panel"; else if (volume <= 0.0) icon = "audio-volume-low-zero-panel"; else if (volume <= 0.3) @@ -622,26 +622,26 @@ public class IndicatorSound.Service: Object { this.update_preferred_players (); } - /** VOLUME CLAMPING **/ + /** VOLUME CLAMPING **/ - private uint _clamp_to_high_timeout = 0; + private uint _clamp_to_high_timeout = 0; - private void stop_clamp_to_high_timeout() { - if (_clamp_to_high_timeout != 0) { - Source.remove(_clamp_to_high_timeout); - _clamp_to_high_timeout = 0; - } - } + private void stop_clamp_to_high_timeout() { + if (_clamp_to_high_timeout != 0) { + Source.remove(_clamp_to_high_timeout); + _clamp_to_high_timeout = 0; + } + } - private void clamp_to_high_soon() { - const uint interval_msec = 200; /* arbitrary, but works */ - if (_clamp_to_high_timeout == 0) - _clamp_to_high_timeout = Timeout.add(interval_msec, clamp_to_high_idle); - } + private void clamp_to_high_soon() { + const uint interval_msec = 200; /* arbitrary, but works */ + if (_clamp_to_high_timeout == 0) + _clamp_to_high_timeout = Timeout.add(interval_msec, clamp_to_high_idle); + } - private bool clamp_to_high_idle() { - _clamp_to_high_timeout = 0; + private bool clamp_to_high_idle() { + _clamp_to_high_timeout = 0; volume_control.clamp_to_high_volume(); - return false; // Source.REMOVE; - } + return false; // Source.REMOVE; + } } diff --git a/src/volume-control-pulse.vala b/src/volume-control-pulse.vala index bc0fa40..21e7a5c 100644 --- a/src/volume-control-pulse.vala +++ b/src/volume-control-pulse.vala @@ -28,8 +28,8 @@ extern unowned PulseAudio.CVolume? vol_set (PulseAudio.CVolume? cv, uint channel [DBus (name="com.canonical.UnityGreeter.List")] interface GreeterListInterface : Object { - public abstract async string get_active_entry () throws IOError; - public signal void entry_selected (string entry_name); + public abstract async string get_active_entry () throws IOError; + public signal void entry_selected (string entry_name); } public class VolumeControlPulse : VolumeControl @@ -212,7 +212,7 @@ public class VolumeControlPulse : VolumeControl vol.volume = volume_to_double (i.volume.max ()); vol.reason = VolumeControl.VolumeReasons.PULSE_CHANGE; this.volume = vol; - } + } } private void source_info_cb (Context c, SourceInfo? i, int eol) @@ -768,9 +768,9 @@ public class VolumeControlPulse : VolumeControl } } private bool calculate_high_volume_approved() { - int64 now = GLib.get_monotonic_time(); - return (_high_volume_approved_at != 0) - && (_high_volume_approved_at + _high_volume_approved_ttl_usec >= now); + int64 now = GLib.get_monotonic_time(); + return (_high_volume_approved_at != 0) + && (_high_volume_approved_at + _high_volume_approved_ttl_usec >= now); } public override void approve_high_volume() { _high_volume_approved_at = GLib.get_monotonic_time(); diff --git a/src/volume-control.vala b/src/volume-control.vala index 4efa85f..6efac35 100644 --- a/src/volume-control.vala +++ b/src/volume-control.vala @@ -46,14 +46,14 @@ public abstract class VolumeControl : Object public virtual bool high_volume_approved { get { return false; } protected set { } } public virtual void approve_high_volume() { } - public virtual void clamp_to_high_volume() { } + public virtual void clamp_to_high_volume() { } public abstract void set_mute (bool mute); - public void set_volume_clamp (double unclamped, VolumeControl.VolumeReasons reason) { - var v = new VolumeControl.Volume(); - v.volume = unclamped.clamp (0.0, this.max_volume); - v.reason = reason; - this.volume = v; - } + public void set_volume_clamp (double unclamped, VolumeControl.VolumeReasons reason) { + var v = new VolumeControl.Volume(); + v.volume = unclamped.clamp (0.0, this.max_volume); + v.reason = reason; + this.volume = v; + } } -- cgit v1.2.3 From 0f5d5ee7a541aeea9a4dcd6d20a64ea0158b0a52 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 12 Aug 2015 09:25:42 -0500 Subject: copyediting: in new code, use unowned strings where practical, slightly better comments, more consistent method names --- src/service.vala | 33 ++++++++++++++++++--------------- src/volume-control-pulse.vala | 19 ++++++++----------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/service.vala b/src/service.vala index 8da44da..f1c37a8 100644 --- a/src/service.vala +++ b/src/service.vala @@ -318,23 +318,26 @@ public class IndicatorSound.Service: Object { if (notify_server_supports_sync && !block_info_notifications) { /* Determine Label */ - string volume_label = ""; - if (loud) { - volume_label = _("High volume can damage your hearing."); - } + unowned string volume_label = loud + ? _("High volume can damage your hearing.") + : ""; /* Choose an icon */ - string icon = ""; - if (loud) - icon = "audio-volume-high"; - else if (volume_control.volume.volume <= 0.0) - icon = "audio-volume-muted"; - else if (volume_control.volume.volume <= 0.3) - icon = "audio-volume-low"; - else if (volume_control.volume.volume <= 0.7) - icon = "audio-volume-medium"; - else + unowned string icon; + if (loud) { icon = "audio-volume-high"; + } else { + var volume = volume_control.volume.volume; + + if (volume <= 0.0) + icon = "audio-volume-muted"; + else if (volume <= 0.3) + icon = "audio-volume-low"; + else if (volume <= 0.7) + icon = "audio-volume-medium"; + else + icon = "audio-volume-high"; + } /* Reset the notification */ var n = this.info_notification; @@ -634,7 +637,7 @@ public class IndicatorSound.Service: Object { } private void clamp_to_high_soon() { - const uint interval_msec = 200; /* arbitrary, but works */ + const uint interval_msec = 200; if (_clamp_to_high_timeout == 0) _clamp_to_high_timeout = Timeout.add(interval_msec, clamp_to_high_idle); } diff --git a/src/volume-control-pulse.vala b/src/volume-control-pulse.vala index 21e7a5c..81938fe 100644 --- a/src/volume-control-pulse.vala +++ b/src/volume-control-pulse.vala @@ -656,12 +656,9 @@ public class VolumeControlPulse : VolumeControl } } private double calculate_max_volume () { - string decibel_key; - if (_shared_settings.get_boolean("allow-amplified-volume")) - decibel_key = "amplified-volume-decibels"; - else - decibel_key = "normal-volume-decibels"; - + unowned string decibel_key = _shared_settings.get_boolean("allow-amplified-volume") + ? "amplified-volume-decibels" + : "normal-volume-decibels"; var volume_dB = _settings.get_double(decibel_key); var volume_sw = PulseAudio.Volume.sw_from_dB (volume_dB); return volume_to_double (volume_sw); @@ -670,7 +667,7 @@ public class VolumeControlPulse : VolumeControl /** HIGH VOLUME PROPERTY **/ private bool _warning_volume_enabled; - private double _warning_volume_norms; + private double _warning_volume_norms; /* 1.0 == PA_VOLUME_NORM */ private bool _high_volume = false; public override bool high_volume { get { return this._high_volume; } @@ -720,9 +717,9 @@ public class VolumeControlPulse : VolumeControl /** HIGH VOLUME APPROVED PROPERTY **/ private bool _high_volume_approved = false; + private uint _high_volume_approved_timer = 0; private int64 _high_volume_approved_at = 0; private int64 _high_volume_approved_ttl_usec = 0; - private uint _high_volume_approved_timer = 0; public override bool high_volume_approved { get { return this._high_volume_approved; } private set { this._high_volume_approved = value; } @@ -745,7 +742,7 @@ public class VolumeControlPulse : VolumeControl int64 now = GLib.get_monotonic_time(); if (expires_at > now) { var seconds_left = 1 + ((expires_at - now) / 1000000); - _high_volume_approved_timer = Timeout.add_seconds((uint)seconds_left, on_high_volume_timer); + _high_volume_approved_timer = Timeout.add_seconds((uint)seconds_left, on_high_volume_approved_timer); } } } @@ -755,7 +752,7 @@ public class VolumeControlPulse : VolumeControl _high_volume_approved_timer = 0; } } - private bool on_high_volume_timer() { + private bool on_high_volume_approved_timer() { _high_volume_approved_timer = 0; update_high_volume_approved(); return false; /* Source.REMOVE */ @@ -774,8 +771,8 @@ public class VolumeControlPulse : VolumeControl } public override void approve_high_volume() { _high_volume_approved_at = GLib.get_monotonic_time(); - update_high_volume_approved_timer(); update_high_volume_approved(); + update_high_volume_approved_timer(); } -- cgit v1.2.3 From 361bd251b15581e5e53f89e2fc6948555f1d73e1 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 12 Aug 2015 13:15:07 -0500 Subject: copyediting: fix missing tab --- src/service.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/service.vala b/src/service.vala index f1c37a8..f17d799 100644 --- a/src/service.vala +++ b/src/service.vala @@ -639,7 +639,7 @@ public class IndicatorSound.Service: Object { private void clamp_to_high_soon() { const uint interval_msec = 200; if (_clamp_to_high_timeout == 0) - _clamp_to_high_timeout = Timeout.add(interval_msec, clamp_to_high_idle); + _clamp_to_high_timeout = Timeout.add(interval_msec, clamp_to_high_idle); } private bool clamp_to_high_idle() { -- cgit v1.2.3 From 480d998efb8bcd94401ff2d7c40a1fb9b81d8db1 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 12 Aug 2015 13:16:40 -0500 Subject: in volume-control-pulse, extract methods from ctor and dtor for readability --- src/volume-control-pulse.vala | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/volume-control-pulse.vala b/src/volume-control-pulse.vala index 81938fe..87af258 100644 --- a/src/volume-control-pulse.vala +++ b/src/volume-control-pulse.vala @@ -105,16 +105,26 @@ public class VolumeControlPulse : VolumeControl _mute_cancellable = new Cancellable (); _volume_cancellable = new Cancellable (); - init_max_volume(); - init_high_volume(); - init_high_volume_approved(); + init_all_properties(); setup_accountsservice.begin (); this.reconnect_to_pulse (); } + private void init_all_properties() + { + init_max_volume(); + init_high_volume(); + init_high_volume_approved(); + } + ~VolumeControlPulse () + { + stop_all_timers(); + } + + private void stop_all_timers() { if (_reconnect_timer != 0) { Source.remove (_reconnect_timer); -- cgit v1.2.3