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
=== modified file 'src/datetime-service.c'
--- src/datetime-service.c 2012-11-03 16:26:05 +0000
+++ src/datetime-service.c 2012-11-05 01:31:20 +0000
@@ -64,11 +64,9 @@
64 #define SETTINGS_APP_INVOCATION "gnome-control-center datetime"64 #define SETTINGS_APP_INVOCATION "gnome-control-center datetime"
65#endif65#endif
6666
67static void geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * path, GError * error, gpointer user_data);
68static gboolean update_appointment_menu_items (gpointer user_data);67static gboolean update_appointment_menu_items (gpointer user_data);
69static void update_location_menu_items (void);68static void update_location_menu_items (void);
70static void day_timer_reset (void);69static void day_timer_reset (void);
71static void geo_client_invalid (GeoclueMasterClient * client, gpointer user_data);
72static gboolean get_greeter_mode (void);70static gboolean get_greeter_mode (void);
7371
74static void quick_set_tz (DbusmenuMenuitem * menuitem, guint timestamp, gpointer user_data);72static void quick_set_tz (DbusmenuMenuitem * menuitem, guint timestamp, gpointer user_data);
@@ -96,10 +94,6 @@
96static GList * appointment_sources = NULL;94static GList * appointment_sources = NULL;
9795
9896
99/* Geoclue trackers */
100static GeoclueMasterClient * geo_master = NULL;
101static GeoclueAddress * geo_address = NULL;
102
103/* Our 2 important timezones */97/* Our 2 important timezones */
104static gchar * current_timezone = NULL;98static gchar * current_timezone = NULL;
105static gchar * geo_timezone = NULL;99static gchar * geo_timezone = NULL;
@@ -1185,31 +1179,41 @@
1185 g_signal_connect(proxy, "g-signal", G_CALLBACK(session_active_change_cb), user_data);1179 g_signal_connect(proxy, "g-signal", G_CALLBACK(session_active_change_cb), user_data);
1186}1180}
11871181
1182
1183/****
1184***** GEOCLUE
1185****/
1186
1187static void geo_start (void);
1188static void geo_stop (void);
1189static void geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * path, GError * error, gpointer user_data);
1190static void geo_client_invalid (GeoclueMasterClient * client, gpointer user_data);
1191
1192static GeoclueMaster * geo_master = NULL;
1193static GeoclueMasterClient * geo_client = NULL;
1194static GeoclueAddress * geo_address = NULL;
1195
1196static void
1197geo_set_timezone (const gchar * timezone)
1198{
1199 if (geo_timezone != timezone) {
1200 g_clear_pointer (&geo_timezone, g_free);
1201 geo_timezone = g_strdup (timezone);
1202 g_debug("Geoclue timezone is: %s", timezone ? timezone : "(Null)");
1203 update_location_menu_items();
1204 }
1205}
1206
1188/* Callback from getting the address */1207/* Callback from getting the address */
1189static void1208static void
1190geo_address_cb (GeoclueAddress * address, int timestamp, GHashTable * addy_data, GeoclueAccuracy * accuracy, GError * error, gpointer user_data)1209geo_address_cb (GeoclueAddress * address, int timestamp, GHashTable * addy_data, GeoclueAccuracy * accuracy, GError * error, gpointer user_data)
1191{1210{
1192 if (error != NULL) {1211 if (error == NULL) {
1212 geo_set_timezone (g_hash_table_lookup (addy_data, "timezone"));
1213 } else {
1193 g_warning("Unable to get Geoclue address: %s", error->message);1214 g_warning("Unable to get Geoclue address: %s", error->message);
1194 g_clear_error (&error);1215 g_clear_error (&error);
1195 return;1216 }
1196 }
1197
1198 g_debug("Geoclue timezone is: %s", (gchar *)g_hash_table_lookup(addy_data, "timezone"));
1199
1200 if (geo_timezone != NULL) {
1201 g_free(geo_timezone);
1202 geo_timezone = NULL;
1203 }
1204
1205 gpointer tz_hash = g_hash_table_lookup(addy_data, "timezone");
1206 if (tz_hash != NULL) {
1207 geo_timezone = g_strdup((gchar *)tz_hash);
1208 }
1209
1210 update_location_menu_items();
1211
1212 return;
1213}1217}
12141218
1215/* Clean up the reference we kept to the address and make sure to1219/* Clean up the reference we kept to the address and make sure to
@@ -1217,16 +1221,10 @@
1217static void1221static void
1218geo_address_clean (void)1222geo_address_clean (void)
1219{1223{
1220 if (geo_address == NULL) {1224 if (geo_address != NULL) {
1221 return;1225 g_signal_handlers_disconnect_by_func (geo_address, geo_address_cb, NULL);
1226 g_clear_object (&geo_address);
1222 }1227 }
1223
1224 g_signal_handlers_disconnect_by_func(G_OBJECT(geo_address), geo_address_cb, NULL);
1225 g_object_unref(G_OBJECT(geo_address));
1226
1227 geo_address = NULL;
1228
1229 return;
1230}1228}
12311229
1232/* Clean up and remove all signal handlers from the client as we1230/* Clean up and remove all signal handlers from the client as we
@@ -1234,16 +1232,10 @@
1234static void1232static void
1235geo_client_clean (void)1233geo_client_clean (void)
1236{1234{
1237 if (geo_master == NULL) {1235 if (geo_client != NULL) {
1238 return;1236 g_signal_handlers_disconnect_by_func (geo_client, geo_client_invalid, NULL);
1237 g_clear_object (&geo_client);
1239 }1238 }
1240
1241 g_signal_handlers_disconnect_by_func(G_OBJECT(geo_master), geo_client_invalid, NULL);
1242 g_object_unref(G_OBJECT(geo_master));
1243
1244 geo_master = NULL;
1245
1246 return;
1247}1239}
12481240
1249/* Callback from creating the address */1241/* Callback from creating the address */
@@ -1263,14 +1255,11 @@
1263 geo_address_clean();1255 geo_address_clean();
12641256
1265 g_debug("Created Geoclue Address");1257 g_debug("Created Geoclue Address");
1266 geo_address = address;1258 geo_address = g_object_ref (address);
1267 g_object_ref(G_OBJECT(geo_address));1259
12681260 geoclue_address_get_address_async (geo_address, geo_address_cb, NULL);
1269 geoclue_address_get_address_async(geo_address, geo_address_cb, NULL);1261
12701262 g_signal_connect (address, "address-changed", G_CALLBACK(geo_address_cb), NULL);
1271 g_signal_connect(G_OBJECT(address), "address-changed", G_CALLBACK(geo_address_cb), NULL);
1272
1273 return;
1274}1263}
12751264
1276/* Callback from setting requirements */1265/* Callback from setting requirements */
@@ -1281,7 +1270,6 @@
1281 g_warning("Unable to set Geoclue requirements: %s", error->message);1270 g_warning("Unable to set Geoclue requirements: %s", error->message);
1282 g_clear_error (&error);1271 g_clear_error (&error);
1283 }1272 }
1284 return;
1285}1273}
12861274
1287/* Client is killing itself rather oddly */1275/* Client is killing itself rather oddly */
@@ -1289,25 +1277,28 @@
1289geo_client_invalid (GeoclueMasterClient * client, gpointer user_data)1277geo_client_invalid (GeoclueMasterClient * client, gpointer user_data)
1290{1278{
1291 g_warning("Master client invalid, rebuilding.");1279 g_warning("Master client invalid, rebuilding.");
12921280 geo_stop ();
1293 /* Client changes we can assume the address is now invalid so we1281 geo_start ();
1294 need to unreference the one we had. */1282}
1295 geo_address_clean();1283
12961284static void
1297 /* And our master client is invalid */1285geo_stop (void)
1298 geo_client_clean();1286{
12991287 geo_set_timezone (NULL);
1300 GeoclueMaster * master = geoclue_master_get_default();1288
1301 geoclue_master_create_client_async(master, geo_create_client, NULL);1289 geo_address_clean ();
13021290 geo_client_clean ();
1303 if (geo_timezone != NULL) {1291 g_clear_object (&geo_master);
1304 g_free(geo_timezone);1292}
1305 geo_timezone = NULL;1293
1306 }1294static void
13071295geo_start (void)
1308 update_location_menu_items();1296{
13091297 g_warn_if_fail (geo_master == NULL);
1310 return;1298
1299 g_clear_object (&geo_master);
1300 geo_master = geoclue_master_get_default();
1301 geoclue_master_create_client_async (geo_master, geo_create_client, NULL);
1311}1302}
13121303
1313/* Callback from creating the client */1304/* Callback from creating the client */
@@ -1316,7 +1307,7 @@
1316{1307{
1317 g_debug("Created Geoclue client at: %s", path);1308 g_debug("Created Geoclue client at: %s", path);
13181309
1319 geo_master = client;1310 geo_client = client;
13201311
1321 if (error != NULL) {1312 if (error != NULL) {
1322 g_warning("Unable to get a GeoClue client! '%s' Geolocation based timezone support will not be available.", error->message);1313 g_warning("Unable to get a GeoClue client! '%s' Geolocation based timezone support will not be available.", error->message);
@@ -1324,17 +1315,17 @@
1324 return;1315 return;
1325 }1316 }
13261317
1327 if (geo_master == NULL) {1318 if (client == NULL) {
1328 g_warning(_("Unable to get a GeoClue client! Geolocation based timezone support will not be available."));1319 g_warning(_("Unable to get a GeoClue client! Geolocation based timezone support will not be available."));
1329 return;1320 return;
1330 }1321 }
13311322
1332 g_object_ref(G_OBJECT(geo_master));1323 g_object_ref (geo_client);
13331324
1334 /* New client, make sure we don't have an address hanging on */1325 /* New client, make sure we don't have an address hanging on */
1335 geo_address_clean();1326 geo_address_clean();
13361327
1337 geoclue_master_client_set_requirements_async(geo_master,1328 geoclue_master_client_set_requirements_async(geo_client,
1338 GEOCLUE_ACCURACY_LEVEL_REGION,1329 GEOCLUE_ACCURACY_LEVEL_REGION,
1339 0,1330 0,
1340 FALSE,1331 FALSE,
@@ -1342,12 +1333,23 @@
1342 geo_req_set,1333 geo_req_set,
1343 NULL);1334 NULL);
13441335
1345 geoclue_master_client_create_address_async(geo_master, geo_create_address, NULL);1336 geoclue_master_client_create_address_async(geo_client, geo_create_address, NULL);
13461337
1347 g_signal_connect(G_OBJECT(client), "invalidated", G_CALLBACK(geo_client_invalid), NULL);1338 g_signal_connect(client, "invalidated", G_CALLBACK(geo_client_invalid), NULL);
13481339}
1349 return;1340
1350}1341static void
1342on_use_geoclue_changed_cb (GSettings * settings, gchar * key, gpointer unused G_GNUC_UNUSED)
1343{
1344 geo_stop ();
1345
1346 if (g_settings_get_boolean (conf, SETTINGS_SHOW_DETECTED_S))
1347 geo_start ();
1348}
1349
1350/****
1351*****
1352****/
13511353
1352static gboolean1354static gboolean
1353get_greeter_mode (void)1355get_greeter_mode (void)
@@ -1413,7 +1415,9 @@
14131415
1414 /* Set up GSettings */1416 /* Set up GSettings */
1415 conf = g_settings_new(SETTINGS_INTERFACE);1417 conf = g_settings_new(SETTINGS_INTERFACE);
1416 // TODO Add a signal handler to catch gsettings changes and respond to them1418 g_signal_connect (conf, "changed::show-auto-detected-location",
1419 G_CALLBACK(on_use_geoclue_changed_cb), NULL);
1420 // TODO Add a signal handler to catch other gsettings changes and respond to them
14171421
1418 /* Build our list of appointment calendar sources.1422 /* Build our list of appointment calendar sources.
1419 When a source changes, update our menu items.1423 When a source changes, update our menu items.
@@ -1439,8 +1443,8 @@
1439 update_current_timezone();1443 update_current_timezone();
14401444
1441 /* Setup geoclue */1445 /* Setup geoclue */
1442 GeoclueMaster * master = geoclue_master_get_default();1446 if (g_settings_get_boolean (conf, SETTINGS_SHOW_DETECTED_S))
1443 geoclue_master_create_client_async(master, geo_create_client, NULL);1447 geo_start ();
14441448
1445 /* Setup dbus interface */1449 /* Setup dbus interface */
1446 dbus = g_object_new(DATETIME_INTERFACE_TYPE, NULL);1450 dbus = g_object_new(DATETIME_INTERFACE_TYPE, NULL);
@@ -1471,7 +1475,6 @@
1471 free_appointment_sources();1475 free_appointment_sources();
14721476
1473 g_object_unref(G_OBJECT(conf));1477 g_object_unref(G_OBJECT(conf));
1474 g_object_unref(G_OBJECT(master));
1475 g_object_unref(G_OBJECT(dbus));1478 g_object_unref(G_OBJECT(dbus));
1476 g_object_unref(G_OBJECT(service));1479 g_object_unref(G_OBJECT(service));
1477 g_object_unref(G_OBJECT(server));1480 g_object_unref(G_OBJECT(server));
@@ -1480,8 +1483,7 @@
14801483
1481 icaltimezone_free_builtin_timezones();1484 icaltimezone_free_builtin_timezones();
14821485
1483 geo_address_clean();1486 geo_stop ();
1484 geo_client_clean();
14851487
1486 return 0;1488 return 0;
1487}1489}

Subscribers

People subscribed via source and target branches