Merge lp:~tintou/wingpanel-indicator-bluetooth/async-creation into lp:~wingpanel-devs/wingpanel-indicator-bluetooth/trunk

Proposed by Corentin Noël
Status: Merged
Approved by: Danielle Foré
Approved revision: 34
Merged at revision: 34
Proposed branch: lp:~tintou/wingpanel-indicator-bluetooth/async-creation
Merge into: lp:~wingpanel-devs/wingpanel-indicator-bluetooth/trunk
Diff against target: 365 lines (+102/-83)
6 files modified
src/Indicator.vala (+11/-31)
src/Services/Manager.vala (+83/-45)
src/Widgets/DisplayWidget.vala (+1/-1)
src/Widgets/PopoverWidget.vala (+3/-3)
src/Widgets/Views/DiscoveryView.vala (+3/-2)
src/Widgets/Views/MainView.vala (+1/-1)
To merge this branch: bzr merge lp:~tintou/wingpanel-indicator-bluetooth/async-creation
Reviewer Review Type Date Requested Status
WingPanel Devs Pending
Review via email: mp+293474@code.launchpad.net

Commit message

Make the indicator asynchronous and showing only if an adapter is present.
Fixed some possible crash with threads

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/Indicator.vala'
2--- src/Indicator.vala 2016-04-04 14:59:57 +0000
3+++ src/Indicator.vala 2016-05-01 00:09:35 +0000
4@@ -15,62 +15,44 @@
5 * along with this program. If not, see <http://www.gnu.org/licenses/>.
6 */
7
8-namespace Bluetooth {
9- public static Bluetooth.Services.ObjectManager object_manager;
10- public static Bluetooth.Indicator indicator;
11-}
12-
13 public class Bluetooth.Indicator : Wingpanel.Indicator {
14 private bool is_in_session = false;
15- private bool last_state_set = false;
16
17 private Bluetooth.Widgets.PopoverWidget popover_widget;
18 private Bluetooth.Widgets.DisplayWidget dynamic_icon;
19+ private Bluetooth.Services.ObjectManager object_manager;
20 public Indicator (bool is_in_session) {
21 Object (code_name: Wingpanel.Indicator.BLUETOOTH,
22 display_name: _("bluetooth"),
23 description:_("The bluetooth indicator"));
24+ this.is_in_session = is_in_session;
25 object_manager = new Services.ObjectManager ();
26-
27- this.visible = object_manager.has_object;
28-
29- if (this.visible) {
30+ object_manager.bind_property ("has-object", this, "visible", GLib.BindingFlags.SYNC_CREATE);
31+
32+ if (object_manager.has_object) {
33 object_manager.set_last_state ();
34- last_state_set = true;
35 }
36
37- object_manager.adapter_added.connect (() => {
38- visible = object_manager.has_object;
39- if (!last_state_set) {
40+ object_manager.notify["has-object"].connect (() => {
41+ if (object_manager.has_object) {
42 object_manager.set_last_state ();
43- last_state_set = true;
44 }
45 });
46
47- object_manager.adapter_removed.connect (() => {
48- visible = object_manager.has_object;
49- });
50-
51- this.is_in_session = is_in_session;
52-
53 debug ("Bluetooth Indicator started");
54 }
55
56 public override Gtk.Widget get_display_widget () {
57 if (dynamic_icon == null) {
58- dynamic_icon = new Bluetooth.Widgets.DisplayWidget ();
59+ dynamic_icon = new Bluetooth.Widgets.DisplayWidget (object_manager);
60 }
61
62 return dynamic_icon;
63 }
64
65 public override Gtk.Widget? get_widget () {
66- if (object_manager.has_object == false) {
67- return null;
68- }
69-
70 if (popover_widget == null) {
71- popover_widget = new Bluetooth.Widgets.PopoverWidget (is_in_session);
72+ popover_widget = new Bluetooth.Widgets.PopoverWidget (object_manager, is_in_session);
73 popover_widget.request_close.connect (() => {
74 close ();
75 });
76@@ -89,9 +71,7 @@
77
78 public Wingpanel.Indicator get_indicator (Module module, Wingpanel.IndicatorManager.ServerType server_type) {
79 debug ("Activating Bluetooth Indicator");
80- if (Bluetooth.indicator == null) {
81- Bluetooth.indicator = new Bluetooth.Indicator (server_type == Wingpanel.IndicatorManager.ServerType.SESSION);
82- }
83+ var indicator = new Bluetooth.Indicator (server_type == Wingpanel.IndicatorManager.ServerType.SESSION);
84
85- return Bluetooth.indicator;
86+ return indicator;
87 }
88
89=== modified file 'src/Services/Manager.vala'
90--- src/Services/Manager.vala 2016-04-04 14:59:57 +0000
91+++ src/Services/Manager.vala 2016-05-01 00:09:35 +0000
92@@ -30,11 +30,7 @@
93 public signal void device_added (Bluetooth.Services.Device adapter);
94 public signal void device_removed (Bluetooth.Services.Device adapter);
95
96- public bool has_object {
97- get {
98- return !adapters.is_empty;
99- }
100- }
101+ public bool has_object { get; private set; default = false; }
102
103 private Settings settings;
104 private Bluetooth.Services.DBusInterface object_interface;
105@@ -42,25 +38,35 @@
106 private Gee.HashMap<string, Bluetooth.Services.Device> devices;
107
108 public ObjectManager () {
109+
110+ }
111+
112+ construct {
113 adapters = new Gee.HashMap<string, Bluetooth.Services.Adapter> (null, null);
114 devices = new Gee.HashMap<string, Bluetooth.Services.Device> (null, null);
115- try {
116- object_interface = Bus.get_proxy_sync (BusType.SYSTEM, "org.bluez", "/", DBusProxyFlags.NONE);
117- var objects = object_interface.get_managed_objects ();
118- objects.foreach ((path, param) => {add_path (path, param);});
119- object_interface.interfaces_added.connect ((path, param) => {add_path (path, param);});
120- object_interface.interfaces_removed.connect ((path, array) => {remove_path (path);});
121- settings = new Settings ("org.pantheon.desktop.wingpanel.indicators.bluetooth");
122- } catch (Error e) {
123- critical (e.message);
124- }
125+ settings = new Settings ("org.pantheon.desktop.wingpanel.indicators.bluetooth");
126+ Bus.get_proxy.begin<Bluetooth.Services.DBusInterface> (BusType.SYSTEM, "org.bluez", "/", DBusProxyFlags.NONE, null, (obj, res) => {
127+ try {
128+ object_interface = Bus.get_proxy.end (res);
129+ object_interface.get_managed_objects ().foreach (add_path);
130+ object_interface.interfaces_added.connect (add_path);
131+ object_interface.interfaces_removed.connect (remove_path);
132+ } catch (Error e) {
133+ critical (e.message);
134+ }
135+ });
136 }
137
138+ [CCode (instance_pos = -1)]
139 private void add_path (ObjectPath path, HashTable<string, HashTable<string, Variant>> param) {
140 if ("org.bluez.Adapter1" in param) {
141 try {
142 Bluetooth.Services.Adapter adapter = Bus.get_proxy_sync (BusType.SYSTEM, "org.bluez", path, DBusProxyFlags.GET_INVALIDATED_PROPERTIES);
143- adapters.set (path, adapter);
144+ lock (adapters) {
145+ adapters.set (path, adapter);
146+ }
147+ has_object = true;
148+
149 adapter_added (adapter);
150 (adapter as DBusProxy).g_properties_changed.connect ((changed, invalid) => {
151 var powered = changed.lookup_value("Powered", new VariantType("b"));
152@@ -75,21 +81,32 @@
153 try {
154 Bluetooth.Services.Device device = Bus.get_proxy_sync (BusType.SYSTEM, "org.bluez", path, DBusProxyFlags.GET_INVALIDATED_PROPERTIES);
155 if (device.paired) {
156- devices.set (path, device);
157+ lock (devices) {
158+ devices.set (path, device);
159+ }
160+
161 device_added (device);
162 }
163+
164 (device as DBusProxy).g_properties_changed.connect ((changed, invalid) => {
165 var connected = changed.lookup_value("Connected", new VariantType("b"));
166 if (connected != null) {
167 check_global_state ();
168 }
169+
170 var paired = changed.lookup_value("Paired", new VariantType("b"));
171 if (paired != null) {
172 if (device.paired) {
173- devices.set (path, device);
174+ lock (devices) {
175+ devices.set (path, device);
176+ }
177+
178 device_added (device);
179 } else {
180- devices.unset (path);
181+ lock (devices) {
182+ devices.unset (path);
183+ }
184+
185 device_removed (device);
186 }
187 }
188@@ -100,31 +117,44 @@
189 }
190 }
191
192+ [CCode (instance_pos = -1)]
193 public void remove_path (ObjectPath path) {
194- var adapter = adapters.get (path);
195- if (adapter != null) {
196- adapters.unset (path);
197- adapter_removed (adapter);
198- return;
199+ lock (adapters) {
200+ var adapter = adapters.get (path);
201+ if (adapter != null) {
202+ adapters.unset (path);
203+ has_object = !adapters.is_empty;
204+
205+ adapter_removed (adapter);
206+ return;
207+ }
208 }
209
210- var device = devices.get (path);
211- if (device != null) {
212- devices.unset (path);
213- device_removed (device);
214+ lock (devices) {
215+ var device = devices.get (path);
216+ if (device != null) {
217+ devices.unset (path);
218+ device_removed (device);
219+ }
220 }
221 }
222
223 public Gee.Collection<Bluetooth.Services.Adapter> get_adapters () {
224- return adapters.values;
225+ lock (adapters) {
226+ return adapters.values;
227+ }
228 }
229
230 public Gee.Collection<Bluetooth.Services.Device> get_devices () {
231- return devices.values;
232+ lock (devices) {
233+ return devices.values;
234+ }
235 }
236
237 public Bluetooth.Services.Adapter? get_adapter_from_path (string path) {
238- return adapters.get (path);
239+ lock (adapters) {
240+ return adapters.get (path);
241+ }
242 }
243
244 private void check_global_state () {
245@@ -132,9 +162,11 @@
246 }
247
248 public bool get_connected () {
249- foreach (var device in devices.values) {
250- if (device.connected) {
251- return true;
252+ lock (devices) {
253+ foreach (var device in devices.values) {
254+ if (device.connected) {
255+ return true;
256+ }
257 }
258 }
259
260@@ -142,9 +174,11 @@
261 }
262
263 public bool get_global_state () {
264- foreach (var adapter in adapters.values) {
265- if (adapter.powered) {
266- return true;
267+ lock (adapters) {
268+ foreach (var adapter in adapters.values) {
269+ if (adapter.powered) {
270+ return true;
271+ }
272 }
273 }
274
275@@ -153,18 +187,22 @@
276
277 public void set_global_state (bool state) {
278 new Thread<void*> (null, () => {
279- foreach (var device in devices.values) {
280- if (device.connected) {
281- try {
282- device.disconnect ();
283- } catch (Error e) {
284- critical (e.message);
285+ lock (devices) {
286+ foreach (var device in devices.values) {
287+ if (device.connected) {
288+ try {
289+ device.disconnect ();
290+ } catch (Error e) {
291+ critical (e.message);
292+ }
293 }
294 }
295 }
296
297- foreach (var adapter in adapters.values) {
298- adapter.powered = state;
299+ lock (adapters) {
300+ foreach (var adapter in adapters.values) {
301+ adapter.powered = state;
302+ }
303 }
304
305 settings.set_boolean ("bluetooth-enabled", state);
306
307=== modified file 'src/Widgets/DisplayWidget.vala'
308--- src/Widgets/DisplayWidget.vala 2015-11-15 15:51:29 +0000
309+++ src/Widgets/DisplayWidget.vala 2016-05-01 00:09:35 +0000
310@@ -16,7 +16,7 @@
311 */
312
313 public class Bluetooth.Widgets.DisplayWidget : Gtk.Image {
314- public DisplayWidget () {
315+ public DisplayWidget (Bluetooth.Services.ObjectManager object_manager) {
316 icon_size = Gtk.IconSize.LARGE_TOOLBAR;
317 set_icon (object_manager.get_global_state (), object_manager.get_connected ());
318
319
320=== modified file 'src/Widgets/PopoverWidget.vala'
321--- src/Widgets/PopoverWidget.vala 2016-02-15 02:04:56 +0000
322+++ src/Widgets/PopoverWidget.vala 2016-05-01 00:09:35 +0000
323@@ -20,10 +20,10 @@
324 private Bluetooth.Widgets.MainView main_view;
325 private Bluetooth.Widgets.DiscoveryView discovery_view;
326
327- public PopoverWidget (bool is_in_session) {
328+ public PopoverWidget (Bluetooth.Services.ObjectManager object_manager, bool is_in_session) {
329 transition_type = Gtk.StackTransitionType.SLIDE_LEFT_RIGHT;
330- main_view = new Bluetooth.Widgets.MainView (is_in_session);
331- discovery_view = new Bluetooth.Widgets.DiscoveryView ();
332+ main_view = new Bluetooth.Widgets.MainView (object_manager, is_in_session);
333+ discovery_view = new Bluetooth.Widgets.DiscoveryView (object_manager);
334
335 add (main_view);
336 add (discovery_view);
337
338=== modified file 'src/Widgets/Views/DiscoveryView.vala'
339--- src/Widgets/Views/DiscoveryView.vala 2016-02-15 02:04:56 +0000
340+++ src/Widgets/Views/DiscoveryView.vala 2016-05-01 00:09:35 +0000
341@@ -19,8 +19,9 @@
342 public Gtk.Button back_button;
343 private Gtk.Grid device_grid;
344
345- public DiscoveryView () {
346-
347+ unowned Bluetooth.Services.ObjectManager object_manager;
348+ public DiscoveryView (Bluetooth.Services.ObjectManager object_manager) {
349+ this.object_manager = object_manager;
350 }
351
352 construct {
353
354=== modified file 'src/Widgets/Views/MainView.vala'
355--- src/Widgets/Views/MainView.vala 2016-02-12 04:24:08 +0000
356+++ src/Widgets/Views/MainView.vala 2016-05-01 00:09:35 +0000
357@@ -27,7 +27,7 @@
358 private Wingpanel.Widgets.Switch main_switch;
359 private Gtk.Box devices_box;
360
361- public MainView (bool is_in_session) {
362+ public MainView (Bluetooth.Services.ObjectManager object_manager, bool is_in_session) {
363 main_switch = new Wingpanel.Widgets.Switch (_("Bluetooth"), object_manager.get_global_state ());
364 show_settings_button = new Wingpanel.Widgets.Button (_("Bluetooth Settings…"));
365 discovery_button = new Wingpanel.Widgets.Button (_("Discover Devices…"));

Subscribers

People subscribed via source and target branches

to all changes: