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
=== modified file 'src/Indicator.vala'
--- src/Indicator.vala 2016-04-04 14:59:57 +0000
+++ src/Indicator.vala 2016-05-01 00:09:35 +0000
@@ -15,62 +15,44 @@
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */16 */
1717
18namespace Bluetooth {
19 public static Bluetooth.Services.ObjectManager object_manager;
20 public static Bluetooth.Indicator indicator;
21}
22
23public class Bluetooth.Indicator : Wingpanel.Indicator {18public class Bluetooth.Indicator : Wingpanel.Indicator {
24 private bool is_in_session = false;19 private bool is_in_session = false;
25 private bool last_state_set = false;
2620
27 private Bluetooth.Widgets.PopoverWidget popover_widget;21 private Bluetooth.Widgets.PopoverWidget popover_widget;
28 private Bluetooth.Widgets.DisplayWidget dynamic_icon;22 private Bluetooth.Widgets.DisplayWidget dynamic_icon;
23 private Bluetooth.Services.ObjectManager object_manager;
29 public Indicator (bool is_in_session) {24 public Indicator (bool is_in_session) {
30 Object (code_name: Wingpanel.Indicator.BLUETOOTH,25 Object (code_name: Wingpanel.Indicator.BLUETOOTH,
31 display_name: _("bluetooth"),26 display_name: _("bluetooth"),
32 description:_("The bluetooth indicator"));27 description:_("The bluetooth indicator"));
28 this.is_in_session = is_in_session;
33 object_manager = new Services.ObjectManager ();29 object_manager = new Services.ObjectManager ();
3430 object_manager.bind_property ("has-object", this, "visible", GLib.BindingFlags.SYNC_CREATE);
35 this.visible = object_manager.has_object;31
3632 if (object_manager.has_object) {
37 if (this.visible) {
38 object_manager.set_last_state ();33 object_manager.set_last_state ();
39 last_state_set = true;
40 }34 }
4135
42 object_manager.adapter_added.connect (() => {36 object_manager.notify["has-object"].connect (() => {
43 visible = object_manager.has_object;37 if (object_manager.has_object) {
44 if (!last_state_set) {
45 object_manager.set_last_state ();38 object_manager.set_last_state ();
46 last_state_set = true;
47 }39 }
48 });40 });
4941
50 object_manager.adapter_removed.connect (() => {
51 visible = object_manager.has_object;
52 });
53
54 this.is_in_session = is_in_session;
55
56 debug ("Bluetooth Indicator started");42 debug ("Bluetooth Indicator started");
57 }43 }
5844
59 public override Gtk.Widget get_display_widget () {45 public override Gtk.Widget get_display_widget () {
60 if (dynamic_icon == null) {46 if (dynamic_icon == null) {
61 dynamic_icon = new Bluetooth.Widgets.DisplayWidget ();47 dynamic_icon = new Bluetooth.Widgets.DisplayWidget (object_manager);
62 }48 }
6349
64 return dynamic_icon;50 return dynamic_icon;
65 }51 }
6652
67 public override Gtk.Widget? get_widget () {53 public override Gtk.Widget? get_widget () {
68 if (object_manager.has_object == false) {
69 return null;
70 }
71
72 if (popover_widget == null) {54 if (popover_widget == null) {
73 popover_widget = new Bluetooth.Widgets.PopoverWidget (is_in_session);55 popover_widget = new Bluetooth.Widgets.PopoverWidget (object_manager, is_in_session);
74 popover_widget.request_close.connect (() => {56 popover_widget.request_close.connect (() => {
75 close ();57 close ();
76 });58 });
@@ -89,9 +71,7 @@
8971
90public Wingpanel.Indicator get_indicator (Module module, Wingpanel.IndicatorManager.ServerType server_type) {72public Wingpanel.Indicator get_indicator (Module module, Wingpanel.IndicatorManager.ServerType server_type) {
91 debug ("Activating Bluetooth Indicator");73 debug ("Activating Bluetooth Indicator");
92 if (Bluetooth.indicator == null) {74 var indicator = new Bluetooth.Indicator (server_type == Wingpanel.IndicatorManager.ServerType.SESSION);
93 Bluetooth.indicator = new Bluetooth.Indicator (server_type == Wingpanel.IndicatorManager.ServerType.SESSION);
94 }
9575
96 return Bluetooth.indicator;76 return indicator;
97}77}
9878
=== modified file 'src/Services/Manager.vala'
--- src/Services/Manager.vala 2016-04-04 14:59:57 +0000
+++ src/Services/Manager.vala 2016-05-01 00:09:35 +0000
@@ -30,11 +30,7 @@
30 public signal void device_added (Bluetooth.Services.Device adapter);30 public signal void device_added (Bluetooth.Services.Device adapter);
31 public signal void device_removed (Bluetooth.Services.Device adapter);31 public signal void device_removed (Bluetooth.Services.Device adapter);
3232
33 public bool has_object {33 public bool has_object { get; private set; default = false; }
34 get {
35 return !adapters.is_empty;
36 }
37 }
3834
39 private Settings settings;35 private Settings settings;
40 private Bluetooth.Services.DBusInterface object_interface;36 private Bluetooth.Services.DBusInterface object_interface;
@@ -42,25 +38,35 @@
42 private Gee.HashMap<string, Bluetooth.Services.Device> devices;38 private Gee.HashMap<string, Bluetooth.Services.Device> devices;
4339
44 public ObjectManager () {40 public ObjectManager () {
41
42 }
43
44 construct {
45 adapters = new Gee.HashMap<string, Bluetooth.Services.Adapter> (null, null);45 adapters = new Gee.HashMap<string, Bluetooth.Services.Adapter> (null, null);
46 devices = new Gee.HashMap<string, Bluetooth.Services.Device> (null, null);46 devices = new Gee.HashMap<string, Bluetooth.Services.Device> (null, null);
47 try {47 settings = new Settings ("org.pantheon.desktop.wingpanel.indicators.bluetooth");
48 object_interface = Bus.get_proxy_sync (BusType.SYSTEM, "org.bluez", "/", DBusProxyFlags.NONE);48 Bus.get_proxy.begin<Bluetooth.Services.DBusInterface> (BusType.SYSTEM, "org.bluez", "/", DBusProxyFlags.NONE, null, (obj, res) => {
49 var objects = object_interface.get_managed_objects ();49 try {
50 objects.foreach ((path, param) => {add_path (path, param);});50 object_interface = Bus.get_proxy.end (res);
51 object_interface.interfaces_added.connect ((path, param) => {add_path (path, param);});51 object_interface.get_managed_objects ().foreach (add_path);
52 object_interface.interfaces_removed.connect ((path, array) => {remove_path (path);});52 object_interface.interfaces_added.connect (add_path);
53 settings = new Settings ("org.pantheon.desktop.wingpanel.indicators.bluetooth");53 object_interface.interfaces_removed.connect (remove_path);
54 } catch (Error e) {54 } catch (Error e) {
55 critical (e.message);55 critical (e.message);
56 }56 }
57 });
57 }58 }
5859
60 [CCode (instance_pos = -1)]
59 private void add_path (ObjectPath path, HashTable<string, HashTable<string, Variant>> param) {61 private void add_path (ObjectPath path, HashTable<string, HashTable<string, Variant>> param) {
60 if ("org.bluez.Adapter1" in param) {62 if ("org.bluez.Adapter1" in param) {
61 try {63 try {
62 Bluetooth.Services.Adapter adapter = Bus.get_proxy_sync (BusType.SYSTEM, "org.bluez", path, DBusProxyFlags.GET_INVALIDATED_PROPERTIES);64 Bluetooth.Services.Adapter adapter = Bus.get_proxy_sync (BusType.SYSTEM, "org.bluez", path, DBusProxyFlags.GET_INVALIDATED_PROPERTIES);
63 adapters.set (path, adapter);65 lock (adapters) {
66 adapters.set (path, adapter);
67 }
68 has_object = true;
69
64 adapter_added (adapter);70 adapter_added (adapter);
65 (adapter as DBusProxy).g_properties_changed.connect ((changed, invalid) => {71 (adapter as DBusProxy).g_properties_changed.connect ((changed, invalid) => {
66 var powered = changed.lookup_value("Powered", new VariantType("b"));72 var powered = changed.lookup_value("Powered", new VariantType("b"));
@@ -75,21 +81,32 @@
75 try {81 try {
76 Bluetooth.Services.Device device = Bus.get_proxy_sync (BusType.SYSTEM, "org.bluez", path, DBusProxyFlags.GET_INVALIDATED_PROPERTIES);82 Bluetooth.Services.Device device = Bus.get_proxy_sync (BusType.SYSTEM, "org.bluez", path, DBusProxyFlags.GET_INVALIDATED_PROPERTIES);
77 if (device.paired) {83 if (device.paired) {
78 devices.set (path, device);84 lock (devices) {
85 devices.set (path, device);
86 }
87
79 device_added (device);88 device_added (device);
80 }89 }
90
81 (device as DBusProxy).g_properties_changed.connect ((changed, invalid) => {91 (device as DBusProxy).g_properties_changed.connect ((changed, invalid) => {
82 var connected = changed.lookup_value("Connected", new VariantType("b"));92 var connected = changed.lookup_value("Connected", new VariantType("b"));
83 if (connected != null) {93 if (connected != null) {
84 check_global_state ();94 check_global_state ();
85 }95 }
96
86 var paired = changed.lookup_value("Paired", new VariantType("b"));97 var paired = changed.lookup_value("Paired", new VariantType("b"));
87 if (paired != null) {98 if (paired != null) {
88 if (device.paired) {99 if (device.paired) {
89 devices.set (path, device);100 lock (devices) {
101 devices.set (path, device);
102 }
103
90 device_added (device);104 device_added (device);
91 } else {105 } else {
92 devices.unset (path);106 lock (devices) {
107 devices.unset (path);
108 }
109
93 device_removed (device);110 device_removed (device);
94 }111 }
95 }112 }
@@ -100,31 +117,44 @@
100 }117 }
101 }118 }
102119
120 [CCode (instance_pos = -1)]
103 public void remove_path (ObjectPath path) {121 public void remove_path (ObjectPath path) {
104 var adapter = adapters.get (path);122 lock (adapters) {
105 if (adapter != null) {123 var adapter = adapters.get (path);
106 adapters.unset (path);124 if (adapter != null) {
107 adapter_removed (adapter);125 adapters.unset (path);
108 return;126 has_object = !adapters.is_empty;
127
128 adapter_removed (adapter);
129 return;
130 }
109 }131 }
110132
111 var device = devices.get (path);133 lock (devices) {
112 if (device != null) {134 var device = devices.get (path);
113 devices.unset (path);135 if (device != null) {
114 device_removed (device);136 devices.unset (path);
137 device_removed (device);
138 }
115 }139 }
116 }140 }
117141
118 public Gee.Collection<Bluetooth.Services.Adapter> get_adapters () {142 public Gee.Collection<Bluetooth.Services.Adapter> get_adapters () {
119 return adapters.values;143 lock (adapters) {
144 return adapters.values;
145 }
120 }146 }
121147
122 public Gee.Collection<Bluetooth.Services.Device> get_devices () {148 public Gee.Collection<Bluetooth.Services.Device> get_devices () {
123 return devices.values;149 lock (devices) {
150 return devices.values;
151 }
124 }152 }
125153
126 public Bluetooth.Services.Adapter? get_adapter_from_path (string path) {154 public Bluetooth.Services.Adapter? get_adapter_from_path (string path) {
127 return adapters.get (path);155 lock (adapters) {
156 return adapters.get (path);
157 }
128 }158 }
129159
130 private void check_global_state () {160 private void check_global_state () {
@@ -132,9 +162,11 @@
132 }162 }
133163
134 public bool get_connected () {164 public bool get_connected () {
135 foreach (var device in devices.values) {165 lock (devices) {
136 if (device.connected) {166 foreach (var device in devices.values) {
137 return true;167 if (device.connected) {
168 return true;
169 }
138 }170 }
139 }171 }
140172
@@ -142,9 +174,11 @@
142 }174 }
143175
144 public bool get_global_state () {176 public bool get_global_state () {
145 foreach (var adapter in adapters.values) {177 lock (adapters) {
146 if (adapter.powered) {178 foreach (var adapter in adapters.values) {
147 return true;179 if (adapter.powered) {
180 return true;
181 }
148 }182 }
149 }183 }
150184
@@ -153,18 +187,22 @@
153187
154 public void set_global_state (bool state) {188 public void set_global_state (bool state) {
155 new Thread<void*> (null, () => {189 new Thread<void*> (null, () => {
156 foreach (var device in devices.values) {190 lock (devices) {
157 if (device.connected) {191 foreach (var device in devices.values) {
158 try {192 if (device.connected) {
159 device.disconnect ();193 try {
160 } catch (Error e) {194 device.disconnect ();
161 critical (e.message);195 } catch (Error e) {
196 critical (e.message);
197 }
162 }198 }
163 }199 }
164 }200 }
165201
166 foreach (var adapter in adapters.values) {202 lock (adapters) {
167 adapter.powered = state;203 foreach (var adapter in adapters.values) {
204 adapter.powered = state;
205 }
168 }206 }
169207
170 settings.set_boolean ("bluetooth-enabled", state);208 settings.set_boolean ("bluetooth-enabled", state);
171209
=== modified file 'src/Widgets/DisplayWidget.vala'
--- src/Widgets/DisplayWidget.vala 2015-11-15 15:51:29 +0000
+++ src/Widgets/DisplayWidget.vala 2016-05-01 00:09:35 +0000
@@ -16,7 +16,7 @@
16 */16 */
1717
18public class Bluetooth.Widgets.DisplayWidget : Gtk.Image {18public class Bluetooth.Widgets.DisplayWidget : Gtk.Image {
19 public DisplayWidget () {19 public DisplayWidget (Bluetooth.Services.ObjectManager object_manager) {
20 icon_size = Gtk.IconSize.LARGE_TOOLBAR;20 icon_size = Gtk.IconSize.LARGE_TOOLBAR;
21 set_icon (object_manager.get_global_state (), object_manager.get_connected ());21 set_icon (object_manager.get_global_state (), object_manager.get_connected ());
2222
2323
=== modified file 'src/Widgets/PopoverWidget.vala'
--- src/Widgets/PopoverWidget.vala 2016-02-15 02:04:56 +0000
+++ src/Widgets/PopoverWidget.vala 2016-05-01 00:09:35 +0000
@@ -20,10 +20,10 @@
20 private Bluetooth.Widgets.MainView main_view;20 private Bluetooth.Widgets.MainView main_view;
21 private Bluetooth.Widgets.DiscoveryView discovery_view;21 private Bluetooth.Widgets.DiscoveryView discovery_view;
2222
23 public PopoverWidget (bool is_in_session) {23 public PopoverWidget (Bluetooth.Services.ObjectManager object_manager, bool is_in_session) {
24 transition_type = Gtk.StackTransitionType.SLIDE_LEFT_RIGHT;24 transition_type = Gtk.StackTransitionType.SLIDE_LEFT_RIGHT;
25 main_view = new Bluetooth.Widgets.MainView (is_in_session);25 main_view = new Bluetooth.Widgets.MainView (object_manager, is_in_session);
26 discovery_view = new Bluetooth.Widgets.DiscoveryView ();26 discovery_view = new Bluetooth.Widgets.DiscoveryView (object_manager);
2727
28 add (main_view);28 add (main_view);
29 add (discovery_view);29 add (discovery_view);
3030
=== modified file 'src/Widgets/Views/DiscoveryView.vala'
--- src/Widgets/Views/DiscoveryView.vala 2016-02-15 02:04:56 +0000
+++ src/Widgets/Views/DiscoveryView.vala 2016-05-01 00:09:35 +0000
@@ -19,8 +19,9 @@
19 public Gtk.Button back_button;19 public Gtk.Button back_button;
20 private Gtk.Grid device_grid;20 private Gtk.Grid device_grid;
2121
22 public DiscoveryView () {22 unowned Bluetooth.Services.ObjectManager object_manager;
23 23 public DiscoveryView (Bluetooth.Services.ObjectManager object_manager) {
24 this.object_manager = object_manager;
24 }25 }
2526
26 construct {27 construct {
2728
=== modified file 'src/Widgets/Views/MainView.vala'
--- src/Widgets/Views/MainView.vala 2016-02-12 04:24:08 +0000
+++ src/Widgets/Views/MainView.vala 2016-05-01 00:09:35 +0000
@@ -27,7 +27,7 @@
27 private Wingpanel.Widgets.Switch main_switch;27 private Wingpanel.Widgets.Switch main_switch;
28 private Gtk.Box devices_box;28 private Gtk.Box devices_box;
2929
30 public MainView (bool is_in_session) {30 public MainView (Bluetooth.Services.ObjectManager object_manager, bool is_in_session) {
31 main_switch = new Wingpanel.Widgets.Switch (_("Bluetooth"), object_manager.get_global_state ());31 main_switch = new Wingpanel.Widgets.Switch (_("Bluetooth"), object_manager.get_global_state ());
32 show_settings_button = new Wingpanel.Widgets.Button (_("Bluetooth Settings…"));32 show_settings_button = new Wingpanel.Widgets.Button (_("Bluetooth Settings…"));
33 discovery_button = new Wingpanel.Widgets.Button (_("Discover Devices…"));33 discovery_button = new Wingpanel.Widgets.Button (_("Discover Devices…"));

Subscribers

People subscribed via source and target branches

to all changes: