Changeset 2933
- Timestamp:
- 11/09/07 12:12:26
- Files:
-
- trunk/ChangeLog (modified) (2 diffs)
- trunk/libtinymail-maemo/Makefile.am (modified) (2 diffs)
- trunk/libtinymail-maemo/tny-maemo-conic-device.c (modified) (31 diffs)
- trunk/libtinymail-maemo/tny-maemo-conic-device.h (modified) (1 diff)
- trunk/libtinymail-maemo/tny-maemo-conic-dummy-device.c (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/ChangeLog
r2931 r2933 1 2007-11-09 Sergio Villar Senin <svillar@igalia.com> 2 3 * libtinymail-maemo/tny-maemo-conic-device.c: 4 Added a new API to allow asynchronous connections 5 in the Maemo conic device. This patch is a new version of an initial 6 patch developed by pvanhoof with some changes. 7 Splitted the Maemo connic device in two files, one for the actual 8 device and the other one for a dummy device (useful for sbox devel) 9 Fixed a problem when linking the maemo conic device 10 1 11 2007-11-08 Jose Dapena Paz <jdapena@igalia.com> 2 12 … … 150 160 * priv->folder_name in TnyCamelFolder sometimes is NULL, which 151 161 doesn't seem right (and is racy). 162 * Improvements for the IDLE support. The Nonblocking read is now 163 actually used correctly, various racy situations should be fixed now 164 and instant event throwing is put in place (during IDLE state). 165 * Removed the (*read_idle) funcptr from CamelTcpStream, as this is no longer 166 required. This to reduce the complexity of the IDLE patch so that we 167 can later, perhaps, more easily bring this feature to upstream Camel. 152 168 153 169 2007-10-19 Philip Van Hoof <pvanhoof@gnome.org> trunk/libtinymail-maemo/Makefile.am
r1834 r2933 10 10 -I$(top_srcdir)/libtinymail-gnomevfs \ 11 11 -DDBUS_API_SUBJECT_TO_CHANGE 12 13 12 14 13 lib_LTLIBRARIES = libtinymail-maemo-1.0.la … … 26 25 tny-maemo-platform-factory.c 27 26 28 EXTRA_libtinymail_maemo_1_0_la_SOURCES = \ 29 tny-maemo-conic-device.c 30 27 if MAEMO_CONIC_DEVICE_DUMMY 28 libtinymail_maemo_1_0_la_SOURCES += tny-maemo-conic-dummy-device.c 29 else 30 libtinymail_maemo_1_0_la_SOURCES += tny-maemo-conic-device.c 31 endif 32 31 33 libtinymail_maemo_1_0_la_LIBADD = \ 32 34 $(LIBTINYMAIL_MAEMO_LIBS) \ 33 35 $(LIBTINYMAIL_MAEMO_CONIC_LIBS) \ 34 @MAEMO_DEVICE@ \35 36 $(top_builddir)/libtinymail/libtinymail-$(API_VERSION).la \ 36 37 $(top_builddir)/libtinymailui/libtinymailui-$(API_VERSION).la \ 37 38 $(top_builddir)/libtinymailui-gtk/libtinymailui-gtk-$(API_VERSION).la \ 38 39 $(top_builddir)/libtinymail-camel/libtinymail-camel-$(API_VERSION).la 39 40 libtinymail_maemo_1_0_la_DEPENDENCIES=\41 @MAEMO_DEVICE@42 40 43 41 libtinymail_maemo_1_0_la_LDFLAGS = -export-dynamic \ trunk/libtinymail-maemo/tny-maemo-conic-device.c
r2825 r2933 1 /* libtinymail-camel - The Tiny Mail base library for Camel1 /* libtinymail-camel - The Tiny Mail base library for Maemo 2 2 * Copyright (C) 2006-2007 Philip Van Hoof <pvanhoof@gnome.org> 3 3 * … … 26 26 #include <conicconnection.h> 27 27 #include <conicconnectionevent.h> 28 #include <string.h> 29 #include <tny-error.h> 28 30 #include <gdk/gdk.h> /* For GDK_THREAD_ENTER/LEAVE */ 29 #include <string.h> /* For strcmp() */ 30 31 32 #ifdef MAEMO_CONIC_DUMMY 33 #include <gtk/gtkmessagedialog.h> 34 #endif 35 36 37 38 static gboolean 39 dnsmasq_has_resolv (void) 40 { 41 /* This is because silly Conic does not have a blocking API that tells 42 * us immediately when the device is online. */ 43 44 if (!g_file_test ("/var/run/resolv.conf", G_FILE_TEST_EXISTS)) 45 if (!g_file_test ("/tmp/resolv.conf.wlan0", G_FILE_TEST_EXISTS)) 46 if (!g_file_test ("/tmp/resolv.conf.ppp0", G_FILE_TEST_EXISTS)) 47 return FALSE; 48 49 return TRUE; 50 } 51 52 #ifdef MAEMO_CONIC_DUMMY 53 /* #include "coniciap-private.h" 54 * This is not installed, so we predeclare the struct instead. Of course, this 55 * is a hack and could break if the private API changes. It would be better for 56 * libconic to support scratchbox. */ 57 58 struct _ConIcIap 59 { 60 GObject parent_instance; 61 gboolean dispose_has_run; 62 gchar *id; 63 gchar *name; 64 gchar *bearer; 65 }; 66 67 #define MAEMO_CONIC_DUMMY_IAP_ID_FILENAME "maemo_conic_dummy_id" 68 #define MAEMO_CONIC_DUMMY_IAP_ID_NONE "none" 69 static gboolean on_dummy_connection_check (gpointer user_data); 70 #endif /* MAEMO_CONIC_DUMMY */ 31 32 static void stop_loop (TnyMaemoConicDevice *self); 71 33 72 34 static gboolean tny_maemo_conic_device_is_online (TnyDevice *self); 73 35 74 36 static GObjectClass *parent_class = NULL; 37 38 typedef struct { 39 TnyMaemoConicDevice *self; 40 gchar* iap_id; 41 gpointer user_data; 42 TnyMaemoConicDeviceConnectCallback callback; 43 } ConnectInfo; 75 44 76 45 typedef struct { … … 79 48 gchar *iap; 80 49 gboolean forced; /* Whether the is_online value is forced rather than real. */ 50 ConnectInfo *connect_slot; 81 51 /* When non-NULL, we are waiting for the success or failure signal. */ 82 52 GMainLoop *loop; 83 #ifdef MAEMO_CONIC_DUMMY84 gint dummy_env_check_timeout;85 #endif /* MAEMO_CONIC_DUMMY */86 53 } TnyMaemoConicDevicePriv; 54 87 55 88 56 #define TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE(o) \ … … 95 63 96 64 static gboolean 65 dnsmasq_has_resolv (void) 66 { 67 /* This is because silly Conic does not have a blocking API that tells 68 * us immediately when the device is online. */ 69 70 if (!g_file_test ("/var/run/resolv.conf", G_FILE_TEST_EXISTS)) 71 if (!g_file_test ("/tmp/resolv.conf.wlan0", G_FILE_TEST_EXISTS)) 72 if (!g_file_test ("/tmp/resolv.conf.ppp0", G_FILE_TEST_EXISTS)) 73 return FALSE; 74 75 return TRUE; 76 } 77 78 static gboolean 97 79 conic_emit_status_idle (gpointer user_data) 98 80 { 99 81 EmitStatusInfo *info = (EmitStatusInfo *) user_data; 100 82 101 /* We lock the gdk thread because tinymail wants implementations to do this102 * before emitting _any_ signals.83 /* We lock the gdk thread because tinymail wants implementations to do 84 * this before emitting signals from within a g_idle_add_full callback. 103 85 * See http://www.tinymail.org/trac/tinymail/wiki/HowTnyLockable */ 104 86 … … 123 105 conic_emit_status (TnyDevice *self, gboolean status) 124 106 { 125 /* If there is a mainloop (if gtk_main() has been run, for instance), 126 * then emit the signal via an idle callback, so that it is 127 * always emitted in the main context as required by tinymail 128 * (libconic does not give any guarantee 129 * about this - it would be nice if libconic documented that). 130 * But if there is no mainloop, then just emit it, as tinymail 131 * requires when there is no mainloop: */ 132 133 /* TODO: We have no way to check for this now, and 134 * at this time it's not even clear whether tinymail should/can really 135 * demand this. murrayc. 15th Aug. 2007. */ 136 137 if (TRUE) /* TODO: But NULL is not allowed here: g_main_loop_is_running (NULL)) */ 138 { 139 /* Emit it in an idle handler: */ 140 EmitStatusInfo *info = g_slice_new (EmitStatusInfo); 141 guint time = 5000; 142 143 info->self = g_object_ref (self); 144 info->status = status; 145 146 if (!dnsmasq_has_resolv()) 147 time = 5000; 148 149 g_timeout_add_full (G_PRIORITY_DEFAULT, time, conic_emit_status_idle, 150 info, conic_emit_status_destroy); 151 152 } else { 153 /* Emit it directly: */ 154 155 /* We lock the gdk thread because tinymail wants implementations 156 * to do this before emitting _any_ signals. 157 * See http://www.tinymail.org/trac/tinymail/wiki/HowTnyLockable */ 158 159 gdk_threads_enter (); 160 g_signal_emit (self, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED], 161 0, status); 162 gdk_threads_leave (); 163 } 107 /* Emit it in an idle handler: */ 108 EmitStatusInfo *info = g_slice_new (EmitStatusInfo); 109 guint time = 1000; 110 111 info->self = g_object_ref (self); 112 info->status = status; 113 114 if (!dnsmasq_has_resolv()) 115 time = 5000; 116 117 g_timeout_add_full (G_PRIORITY_DEFAULT, time, conic_emit_status_idle, 118 info, conic_emit_status_destroy); 164 119 165 120 return; … … 186 141 } 187 142 188 #ifndef MAEMO_CONIC_DUMMY 143 static void 144 handle_connect (TnyMaemoConicDevice *self, int con_err, int con_state) 145 { 146 TnyMaemoConicDevicePriv *priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 147 148 if (priv->connect_slot) 149 { 150 GError *err = NULL; 151 gboolean canceled = FALSE; 152 ConnectInfo *info = priv->connect_slot; 153 154 /* Mark it as handled (TODO, this needs a small lock) */ 155 priv->connect_slot = NULL; 156 157 switch (con_err) { 158 case CON_IC_CONNECTION_ERROR_NONE: 159 break; 160 case CON_IC_CONNECTION_ERROR_INVALID_IAP: 161 g_set_error (&err, TNY_ACCOUNT_ERROR, TNY_ERROR_UNSPEC, 162 "IAP is invalid"); 163 break; 164 case CON_IC_CONNECTION_ERROR_CONNECTION_FAILED: 165 g_set_error (&err, TNY_ACCOUNT_ERROR, TNY_ERROR_UNSPEC, 166 "Connection failed"); 167 break; 168 case CON_IC_CONNECTION_ERROR_USER_CANCELED: 169 default: 170 canceled = TRUE; 171 break; 172 } 173 174 if (info->callback) { 175 /* We lock the gdk thread because tinymail wants implementations to do 176 * this before invoking callbacks from within a g_idle_add_full callback. 177 * See http://www.tinymail.org/trac/tinymail/wiki/HowTnyLockable */ 178 179 gdk_threads_enter (); 180 info->callback (info->self, info->iap_id, canceled, err, info->user_data); 181 gdk_threads_leave (); 182 } 183 184 if (err) 185 g_error_free (err); 186 187 g_object_unref (info->self); 188 g_free (info->self); 189 g_slice_free (ConnectInfo, info); 190 } 191 192 return; 193 } 194 195 typedef struct { 196 TnyMaemoConicDevice *self; 197 int con_err; 198 int con_state; 199 } HandleConnInfo; 200 201 static gboolean 202 handle_con_idle (gpointer data) 203 { 204 HandleConnInfo *info = (HandleConnInfo *) data; 205 handle_connect (info->self, info->con_err, info->con_state); 206 return FALSE; 207 } 189 208 190 209 static void 191 stop_loop (TnyMaemoConicDevice *self) 192 { 193 TnyMaemoConicDevicePriv *priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self);194 if (priv->loop)195 g_main_loop_quit (priv->loop);196 return; 197 } 210 handle_con_idle_destroy (gpointer data) 211 { 212 HandleConnInfo *info = (HandleConnInfo *) data; 213 g_object_unref (info->self); 214 g_slice_free (HandleConnInfo, data); 215 } 216 198 217 199 218 static void … … 204 223 gboolean is_online = FALSE; 205 224 gboolean emit = FALSE; 225 HandleConnInfo *iinfo; 226 int con_err, con_state; 206 227 207 228 /* Don't emit nor make any changes in case of forced state */ 229 208 230 if (priv->forced) 209 231 return; 210 232 211 g_return_if_fail (CON_IC_IS_CONNECTION(cnx)); 212 213 #ifdef DEBUG 214 g_message (__FUNCTION__); 215 #endif 216 217 switch (con_ic_connection_event_get_error(event)) 218 { 233 con_err = con_ic_connection_event_get_error (event); 234 con_state = con_ic_connection_event_get_status (event); 235 236 switch (con_err) { 219 237 case CON_IC_CONNECTION_ERROR_NONE: 220 238 break; … … 232 250 } 233 251 234 switch (con_ic_connection_event_get_status(event)) 235 { 252 switch (con_state) { 236 253 case CON_IC_STATUS_CONNECTED: 237 254 if (priv->iap) … … 262 279 priv->is_online = is_online; 263 280 264 #ifdef DEBUG 265 g_message ("DEBUG: %s: emitting signal CONNECTION_CHANGED: %s", 266 __FUNCTION__, is_online ? "online" : "offline"); 267 #endif 281 if (priv->connect_slot && 282 (con_err != CON_IC_CONNECTION_ERROR_NONE || 283 con_state == CON_IC_STATUS_CONNECTED)) 284 { 285 286 /* If there's an error or if we just connected, we call the 287 * callback for tny_maemo_conic_device_connect, if any */ 288 289 iinfo = g_slice_new (HandleConnInfo); 290 iinfo->self = (TnyMaemoConicDevice *) g_object_ref (device); 291 iinfo->con_err = con_err; 292 iinfo->con_state = con_state; 293 294 g_idle_add_full (G_PRIORITY_HIGH, handle_con_idle, iinfo, 295 handle_con_idle_destroy); 296 } 268 297 269 298 if (emit) … … 272 301 return; 273 302 } 274 #endif /* MAEMO_CONIC_DUMMY */275 276 #ifdef MAEMO_CONIC_DUMMY277 278 static gchar*279 get_dummy_filename ()280 {281 gchar *filename = g_build_filename (282 g_get_home_dir (),283 MAEMO_CONIC_DUMMY_IAP_ID_FILENAME,284 NULL);285 return filename;286 }287 288 static gboolean289 dummy_con_ic_connection_connect_by_id (TnyMaemoConicDevice *self, const gchar* iap_id)290 {291 int response = 0;292 293 /* Show a dialog, because libconic would show a dialog here,294 * and give the user a chance to refuse a new connection, because libconic would allow that too.295 * This allows us to see roughly similar behaviour in scratchbox as on the device. */296 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new( NULL, GTK_DIALOG_MODAL,297 GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL,298 "TnyMaemoConicDevice fake scratchbox implementation:\nThe application requested a connection. Make a fake connection?"));299 300 response = gtk_dialog_run (dialog);301 gtk_widget_hide (GTK_WIDGET (dialog));302 gtk_widget_destroy (GTK_WIDGET (dialog));303 304 if (response == GTK_RESPONSE_OK) {305 GError* error = NULL;306 /* Make a connection, by setting a name in our dummy text file,307 * which will be read later: */308 gchar *filename = get_dummy_filename ();309 310 g_file_set_contents (filename, "debug id0", -1, &error);311 if(error) {312 g_warning("%s: error from g_file_set_contents(): %s\n", __FUNCTION__, error->message);313 g_error_free (error);314 error = NULL;315 }316 317 g_free (filename);318 319 return TRUE;320 }321 else322 return FALSE;323 }324 325 #endif /* MAEMO_CONIC_DUMMY */326 303 327 304 … … 330 307 * @self: a #TnyDevice object 331 308 * @iap_id: the id of the Internet Access Point (IAP), or NULL for 'any; 309 * @callback: a #TnyMaemoConicDeviceConnectCallback 310 * @user_data: user data for @callback 332 311 * 333 312 * Try to connect to a specific IAP, or to any if @iap_id == NULL 334 313 * this calls con_ic_connection_connect(_by_id). 335 314 * This may show a dialog to allow the user to select a connection, or 336 * may otherwise take a significant amount of time. This function blocks until 337 * the connection has either succeeded or failed. 338 * 339 * Returns TRUE if a connection was made, FALSE otherwise. 315 * may otherwise take a significant amount of time. 340 316 **/ 341 gboolean 342 tny_maemo_conic_device_connect (TnyMaemoConicDevice *self, const gchar* iap_id)343 { 344 #ifdef MAEMO_CONIC_DUMMY345 return dummy_con_ic_connection_connect_by_id (self, iap_id);346 #else 317 void 318 tny_maemo_conic_device_connect_async (TnyMaemoConicDevice *self, 319 const gchar* iap_id, 320 TnyMaemoConicDeviceConnectCallback callback, 321 gpointer user_data) 322 { 347 323 TnyMaemoConicDevicePriv *priv = NULL; 348 324 gboolean request_failed = FALSE; 349 350 g_return_val_if_fail (TNY_IS_DEVICE(self), FALSE);351 priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 352 353 g_return_val_if_fail (priv->cnx, FALSE); 354 355 #ifdef DEBUG 356 g_message (__FUNCTION__);357 g_message ("connecting to %s", iap_id ? iap_id : "<any>");358 #endif 359 360 priv-> loop = g_main_loop_new(NULL, FALSE /* not running immediately. */);325 ConnectInfo *info; 326 GError *err = NULL; 327 328 priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 329 330 info = g_slice_new (ConnectInfo); 331 info->self = (TnyMaemoConicDevice *) g_object_ref (info); 332 info->callback = callback; 333 info->user_data = user_data; 334 info->iap_id = g_strdup (iap_id); 335 336 priv->connect_slot = info; 361 337 362 338 if (iap_id) { 363 339 if (!con_ic_connection_connect_by_id (priv->cnx, iap_id, CON_IC_CONNECT_FLAG_NONE)) { 364 g_warning ("could not send connect_by_id dbus message"); 340 g_set_error (&err, TNY_ACCOUNT_ERROR, TNY_ERROR_UNSPEC, 341 "Could not send connect_by_id dbus message"); 365 342 request_failed = TRUE; 366 343 } 367 344 } else { 368 345 if (!con_ic_connection_connect (priv->cnx, CON_IC_CONNECT_FLAG_NONE)) { 369 g_warning ("could not send connect dbus message"); 346 g_set_error (&err, TNY_ACCOUNT_ERROR, TNY_ERROR_UNSPEC, 347 "Could not send connect dbus message"); 370 348 request_failed = TRUE; 371 349 } … … 373 351 374 352 if (request_failed) { 375 g_object_unref (priv->loop); 376 priv->loop = NULL; 377 } 378 379 /* Wait for the CON_IC_STATUS_CONNECTED (succeeded) or 380 * CON_IC_STATUS_DISCONNECTED event: */ 381 382 /* This is based on code found in gtk_dialog_run(): */ 383 GDK_THREADS_LEAVE(); 384 /* Run until g_main_loop_quit() is called by our signal handler. */ 385 g_main_loop_run (priv->loop); 386 GDK_THREADS_ENTER(); 387 388 g_main_loop_unref (priv->loop); 389 priv->loop = NULL; 390 391 return priv->is_online; 392 #endif /* MAEMO_CONIC_DUMMY */ 353 priv->connect_slot = NULL; 354 if (info->callback) 355 info->callback (info->self, iap_id, FALSE, err, info->user_data); 356 g_free (info->iap_id); 357 g_object_unref (info->self); 358 g_slice_free (ConnectInfo, info); 359 } 360 361 return; 393 362 } 394 363 … … 407 376 tny_maemo_conic_device_disconnect (TnyMaemoConicDevice *self, const gchar* iap_id) 408 377 { 409 /* don't try to disconnect if we're in dummy mode, as we're not "really"410 * connected in that case either411 */412 #ifndef MAEMO_CONIC_DUMMY413 378 TnyMaemoConicDevicePriv *priv = NULL; 414 379 … … 417 382 priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 418 383 g_return_val_if_fail (priv->cnx, FALSE); 419 420 #ifdef DEBUG421 g_message (__FUNCTION__);422 g_message ("disconnecting from %s", iap_id ? iap_id : "<any>");423 #endif424 384 425 385 if (iap_id) { 426 386 if (!con_ic_connection_disconnect_by_id (priv->cnx, iap_id)) { 427 g_warning (" could not send disconnect_by_id dbus message");387 g_warning ("Could not send disconnect_by_id dbus message"); 428 388 return FALSE; 429 389 } 430 390 } else { 431 391 /* don't try to disconnect if iap_id==NULL, or conic will crash... */ 432 g_warning (" could not send disconnect dbus message");392 g_warning ("Could not send disconnect dbus message"); 433 393 return FALSE; 434 394 } 435 #endif /* MAEMO_CONIC_DUMMY*/436 395 437 396 return TRUE; … … 439 398 440 399 441 #ifdef MAEMO_CONIC_DUMMY442 static gboolean443 on_dummy_connection_check (gpointer user_data)444 {445 TnyMaemoConicDevice *self = NULL;446 TnyMaemoConicDevicePriv *priv = NULL;447 gchar *filename = NULL;448 gchar *contents = NULL;449 GError* error = NULL;450 gboolean test = FALSE;451 452 self = TNY_MAEMO_CONIC_DEVICE (user_data);453 454 priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self);455 456 /* Check whether the enviroment variable has changed,457 * so we can fake a connection change: */458 filename = get_dummy_filename ();459 460 test = g_file_get_contents (filename, &contents, NULL, &error);461 462 if(error) {463 /* g_debug("%s: error from g_file_get_contents(): %s\n", __FUNCTION__, error->message); */464 g_error_free (error);465 error = NULL;466 }467 468 if (!test || !contents) {469 /* g_debug ("DEBUG1: %s: priv->iap = %s\n", priv->iap); */470 /* Default to the first debug connection: */471 contents = g_strdup ("debug id0");472 }473 474 if (contents)475 g_strstrip(contents);476 477 if ((priv->iap == NULL) || (strcmp (contents, priv->iap) != 0)) {478 if (priv->iap) {479 g_free (priv->iap);480 priv->iap = NULL;481 }482 483 /* We store even the special "none" text, so we can detect changes. */484 priv->iap = g_strdup (contents);485 486 if (strcmp (priv->iap, MAEMO_CONIC_DUMMY_IAP_ID_NONE) == 0) {487 priv->is_online = FALSE;488 g_debug ("DEBUG: TnyMaemoConicDevice: %s:\n Dummy connection changed to no connection.\n", __FUNCTION__);489 } else {490 priv->is_online = TRUE;491 g_debug ("DEBUG: TnyMaemoConicDevice: %s:\n Dummy connection changed to '%s\n", __FUNCTION__, priv->iap);492 }493 494 g_debug ("DEBUG1: %s: emitting is_online=%d\n", __FUNCTION__, priv->is_online);495 496 conic_emit_status (TNY_DEVICE (self), priv->is_online);497 498 }499 500 g_free (contents);501 g_free (filename);502 503 return TRUE;504 }505 #endif /* MAEMO_CONIC_DUMMY */506 400 507 401 /** … … 524 418 priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 525 419 526 #ifdef MAEMO_CONIC_DUMMY527 on_dummy_connection_check (self);528 /* Handle the special "none" text: */529 if (priv->iap && (strcmp (priv->iap, MAEMO_CONIC_DUMMY_IAP_ID_NONE) == 0))530 return NULL;531 #endif532 533 420 return priv->iap; 534 421 } … … 551 438 tny_maemo_conic_device_get_iap (TnyMaemoConicDevice *self, const gchar *iap_id) 552 439 { 553 #ifdef MAEMO_CONIC_DUMMY554 ConIcIap *iap = NULL;555 #else556 440 TnyMaemoConicDevicePriv *priv = NULL; 557 #endif558 559 441 g_return_val_if_fail (TNY_IS_MAEMO_CONIC_DEVICE(self), NULL); 560 442 g_return_val_if_fail (iap_id, NULL); 561 562 #ifdef MAEMO_CONIC_DUMMY563 /* Note that we have re-declared the private struct so that we564 * can do this, which is very bad and fragile: */565 iap = g_object_new (CON_IC_TYPE_IAP, NULL);566 iap->id = g_strdup(iap_id);567 iap->name = g_strdup_printf("%s name", iap->id);568 return iap;569 #else570 443 priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 571 444 g_return_val_if_fail (priv->cnx, NULL); 572 445 573 /* Note that it is very unusual to return a reference from a get_() function,574 * but we must do so because that mistake has already been made in575 * con_ic_connection_get_iap().576 * If we just unref immediately then libconic might destroy the object.577 */ 446 /* Note that it is very unusual to return a reference from a get_() 447 * function, but we must do so because that mistake has already been 448 * made in con_ic_connection_get_iap (). If we just unref immediately 449 * then libconic might destroy the object. */ 450 578 451 return con_ic_connection_get_iap (priv->cnx, iap_id); 579 #endif580 452 } 581 453 … … 594 466 tny_maemo_conic_device_get_iap_list (TnyMaemoConicDevice *self) 595 467 { 596 #ifdef MAEMO_CONIC_DUMMY597 GSList* result = NULL;598 int i = 0;599 #else600 468 TnyMaemoConicDevicePriv *priv = NULL; 601 #endif /* MAEMO_CONIC_DUMMY */ 602 603 g_return_val_if_fail (TNY_IS_MAEMO_CONIC_DEVICE(self), NULL); 604 605 #ifdef MAEMO_CONIC_DUMMY 606 607 /* libconic does not return a list of connections when running 608 * in scratchbox, though it might do this in future when 609 * "ethernet support" is implemented. 610 * So we return a fake list so we can exercise funcationality 611 * that uses connections: */ 612 for (i = 0; i < 10; ++i) { 613 /* con_ic_iap_new (id) would checkc for a gconf dir and 614 * fails, though _new() functions should just call g_object_new(). 615 * 616 gchar *id = g_strdup_printf("debug id%d", i); 617 ConIcIap *iap = con_ic_iap_new (id); 618 g_free (id); 619 */ 620 621 /* Note that we have re-declared the private struct so that we 622 * can do this, which is very bad and fragile: */ 623 ConIcIap *iap = g_object_new (CON_IC_TYPE_IAP, NULL); 624 iap->id = g_strdup_printf("debug id%d", i); 625 iap->name = g_strdup_printf("%s name", iap->id); 626 627 result = g_slist_append (result, iap); 628 } 629 630 return result; 631 #else 469 632 470 priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 633 471 g_return_val_if_fail (priv->cnx, NULL); 634 472 635 473 return con_ic_connection_get_all_iaps (priv->cnx); 636 #endif637 474 } 638 475 … … 641 478 * tny_maemo_conic_device_free_iap_list: 642 479 * @self: a #TnyDevice object 643 * 480 * @cnx_list: a list of IAP objects 481 * 644 482 * free a list of IAP objects retrieved from tny_maemo_conic_device_get_iap_list 645 *646 483 **/ 647 484 void … … 654 491 } 655 492 g_slist_free (cnx_list); 656 } 657 493 return; 494 } 658 495 659 496 … … 667 504 self = TNY_MAEMO_CONIC_DEVICE (device); 668 505 priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 669 506 670 507 already_online = tny_maemo_conic_device_is_online (device); 671 508 672 #ifdef DEBUG673 g_message (__FUNCTION__);674 g_message ("force online, current status is: %s", already_online ? "online" : "offline");675 #endif676 677 509 priv->forced = TRUE; 510 priv->is_online = TRUE; 678 511 679 512 /* Signal if it changed: */ 680 513 if (!already_online) 681 g_signal_emit (device, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED], 682 0, TRUE); 514 g_signal_emit (device, tny_device_signals [TNY_DEVICE_CONNECTION_CHANGED], 0, TRUE); 683 515 } 684 516 … … 689 521 TnyMaemoConicDevice *self; 690 522 TnyMaemoConicDevicePriv *priv; 691 #ifndef MAEMO_CONIC_DUMMY692 523 gboolean already_offline = FALSE; 693 #endif694 524 695 525 g_return_if_fail (TNY_IS_DEVICE(device)); … … 697 527 priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 698 528 699 #ifdef MAEMO_CONIC_DUMMY700 return;701 #else702 529 already_offline = !tny_maemo_conic_device_is_online (device); 703 530 priv->forced = TRUE; 531 priv->is_online = FALSE; 532 704 533 /* Signal if it changed: */ 705 534 if (!already_offline) 706 535 conic_emit_status (device, FALSE); 707 return; 708 #endif 536 537 return; 709 538 } 710 539 … … 714 543 g_return_val_if_fail (TNY_IS_DEVICE(self), FALSE); 715 544 716 #ifdef MAEMO_CONIC_DUMMY717 on_dummy_connection_check (self);718 #endif /* MAEMO_CONIC_DUMMY */719 720 545 return TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self)->is_online; 721 546 } … … 729 554 730 555 /* We should not have a real is_online, based on what libconic has told us: */ 556 731 557 priv->forced = FALSE; 732 558 priv->iap = NULL; 733 559 priv->is_online = dnsmasq_has_resolv (); 734 560 735 736 #ifndef MAEMO_CONIC_DUMMY737 561 priv->cnx = con_ic_connection_new (); 738 if (!priv->cnx) { 562 563 if (!priv->cnx) 739 564 g_warning ("con_ic_connection_new failed. The TnyMaemoConicDevice will be useless."); 740 }741 565 742 566 /* This might be necessary to make the connection object actually emit … … 744 568 * even when this is not set, when we explicitly try to connect. The 745 569 * signal still does not seem to be emitted. */ 746 747 570 g_object_set (priv->cnx, "automatic-connection-events", TRUE, NULL); 748 571 749 572 g_signal_connect (priv->cnx, "connection-event", 750 573 G_CALLBACK(on_connection_event), self); 751 574 752 575 /* This will get us in connected state only if there is already a connection. 753 576 * thus, this will setup our state correctly when we receive the signals. */ 754 755 577 if (!con_ic_connection_connect (priv->cnx, CON_IC_CONNECT_FLAG_AUTOMATICALLY_TRIGGERED)) 756 578 g_warning ("could not send connect dbus message"); 757 758 #endif /* MAEMO_CONIC_DUMMY */ 759 760 761 #ifdef MAEMO_CONIC_DUMMY 762 763 /* Allow debuggers to fake a connection change by setting an environment 764 * variable, which we check ever 1 second. This should match one of the 765 * fake iap IDs that we created in tny_maemo_conic_device_get_iap_list().*/ 766 767 priv->dummy_env_check_timeout = 768 g_timeout_add (1000, on_dummy_connection_check, self); 769 #endif /* MAEMO_CONIC_DUMMY */ 579 580 return; 770 581 } 771 582 … … 780 591 { 781 592 TnyMaemoConicDevice *self = g_object_new (TNY_TYPE_MAEMO_CONIC_DEVICE, NULL); 593 782 594 return TNY_DEVICE (self); 783 595 } … … 788 600 TnyMaemoConicDevicePriv *priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (obj); 789 601 790 #ifndef MAEMO_CONIC_DUMMY791 602 if (priv->cnx && CON_IC_IS_CONNECTION(priv->cnx)) { 792 if (!tny_maemo_conic_device_disconnect (TNY_MAEMO_CONIC_DEVICE(obj),priv->iap)) 793 g_warning ("failed to disconnect dbus message"); 603 tny_maemo_conic_device_disconnect (TNY_MAEMO_CONIC_DEVICE(obj),priv->iap); 794 604 g_object_unref (priv->cnx); 795 605 priv->cnx = NULL; 796 606 } 797 #else798 if (priv->dummy_env_check_timeout) {799 g_source_remove (priv->dummy_env_check_timeout);800 priv->dummy_env_check_timeout = 0;801 }802 #endif /* MAEMO_CONIC_DUMMY */803 607 804 608 if (priv->iap) { … … 806 610 priv->iap = NULL; 807 611 } 808 809 612 810 613 (*parent_class->finalize) (obj); … … 822 625 klass->force_online_func = tny_maemo_conic_device_force_online; 823 626 } 824 825 627 826 628 … … 875 677 return type; 876 678 } 679 680 static void 681 stop_loop (TnyMaemoConicDevice *self) 682 { 683 TnyMaemoConicDevicePriv *priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 684 if (priv->loop) 685 g_main_loop_quit (priv->loop); 686 return; 687 } 688 689 690 /** 691 * tny_maemo_conic_device_connect: 692 * @self: a #TnyDevice object 693 * @iap_id: the id of the Internet Access Point (IAP), or NULL for 'any; 694 * 695 * Try to connect to a specific IAP, or to any if @iap_id == NULL 696 * this calls con_ic_connection_connect(_by_id). 697 * This may show a dialog to allow the user to select a connection, or 698 * may otherwise take a significant amount of time. This function blocks until 699 * the connection has either succeeded or failed. 700 * 701 * Returns TRUE if a connection was made, FALSE otherwise. 702 **/ 703 gboolean 704 tny_maemo_conic_device_connect (TnyMaemoConicDevice *self, const gchar* iap_id) 705 { 706 TnyMaemoConicDevicePriv *priv = NULL; 707 gboolean request_failed = FALSE; 708 709 g_return_val_if_fail (TNY_IS_DEVICE(self), FALSE); 710 priv = TNY_MAEMO_CONIC_DEVICE_GET_PRIVATE (self); 711 712 g_return_val_if_fail (priv->cnx, FALSE); 713 priv->loop = g_main_loop_new(NULL, FALSE /* not running immediately. */); 714 715 if (iap_id) { 716 if (!con_ic_connection_connect_by_id (priv->cnx, iap_id, CON_IC_CONNECT_FLAG_NONE)) { 717 g_warning ("could not send connect_by_id dbus message"); 718 request_failed = TRUE; 719 } 720 } else { 721 if (!con_ic_connection_connect (priv->cnx, CON_IC_CONNECT_FLAG_NONE)) { 722 g_warning ("could not send connect dbus message"); 723 request_failed = TRUE; 724 } 725 } 726 727 if (request_failed) { 728 g_object_unref (priv->loop); 729 priv->loop = NULL; 730 } 731 732 /* Wait for the CON_IC_STATUS_CONNECTED (succeeded) or 733 * CON_IC_STATUS_DISCONNECTED event: */ 734 735 /* This is based on code found in gtk_dialog_run(): */ 736 GDK_THREADS_LEAVE(); 737 /* Run until g_main_loop_quit() is called by our signal handler. */ 738 if (priv->loop) 739 g_main_loop_run (priv->loop); 740 GDK_THREADS_ENTER(); 741 742 g_main_loop_unref (priv->loop); 743 priv->loop = NULL; 744 745 return priv->is_online; 746 } trunk/libtinymail-maemo/tny-maemo-conic-device.h
r2825 r2933 56 56 57 57 gboolean tny_maemo_conic_device_connect (TnyMaemoConicDevice *self, const gchar* iap_id); 58 typedef void (*TnyMaemoConicDeviceConnectCallback) (TnyMaemoConicDevice *self, const gchar* iap_id, gboolean canceled, GError *err, gpointer user_data); 59 void tny_maemo_conic_device_connect_async (TnyMaemoConicDevice *self, 60 const gchar* iap_id, 61  
