Merge lp:~charlesk/indicator-bluetooth/lp-1236249 into lp:indicator-bluetooth/13.10

Proposed by Charles Kerr
Status: Merged
Approved by: Ted Gould
Approved revision: 73
Merged at revision: 70
Proposed branch: lp:~charlesk/indicator-bluetooth/lp-1236249
Merge into: lp:indicator-bluetooth/13.10
Diff against target: 422 lines (+133/-84)
8 files modified
src/bluetooth.vala (+8/-41)
src/bluez.vala (+108/-26)
src/desktop.vala (+2/-6)
src/killswitch.vala (+7/-0)
src/main.vala (+1/-1)
src/org-bluez.vala (+1/-1)
src/phone.vala (+1/-1)
src/profile.vala (+5/-8)
To merge this branch: bzr merge lp:~charlesk/indicator-bluetooth/lp-1236249
Reviewer Review Type Date Requested Status
Ted Gould (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+190669@code.launchpad.net

Commit message

When the user chooses to toggle bluetooth on or off, if /dev/rfkill isn't available, fall back to toggling org.bluez.Adapter's Powered property.

Description of the change

* Use org.bluez.Adapter's Powered property to toggle bluetooth on and off. Skip /dev/rfkill entirely for 13.10, there are issues there that can't be resolved in time for 13.10.

* Leave the killswitch /dev/rfkill code in the codebase, though disabled for now, because it's likely to return post-13.10

* Do a better job of monitoring the bluez Manager and Adapter for changes s.t. the indicator can update its own state appropriately.

See also https://bugs.launchpad.net/ubuntu/+source/unity8/+bug/1236249/comments/8

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ted Gould (ted) wrote :

Don't see anything objectionable (a lot of code though). Works for me on my Galaxy Nexus.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/bluetooth.vala'
--- src/bluetooth.vala 2013-10-10 19:58:46 +0000
+++ src/bluetooth.vala 2013-10-14 23:34:48 +0000
@@ -27,22 +27,19 @@
27 This work as a proxy for "does this hardware support bluetooth?" */27 This work as a proxy for "does this hardware support bluetooth?" */
28 public abstract bool supported { get; protected set; }28 public abstract bool supported { get; protected set; }
2929
30 /* True if there are any bluetooth adapters powered up on the system.30 /* True if bluetooth's enabled on this system.
31 In short, whether or not this system's bluetooth is "on". */31 Bluetooth can be soft-blocked by software and hard-blocked physically,
32 public abstract bool powered { get; protected set; }32 eg by a laptop's network killswitch */
33 public abstract bool enabled { get; protected set; }
34
35 /* Try to enable/disable bluetooth. This can fail if it's overridden
36 by the system, eg by a laptop's network killswitch */
37 public abstract void try_set_enabled (bool b);
3338
34 /* True if our system can be seen by other bluetooth devices */39 /* True if our system can be seen by other bluetooth devices */
35 public abstract bool discoverable { get; protected set; }40 public abstract bool discoverable { get; protected set; }
36 public abstract void try_set_discoverable (bool discoverable);41 public abstract void try_set_discoverable (bool discoverable);
3742
38 /* True if bluetooth's blocked. This can be soft-blocked by software and
39 * hard-blocked physically, eg by a laptop's network killswitch */
40 public abstract bool blocked { get; protected set; }
41
42 /* Try to block/unblock bluetooth. This can fail if it's overridden
43 by the system, eg by a laptop's network killswitch */
44 public abstract void try_set_blocked (bool b);
45
46 /* Get a list of the Device structs that we know about */43 /* Get a list of the Device structs that we know about */
47 public abstract List<unowned Device> get_devices ();44 public abstract List<unowned Device> get_devices ();
4845
@@ -53,33 +50,3 @@
53 The device_key argument comes from the Device struct */50 The device_key argument comes from the Device struct */
54 public abstract void set_device_connected (uint device_key, bool connected);51 public abstract void set_device_connected (uint device_key, bool connected);
55}52}
56
57
58
59/**
60 * Base class for Bluetooth objects that use a killswitch to implement
61 * the 'discoverable' property.
62 */
63public abstract class KillswitchBluetooth: Object, Bluetooth
64{
65 private KillSwitch killswitch;
66
67 public KillswitchBluetooth (KillSwitch killswitch)
68 {
69 // always sync our 'blocked' property with the one in killswitch
70 this.killswitch = killswitch;
71 blocked = killswitch.blocked;
72 killswitch.notify["blocked"].connect (() => blocked = killswitch.blocked );
73 }
74
75 public bool supported { get; protected set; default = false; }
76 public bool powered { get; protected set; default = false; }
77 public bool discoverable { get; protected set; default = false; }
78 public bool blocked { get; protected set; default = true; }
79 public void try_set_blocked (bool b) { killswitch.try_set_blocked (b); }
80
81 // empty implementations
82 public abstract void try_set_discoverable (bool b);
83 public abstract List<unowned Device> get_devices ();
84 public abstract void set_device_connected (uint device_key, bool connected);
85}
8653
=== modified file 'src/bluez.vala'
--- src/bluez.vala 2013-10-10 19:58:46 +0000
+++ src/bluez.vala 2013-10-14 23:34:48 +0000
@@ -22,12 +22,25 @@
22/**22/**
23 * Bluetooth implementaion which uses org.bluez on DBus 23 * Bluetooth implementaion which uses org.bluez on DBus
24 */24 */
25public class Bluez: KillswitchBluetooth25public class Bluez: Bluetooth, Object
26{26{
27 uint next_device_id = 1;27 uint next_device_id = 1;
28 org.bluez.Manager manager;28 org.bluez.Manager manager;
29 org.bluez.Adapter default_adapter;29 org.bluez.Adapter default_adapter;
3030
31 private bool _powered = false;
32
33 private bool powered {
34 get { return _powered; }
35 set { _powered = value; update_enabled(); }
36 }
37
38 private KillSwitch killswitch = null;
39
40 private string adapter_path = null;
41
42 private DBusConnection bus = null;
43
31 /* maps an org.bluez.Device's object_path to the org.bluez.Device proxy */44 /* maps an org.bluez.Device's object_path to the org.bluez.Device proxy */
32 HashTable<string,org.bluez.Device> path_to_proxy;45 HashTable<string,org.bluez.Device> path_to_proxy;
3346
@@ -40,44 +53,87 @@
40 /* maps our arbitrary unique id to a Bluetooth.Device struct for public consumption */53 /* maps our arbitrary unique id to a Bluetooth.Device struct for public consumption */
41 HashTable<uint,Device> id_to_device;54 HashTable<uint,Device> id_to_device;
4255
43 public Bluez (KillSwitch killswitch)56 public Bluez (KillSwitch? killswitch)
44 {57 {
45 base (killswitch);58 try
59 {
60 bus = Bus.get_sync (BusType.SYSTEM);
61 }
62 catch (Error e)
63 {
64 critical (@"$(e.message)");
65 }
4666
47 string adapter_path = null;67 if ((killswitch != null) && (killswitch.is_valid()))
68 {
69 this.killswitch = killswitch;
70 killswitch.notify["blocked"].connect (() => update_enabled());
71 update_enabled ();
72 }
4873
49 id_to_path = new HashTable<uint,string> (direct_hash, direct_equal);74 id_to_path = new HashTable<uint,string> (direct_hash, direct_equal);
50 id_to_device = new HashTable<uint,Device> (direct_hash, direct_equal);75 id_to_device = new HashTable<uint,Device> (direct_hash, direct_equal);
51 path_to_id = new HashTable<string,uint> (str_hash, str_equal);76 path_to_id = new HashTable<string,uint> (str_hash, str_equal);
52 path_to_proxy = new HashTable<string,org.bluez.Device> (str_hash, str_equal);77 path_to_proxy = new HashTable<string,org.bluez.Device> (str_hash, str_equal);
5378
79 reset_manager ();
80 }
81
82 private void reset_manager ()
83 {
84 string new_adapter_path = null;
54 try85 try
55 {86 {
56 manager = Bus.get_proxy_sync (BusType.SYSTEM, "org.bluez", "/");87 manager = bus.get_proxy_sync ("org.bluez", "/");
5788
58 // get the current default adapter & watch for future default adapters89 // if the default adapter changes, update our connections
59 adapter_path = manager.default_adapter ();
60 manager.default_adapter_changed.connect ((object_path)90 manager.default_adapter_changed.connect ((object_path)
61 => on_default_adapter_changed (object_path));91 => on_default_adapter_changed (object_path));
92
93 // if the current adapter disappears, call clear_adapter()
94 manager.adapter_removed.connect ((object_path) => {
95 if (object_path == adapter_path)
96 clear_adapter ();
97 });
98
99 // get the current default adapter & watch for future default adapters
100 new_adapter_path = manager.default_adapter ();
62 }101 }
63 catch (Error e)102 catch (Error e)
64 {103 {
65 critical (@"$(e.message)");104 critical (@"$(e.message)");
66 }105 }
67106
68 on_default_adapter_changed (adapter_path);107 on_default_adapter_changed (new_adapter_path);
69 }108 }
70109
71 private void on_default_adapter_changed (string? object_path)110 private void clear_adapter ()
72 {111 {
73 supported = object_path != null;112 if (adapter_path != null)
113 debug (@"clearing adapter; was using $adapter_path");
114
115 path_to_proxy.remove_all ();
116 path_to_id.remove_all ();
117 id_to_path.remove_all ();
118 id_to_device.remove_all ();
119
120 default_adapter = null;
121 adapter_path = null;
122
123 discoverable = false;
124 powered = false;
125 }
126
127 void on_default_adapter_changed (string? object_path)
128 {
129 clear_adapter ();
74130
75 if (object_path != null) try131 if (object_path != null) try
76 {132 {
77 debug (@"using default adapter at $object_path");133 adapter_path = object_path;
78 default_adapter = Bus.get_proxy_sync (BusType.SYSTEM,134 default_adapter = Bus.get_proxy_sync (BusType.SYSTEM,
79 "org.bluez",135 "org.bluez",
80 object_path);136 adapter_path);
81137
82 default_adapter.property_changed.connect (()138 default_adapter.property_changed.connect (()
83 => on_default_adapter_properties_changed ());139 => on_default_adapter_properties_changed ());
@@ -104,6 +160,8 @@
104 on_default_adapter_properties_changed ();160 on_default_adapter_properties_changed ();
105 }161 }
106162
163 /* When the default adapter's properties change,
164 update our own properties "powered" and "discoverable" */
107 private void on_default_adapter_properties_changed ()165 private void on_default_adapter_properties_changed ()
108 {166 {
109 bool is_discoverable = false;167 bool is_discoverable = false;
@@ -217,7 +275,6 @@
217 private void device_connect_on_interface (DBusProxy proxy,275 private void device_connect_on_interface (DBusProxy proxy,
218 string interface_name)276 string interface_name)
219 {277 {
220 var bus = proxy.get_connection ();
221 var object_path = proxy.get_object_path ();278 var object_path = proxy.get_object_path ();
222279
223 debug (@"trying to connect to $object_path: $(interface_name)");280 debug (@"trying to connect to $object_path: $(interface_name)");
@@ -359,11 +416,21 @@
359 devices_changed ();416 devices_changed ();
360 }417 }
361418
419 /* update the 'enabled' property by looking at the killswitch state
420 and the 'powered' property state */
421 void update_enabled ()
422 {
423 var blocked = (killswitch != null) && killswitch.blocked;
424 debug (@"in upate_enabled, powered is $powered, blocked is $blocked");
425 enabled = powered && !blocked;
426 }
427
428
362 ////429 ////
363 //// Public API430 //// Public API
364 ////431 ////
365432
366 public override void set_device_connected (uint id, bool connected)433 public void set_device_connected (uint id, bool connected)
367 {434 {
368 var device = id_to_device.lookup (id);435 var device = id_to_device.lookup (id);
369 var path = id_to_path.lookup (id);436 var path = id_to_path.lookup (id);
@@ -380,20 +447,35 @@
380 }447 }
381 }448 }
382449
383 public override void try_set_discoverable (bool b)450 public void try_set_discoverable (bool b)
384 {451 {
385 if (discoverable != b) try452 if (discoverable != b)
386 {453 {
387 default_adapter.set_property ("Discoverable", new Variant.boolean (b));454 default_adapter.set_property.begin ("Discoverable", new Variant.boolean (b));
388 }
389 catch (Error e)
390 {
391 critical (@"$(e.message)");
392 }455 }
393 }456 }
394457
395 public override List<unowned Device> get_devices ()458 public List<unowned Device> get_devices ()
396 {459 {
397 return id_to_device.get_values();460 return id_to_device.get_values();
398 }461 }
462
463 public bool supported { get; protected set; default = false; }
464 public bool discoverable { get; protected set; default = false; }
465 public bool enabled { get; protected set; default = false; }
466
467 public void try_set_enabled (bool b)
468 {
469 if (killswitch != null)
470 {
471 debug (@"setting killswitch blocked to $(!b)");
472 killswitch.try_set_blocked (!b);
473 }
474 else if (default_adapter != null)
475 {
476 debug (@"setting bluez Adapter's Powered property to $b");
477 default_adapter.set_property.begin ("Powered", new Variant.boolean (b));
478 powered = b;
479 }
480 }
399}481}
400482
=== modified file 'src/desktop.vala'
--- src/desktop.vala 2013-10-10 19:58:46 +0000
+++ src/desktop.vala 2013-10-14 23:34:48 +0000
@@ -66,7 +66,7 @@
6666
67 // know when to show the indicator & when to hide it67 // know when to show the indicator & when to hide it
68 settings.changed["visible"].connect (()=> update_visibility());68 settings.changed["visible"].connect (()=> update_visibility());
69 bluetooth.notify.connect (() => update_visibility());69 bluetooth.notify["enabled"].connect (() => update_visibility());
70 update_visibility ();70 update_visibility ();
7171
72 // when devices change, rebuild our device section72 // when devices change, rebuild our device section
@@ -82,7 +82,7 @@
8282
83 void update_visibility ()83 void update_visibility ()
84 {84 {
85 visible = bluetooth.powered && !bluetooth.blocked && settings.get_boolean("visible");85 visible = bluetooth.enabled && settings.get_boolean("visible");
86 }86 }
8787
88 ///88 ///
@@ -229,10 +229,6 @@
229 bluetooth.notify["discoverable"].connect (()229 bluetooth.notify["discoverable"].connect (()
230 => action.set_state (bluetooth.discoverable));230 => action.set_state (bluetooth.discoverable));
231231
232 action.set_enabled (bluetooth.powered);
233 bluetooth.notify["powered"].connect (()
234 => action.set_enabled (bluetooth.powered));
235
236 return action;232 return action;
237 }233 }
238234
239235
=== modified file 'src/killswitch.vala'
--- src/killswitch.vala 2013-08-06 20:33:26 +0000
+++ src/killswitch.vala 2013-10-14 23:34:48 +0000
@@ -26,6 +26,8 @@
26 */26 */
27public interface KillSwitch: Object27public interface KillSwitch: Object
28{28{
29 public abstract bool is_valid ();
30
29 public abstract bool blocked { get; protected set; }31 public abstract bool blocked { get; protected set; }
3032
31 /* Try to block/unblock bluetooth.33 /* Try to block/unblock bluetooth.
@@ -109,6 +111,11 @@
109 }111 }
110 }112 }
111113
114 public bool is_valid ()
115 {
116 return fd != -1;
117 }
118
112 private bool on_channel_event (IOChannel source, IOCondition condition)119 private bool on_channel_event (IOChannel source, IOCondition condition)
113 {120 {
114 read_event ();121 read_event ();
115122
=== modified file 'src/main.vala'
--- src/main.vala 2013-08-06 00:43:18 +0000
+++ src/main.vala 2013-10-14 23:34:48 +0000
@@ -26,7 +26,7 @@
26 Intl.textdomain (Config.GETTEXT_PACKAGE);26 Intl.textdomain (Config.GETTEXT_PACKAGE);
2727
28 // create the backend28 // create the backend
29 var bluetooth = new Bluez (new RfKillSwitch ());29 var bluetooth = new Bluez (null);
30 30
31 // start the service31 // start the service
32 var service = new Service (bluetooth);32 var service = new Service (bluetooth);
3333
=== modified file 'src/org-bluez.vala'
--- src/org-bluez.vala 2013-08-01 23:21:05 +0000
+++ src/org-bluez.vala 2013-10-14 23:34:48 +0000
@@ -69,7 +69,7 @@
69 public abstract GLib.HashTable<string, GLib.Variant> get_properties() throws DBusError, IOError;69 public abstract GLib.HashTable<string, GLib.Variant> get_properties() throws DBusError, IOError;
7070
71 [DBus (name = "SetProperty")]71 [DBus (name = "SetProperty")]
72 public abstract void set_property(string name, GLib.Variant value) throws DBusError, IOError;72 public abstract async void set_property(string name, GLib.Variant value) throws DBusError, IOError;
7373
74 [DBus (name = "RequestSession")]74 [DBus (name = "RequestSession")]
75 public abstract void request_session() throws DBusError, IOError;75 public abstract void request_session() throws DBusError, IOError;
7676
=== modified file 'src/phone.vala'
--- src/phone.vala 2013-10-10 19:58:46 +0000
+++ src/phone.vala 2013-10-14 23:34:48 +0000
@@ -53,7 +53,7 @@
5353
54 void update_visibility ()54 void update_visibility ()
55 {55 {
56 visible = bluetooth.powered && !bluetooth.blocked;56 visible = bluetooth.enabled;
57 }57 }
5858
59 ///59 ///
6060
=== modified file 'src/profile.vala'
--- src/profile.vala 2013-10-10 19:58:46 +0000
+++ src/profile.vala 2013-10-14 23:34:48 +0000
@@ -123,16 +123,16 @@
123 {123 {
124 var action = new SimpleAction.stateful ("bluetooth-enabled",124 var action = new SimpleAction.stateful ("bluetooth-enabled",
125 null,125 null,
126 !bluetooth.blocked);126 bluetooth.enabled);
127127
128 action.activate.connect (()128 action.activate.connect (()
129 => action.change_state (!action.get_state().get_boolean()));129 => action.change_state (!action.get_state().get_boolean()));
130130
131 action.change_state.connect ((action, requestedValue)131 action.change_state.connect ((action, requestedValue)
132 => bluetooth.try_set_blocked (!requestedValue.get_boolean()));132 => bluetooth.try_set_enabled (requestedValue.get_boolean()));
133133
134 bluetooth.notify["blocked"].connect (()134 bluetooth.notify["enabled"].connect (()
135 => action.set_state (!bluetooth.blocked));135 => action.set_state (bluetooth.enabled));
136136
137 return action;137 return action;
138 }138 }
@@ -144,12 +144,9 @@
144144
145 protected Variant action_state_for_root ()145 protected Variant action_state_for_root ()
146 {146 {
147 var blocked = bluetooth.blocked;
148 var powered = bluetooth.powered;
149
150 string a11y;147 string a11y;
151 string icon_name;148 string icon_name;
152 if (powered && !blocked)149 if (bluetooth.enabled)
153 {150 {
154 a11y = "Bluetooth (on)";151 a11y = "Bluetooth (on)";
155 icon_name = "bluetooth-active";152 icon_name = "bluetooth-active";

Subscribers

People subscribed via source and target branches