[epiphany/wip/ephy-sync] sync-service: Notify the user to sign in with the new password



commit bb7d45bb8356c5865128b07934cfb49d89adcc1a
Author: Gabriel Ivascu <ivascu gabriel59 gmail com>
Date:   Sun Aug 21 19:15:39 2016 +0300

    sync-service: Notify the user to sign in with the new password

 configure.ac                          |    2 +-
 embed/Makefile.am                     |    5 +
 embed/ephy-embed.c                    |   42 +++++++--
 embed/ephy-embed.h                    |   32 ++++---
 embed/ephy-fx-password-notification.c |  162 +++++++++++++++++++++++++++++++++
 embed/ephy-fx-password-notification.h |   47 ++++++++++
 embed/ephy-notification-manager.c     |  112 +++++++++++++++++++++++
 embed/ephy-notification-manager.h     |   50 ++++++++++
 src/ephy-sync-service.c               |   19 +++-
 src/ephy-window.c                     |    4 +
 10 files changed, 445 insertions(+), 30 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index c307f3f..32faa45 100644
--- a/configure.ac
+++ b/configure.ac
@@ -96,7 +96,7 @@ AC_MSG_RESULT([$enable_tests])
 
 AM_CONDITIONAL([ENABLE_TESTS],[test "$enable_tests" = "yes"])
 
