r7134 - in dumbhippo/trunk/client: common/hippo linux/src



Author: hp
Date: 2008-01-04 16:06:22 -0600 (Fri, 04 Jan 2008)
New Revision: 7134

Modified:
   dumbhippo/trunk/client/common/hippo/hippo-connection.c
   dumbhippo/trunk/client/common/hippo/hippo-platform.c
   dumbhippo/trunk/client/common/hippo/hippo-platform.h
   dumbhippo/trunk/client/linux/src/hippo-cookies-linux.c
   dumbhippo/trunk/client/linux/src/hippo-cookies-linux.h
   dumbhippo/trunk/client/linux/src/hippo-platform-impl.c
Log:
put a file monitor on cookie files so we instantly notice new cookies

Modified: dumbhippo/trunk/client/common/hippo/hippo-connection.c
===================================================================
--- dumbhippo/trunk/client/common/hippo/hippo-connection.c	2008-01-04 22:03:55 UTC (rev 7133)
+++ dumbhippo/trunk/client/common/hippo/hippo-connection.c	2008-01-04 22:06:22 UTC (rev 7134)
@@ -153,12 +153,14 @@
 static void     hippo_connection_stop_signin_timeout  (HippoConnection *connection);
 static void     hippo_connection_start_retry_timeout  (HippoConnection *connection);
 static void     hippo_connection_stop_retry_timeout   (HippoConnection *connection);
+static void     hippo_connection_run_signin_timeout   (HippoConnection *connection);
 static void     hippo_connection_stop_music_timeout   (HippoConnection *connection);
 static void     hippo_connection_queue_request_blocks (HippoConnection *connection);
 static void     hippo_connection_unqueue_request_blocks (HippoConnection *connection);
 static void     hippo_connection_connect              (HippoConnection *connection,
                                                        const char      *redirect_host);
 static void     hippo_connection_disconnect           (HippoConnection *connection);
+static void     hippo_connection_retry                (HippoConnection *connection);
 static void     hippo_connection_state_change         (HippoConnection *connection,
                                                        HippoState       state);
 static gboolean hippo_connection_load_auth            (HippoConnection *connection);
@@ -219,6 +221,9 @@
 static gboolean handle_data_notify (HippoConnection *connection,
                                     LmMessage       *message);
 
+static void on_cookies_maybe_changed(HippoPlatform     *platform,
+                                     gpointer           data);
+
 struct _HippoConnection {
     GObject parent;
     HippoPlatform *platform;
@@ -535,6 +540,9 @@
     
     connection->platform = platform;
     g_object_ref(connection->platform);
+
+    g_signal_connect(G_OBJECT(connection->platform), "cookies-maybe-changed",
+                     G_CALLBACK(on_cookies_maybe_changed), connection);
     
     return connection;
 }
@@ -705,6 +713,28 @@
     return connection->state == HIPPO_STATE_AUTHENTICATED;
 }
 
+static void
+on_cookies_maybe_changed(HippoPlatform     *platform,
+                         gpointer           data)
+{
+    HippoConnection *connection = HIPPO_CONNECTION(data);
+    
+    g_debug("cookies maybe changed");
+
+    /* the semantics here should be that if we had a timeout waiting to
+     * try reconnect or reauth, we should run it now, but otherwise
+     * we don't care that cookies changed.
+     *
+     * A future enhancement might disconnect if we no longer have the auth
+     * cookie, but we don't do that for now.
+     */
+    if (connection->signin_timeout_id != 0) {
+        hippo_connection_run_signin_timeout(connection);
+    } else if (connection->retry_timeout_id != 0) {
+        hippo_connection_retry(connection);
+    }
+}
+
 /* Returns whether we have the login cookie */
 gboolean
 hippo_connection_signin(HippoConnection *connection)
