Merge lp:~charlesk/indicator-datetime/lp-1074999 into lp:indicator-datetime/13.04

Proposed by Charles Kerr
Status: Merged
Approved by: Allan LeSage
Approved revision: 200
Merged at revision: 194
Proposed branch: lp:~charlesk/indicator-datetime/lp-1074999
Merge into: lp:indicator-datetime/13.04
Diff against target: 303 lines (+89/-87)
1 file modified
src/datetime-service.c (+89/-87)
To merge this branch: bzr merge lp:~charlesk/indicator-datetime/lp-1074999
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Lars Karlitski (community) Approve
Review via email: mp+132829@code.launchpad.net

Commit message

Don't use geoclue until the user clicks the "Show time in auto-detected location" checkbox.

Description of the change

Don't use geoclue until the user clicks the "Show time in auto-detected location" checkbox.

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
Lars Karlitski (larsu) wrote :

Nice cleanup!

`geo_master` doesn't need to be a global variable: it's only ever used in geo_start.

Why are you calling geo_stop unconditionally in on_use_geoclue_changed? I'd put it in the `else` below, in case the callback is called even though the value hasn't changed (which may happen according to the docs).

review: Needs Fixing
Revision history for this message
Charles Kerr (charlesk) wrote :

> `geo_master` doesn't need to be a global variable: it's only ever used in geo_start.

The issue is that geoclue_master_create_client_async() populates its private GeoclueMasterAsyncData struct with a pointer to that master without reffing it. That's why datetime-service keeps its own ref.

> Why are you calling geo_stop unconditionally in on_use_geoclue_changed? I'd put it in the `else` below, in case the callback is called even though the value hasn't changed (which may happen according to the docs).

It's to ensure that even if the callback triggered multiple calls to geo_start(), we would have a call to geo_stop() in between to guarantee that geo_master, geo_client, and geo_address were cleaned up.

Revision history for this message
Lars Karlitski (larsu) wrote :

> > `geo_master` doesn't need to be a global variable: it's only ever used in
> geo_start.
>
> The issue is that geoclue_master_create_client_async() populates its private
> GeoclueMasterAsyncData struct with a pointer to that master without reffing
> it. That's why datetime-service keeps its own ref.

That should be fixed in geoclue.

> > Why are you calling geo_stop unconditionally in on_use_geoclue_changed? I'd
> put it in the `else` below, in case the callback is called even though the
> value hasn't changed (which may happen according to the docs).
>
> It's to ensure that even if the callback triggered multiple calls to
> geo_start(), we would have a call to geo_stop() in between to guarantee that
> geo_master, geo_client, and geo_address were cleaned up.

Sounds reasonable.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Allan LeSage (allanlesage) wrote :

Misconfiguration foiled autolanding; re-approving to send through again.

Revision history for this message
Charles Kerr (charlesk) wrote :