-LIBGD_INIT([_view-common static])
+LIBGD_INIT([_view-common notification static])
 
 PKG_CHECK_MODULES([DEPENDENCIES], [
                  glib-2.0 >= $GLIB_REQUIRED
diff --git a/embed/Makefile.am b/embed/Makefile.am
index 8969e1b..1503ace 100644
--- a/embed/Makefile.am
+++ b/embed/Makefile.am
@@ -43,6 +43,10 @@ libephyembed_la_SOURCES = \
        ephy-file-monitor.h             \
        ephy-find-toolbar.c             \
        ephy-find-toolbar.h             \
+       ephy-fx-password-notification.c \
+       ephy-fx-password-notification.h \
+       ephy-notification-manager.c     \
+       ephy-notification-manager.h     \
        ephy-embed-prefs.c              \
        ephy-web-view.c                 \
        ephy-web-view.h                 \
@@ -60,6 +64,7 @@ libephyembed_la_CPPFLAGS = \
        -I$(top_srcdir)/lib/history         \
        -I$(top_srcdir)/lib/widgets         \
        -I$(top_builddir)/lib/widgets       \
+       -I$(top_srcdir)/libgd               \
        $(AM_CPPFLAGS)
 
 libephyembed_la_CFLAGS = \
diff --git a/embed/ephy-embed.c b/embed/ephy-embed.c
index 4e5ce46..e003e4f 100644
--- a/embed/ephy-embed.c
+++ b/embed/ephy-embed.c
@@ -29,6 +29,7 @@
 #include "ephy-embed-shell.h"
 #include "ephy-embed-utils.h"
 #include "ephy-find-toolbar.h"
+#include "ephy-notification-manager.h"
 #include "ephy-prefs.h"
 #include "ephy-settings.h"
 #include "ephy-string.h"
@@ -60,6 +61,7 @@ struct _EphyEmbed {
   GtkPaned *paned;
   WebKitWebView *web_view;
   GSList *destroy_on_transition_list;
+  GtkWidget *overlay;
   GtkWidget *floating_bar;
   GtkWidget *progress;
   GtkWidget *fullscreen_message_label;
@@ -708,7 +710,6 @@ ephy_embed_constructed (GObject *object)
   EphyEmbedShell *shell = ephy_embed_shell_get_default ();
   GtkWidget *paned;
   WebKitWebInspector *inspector;
-  GtkWidget *overlay;
 
   g_signal_connect (shell, "window-restored",
                     G_CALLBACK (ephy_embed_restored_window_cb), embed);
@@ -717,12 +718,12 @@ ephy_embed_constructed (GObject *object)
                     G_CALLBACK (ephy_embed_mapped_cb), NULL);
 
   /* Skeleton */
-  overlay = gtk_overlay_new ();
+  embed->overlay = gtk_overlay_new ();
 
-  gtk_widget_add_events (overlay,
+  gtk_widget_add_events (embed->overlay,
                          GDK_ENTER_NOTIFY_MASK |
                          GDK_LEAVE_NOTIFY_MASK);
-  gtk_container_add (GTK_CONTAINER (overlay), GTK_WIDGET (embed->web_view));
+  gtk_container_add (GTK_CONTAINER (embed->overlay), GTK_WIDGET (embed->web_view));
 
   /* Floating message popup for fullscreen mode. */
   embed->fullscreen_message_label = gtk_label_new (NULL);
@@ -730,7 +731,7 @@ ephy_embed_constructed (GObject *object)
   gtk_widget_set_halign (embed->fullscreen_message_label, GTK_ALIGN_CENTER);
   gtk_widget_set_valign (embed->fullscreen_message_label, GTK_ALIGN_CENTER);
   gtk_widget_set_no_show_all (embed->fullscreen_message_label, TRUE);
-  gtk_overlay_add_overlay (GTK_OVERLAY (overlay), embed->fullscreen_message_label);
+  gtk_overlay_add_overlay (GTK_OVERLAY (embed->overlay), embed->fullscreen_message_label);
   ephy_embed_set_fullscreen_message (embed, FALSE);
 
   /* statusbar is hidden by default */
@@ -739,14 +740,14 @@ ephy_embed_constructed (GObject *object)
   gtk_widget_set_valign (embed->floating_bar, GTK_ALIGN_END);
   gtk_widget_set_no_show_all (embed->floating_bar, TRUE);
 
-  gtk_overlay_add_overlay (GTK_OVERLAY (overlay), embed->floating_bar);
+  gtk_overlay_add_overlay (GTK_OVERLAY (embed->overlay), embed->floating_bar);
 
   embed->progress = gtk_progress_bar_new ();
   gtk_style_context_add_class (gtk_widget_get_style_context (embed->progress),
                                GTK_STYLE_CLASS_OSD);
   gtk_widget_set_halign (embed->progress, GTK_ALIGN_FILL);
   gtk_widget_set_valign (embed->progress, GTK_ALIGN_START);
-  gtk_overlay_add_overlay (GTK_OVERLAY (overlay), embed->progress);
+  gtk_overlay_add_overlay (GTK_OVERLAY (embed->overlay), embed->progress);
 
   embed->find_toolbar = ephy_find_toolbar_new (embed->web_view);
   g_signal_connect (embed->find_toolbar, "close",
@@ -761,7 +762,7 @@ ephy_embed_constructed (GObject *object)
 
   embed->progress_update_handler_id = g_signal_connect (embed->web_view, "notify::estimated-load-progress",
                                                         G_CALLBACK (progress_update), object);
-  gtk_paned_pack1 (GTK_PANED (paned), GTK_WIDGET (overlay),
+  gtk_paned_pack1 (GTK_PANED (paned), GTK_WIDGET (embed->overlay),
                    TRUE, FALSE);
 
   gtk_box_pack_start (GTK_BOX (embed),
@@ -957,3 +958,28 @@ ephy_embed_inspector_is_loaded (EphyEmbed *embed)
 
   return embed->inspector_loaded;
 }
+
+void
+ephy_embed_attach_notification_manager (EphyEmbed *embed)
+{
+  EphyNotificationManager *manager;
+
+  g_return_if_fail (EPHY_IS_EMBED (embed));
+
+  manager = ephy_notification_manager_dup_singleton ();
+  gtk_overlay_add_overlay (GTK_OVERLAY (embed->overlay), GTK_WIDGET (manager));
+
+  if (ephy_notification_manager_get_children_num (manager) == 0)
+    gtk_widget_hide (GTK_WIDGET (manager));
+}
+
+void
+ephy_embed_detach_notification_manager (EphyEmbed *embed)
+{
+  EphyNotificationManager *manager;
+
+  g_return_if_fail (EPHY_IS_EMBED (embed));
+
+  manager = ephy_notification_manager_dup_singleton ();
+  gtk_container_remove (GTK_CONTAINER (embed->overlay), GTK_WIDGET (manager));
+}
diff --git a/embed/ephy-embed.h b/embed/ephy-embed.h
index 22f85bf..4da54dd 100644
--- a/embed/ephy-embed.h
+++ b/embed/ephy-embed.h
@@ -31,21 +31,23 @@ G_BEGIN_DECLS
 
 G_DECLARE_FINAL_TYPE (EphyEmbed, ephy_embed, EPHY, EMBED, GtkBox)
 
-EphyWebView*     ephy_embed_get_web_view             (EphyEmbed  *embed);
-EphyFindToolbar* ephy_embed_get_find_toolbar         (EphyEmbed  *embed);
-void             ephy_embed_add_top_widget           (EphyEmbed  *embed,
-                                                      GtkWidget  *widget,
-                                                      gboolean    destroy_on_transition);
-void             ephy_embed_remove_top_widget        (EphyEmbed  *embed,
-                                                      GtkWidget  *widget);
-void             ephy_embed_entering_fullscreen      (EphyEmbed *embed);
-void             ephy_embed_leaving_fullscreen       (EphyEmbed *embed);
-void             ephy_embed_set_delayed_load_request (EphyEmbed *embed,
-                                                      WebKitURIRequest          *request,
-                                                      WebKitWebViewSessionState *state);
-gboolean         ephy_embed_has_load_pending         (EphyEmbed *embed);
-gboolean         ephy_embed_inspector_is_loaded      (EphyEmbed *embed);
-const char      *ephy_embed_get_title                (EphyEmbed *embed);
+EphyWebView*     ephy_embed_get_web_view                (EphyEmbed  *embed);
+EphyFindToolbar* ephy_embed_get_find_toolbar            (EphyEmbed  *embed);
+void             ephy_embed_add_top_widget              (EphyEmbed  *embed,
+                                                         GtkWidget  *widget,
+                                                         gboolean    destroy_on_transition);
+void             ephy_embed_remove_top_widget           (EphyEmbed  *embed,
+                                                         GtkWidget  *widget);
+void             ephy_embed_entering_fullscreen         (EphyEmbed *embed);
+void             ephy_embed_leaving_fullscreen          (EphyEmbed *embed);
+void             ephy_embed_set_delayed_load_request    (EphyEmbed *embed,
+                                                         WebKitURIRequest          *request,
+                                                         WebKitWebViewSessionState *state);
+gboolean         ephy_embed_has_load_pending            (EphyEmbed *embed);
+gboolean         ephy_embed_inspector_is_loaded         (EphyEmbed *embed);
+const char      *ephy_embed_get_title                   (EphyEmbed *embed);
+void             ephy_embed_attach_notification_manager (EphyEmbed *embed);
+void             ephy_embed_detach_notification_manager (EphyEmbed *embed);
 
 G_END_DECLS
 
diff --git a/embed/ephy-fx-password-notification.c b/embed/ephy-fx-password-notification.c
new file mode 100644
index 0000000..9796b46
--- /dev/null
+++ b/embed/ephy-fx-password-notification.c
@@ -0,0 +1,162 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2016 Gabriel Ivascu <ivascu gabriel59 gmail com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include "ephy-fx-password-notification.h"
+
+#include "ephy-notification-manager.h"
+
+#include <glib/gi18n.h>
+
+struct _EphyFxPasswordNotification {
+  GtkGrid                  parent_instance;
+
+  GtkWidget               *note;
+  GtkWidget               *suggestion;
+
+  const char              *user;
+};
+
+struct _EphyFxPasswordNotificationClass {
+  GtkGridClass parent_class;
+};
+
+enum {
+  PROP_0,
+  PROP_USER
+};
+
+G_DEFINE_TYPE (EphyFxPasswordNotification, ephy_fx_password_notification, GTK_TYPE_GRID);
+
+static void
+ephy_fx_password_notification_constructed (GObject *object)
+{
+  EphyFxPasswordNotification *self = EPHY_FX_PASSWORD_NOTIFICATION (object);
+  char *text;
+
+  text = g_strdup_printf (_("We noticed that the password of your Firefox "
+                            "Account <b>%s</b> has been changed."),
+                          self->user);
+  gtk_label_set_markup (GTK_LABEL (self->note), text);
+  gtk_label_set_text (GTK_LABEL (self->suggestion),
+                      _("Please visit Preferences and sign in with the new "
+                        "password to continue the sync process."));
+  g_free (text);
+
+  G_OBJECT_CLASS (ephy_fx_password_notification_parent_class)->constructed (object);
+}
+
+static void
+ephy_fx_password_notification_dispose (GObject *object)
+{
+  EphyFxPasswordNotification *self = EPHY_FX_PASSWORD_NOTIFICATION (object);
+
+  g_clear_pointer (&self->user, g_free);
+
+  G_OBJECT_CLASS (ephy_fx_password_notification_parent_class)->dispose (object);
+}
+
+static void
+ephy_fx_password_notification_set_property (GObject      *object,
+                                            guint         prop_id,
+                                            const GValue *value,
+                                            GParamSpec   *pspec)
+{
+  EphyFxPasswordNotification *self = EPHY_FX_PASSWORD_NOTIFICATION (object);
+
+  switch (prop_id) {
+    case PROP_USER:
+      self->user = g_value_dup_string (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+ephy_fx_password_notification_get_property (GObject      *object,
+                                            guint         prop_id,
+                                            GValue       *value,
+                                            GParamSpec   *pspec)
+{
+  EphyFxPasswordNotification *self = EPHY_FX_PASSWORD_NOTIFICATION (object);
+
+  switch (prop_id) {
+    case PROP_USER:
+      g_value_set_string (value, self->user);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+ephy_fx_password_notification_init (EphyFxPasswordNotification *self)
+{
+  g_return_if_fail (EPHY_IS_FX_PASSWORD_NOTIFICATION (self));
+
+  self->note = gtk_label_new (NULL);
+  gtk_widget_set_halign (self->note, GTK_ALIGN_CENTER);
+  gtk_widget_set_hexpand (self->note, TRUE);
+  gtk_grid_attach (GTK_GRID (self), self->note, 0, 0, 1, 1);
+
+  self->suggestion = gtk_label_new (NULL);
+  gtk_widget_set_halign (self->suggestion, GTK_ALIGN_CENTER);
+  gtk_widget_set_hexpand (self->suggestion, TRUE);
+  gtk_grid_attach (GTK_GRID (self), self->suggestion, 0, 1, 1, 1);
+}
+
+static void
+ephy_fx_password_notification_class_init (EphyFxPasswordNotificationClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->constructed = ephy_fx_password_notification_constructed;
+  object_class->dispose = ephy_fx_password_notification_dispose;
+  object_class->set_property = ephy_fx_password_notification_set_property;
+  object_class->get_property = ephy_fx_password_notification_get_property;
+
+  g_object_class_install_property (object_class,
+                                   PROP_USER,
+                                   g_param_spec_string ("user",
+                                                        "User",
+                                                        "The email of the signed in user",
+                                                        "",
+                                                        G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
+}
+
+EphyFxPasswordNotification *
+ephy_fx_password_notification_new (const char *user)
+{
+  return g_object_new (EPHY_TYPE_FX_PASSWORD_NOTIFICATION,
+                       "column-spacing", 12,
+                       "orientation", GTK_ORIENTATION_HORIZONTAL,
+                       "user", user,
+                       NULL);
+}
+
+void
+ephy_fx_password_notification_show (EphyFxPasswordNotification *self)
+{
+  g_return_if_fail (EPHY_IS_FX_PASSWORD_NOTIFICATION (self));
+
+  ephy_notification_manager_add_notification (ephy_notification_manager_dup_singleton (),
+                                              GTK_WIDGET (self));
+}
diff --git a/embed/ephy-fx-password-notification.h b/embed/ephy-fx-password-notification.h
new file mode 100644
index 0000000..0d28aab
--- /dev/null
+++ b/embed/ephy-fx-password-notification.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2016 Gabriel Ivascu <ivascu gabriel59 gmail com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef EPHY_FX_PASSWORD_NOTIFICATION_H
+#define EPHY_FX_PASSWORD_NOTIFICATION_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_FX_PASSWORD_NOTIFICATION (ephy_fx_password_notification_get_type ())
+
+#define EPHY_FX_PASSWORD_NOTIFICATION(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+   EPHY_TYPE_FX_PASSWORD_NOTIFICATION, EphyFxPasswordNotification))
+
+#define EPHY_IS_FX_PASSWORD_NOTIFICATION(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+   EPHY_TYPE_FX_PASSWORD_NOTIFICATION))
+
+typedef struct _EphyFxPasswordNotification      EphyFxPasswordNotification;
+typedef struct _EphyFxPasswordNotificationClass EphyFxPasswordNotificationClass;
+
+GType                       ephy_fx_password_notification_get_type (void) G_GNUC_CONST;
+
+EphyFxPasswordNotification *ephy_fx_password_notification_new      (const char *user);
+
+void                        ephy_fx_password_notification_show     (EphyFxPasswordNotification *self);
+
+G_END_DECLS
+
+#endif
diff --git a/embed/ephy-notification-manager.c b/embed/ephy-notification-manager.c
new file mode 100644
index 0000000..046ff38
--- /dev/null
+++ b/embed/ephy-notification-manager.c
@@ -0,0 +1,112 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2016 Gabriel Ivascu <ivascu gabriel59 gmail com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include "ephy-notification-manager.h"
+
+struct _EphyNotificationManager {
+  GdNotification  parent_instance;
+
+  GtkWidget      *grid;
+};
+
+struct _EphyNotificationManagerClass {
+  GdNotificationClass parent_class;
+};
+
+G_DEFINE_TYPE (EphyNotificationManager, ephy_notification_manager, GD_TYPE_NOTIFICATION);
+
+static GObject *
+ephy_notification_manager_constructor (GType                  type,
+                                       guint                  n_construct_params,
+                                       GObjectConstructParam *construct_params)
+{
+  static GObject *self = NULL;
+
+  if (self == NULL) {
+    self = G_OBJECT_CLASS (ephy_notification_manager_parent_class)->constructor (type,
+                                                                                 n_construct_params,
+                                                                                 construct_params);
+    g_object_add_weak_pointer (self, (gpointer) &self);
+  }
+
+  return g_object_ref_sink (self);
+}
+
+static void
+ephy_notification_manager_dispose (GObject *object)
+{
+  EphyNotificationManager *self = EPHY_NOTIFICATION_MANAGER (object);
+
+  if (ephy_notification_manager_get_children_num (self) > 0)
+    g_list_free (gtk_container_get_children (GTK_CONTAINER (self->grid)));
+
+  G_OBJECT_CLASS (ephy_notification_manager_parent_class)->dispose (object);
+}
+
+static void
+ephy_notification_manager_init (EphyNotificationManager *self)
+{
+  g_return_if_fail (EPHY_IS_NOTIFICATION_MANAGER (self));
+
+  gtk_widget_set_halign (GTK_WIDGET (self), GTK_ALIGN_CENTER);
+  gtk_widget_set_valign (GTK_WIDGET (self), GTK_ALIGN_START);
+  gtk_widget_set_visible (GTK_WIDGET (self), TRUE);
+
+  self->grid = gtk_grid_new ();
+  gtk_orientable_set_orientation (GTK_ORIENTABLE (self->grid), GTK_ORIENTATION_VERTICAL);
+  gtk_grid_set_row_spacing (GTK_GRID (self->grid), 6);
+  gtk_container_add (GTK_CONTAINER (self), self->grid);
+}
+
+static void
+ephy_notification_manager_class_init (EphyNotificationManagerClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->constructor = ephy_notification_manager_constructor;
+  object_class->dispose = ephy_notification_manager_dispose;
+}
+
+EphyNotificationManager *
+ephy_notification_manager_dup_singleton (void)
+{
+  return g_object_new (EPHY_TYPE_NOTIFICATION_MANAGER,
+                       "show-close-button", TRUE,
+                       "timeout", -1,
+                       NULL);
+}
+
+void
+ephy_notification_manager_add_notification (EphyNotificationManager *self,
+                                            GtkWidget               *notification)
+{
+  g_return_if_fail (EPHY_IS_NOTIFICATION_MANAGER (self));
+  g_return_if_fail (GTK_IS_WIDGET (notification));
+
+  gtk_container_add (GTK_CONTAINER (self->grid), notification);
+  gtk_widget_show_all (GTK_WIDGET (self));
+}
+
+guint
+ephy_notification_manager_get_children_num (EphyNotificationManager *self)
+{
+  g_return_val_if_fail (EPHY_IS_NOTIFICATION_MANAGER (self), 0);
+
+  return g_list_length (gtk_container_get_children (GTK_CONTAINER (self->grid)));
+}
diff --git a/embed/ephy-notification-manager.h b/embed/ephy-notification-manager.h
new file mode 100644
index 0000000..3b3424f
--- /dev/null
+++ b/embed/ephy-notification-manager.h
@@ -0,0 +1,50 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2016 Gabriel Ivascu <ivascu gabriel59 gmail com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef EPHY_NOTIFICATION_MANAGER_H
+#define EPHY_NOTIFICATION_MANAGER_H
+
+#include <libgd/gd.h>
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_NOTIFICATION_MANAGER (ephy_notification_manager_get_type ())
+
+#define EPHY_NOTIFICATION_MANAGER(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+   EPHY_TYPE_NOTIFICATION_MANAGER, EphyNotificationManager))
+
+#define EPHY_IS_NOTIFICATION_MANAGER(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+   EPHY_TYPE_NOTIFICATION_MANAGER))
+
+typedef struct _EphyNotificationManager      EphyNotificationManager;
+typedef struct _EphyNotificationManagerClass EphyNotificationManagerClass;
+
+GType                    ephy_notification_manager_get_type         (void) G_GNUC_CONST;
+
+EphyNotificationManager *ephy_notification_manager_dup_singleton    (void);
+
+void                     ephy_notification_manager_add_notification (EphyNotificationManager *self,
+                                                                     GtkWidget               *notification);
+
+guint                    ephy_notification_manager_get_children_num (EphyNotificationManager *self);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ephy-sync-service.c b/src/ephy-sync-service.c
index c9d8d16..cd263a2 100644
--- a/src/ephy-sync-service.c
+++ b/src/ephy-sync-service.c
@@ -22,6 +22,7 @@
 #include "ephy-bookmark.h"
 #include "ephy-bookmarks-manager.h"
 #include "ephy-debug.h"
+#include "ephy-fx-password-notification.h"
 #include "ephy-settings.h"
 #include "ephy-shell.h"
 #include "ephy-sync-crypto.h"
@@ -363,12 +364,6 @@ obtain_storage_credentials_response_cb (SoupSession *session,
   json_parser_load_from_data (parser, msg->response_body->data, -1, NULL);
   json = json_node_get_object (json_parser_get_root (parser));
 
-  /* FIXME: Since a new Firefox Account password means a new kB, and a new kB
-   * means a new "X-Client-State" header, this will fail with a 401 error status
-   * code and an "invalid-client-state" status string if the user has changed his
-   * password since the last time he signed in. If this happens, the user needs
-   * to be asked to sign in again with the new password.
-   */
   if (msg->status_code == 200) {
     service->storage_endpoint = g_strdup (json_object_get_string_member (json, "api_endpoint"));
     service->storage_credentials_id = g_strdup (json_object_get_string_member (json, "id"));
@@ -445,6 +440,7 @@ obtain_signed_certificate_response_cb (SoupSession *session,
 {
   StorageServerRequestAsyncData *data;
   EphySyncService *service;
+  EphyFxPasswordNotification *notification;
   JsonParser *parser;
   JsonObject *json;
   const char *certificate;
@@ -456,6 +452,17 @@ obtain_signed_certificate_response_cb (SoupSession *session,
   json_parser_load_from_data (parser, msg->response_body->data, -1, NULL);
   json = json_node_get_object (json_parser_get_root (parser));
 
+  /* Since a new Firefox Account password implies new tokens, this will fail
+   * with an error code 110 (Invalid authentication token in request signature)
+   * if the user has changed his password since the last time he signed in.
+   * When this happens, notify the user to sign in with the new password. */
+  if (msg->status_code == 401 && json_object_get_int_member (json, "errno") == 110) {
+    notification = ephy_fx_password_notification_new (ephy_sync_service_get_user_email (service));
+    ephy_fx_password_notification_show (notification);
+    storage_server_request_async_data_free (data);
+    goto out;
+  }
+
   if (msg->status_code != 200) {
     g_warning ("FxA server errno: %ld, errmsg: %s",
                json_object_get_int_member (json, "errno"),
diff --git a/src/ephy-window.c b/src/ephy-window.c
index 6e77bd3..dd68654 100644
--- a/src/ephy-window.c
+++ b/src/ephy-window.c
@@ -2075,6 +2075,8 @@ ephy_window_connect_active_embed (EphyWindow *window)
   view = ephy_embed_get_web_view (embed);
   web_view = EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed);
 
+  ephy_embed_attach_notification_manager (window->active_embed);
+
   sync_tab_security (view, NULL, window);
   sync_tab_document_type (view, NULL, window);
   sync_tab_load_status (view, WEBKIT_LOAD_STARTED, window);
@@ -2155,6 +2157,8 @@ ephy_window_disconnect_active_embed (EphyWindow *window)
   web_view = EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed);
   view = EPHY_WEB_VIEW (web_view);
 
+  ephy_embed_detach_notification_manager (window->active_embed);
+
   g_signal_handlers_disconnect_by_func (web_view,
                                         G_CALLBACK (sync_tab_zoom),
                                         window);


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