@@ -990,7 +1020,8 @@
     connection->signin_timeout_count += 1;
     if (connection->signin_timeout_count == SIGN_IN_INITIAL_COUNT) {
         /* Try more slowly */
-        g_source_remove (connection->signin_timeout_id);
+        if (connection->signin_timeout_id != 0) /* 0 if we were called directly */
+            g_source_remove (connection->signin_timeout_id);
         connection->signin_timeout_id = g_timeout_add (SIGN_IN_SUBSEQUENT_TIMEOUT, signin_timeout, 
                                                        connection);
         return FALSE;
@@ -999,7 +1030,15 @@
     return TRUE;
 }
 
+/* run the signin timeout immediately */
 static void
+hippo_connection_run_signin_timeout(HippoConnection *connection)
+{
+    hippo_connection_stop_signin_timeout(connection);
+    signin_timeout(connection);
+}
+
+static void
 hippo_connection_start_signin_timeout(HippoConnection *connection)
 {
     if (connection->signin_timeout_id == 0) {

Modified: dumbhippo/trunk/client/common/hippo/hippo-platform.c
===================================================================
--- dumbhippo/trunk/client/common/hippo/hippo-platform.c	2008-01-04 22:03:55 UTC (rev 7133)
+++ dumbhippo/trunk/client/common/hippo/hippo-platform.c	2008-01-04 22:06:22 UTC (rev 7134)
@@ -24,6 +24,7 @@
 
 enum {
     NETWORK_STATUS_CHANGED,
+    COOKIES_MAYBE_CHANGED,
     LAST_SIGNAL
 };
 static int signals[LAST_SIGNAL];
@@ -45,6 +46,15 @@
                           g_cclosure_marshal_VOID__INT,
                           G_TYPE_NONE, 1, G_TYPE_INT);        
         
+        signals[COOKIES_MAYBE_CHANGED] =
+            g_signal_new ("cookies-maybe-changed",
+                          HIPPO_TYPE_PLATFORM,
+                          G_SIGNAL_RUN_LAST,
+                          0,
+                          NULL, NULL,
+                          g_cclosure_marshal_VOID__VOID,
+                          G_TYPE_NONE, 0);
+        
         initialized = TRUE;   
     }
 }
@@ -304,3 +314,9 @@
 {
     g_signal_emit(G_OBJECT(platform), signals[NETWORK_STATUS_CHANGED], 0, status);
 }
+
+void
+hippo_platform_emit_cookies_maybe_changed (HippoPlatform *platform)
+{
+    g_signal_emit(G_OBJECT(platform), signals[COOKIES_MAYBE_CHANGED], 0);
+}

Modified: dumbhippo/trunk/client/common/hippo/hippo-platform.h
===================================================================
--- dumbhippo/trunk/client/common/hippo/hippo-platform.h	2008-01-04 22:03:55 UTC (rev 7133)
+++ dumbhippo/trunk/client/common/hippo/hippo-platform.h	2008-01-04 22:06:22 UTC (rev 7134)
@@ -11,7 +11,7 @@
 
 typedef struct {
     const char *name;         /* "windows" or "linux" */
-    const char *distribution; /* Not used on Window. "Fedora", "Ubuntu", etc, on Linux */
+    const char *distribution; /* Not used on Windows. "Fedora", "Ubuntu", etc, on Linux */
     const char *version;      /* May be NULL if we don't know anything better */
     const char *architecture; /* May be NULL for "unknown" */
 } HippoPlatformInfo;
@@ -157,6 +157,7 @@
 
 void               hippo_platform_emit_network_status_changed (HippoPlatform *platform,
                                                                HippoNetworkStatus status);
+void               hippo_platform_emit_cookies_maybe_changed  (HippoPlatform *platform);
 
 /* Preferences */
 HippoInstanceType hippo_platform_get_instance_type (HippoPlatform *platform);

Modified: dumbhippo/trunk/client/linux/src/hippo-cookies-linux.c
===================================================================
--- dumbhippo/trunk/client/linux/src/hippo-cookies-linux.c	2008-01-04 22:03:55 UTC (rev 7133)
+++ dumbhippo/trunk/client/linux/src/hippo-cookies-linux.c	2008-01-04 22:06:22 UTC (rev 7134)
@@ -2,7 +2,93 @@
 #include <config.h>
 #include "hippo-cookies-linux.h"
 #include <string.h>
