[epiphany/wip/missing-codecs: 6/8] Allow sites to request access to webcam/microphone



commit 81233eb6b7184d74d713aae6806b73a709cca3c0
Author: Michael Catanzaro <mcatanzaro gnome org>
Date:   Sun Nov 6 21:18:17 2016 -0600

    Allow sites to request access to webcam/microphone
    
    This is not tested at all since I don't want to context switch to my
    laptop. It probably works. Users should complain if not.

 data/org.gnome.epiphany.host.gschema.xml |   10 ++++
 embed/ephy-web-view.c                    |   86 +++++++++++++++++++++++-------
 lib/ephy-hosts-manager.c                 |   44 +++++++++++++++
 lib/ephy-hosts-manager.h                 |    4 +-
 4 files changed, 123 insertions(+), 21 deletions(-)
---
diff --git a/data/org.gnome.epiphany.host.gschema.xml b/data/org.gnome.epiphany.host.gschema.xml
index 4f8813a..6b53e59 100644
--- a/data/org.gnome.epiphany.host.gschema.xml
+++ b/data/org.gnome.epiphany.host.gschema.xml
@@ -6,6 +6,11 @@
   </enum>
 
   <schema id="org.gnome.Epiphany.host" gettext-domain="">
+    <key name="audio-device-permission" enum="org.gnome.Epiphany.host.permissions">
+      <default>"undecided"</default>
+      <summary>Decision to apply when microphone permission is requested for this host</summary>
+      <description>This option is used to save whether a given host has been given permission to access the 
user's microphone. The 'undecided' default means the browser needs to ask the user for permission, while 
'allow' and 'deny' tell it to automatically make the decision upon request.</description>
+    </key>
     <key name="geolocation-permission" enum="org.gnome.Epiphany.host.permissions">
       <default>"undecided"</default>
       <summary>Decision to apply when geolocation permission is requested for this host</summary>
@@ -21,5 +26,10 @@
       <summary>Decision to apply when save password permission is requested for this host</summary>
       <description>This option is used to save whether a given host has been given permission to save 
passwords. The 'undecided' default means the browser needs to ask the user for permission, while 'allow' and 
'deny' tell it to automatically make the decision upon request.</description>
     </key>
+    <key name="video-device-permission" enum="org.gnome.Epiphany.host.permissions">
+      <default>"undecided"</default>
+      <summary>Decision to apply when webcam permission is requested for this host</summary>
+      <description>This option is used to save whether a given host has been given permission to access the 
user's webcam. The 'undecided' default means the browser needs to ask the user for permission, while 'allow' 
and 'deny' tell it to automatically make the decision upon request.</description>
+    </key>
   </schema>
 </schemalist>
diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c
index 8c42f4a..90360e5 100644
--- a/embed/ephy-web-view.c
+++ b/embed/ephy-web-view.c
@@ -98,6 +98,8 @@ struct _EphyWebView {
 
   GtkWidget *geolocation_info_bar;
   GtkWidget *notification_info_bar;
+  GtkWidget *microphone_info_bar;
+  GtkWidget *webcam_info_bar;
   GtkWidget *password_info_bar;
 
   EphyHistoryService *history_service;
@@ -1258,6 +1260,7 @@ decide_on_permission_request (GtkWidget               *info_bar,
                               PermissionRequestData   *data)
 {
   const char *address;
+  EphyHostPermissionType permission_type;
 
   switch (response) {
     case GTK_RESPONSE_YES:
@@ -1268,25 +1271,33 @@ decide_on_permission_request (GtkWidget               *info_bar,
       break;
   }
 
+  if (WEBKIT_IS_GEOLOCATION_PERMISSION_REQUEST (data->request)) {
+    permission_type = EPHY_HOST_PERMISSION_TYPE_ACCESS_LOCATION;
+  } else if (WEBKIT_IS_NOTIFICATION_PERMISSION_REQUEST (data->request)) {
+    permission_type = EPHY_HOST_PERMISSION_TYPE_SHOW_NOTIFICATIONS;
+  } else if (WEBKIT_IS_USER_MEDIA_PERMISSION_REQUEST (data->request)) {
+    if (webkit_user_media_permission_is_for_video_device (WEBKIT_USER_MEDIA_PERMISSION_REQUEST 
(data->request)))
+      permission_type = EPHY_HOST_PERMISSION_TYPE_ACCESS_WEBCAM;
+    else
+      permission_type = EPHY_HOST_PERMISSION_TYPE_ACCESS_MICROPHONE;
+  } else {
+    g_assert_not_reached ();
+  }
+
   address = ephy_web_view_get_address (data->web_view);
 
-  if ((WEBKIT_IS_NOTIFICATION_PERMISSION_REQUEST (data->request) ||
-       WEBKIT_IS_GEOLOCATION_PERMISSION_REQUEST (data->request)) &&
-      response != GTK_RESPONSE_NONE &&
-      ephy_embed_utils_address_has_web_scheme (address)) {
+  if (response != GTK_RESPONSE_NONE && ephy_embed_utils_address_has_web_scheme (address)) {
     EphyEmbedShell *shell;
     EphyHostsManager *hosts_manager;
 
     shell = ephy_embed_shell_get_default ();
     hosts_manager = ephy_embed_shell_get_hosts_manager (shell);
 
-    ephy_hosts_manager_set_permission_for_address (
-      hosts_manager,
-      WEBKIT_IS_GEOLOCATION_PERMISSION_REQUEST (data->request) ? EPHY_HOST_PERMISSION_TYPE_ACCESS_LOCATION
-                                                               : 
EPHY_HOST_PERMISSION_TYPE_SHOW_NOTIFICATIONS,
-      address,
-      response == GTK_RESPONSE_YES ? EPHY_HOST_PERMISSION_ALLOW
-                                   : EPHY_HOST_PERMISSION_DENY);
+    ephy_hosts_manager_set_permission_for_address (hosts_manager,
+                                                   permission_type,
+                                                   address,
+                                                   response == GTK_RESPONSE_YES ? EPHY_HOST_PERMISSION_ALLOW
+                                                                                : EPHY_HOST_PERMISSION_DENY);
   }
 
   gtk_widget_destroy (info_bar);
@@ -1296,7 +1307,8 @@ decide_on_permission_request (GtkWidget               *info_bar,
 
 static void
 show_permission_request_info_bar (WebKitWebView           *web_view,
-                                  WebKitPermissionRequest *decision)
+                                  WebKitPermissionRequest *decision,
+                                  EphyHostPermissionType   permission_type)
 {
   PermissionRequestData *data;
   GtkWidget *info_bar;
@@ -1317,14 +1329,30 @@ show_permission_request_info_bar (WebKitWebView           *web_view,
   /* Label */
   host = ephy_string_get_host_name (webkit_web_view_get_uri (web_view));
 
-  if (WEBKIT_IS_GEOLOCATION_PERMISSION_REQUEST (decision)) {
+  switch (permission_type) {
+  case EPHY_HOST_PERMISSION_TYPE_SHOW_NOTIFICATIONS:
+    /* Translators: Notification policy for a specific site. */
+    message = g_markup_printf_escaped (_("The page at <b>%s</b> wants to show desktop notifications."),
+                                       host);
+    break;
+  case EPHY_HOST_PERMISSION_TYPE_ACCESS_LOCATION:
     /* Translators: Geolocation policy for a specific site. */
     message = g_markup_printf_escaped (_("The page at <b>%s</b> wants to know your location."),
                                        host);
-  } else {
-    /* Translators: Notification policy for a specific site. */
-    message = g_markup_printf_escaped (_("The page at <b>%s</b> wants to show desktop notifications."),
+    break;
+  case EPHY_HOST_PERMISSION_TYPE_ACCESS_MICROPHONE:
+    /* Translators: Microphone policy for a specific site. */
+    message = g_markup_printf_escaped (_("The page at <b>%s</b> wants to use your microphone."),
                                        host);
+    break;
+  case EPHY_HOST_PERMISSION_TYPE_ACCESS_WEBCAM:
+    /* Translators: Webcam policy for a specific site. */
+    message = g_markup_printf_escaped (_("The page at <b>%s</b> wants to use your webcam."),
+                                       host);
+    break;
+  case EPHY_HOST_PERMISSION_TYPE_SAVE_PASSWORD:
+  default:
+    g_assert_not_reached ();
   }
 
   g_free (host);
@@ -1349,10 +1377,23 @@ show_permission_request_info_bar (WebKitWebView           *web_view,
                     G_CALLBACK (decide_on_permission_request),
                     data);
 
-  if (WEBKIT_IS_GEOLOCATION_PERMISSION_REQUEST (decision))
-    ephy_web_view_track_info_bar (info_bar, &EPHY_WEB_VIEW (web_view)->geolocation_info_bar);
-  else
+  switch (permission_type) {
+  case EPHY_HOST_PERMISSION_TYPE_SHOW_NOTIFICATIONS:
     ephy_web_view_track_info_bar (info_bar, &EPHY_WEB_VIEW (web_view)->notification_info_bar);
+    break;
+  case EPHY_HOST_PERMISSION_TYPE_ACCESS_LOCATION:
+    ephy_web_view_track_info_bar (info_bar, &EPHY_WEB_VIEW (web_view)->geolocation_info_bar);
+    break;
+  case EPHY_HOST_PERMISSION_TYPE_ACCESS_MICROPHONE:
+    ephy_web_view_track_info_bar (info_bar, &EPHY_WEB_VIEW (web_view)->microphone_info_bar);
+    break;
+  case EPHY_HOST_PERMISSION_TYPE_ACCESS_WEBCAM:
+    ephy_web_view_track_info_bar (info_bar, &EPHY_WEB_VIEW (web_view)->webcam_info_bar);
+    break;
+  case EPHY_HOST_PERMISSION_TYPE_SAVE_PASSWORD:
+  default:
+    g_assert_not_reached ();
+  }
 
   ephy_embed_add_top_widget (EPHY_GET_EMBED_FROM_EPHY_WEB_VIEW (web_view),
                              info_bar, TRUE);
@@ -1379,6 +1420,11 @@ permission_request_cb (WebKitWebView           *web_view,
       return TRUE;
     }
     permission_type = EPHY_HOST_PERMISSION_TYPE_SHOW_NOTIFICATIONS;
+  } else if (WEBKIT_IS_USER_MEDIA_PERMISSION_REQUEST (decision)) {
+    if (webkit_user_media_permission_is_for_video_device (WEBKIT_USER_MEDIA_PERMISSION_REQUEST (decision)))
+      permission_type = EPHY_HOST_PERMISSION_TYPE_ACCESS_WEBCAM;
+    else
+      permission_type = EPHY_HOST_PERMISSION_TYPE_ACCESS_MICROPHONE;
   } else {
     return FALSE;
   }
@@ -1401,7 +1447,7 @@ permission_request_cb (WebKitWebView           *web_view,
     break;
   }
 
-  show_permission_request_info_bar (web_view, decision);
+  show_permission_request_info_bar (web_view, decision, permission_type);
   return TRUE;
 }
 
diff --git a/lib/ephy-hosts-manager.c b/lib/ephy-hosts-manager.c
index cb3b06b..5afc23c 100644
--- a/lib/ephy-hosts-manager.c
+++ b/lib/ephy-hosts-manager.c
@@ -186,6 +186,40 @@ ephy_hosts_manager_set_geolocation_permission_for_address (EphyHostsManager   *m
   g_settings_set_enum (settings, "geolocation-permission", permission);
 }
 
+static EphyHostPermission
+ephy_hosts_manager_get_audio_device_permission_for_address (EphyHostsManager *manager,
+                                                            const char       *address)
+{
+  GSettings *settings = ephy_hosts_manager_get_settings_for_address (manager, address);
+  return g_settings_get_enum (settings, "audio-device-permission");
+}
+
+static void
+ephy_hosts_manager_set_audio_device_permission_for_address (EphyHostsManager   *manager,
+                                                            const char         *address,
+                                                            EphyHostPermission  permission)
+{
+  GSettings *settings = ephy_hosts_manager_get_settings_for_address (manager, address);
+  g_settings_set_enum (settings, "audio-device-permission", permission);
+}
+
+static EphyHostPermission
+ephy_hosts_manager_get_video_device_permission_for_address (EphyHostsManager *manager,
+                                                            const char       *address)
+{
+  GSettings *settings = ephy_hosts_manager_get_settings_for_address (manager, address);
+  return g_settings_get_enum (settings, "video-device-permission");
+}
+
+static void
+ephy_hosts_manager_set_video_device_permission_for_address (EphyHostsManager   *manager,
+                                                            const char         *address,
+                                                            EphyHostPermission  permission)
+{
+  GSettings *settings = ephy_hosts_manager_get_settings_for_address (manager, address);
+  g_settings_set_enum (settings, "video-device-permission", permission);
+}
+
 EphyHostPermission
 ephy_hosts_manager_get_permission_for_address (EphyHostsManager       *manager,
                                                EphyHostPermissionType  type,
@@ -198,6 +232,10 @@ ephy_hosts_manager_get_permission_for_address (EphyHostsManager       *manager,
     return ephy_hosts_manager_get_save_password_permission_for_address (manager, address);
   case EPHY_HOST_PERMISSION_TYPE_ACCESS_LOCATION:
     return ephy_hosts_manager_get_geolocation_permission_for_address (manager, address);
+  case EPHY_HOST_PERMISSION_TYPE_ACCESS_MICROPHONE:
+    return ephy_hosts_manager_get_audio_device_permission_for_address (manager, address);
+  case EPHY_HOST_PERMISSION_TYPE_ACCESS_WEBCAM:
+    return ephy_hosts_manager_get_video_device_permission_for_address (manager, address);
   default:
     g_assert_not_reached ();
   }
@@ -219,6 +257,12 @@ ephy_hosts_manager_set_permission_for_address (EphyHostsManager       *manager,
   case EPHY_HOST_PERMISSION_TYPE_ACCESS_LOCATION:
     ephy_hosts_manager_set_geolocation_permission_for_address (manager, address, permission);
     break;
+  case EPHY_HOST_PERMISSION_TYPE_ACCESS_MICROPHONE:
+    ephy_hosts_manager_set_audio_device_permission_for_address (manager, address, permission);
+    break;
+  case EPHY_HOST_PERMISSION_TYPE_ACCESS_WEBCAM:
+    ephy_hosts_manager_set_video_device_permission_for_address (manager, address, permission);
+    break;
   default:
     g_assert_not_reached ();
   }
diff --git a/lib/ephy-hosts-manager.h b/lib/ephy-hosts-manager.h
index 0468dee..9472c58 100644
--- a/lib/ephy-hosts-manager.h
+++ b/lib/ephy-hosts-manager.h
@@ -38,7 +38,9 @@ typedef enum {
 typedef enum {
   EPHY_HOST_PERMISSION_TYPE_SHOW_NOTIFICATIONS,
   EPHY_HOST_PERMISSION_TYPE_SAVE_PASSWORD,
-  EPHY_HOST_PERMISSION_TYPE_ACCESS_LOCATION
+  EPHY_HOST_PERMISSION_TYPE_ACCESS_LOCATION,
+  EPHY_HOST_PERMISSION_TYPE_ACCESS_MICROPHONE,
+  EPHY_HOST_PERMISSION_TYPE_ACCESS_WEBCAM
 } EphyHostPermissionType;
 
 EphyHostsManager*       ephy_hosts_manager_new                                      (void);


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