aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/com.canonical.indicator.sound.gschema.xml9
-rw-r--r--debian/changelog29
-rw-r--r--src/CMakeLists.txt8
-rw-r--r--src/accounts-service-privacy-settings.vala26
-rw-r--r--src/accounts-service-system-sound-settings.vala25
-rw-r--r--src/accounts-service-user.vala74
-rw-r--r--src/media-player-mpris.vala2
-rw-r--r--src/service.vala96
-rw-r--r--src/sound-menu.vala20
-rw-r--r--src/volume-control.vala20
10 files changed, 258 insertions, 51 deletions
diff --git a/data/com.canonical.indicator.sound.gschema.xml b/data/com.canonical.indicator.sound.gschema.xml
index c34dfd6..102a1db 100644
--- a/data/com.canonical.indicator.sound.gschema.xml
+++ b/data/com.canonical.indicator.sound.gschema.xml
@@ -48,14 +48,5 @@
Whether or not to show the sound indicator in the menu bar.
</description>
</key>
- <key name="greeter-export" type="b">
- <default>true</default>
- <summary>Whether or not to export the currently playing song to the greeter.</summary>
- <description>
- If enabled the sound indicator will export the current player and
- song to the greeter so that it can be shown if the user is selected
- and the sound menu is shown.
- </description>
- </key>
</schema>
</schemalist>
diff --git a/debian/changelog b/debian/changelog
index e472d77..79f21ea 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,32 @@
+indicator-sound (12.10.2+14.10.20141010-0ubuntu3) UNRELEASED; urgency=medium
+
+ * Remove various Vala warnings
+ * Show notifications on volume change (LP: #1378564, #1378961)
+
+ -- Ted Gould <ted@ubuntu.com> Wed, 05 Nov 2014 10:31:30 -0600
+
+indicator-sound (12.10.2+14.10.20141010-0ubuntu1) utopic; urgency=low
+
+ [ Ricardo Salveti de Araujo ]
+ * volume-control: making sure we're always in sync with accountservice
+ (LP: #1379618)
+
+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 10 Oct 2014 15:40:30 +0000
+
+indicator-sound (12.10.2+14.10.20141009-0ubuntu1) utopic; urgency=low
+
+ [ Ted Gould ]
+ * Show a silent mode checkbox (LP: #1342151)
+
+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Thu, 09 Oct 2014 13:32:54 +0000
+
+indicator-sound (12.10.2+14.10.20141008-0ubuntu1) utopic; urgency=low
+
+ [ Ted Gould ]
+ * Revert notifications on volume change.
+
+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 08 Oct 2014 18:55:06 +0000
+
indicator-sound (12.10.2+14.10.20141007-0ubuntu1) utopic; urgency=low
[ Ted Gould ]
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3cab736..c18726c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -104,12 +104,20 @@ vala_add(indicator-sound-service
media-player
mpris2-interfaces
accounts-service-sound-settings
+ accounts-service-privacy-settings
+ accounts-service-system-sound-settings
greeter-broadcast
)
vala_add(indicator-sound-service
accounts-service-sound-settings.vala
)
vala_add(indicator-sound-service
+ accounts-service-privacy-settings.vala
+)
+vala_add(indicator-sound-service
+ accounts-service-system-sound-settings.vala
+)
+vala_add(indicator-sound-service
greeter-broadcast.vala
)
diff --git a/src/accounts-service-privacy-settings.vala b/src/accounts-service-privacy-settings.vala
new file mode 100644
index 0000000..ef5c309
--- /dev/null
+++ b/src/accounts-service-privacy-settings.vala
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2014 © Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Ted Gould <ted@canonical.com>
+ */
+
+[DBus (name = "com.ubuntu.touch.AccountsService.SecurityPrivacy")]
+public interface AccountsServicePrivacySettings : Object {
+ // properties
+ public abstract bool stats_welcome_screen {owned get; set;}
+ public abstract bool messages_welcome_screen {owned get; set;}
+}
+
diff --git a/src/accounts-service-system-sound-settings.vala b/src/accounts-service-system-sound-settings.vala
new file mode 100644
index 0000000..283a606
--- /dev/null
+++ b/src/accounts-service-system-sound-settings.vala
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2014 © Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Ted Gould <ted@canonical.com>
+ */
+
+[DBus (name = "com.ubuntu.touch.AccountsService.Sound")]
+public interface AccountsServiceSystemSoundSettings : Object {
+ // properties
+ public abstract bool silent_mode {owned get; set;}
+}
+
diff --git a/src/accounts-service-user.vala b/src/accounts-service-user.vala
index 04c38cc..ec52730 100644
--- a/src/accounts-service-user.vala
+++ b/src/accounts-service-user.vala
@@ -21,10 +21,25 @@ public class AccountsServiceUser : Object {
Act.UserManager accounts_manager = Act.UserManager.get_default();
Act.User? user = null;
AccountsServiceSoundSettings? proxy = null;
+ AccountsServicePrivacySettings? privacyproxy = null;
+ AccountsServiceSystemSoundSettings? syssoundproxy = null;
uint timer = 0;
MediaPlayer? _player = null;
GreeterBroadcast? greeter = null;
+ public bool showDataOnGreeter { get; set; }
+
+ bool _silentMode = false;
+ public bool silentMode {
+ get {
+ return _silentMode;
+ }
+ set {
+ if (syssoundproxy != null)
+ syssoundproxy.silent_mode = value;
+ }
+ }
+
public MediaPlayer? player {
set {
this._player = value;
@@ -124,7 +139,23 @@ public class AccountsServiceUser : Object {
user.get_object_path(),
DBusProxyFlags.GET_INVALIDATED_PROPERTIES,
null,
- new_proxy);
+ new_sound_proxy);
+
+ Bus.get_proxy.begin<AccountsServicePrivacySettings> (
+ BusType.SYSTEM,
+ "org.freedesktop.Accounts",
+ user.get_object_path(),
+ DBusProxyFlags.GET_INVALIDATED_PROPERTIES,
+ null,
+ new_privacy_proxy);
+
+ Bus.get_proxy.begin<AccountsServiceSystemSoundSettings> (
+ BusType.SYSTEM,
+ "org.freedesktop.Accounts",
+ user.get_object_path(),
+ DBusProxyFlags.GET_INVALIDATED_PROPERTIES,
+ null,
+ new_system_sound_proxy);
}
}
@@ -138,7 +169,7 @@ public class AccountsServiceUser : Object {
}
}
- void new_proxy (GLib.Object? obj, AsyncResult res) {
+ void new_sound_proxy (GLib.Object? obj, AsyncResult res) {
try {
this.proxy = Bus.get_proxy.end (res);
this.player = _player;
@@ -148,6 +179,45 @@ public class AccountsServiceUser : Object {
}
}
+ void new_privacy_proxy (GLib.Object? obj, AsyncResult res) {
+ try {
+ this.privacyproxy = Bus.get_proxy.end (res);
+
+ (this.privacyproxy as DBusProxy).g_properties_changed.connect((proxy, changed, invalid) => {
+ var welcomeval = changed.lookup_value("MessagesWelcomeScreen", new VariantType("b"));
+ if (welcomeval != null) {
+ debug("Messages on welcome screen changed");
+ this.showDataOnGreeter = welcomeval.get_boolean();
+ }
+ });
+
+ this.showDataOnGreeter = this.privacyproxy.messages_welcome_screen;
+ } catch (Error e) {
+ this.privacyproxy = null;
+ warning("Unable to get proxy to user privacy settings: %s", e.message);
+ }
+ }
+
+ void new_system_sound_proxy (GLib.Object? obj, AsyncResult res) {
+ try {
+ this.syssoundproxy = Bus.get_proxy.end (res);
+
+ (this.syssoundproxy as DBusProxy).g_properties_changed.connect((proxy, changed, invalid) => {
+ var silentvar = changed.lookup_value("SilentMode", new VariantType("b"));
+ if (silentvar != null) {
+ debug("Silent Mode changed");
+ this._silentMode = silentvar.get_boolean();
+ this.notify_property("silentMode");
+ }
+ });
+
+ this.silentMode = this.syssoundproxy.silent_mode;
+ } catch (Error e) {
+ this.syssoundproxy = null;
+ warning("Unable to get proxy to system sound settings: %s", e.message);
+ }
+ }
+
void greeter_proxy_new (GLib.Object? obj, AsyncResult res) {
try {
this.greeter = Bus.get_proxy.end (res);
diff --git a/src/media-player-mpris.vala b/src/media-player-mpris.vala
index 25ddac4..bf25e21 100644
--- a/src/media-player-mpris.vala
+++ b/src/media-player-mpris.vala
@@ -283,7 +283,7 @@ public class MediaPlayerMpris: MediaPlayer {
this.fetch_playlists ();
}
- void update_current_track (Variant metadata) {
+ void update_current_track (Variant? metadata) {
if (metadata != null) {
this.current_track = new Track (
sanitize_metadata_value (metadata.lookup_value ("xesam:artist", null)),
diff --git a/src/service.vala b/src/service.vala
index 4e02769..4298ad7 100644
--- a/src/service.vala
+++ b/src/service.vala
@@ -27,30 +27,39 @@ public class IndicatorSound.Service: Object {
this.volume_control = new VolumeControl ();
+ /* If we're on the greeter, don't export */
+ if (GLib.Environment.get_user_name() != "lightdm") {
+ this.accounts_service = new AccountsServiceUser();
+
+ this.accounts_service.notify["showDataOnGreeter"].connect(() => {
+ this.export_to_accounts_service = this.accounts_service.showDataOnGreeter;
+ eventually_update_player_actions();
+ });
+
+ this.export_to_accounts_service = this.accounts_service.showDataOnGreeter;
+ }
+
this.players = playerlist;
this.players.player_added.connect (this.player_added);
this.players.player_removed.connect (this.player_removed);
this.actions = new SimpleActionGroup ();
this.actions.add_action_entries (action_entries, this);
+ this.actions.add_action (this.create_silent_mode_action ());
this.actions.add_action (this.create_mute_action ());
this.actions.add_action (this.create_volume_action ());
this.actions.add_action (this.create_mic_volume_action ());
this.menus = new HashTable<string, SoundMenu> (str_hash, str_equal);
- this.menus.insert ("desktop_greeter", new SoundMenu (null, SoundMenu.DisplayFlags.SHOW_MUTE | SoundMenu.DisplayFlags.HIDE_PLAYERS));
- this.menus.insert ("phone_greeter", new SoundMenu (null, SoundMenu.DisplayFlags.HIDE_INACTIVE_PLAYERS));
+ this.menus.insert ("desktop_greeter", new SoundMenu (null, SoundMenu.DisplayFlags.SHOW_MUTE | SoundMenu.DisplayFlags.HIDE_PLAYERS | SoundMenu.DisplayFlags.GREETER_PLAYERS));
+ this.menus.insert ("phone_greeter", new SoundMenu (null, SoundMenu.DisplayFlags.SHOW_SILENT_MODE | SoundMenu.DisplayFlags.HIDE_INACTIVE_PLAYERS | SoundMenu.DisplayFlags.GREETER_PLAYERS));
this.menus.insert ("desktop", new SoundMenu ("indicator.desktop-settings", SoundMenu.DisplayFlags.SHOW_MUTE));
- this.menus.insert ("phone", new SoundMenu ("indicator.phone-settings", SoundMenu.DisplayFlags.HIDE_INACTIVE_PLAYERS));
+ this.menus.insert ("phone", new SoundMenu ("indicator.phone-settings", SoundMenu.DisplayFlags.SHOW_SILENT_MODE | SoundMenu.DisplayFlags.HIDE_INACTIVE_PLAYERS));
this.menus.@foreach ( (profile, menu) => {
this.volume_control.bind_property ("active-mic", menu, "show-mic-volume", BindingFlags.SYNC_CREATE);
});
- /* Setup handling for the greeter-export setting */
- this.settings.changed["greeter-export"].connect( () => this.build_accountsservice() );
- build_accountsservice();
-
this.sync_preferred_players ();
this.settings.changed["interested-media-players"].connect ( () => {
this.sync_preferred_players ();
@@ -60,7 +69,7 @@ public class IndicatorSound.Service: Object {
List<string> caps = Notify.get_server_caps ();
if (caps.find_custom ("x-canonical-private-synchronous", strcmp) != null) {
this.notification = new Notify.Notification ("indicator-sound", "", "");
- this.notification.set_hint_string ("x-canonical-private-synchronous", "indicator-sound");
+ this.notification.set_hint ("x-canonical-private-synchronous", "indicator-sound");
}
}
@@ -74,25 +83,8 @@ public class IndicatorSound.Service: Object {
}
}
- void build_accountsservice () {
- clear_acts_player();
- this.accounts_service = null;
-
- /* If we're not exporting, don't build anything */
- if (!this.settings.get_boolean("greeter-export")) {
- debug("Accounts service export disabled due to user setting");
- return;
- }
-
- /* If we're on the greeter, don't export */
- if (GLib.Environment.get_user_name() == "lightdm") {
- debug("Accounts service export disabled due to being used on the greeter");
- return;
- }
-
- this.accounts_service = new AccountsServiceUser();
-
- this.eventually_update_player_actions();
+ bool greeter_show_track () {
+ return export_to_accounts_service;
}
void clear_acts_player () {
@@ -167,6 +159,7 @@ public class IndicatorSound.Service: Object {
Notify.Notification notification;
bool syncing_preferred_players = false;
AccountsServiceUser? accounts_service = null;
+ bool export_to_accounts_service = false;
/* Maximum volume as a scaling factor between the volume action's state and the value in
* this.volume_control. See create_volume_action().
@@ -193,7 +186,7 @@ public class IndicatorSound.Service: Object {
icon = "notification-audio-volume-high";
this.notification.update ("indicator-sound", "", icon);
- this.notification.set_hint_int32 ("value", ((int32) (100 * v / this.max_volume)).clamp (-1, 101));
+ this.notification.set_hint ("value", ((int32) (100 * v / this.max_volume)).clamp (-1, 101));
try {
this.notification.show ();
}
@@ -265,6 +258,36 @@ public class IndicatorSound.Service: Object {
root_action.set_state (builder.end());
}
+ Action create_silent_mode_action () {
+ bool silentNow = false;
+ if (this.accounts_service != null) {
+ silentNow = this.accounts_service.silentMode;
+ }
+
+ var silent_action = new SimpleAction.stateful ("silent-mode", null, new Variant.boolean (silentNow));
+
+ /* If we're not dealing with accounts service, we'll just always be out
+ of silent mode and that's cool. */
+ if (this.accounts_service == null) {
+ return silent_action;
+ }
+
+ this.accounts_service.notify["silentMode"].connect(() => {
+ silent_action.set_state(new Variant.boolean(this.accounts_service.silentMode));
+ this.update_root_icon ();
+ });
+
+ silent_action.activate.connect ((action, param) => {
+ action.change_state (new Variant.boolean (!action.get_state().get_boolean()));
+ });
+
+ silent_action.change_state.connect ((action, val) => {
+ this.accounts_service.silentMode = val.get_boolean();
+ });
+
+ return silent_action;
+ }
+
Action create_mute_action () {
var mute_action = new SimpleAction.stateful ("mute", null, new Variant.boolean (this.volume_control.mute));
@@ -379,11 +402,11 @@ public class IndicatorSound.Service: Object {
this.loop.quit ();
}
- Variant action_state_for_player (MediaPlayer player) {
+ Variant action_state_for_player (MediaPlayer player, bool show_track = true) {
var builder = new VariantBuilder (new VariantType ("a{sv}"));
builder.add ("{sv}", "running", new Variant ("b", player.is_running));
builder.add ("{sv}", "state", new Variant ("s", player.state));
- if (player.current_track != null) {
+ if (player.current_track != null && show_track) {
builder.add ("{sv}", "title", new Variant ("s", player.current_track.title));
builder.add ("{sv}", "artist", new Variant ("s", player.current_track.artist));
builder.add ("{sv}", "album", new Variant ("s", player.current_track.album));
@@ -402,8 +425,14 @@ public class IndicatorSound.Service: Object {
action.set_enabled (player.can_raise);
}
+ SimpleAction? greeter_action = this.actions.lookup_action (player.id + ".greeter") as SimpleAction;
+ if (greeter_action != null) {
+ greeter_action.set_state (this.action_state_for_player (player, greeter_show_track()));
+ greeter_action.set_enabled (player.can_raise);
+ }
+
/* If we're playing then put that data in accounts service */
- if (player.is_running && accounts_service != null) {
+ if (player.is_running && export_to_accounts_service && accounts_service != null) {
accounts_service.player = player;
clear_accounts_player = false;
}
@@ -446,6 +475,11 @@ public class IndicatorSound.Service: Object {
action.activate.connect ( () => { player.activate (); });
this.actions.add_action (action);
+ SimpleAction greeter_action = new SimpleAction.stateful (player.id + ".greeter", null, this.action_state_for_player (player, greeter_show_track()));
+ greeter_action.set_enabled (player.can_raise);
+ greeter_action.activate.connect ( () => { player.activate (); });
+ this.actions.add_action (greeter_action);
+
var play_action = new SimpleAction.stateful ("play." + player.id, null, player.state);
play_action.activate.connect ( () => player.play_pause () );
this.actions.add_action (play_action);
diff --git a/src/sound-menu.vala b/src/sound-menu.vala
index 03faa89..f245a1f 100644
--- a/src/sound-menu.vala
+++ b/src/sound-menu.vala
@@ -23,7 +23,9 @@ public class SoundMenu: Object
NONE = 0,
SHOW_MUTE = 1,
HIDE_INACTIVE_PLAYERS = 2,
- HIDE_PLAYERS = 4
+ HIDE_PLAYERS = 4,
+ GREETER_PLAYERS = 8,
+ SHOW_SILENT_MODE = 16
}
public SoundMenu (string? settings_action, DisplayFlags flags) {
@@ -33,8 +35,15 @@ public class SoundMenu: Object
*/
this.volume_section = new Menu ();
+
if ((flags & DisplayFlags.SHOW_MUTE) != 0)
volume_section.append (_("Mute"), "indicator.mute");
+ if ((flags & DisplayFlags.SHOW_SILENT_MODE) != 0) {
+ var item = new MenuItem(_("Silent Mode"), "indicator.silent-mode");
+ item.set_attribute("x-canonical-type", "s", "com.canonical.indicator.switch");
+ volume_section.append_item(item);
+ }
+
volume_section.append_item (this.create_slider_menu_item (_("Volume"), "indicator.volume(0)", 0.0, 1.0, 0.01,
"audio-volume-low-zero-panel",
"audio-volume-high-panel"));
@@ -59,6 +68,8 @@ public class SoundMenu: Object
this.hide_players = (flags & DisplayFlags.HIDE_PLAYERS) != 0;
this.hide_inactive = (flags & DisplayFlags.HIDE_INACTIVE_PLAYERS) != 0;
this.notify_handlers = new HashTable<MediaPlayer, ulong> (direct_hash, direct_equal);
+
+ this.greeter_players = (flags & DisplayFlags.GREETER_PLAYERS) != 0;
}
public void export (DBusConnection connection, string object_path) {
@@ -133,6 +144,7 @@ public class SoundMenu: Object
bool hide_inactive;
bool hide_players = false;
HashTable<MediaPlayer, ulong> notify_handlers;
+ bool greeter_players = false;
/* returns the position in this.menu of the section that's associated with @player */
int find_player_section (MediaPlayer player) {
@@ -166,7 +178,11 @@ public class SoundMenu: Object
if (icon == null)
icon = new ThemedIcon.with_default_fallbacks ("application-default-icon");
- var player_item = new MenuItem (player.name, "indicator." + player.id);
+ var base_action = "indicator." + player.id;
+ if (this.greeter_players)
+ base_action += ".greeter";
+
+ var player_item = new MenuItem (player.name, base_action);
player_item.set_attribute ("x-canonical-type", "s", "com.canonical.unity.media-player");
if (icon != null)
player_item.set_attribute_value ("icon", icon.serialize ());
diff --git a/src/volume-control.vala b/src/volume-control.vala
index 0541397..dd1128c 100644
--- a/src/volume-control.vala
+++ b/src/volume-control.vala
@@ -179,6 +179,7 @@ public class VolumeControl : Object
{
_volume = volume_to_double (i.volume.max ());
volume_changed (_volume);
+ start_local_volume_timer();
}
}
@@ -247,6 +248,7 @@ public class VolumeControl : Object
/* Someone else changed the volume for this role, reflect on the indicator */
_volume = volume_to_double (volume);
volume_changed (_volume);
+ start_local_volume_timer();
}
}
}
@@ -289,6 +291,7 @@ public class VolumeControl : Object
_volume = volume_to_double (volume);
volume_changed (_volume);
+ start_local_volume_timer();
} catch (GLib.Error e) {
warning ("unable to get volume for active role %s (%s)", sink_input_objp, e.message);
}
@@ -561,7 +564,8 @@ public class VolumeControl : Object
bool set_volume_internal (double volume)
{
- return_val_if_fail (context.get_state () == Context.State.READY, false);
+ if (context.get_state () != Context.State.READY)
+ return false;
if (_volume != volume) {
_volume = volume;
@@ -720,7 +724,7 @@ public class VolumeControl : Object
}
/* AccountsService operations */
- private void accountsservice_props_changed_cb (DBusProxy proxy, Variant changed_properties, string[] invalidated_properties)
+ private void accountsservice_props_changed_cb (DBusProxy proxy, Variant changed_properties, string[]? invalidated_properties)
{
Variant volume_variant = changed_properties.lookup_value ("Volume", new VariantType ("d"));
if (volume_variant != null) {
@@ -778,10 +782,14 @@ public class VolumeControl : Object
// Get current values and listen for changes
_user_proxy.g_properties_changed.connect (accountsservice_props_changed_cb);
- var props_variant = yield _user_proxy.get_connection ().call (_user_proxy.get_name (), _user_proxy.get_object_path (), "org.freedesktop.DBus.Properties", "GetAll", new Variant ("(s)", _user_proxy.get_interface_name ()), null, DBusCallFlags.NONE, -1);
- Variant props;
- props_variant.get ("(@a{sv})", out props);
- accountsservice_props_changed_cb(_user_proxy, props, null);
+ try {
+ var props_variant = yield _user_proxy.get_connection ().call (_user_proxy.get_name (), _user_proxy.get_object_path (), "org.freedesktop.DBus.Properties", "GetAll", new Variant ("(s)", _user_proxy.get_interface_name ()), null, DBusCallFlags.NONE, -1);
+ Variant props;
+ props_variant.get ("(@a{sv})", out props);
+ accountsservice_props_changed_cb(_user_proxy, props, null);
+ } catch (GLib.Error e) {
+ debug("Unable to get properties for user %s at first try: %s", username, e.message);
+ }
}
private void greeter_user_changed (string username)