+#include <libgnomevfs/gnome-vfs.h>
 
+typedef struct {
+    HippoCookiesMonitorFunc func;
+    void                   *data;    
+} CookieMonitor;
+
+typedef struct {
+    char *path;
+    GnomeVFSMonitorHandle *handle;
+} MonitoredCookieFile;
+
+static int cookie_monitors_serial = 0;
+static GSList *cookie_monitors = NULL;
+static GHashTable *monitored_files = NULL;
+
+static void
+cookie_monitors_notify(void)
+{
+    GSList *l;
+    int start_serial;
+        
+    start_serial = cookie_monitors_serial;
+    for (l = cookie_monitors; l != NULL; l = l->next) {
+        CookieMonitor *cm = l->data;
+
+        (* cm->func) (cm->data);
+        
+        if (start_serial != cookie_monitors_serial) {
+            /* This is not supposed to happen, the warning is here in case we
+             * ever accidentally create the bug
+             */
+            g_warning("Cookie monitor added/removed while notifying cookie monitors");
+            return;
+        }
+    }
+}
+
+static void
+on_cookie_file_changed(GnomeVFSMonitorHandle *handle,
+                       const gchar *monitor_uri,
+                       const gchar *info_uri,
+                       GnomeVFSMonitorEventType event_type,
+                       gpointer user_data)
+{
+    cookie_monitors_notify();
+}
+
+static void
+add_monitored_cookie_file(const char *path)
+{
+    MonitoredCookieFile *mcf;
+    GnomeVFSResult result;
+    
+    if (monitored_files == NULL) {
+        monitored_files = g_hash_table_new(g_str_hash, g_str_equal);
+    }
+
+    if (g_hash_table_lookup(monitored_files, path) != NULL) {
+        /* already monitored */
+        return;
+    }
+    
+    /* This is idempotent and fairly cheap, so do it here to avoid initializing
+     * gnome-vfs on application startup
+     */
+    gnome_vfs_init();
+
+    mcf = g_new0(MonitoredCookieFile, 1);
+
+    mcf->path = g_strdup(path);
+
+    result = gnome_vfs_monitor_add(&mcf->handle,
+                                   mcf->path,
+                                   GNOME_VFS_MONITOR_FILE,
+                                   on_cookie_file_changed,
+                                   NULL);
+    if (result != GNOME_VFS_OK) {
+        g_warning("Failed to monitor cookie file '%s'", mcf->path);
+        g_free(mcf->path);
+        g_free(mcf);
+        return;
+    }
+    
+    g_hash_table_replace(monitored_files, mcf->path, mcf);
+}
+
 GSList*
 hippo_load_cookies(const char *domain,
                    int         port,
@@ -22,26 +108,31 @@
                             ".gnome2/epiphany/mozilla/epiphany/cookies.txt",
                             NULL);
     hippo_cookie_locator_add_file(locator, path, HIPPO_BROWSER_EPIPHANY);
+    add_monitored_cookie_file(path);
     g_free(path);
 
     path = g_build_filename(homedir,
                             ".galeon/mozilla/galeon/cookies.txt",
                             NULL);
     hippo_cookie_locator_add_file(locator, path, HIPPO_BROWSER_GALEON);
+    add_monitored_cookie_file(path);
     g_free(path);
 
     path = g_build_filename(homedir,
                             ".mozilla/microb/cookies.txt",
                             NULL);
     hippo_cookie_locator_add_file(locator, path, HIPPO_BROWSER_MAEMO);
+    add_monitored_cookie_file(path);
     g_free(path);
     
     path = g_build_filename(homedir, ".mozilla/firefox", NULL);
     hippo_cookie_locator_add_directory(locator, path, HIPPO_BROWSER_FIREFOX);