Thanks Allan!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/datetime-service.c'
2--- src/datetime-service.c 2012-11-03 16:26:05 +0000
3+++ src/datetime-service.c 2012-11-05 01:31:20 +0000
4@@ -64,11 +64,9 @@
5 #define SETTINGS_APP_INVOCATION "gnome-control-center datetime"
6 #endif
7
8-static void geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * path, GError * error, gpointer user_data);
9 static gboolean update_appointment_menu_items (gpointer user_data);
10 static void update_location_menu_items (void);
11 static void day_timer_reset (void);
12-static void geo_client_invalid (GeoclueMasterClient * client, gpointer user_data);
13 static gboolean get_greeter_mode (void);
14
15 static void quick_set_tz (DbusmenuMenuitem * menuitem, guint timestamp, gpointer user_data);
16@@ -96,10 +94,6 @@
17 static GList * appointment_sources = NULL;
18
19
20-/* Geoclue trackers */
21-static GeoclueMasterClient * geo_master = NULL;
22-static GeoclueAddress * geo_address = NULL;
23-
24 /* Our 2 important timezones */
25 static gchar * current_timezone = NULL;
26 static gchar * geo_timezone = NULL;
27@@ -1185,31 +1179,41 @@
28 g_signal_connect(proxy, "g-signal", G_CALLBACK(session_active_change_cb), user_data);
29 }
30
31+
32+/****
33+***** GEOCLUE
34+****/
35+
36+static void geo_start (void);
37+static void geo_stop (void);
38+static void geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * path, GError * error, gpointer user_data);
39+static void geo_client_invalid (GeoclueMasterClient * client, gpointer user_data);
40+
41+static GeoclueMaster * geo_master = NULL;
42+static GeoclueMasterClient * geo_client = NULL;
43+static GeoclueAddress * geo_address = NULL;
44+
45+static void
46+geo_set_timezone (const gchar * timezone)
47+{
48+ if (geo_timezone != timezone) {
49+ g_clear_pointer (&geo_timezone, g_free);
50+ geo_timezone = g_strdup (timezone);
51+ g_debug("Geoclue timezone is: %s", timezone ? timezone : "(Null)");
52+ update_location_menu_items();
53+ }
54+}
55+
56 /* Callback from getting the address */
57 static void
58 geo_address_cb (GeoclueAddress * address, int timestamp, GHashTable * addy_data, GeoclueAccuracy * accuracy, GError * error, gpointer user_data)
59 {
60- if (error != NULL) {
61+ if (error == NULL) {
62+ geo_set_timezone (g_hash_table_lookup (addy_data, "timezone"));
63+ } else {
64 g_warning("Unable to get Geoclue address: %s", error->message);
65 g_clear_error (&error);
66- return;
67- }
68-
69- g_debug("Geoclue timezone is: %s", (gchar *)g_hash_table_lookup(addy_data, "timezone"));
70-
71- if (geo_timezone != NULL) {
72- g_free(geo_timezone);
73- geo_timezone = NULL;
74- }
75-
76- gpointer tz_hash = g_hash_table_lookup(addy_data, "timezone");
77- if (tz_hash != NULL) {
78- geo_timezone = g_strdup((gchar *)tz_hash);
79- }
80-
81- update_location_menu_items();
82-
83- return;
84+ }
85 }
86
87 /* Clean up the reference we kept to the address and make sure to
88@@ -1217,16 +1221,10 @@
89 static void
90 geo_address_clean (void)
91 {
92- if (geo_address == NULL) {
93- return;
94+ if (geo_address != NULL) {
95+ g_signal_handlers_disconnect_by_func (geo_address, geo_address_cb, NULL);
96+ g_clear_object (&geo_address);
97 }
98-
99- g_signal_handlers_disconnect_by_func(G_OBJECT(geo_address), geo_address_cb, NULL);
100- g_object_unref(G_OBJECT(geo_address));
101-
102- geo_address = NULL;
103-
104- return;
105 }
106
107 /* Clean up and remove all signal handlers from the client as we
108@@ -1234,16 +1232,10 @@
109 static void
110 geo_client_clean (void)
111 {
112- if (geo_master == NULL) {
113- return;
114+ if (geo_client != NULL) {
115+ g_signal_handlers_disconnect_by_func (geo_client, geo_client_invalid, NULL);
116+ g_clear_object (&geo_client);
117 }
118-
119- g_signal_handlers_disconnect_by_func(G_OBJECT(geo_master), geo_client_invalid, NULL);
120- g_object_unref(G_OBJECT(geo_master));
121-
122- geo_master = NULL;
123-
124- return;
125 }
126
127 /* Callback from creating the address */
128@@ -1263,14 +1255,11 @@
129 geo_address_clean();
130
131 g_debug("Created Geoclue Address");
132- geo_address = address;
133- g_object_ref(G_OBJECT(geo_address));
134-
135- geoclue_address_get_address_async(geo_address, geo_address_cb, NULL);
136-
137- g_signal_connect(G_OBJECT(address), "address-changed", G_CALLBACK(geo_address_cb), NULL);
138-
139- return;
140+ geo_address = g_object_ref (address);
141+
142+ geoclue_address_get_address_async (geo_address, geo_address_cb, NULL);
143+
144+ g_signal_connect (address, "address-changed", G_CALLBACK(geo_address_cb), NULL);
145 }
146
147 /* Callback from setting requirements */
148@@ -1281,7 +1270,6 @@
149 g_warning("Unable to set Geoclue requirements: %s", error->message);
150 g_clear_error (&error);
151 }
152- return;
153 }
154
155 /* Client is killing itself rather oddly */
156@@ -1289,25 +1277,28 @@
157 geo_client_invalid (GeoclueMasterClient * client, gpointer user_data)
158 {
159 g_warning("Master client invalid, rebuilding.");
160-
161- /* Client changes we can assume the address is now invalid so we
162- need to unreference the one we had. */
163- geo_address_clean();
164-
165- /* And our master client is invalid */
166- geo_client_clean();
167-
168- GeoclueMaster * master = geoclue_master_get_default();
169- geoclue_master_create_client_async(master, geo_create_client, NULL);
170-
171- if (geo_timezone != NULL) {
172- g_free(geo_timezone);
173- geo_timezone = NULL;
174- }
175-
176- update_location_menu_items();
177-
178- return;
179+ geo_stop ();
180+ geo_start ();
181+}
182+
183+static void
184+geo_stop (void)
185+{
186+ geo_set_timezone (NULL);
187+
188+ geo_address_clean ();
189+ geo_client_clean ();
190+ g_clear_object (&geo_master);
191+}
192+
193+static void
194+geo_start (void)
195+{
196+ g_warn_if_fail (geo_master == NULL);
197+
198+ g_clear_object (&geo_master);
199+ geo_master = geoclue_master_get_default();
200+ geoclue_master_create_client_async (geo_master, geo_create_client, NULL);
201 }
202
203 /* Callback from creating the client */
204@@ -1316,7 +1307,7 @@
205 {
206 g_debug("Created Geoclue client at: %s", path);
207
208- geo_master = client;
209+ geo_client = client;
210
211 if (error != NULL) {
212 g_warning("Unable to get a GeoClue client! '%s' Geolocation based timezone support will not be available.", error->message);
213@@ -1324,17 +1315,17 @@
214 return;
215 }
216
217- if (geo_master == NULL) {
218+ if (client == NULL) {
219 g_warning(_("Unable to get a GeoClue client! Geolocation based timezone support will not be available."));
220 return;
221 }
222
223- g_object_ref(G_OBJECT(geo_master));
224+ g_object_ref (geo_client);
225
226 /* New client, make sure we don't have an address hanging on */
227 geo_address_clean();
228
229- geoclue_master_client_set_requirements_async(geo_master,
230+ geoclue_master_client_set_requirements_async(geo_client,
231 GEOCLUE_ACCURACY_LEVEL_REGION,
232 0,
233 FALSE,
234@@ -1342,12 +1333,23 @@
235 geo_req_set,
236 NULL);
237
238- geoclue_master_client_create_address_async(geo_master, geo_create_address, NULL);
239-
240- g_signal_connect(G_OBJECT(client), "invalidated", G_CALLBACK(geo_client_invalid), NULL);
241-
242- return;
243-}
244+ geoclue_master_client_create_address_async(geo_client, geo_create_address, NULL);
245+
246+ g_signal_connect(client, "invalidated", G_CALLBACK(geo_client_invalid), NULL);
247+}
248+
249+static void
250+on_use_geoclue_changed_cb (GSettings * settings, gchar * key, gpointer unused G_GNUC_UNUSED)
251+{
252+ geo_stop ();
253+
254+ if (g_settings_get_boolean (conf, SETTINGS_SHOW_DETECTED_S))
255+ geo_start ();
256+}
257+
258+/****
259+*****
260+****/
261
262 static gboolean
263 get_greeter_mode (void)
264@@ -1413,7 +1415,9 @@
265
266 /* Set up GSettings */
267 conf = g_settings_new(SETTINGS_INTERFACE);
268- // TODO Add a signal handler to catch gsettings changes and respond to them
269+ g_signal_connect (conf, "changed::show-auto-detected-location",
270+ G_CALLBACK(on_use_geoclue_changed_cb), NULL);
271+ // TODO Add a signal handler to catch other gsettings changes and respond to them
272
273 /* Build our list of appointment calendar sources.
274 When a source changes, update our menu items.
275@@ -1439,8 +1443,8 @@
276 update_current_timezone();
277
278 /* Setup geoclue */
279- GeoclueMaster * master = geoclue_master_get_default();
280- geoclue_master_create_client_async(master, geo_create_client, NULL);
281+ if (g_settings_get_boolean (conf, SETTINGS_SHOW_DETECTED_S))
282+ geo_start ();
283
284 /* Setup dbus interface */
285 dbus = g_object_new(DATETIME_INTERFACE_TYPE, NULL);
286@@ -1471,7 +1475,6 @@
287 free_appointment_sources();
288
289 g_object_unref(G_OBJECT(conf));
290- g_object_unref(G_OBJECT(master));
291 g_object_unref(G_OBJECT(dbus));
292 g_object_unref(G_OBJECT(service));
293 g_object_unref(G_OBJECT(server));
294@@ -1480,8 +1483,7 @@
295
296 icaltimezone_free_builtin_timezones();
297
298- geo_address_clean();
299- geo_client_clean();
300+ geo_stop ();
301
302 return 0;
303 }

Subscribers

People subscribed via source and target branches