+    add_monitored_cookie_file(path);
     g_free(path);
     
     path = g_build_filename(homedir, ".firefox", NULL);
     hippo_cookie_locator_add_directory(locator, path, HIPPO_BROWSER_FIREFOX);
+    add_monitored_cookie_file(path);
     g_free(path);
 
     cookies = hippo_cookie_locator_load_cookies(locator, domain, port, name);
@@ -54,6 +145,37 @@
     return cookies;
 }
 
+void
+hippo_cookie_monitor_add (HippoCookiesMonitorFunc  func,
+                          void                    *data)
+{
+    CookieMonitor *cm;
+
+    cm = g_new0(CookieMonitor, 1);
+    cookie_monitors = g_slist_append(cookie_monitors, cm);
+
+    ++cookie_monitors_serial;
+}
+
+void
+hippo_cookie_monitor_remove (HippoCookiesMonitorFunc  func,
+                             void                    *data)
+{
+    GSList *l;
+
+    for (l = cookie_monitors; l != NULL; l = l->next) {
+        CookieMonitor *cm = l->data;
+
+        if (cm->func == func && cm->data == data) {
+            cookie_monitors = g_slist_remove(cookie_monitors, cm);
+            ++cookie_monitors_serial;
+            return;
+        }
+    }
+
+    g_warning("Attempt to remove cookie monitor that was not found");
+}
+
 #if 0
 static void
 print_and_eat_cookies(GSList *cookies)

Modified: dumbhippo/trunk/client/linux/src/hippo-cookies-linux.h
===================================================================
--- dumbhippo/trunk/client/linux/src/hippo-cookies-linux.h	2008-01-04 22:03:55 UTC (rev 7133)
+++ dumbhippo/trunk/client/linux/src/hippo-cookies-linux.h	2008-01-04 22:06:22 UTC (rev 7134)
@@ -4,6 +4,8 @@
 
 #include <hippo/hippo-common.h>
 
+typedef void (* HippoCookiesMonitorFunc) (void *data);
+
 /* returns list of HippoCookie from the cookies.txt file we determine is relevant,
  * with the given domain, port, name
  */
@@ -11,4 +13,9 @@
                            int         port,
                            const char *name);
 
+void    hippo_cookie_monitor_add    (HippoCookiesMonitorFunc  func,
+                                     void                    *data);
+void    hippo_cookie_monitor_remove (HippoCookiesMonitorFunc  func,
+                                     void                    *data);
+
 #endif /* __HIPPO_COOKIES_LINUX_H__ */

Modified: dumbhippo/trunk/client/linux/src/hippo-platform-impl.c
===================================================================
--- dumbhippo/trunk/client/linux/src/hippo-platform-impl.c	2008-01-04 22:03:55 UTC (rev 7133)
+++ dumbhippo/trunk/client/linux/src/hippo-platform-impl.c	2008-01-04 22:06:22 UTC (rev 7134)
@@ -172,6 +172,16 @@
     }
 }
 
+static void
+on_cookie_monitor_notification(void *data)
+{
+    HippoPlatformImpl *impl;
+
+    impl = HIPPO_PLATFORM_IMPL(data);
+
+    hippo_platform_emit_cookies_maybe_changed(HIPPO_PLATFORM(impl));
+}
+
 HippoPlatform*
 hippo_platform_impl_new(HippoInstanceType instance)
 {
@@ -191,6 +201,8 @@
         g_error_free(error);
     }
     impl->network_status = HIPPO_NETWORK_STATUS_UNKNOWN;
+
+    hippo_cookie_monitor_add(on_cookie_monitor_notification, impl);
     
     return HIPPO_PLATFORM(impl);
 }
@@ -208,6 +220,8 @@
         g_object_unref(impl->system_dbus);
         impl->system_dbus = NULL;
     }
+
+    hippo_cookie_monitor_remove(on_cookie_monitor_notification, impl);
     
     G_OBJECT_CLASS(hippo_platform_impl_parent_class)->finalize(object);
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]