[gnome-software/mwleeds/pwa-plugin: 229/234] Revert "Remove webapp support"




commit 67d40e1bf11cfe678062e1817863644906c41d3d
Author: Phaedrus Leeds <mwleeds protonmail com>
Date:   Mon Nov 29 14:09:46 2021 -0800

    Revert "Remove webapp support"
    
    This reverts commit ea5eb222f514895f41ad0ce80f48fff98207bdc6.
    
    This is the first step toward bringing back webapp support. I am doing
    this as a project sponsored by a GNOME Foundation grant and with Endless
    OS as the primary target. The goal is to include a set of Progressive
    Web Apps in Software that can be installed via Epiphany's web app
    support (and potentially also via Chromium), to expand the selection of
    apps available to users who might not otherwise find them. While
    Epiphany's web apps do not currently implement support for PWA
    manifests, that is hopefully going to be in scope for this project.
    While the plan is to only include PWAs in the set hard coded into
    Software, non-PWA web apps installed via Epiphany will also show up in
    Software.
    
    The previous implementation of web apps in Software was dropped because
    it was buggy and users did not like it, since they didn't perceive much
    benefit of using sites as web apps versus using a normal browser and
    were confused by the apps not being native desktop apps. The following
    factors should mitigate or address those issues for the new
    implementation:
    1) We're going to use a D-Bus API provided by Epiphany for enumerating,
       installing, and removing web apps rather than re-implementing those
       functions in Software. This avoids bugs that can occur when the
       implementations are out of sync.
    2) We're going to differentiate web apps from native apps in the UI,
       pending design input on how to do so.
    3) The set of PWAs included with Software will be mostly or entirely
       apps that would not otherwise be available to the user, because they
       are only available as PWAs and not native apps.
    4) Once we have support for PWA manifests in Epiphany, or support for
       Chromium-based web apps which already support manifests, the apps
       should be more featureful and closer to native apps than the current
       web app implementation, e.g. they may work offline to some extent.
    
    (The reverted changes have been edited, for example to remove the
    dependency on epiphany-runtime in the spec file, because it's not clear
    yet if this feature will be enabled by default in Fedora and
    the plan is to make this work with flatpak'd Epiphany which doesn't have
    an analogous way to install epiphany without a desktop icon; see
    https://bugzilla.redhat.com/show_bug.cgi?id=1781359 for context)

 contrib/gnome-software.spec.in                     |   2 +
 meson_options.txt                                  |   1 +
 plugins/epiphany/gs-plugin-epiphany.c              | 322 +++++++++++++++++++++
 plugins/epiphany/gs-self-test.c                    |  98 +++++++
 plugins/epiphany/meson.build                       |  52 ++++
 ....gnome.Software.Plugin.Epiphany.metainfo.xml.in |  11 +
 plugins/meson.build                                |   3 +
 7 files changed, 489 insertions(+)
---
diff --git a/contrib/gnome-software.spec.in b/contrib/gnome-software.spec.in
index f3b35578b..5ea8ec639 100644
--- a/contrib/gnome-software.spec.in
+++ b/contrib/gnome-software.spec.in
@@ -144,11 +144,13 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop
 %{_datadir}/gnome-software/featured-*.svg
 %{_datadir}/gnome-software/featured-*.jpg
 %{_datadir}/metainfo/org.gnome.Software.appdata.xml
+%{_datadir}/metainfo/org.gnome.Software.Plugin.Epiphany.metainfo.xml
 %{_datadir}/metainfo/org.gnome.Software.Plugin.Flatpak.metainfo.xml
 %{_datadir}/metainfo/org.gnome.Software.Plugin.Fwupd.metainfo.xml
 %dir %{gs_plugin_dir}
 %{gs_plugin_dir}/libgs_plugin_appstream.so
 %{gs_plugin_dir}/libgs_plugin_dummy.so
+%{gs_plugin_dir}/libgs_plugin_epiphany.so
 %{gs_plugin_dir}/libgs_plugin_fedora-langpacks.so
 %{gs_plugin_dir}/libgs_plugin_fedora-pkgdb-collections.so
 %{gs_plugin_dir}/libgs_plugin_flatpak.so
diff --git a/meson_options.txt b/meson_options.txt
index 70f62c52b..27a844d50 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -9,6 +9,7 @@ option('fwupd', type : 'boolean', value : true, description : 'enable fwupd supp
 option('flatpak', type : 'boolean', value : true, description : 'enable Flatpak support')
 option('malcontent', type : 'boolean', value : true, description : 'enable parental controls support using 
libmalcontent')
 option('rpm_ostree', type : 'boolean', value : false, description : 'enable rpm-ostree support')
+option('webapps', type : 'boolean', value : true, description : 'enable webapps support')
 option('gudev', type : 'boolean', value : true, description : 'enable GUdev support')
 option('apt', type : 'boolean', value : false, description : 'enable apt: URL handler in the .desktop file')
 option('snap', type : 'boolean', value : false, description : 'enable Snap support')
diff --git a/plugins/epiphany/gs-plugin-epiphany.c b/plugins/epiphany/gs-plugin-epiphany.c
new file mode 100644
index 000000000..9a83e8004
--- /dev/null
+++ b/plugins/epiphany/gs-plugin-epiphany.c
@@ -0,0 +1,322 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2013-2014 Richard Hughes <richard hughsie com>
+ * Copyright (C) 2015 Kalev Lember <klember redhat com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <gnome-software.h>
+
+/*
+ * SECTION:
+ * Uses epiphany to launch web applications.
+ *
+ * If the epiphany binary is not present then it self-disables.
+ */
+
+void
+gs_plugin_initialize (GsPlugin *plugin)
+{
+       g_autofree gchar *epiphany = NULL;
+
+       /* we can only work with epiphany */
+       epiphany = g_find_program_in_path ("epiphany");
+       if (epiphany == NULL) {
+               gs_plugin_set_enabled (plugin, FALSE);
+               g_debug ("disabling '%s' as epiphany does not exist",
+                        gs_plugin_get_name (plugin));
+       }
+
+       /* set name of MetaInfo file */
+       gs_plugin_set_appstream_id (plugin, "org.gnome.Software.Plugin.Epiphany");
+
+       /* need help from appstream */
+       gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_RUN_AFTER, "appstream");
+}
+
+void
+gs_plugin_adopt_app (GsPlugin *plugin, GsApp *app)
+{
+       if (gs_app_get_kind (app) == AS_APP_KIND_WEB_APP &&
+           gs_app_get_bundle_kind (app) != AS_BUNDLE_KIND_PACKAGE) {
+               gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
+       }
+}
+
+static gchar *
+_gs_app_get_id_nonfull (GsApp *app)
+{
+       gchar *id;
+       gchar *tmp;
+
+       id = g_strdup (gs_app_get_id (app));
+       tmp = g_strrstr (id, ".desktop");
+       if (tmp != NULL)
+               *tmp = '\0';
+       return id;
+}
+
+gboolean
+gs_plugin_app_install (GsPlugin *plugin, GsApp *app,
+                      GCancellable *cancellable, GError **error)
+{
+       AsIcon *icon;
+       GPtrArray *icons;
+       gboolean ret = TRUE;
+       gsize kf_length;
+       g_autoptr(GError) error_local = NULL;
+       g_autofree gchar *app_desktop = NULL;
+       g_autofree gchar *epi_desktop = NULL;
+       g_autofree gchar *epi_dir = NULL;
+       g_autofree gchar *epi_icon = NULL;
+       g_autofree gchar *exec = NULL;
+       g_autofree gchar *hash = NULL;
+       g_autofree gchar *id_nonfull = NULL;
+       g_autofree gchar *kf_data = NULL;
+       g_autofree gchar *wmclass = NULL;
+       g_autoptr(GKeyFile) kf = NULL;
+       g_autoptr(GFile) symlink_desktop = NULL;
+       g_autoptr(GFile) symlink_icon = NULL;
+       const gchar *url = NULL;
+
+       /* only process this app if was created by this plugin */
+       if (g_strcmp0 (gs_app_get_management_plugin (app),
+                      gs_plugin_get_name (plugin)) != 0)
+               return TRUE;
+
+       /* create the correct directory */
+       id_nonfull = _gs_app_get_id_nonfull (app);
+       hash = g_compute_checksum_for_string (G_CHECKSUM_SHA1, gs_app_get_name (app), -1);
+       epi_dir = g_strdup_printf ("%s/epiphany/app-%s-%s",
+                                  g_get_user_config_dir (),
+                                  id_nonfull,
+                                  hash);
+       g_mkdir_with_parents (epi_dir, 0755);
+
+       /* symlink icon */
+       epi_icon = g_build_filename (epi_dir, "app-icon.png", NULL);
+       symlink_icon = g_file_new_for_path (epi_icon);
+       icons = gs_app_get_icons (app);
+       if (icons->len == 0) {
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_NOT_SUPPORTED,
+                            "no icons for %s",
+                            gs_app_get_id (app));
+               return FALSE;
+       }
+       icon = g_ptr_array_index (icons, 0);
+       if (as_icon_get_filename (icon) == NULL) {
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_NOT_SUPPORTED,
+                            "no filename for icon %s",
+                            as_icon_get_name (icon));
+               return FALSE;
+       }
+       ret = g_file_make_symbolic_link (symlink_icon,
+                                        as_icon_get_filename (icon),
+                                        NULL,
+                                        &error_local);
+       if (!ret) {
+               if (g_error_matches (error_local, G_IO_ERROR, G_IO_ERROR_EXISTS)) {
+                       g_debug ("ignoring icon symlink failure: %s",
+                                error_local->message);
+               } else {
+                       g_set_error (error,
+                                    GS_PLUGIN_ERROR,
+                                    GS_PLUGIN_ERROR_WRITE_FAILED,
+                                    "Can't symlink icon: %s",
+                                    error_local->message);
+                       return FALSE;
+               }
+       }
+
+       /* add desktop file */
+       wmclass = g_strdup_printf ("%s-%s", id_nonfull, hash);
+       kf = g_key_file_new ();
+       g_key_file_set_string (kf,
+                              G_KEY_FILE_DESKTOP_GROUP,
+                              G_KEY_FILE_DESKTOP_KEY_NAME,
+                              gs_app_get_name (app));
+       g_key_file_set_string (kf,
+                              G_KEY_FILE_DESKTOP_GROUP,
+                              G_KEY_FILE_DESKTOP_KEY_COMMENT,
+                              gs_app_get_summary (app));
+       url = gs_app_get_launchable (app, AS_LAUNCHABLE_KIND_URL);
+       if (url == NULL)
+               url = gs_app_get_url (app, AS_URL_KIND_HOMEPAGE);
+       exec = g_strdup_printf ("epiphany --application-mode --profile=\"%s\" %s",
+                               epi_dir,
+                               url);
+       g_key_file_set_string (kf,
+                              G_KEY_FILE_DESKTOP_GROUP,
+                              G_KEY_FILE_DESKTOP_KEY_EXEC,
+                              exec);
+       g_key_file_set_boolean (kf,
+                               G_KEY_FILE_DESKTOP_GROUP,
+                               G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY,
+                               TRUE);
+       g_key_file_set_boolean (kf,
+                               G_KEY_FILE_DESKTOP_GROUP,
+                               G_KEY_FILE_DESKTOP_KEY_TERMINAL,
+                               FALSE);
+       g_key_file_set_boolean (kf,
+                               G_KEY_FILE_DESKTOP_GROUP,
+                               G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY,
+                               FALSE);
+       g_key_file_set_string (kf,
+                              G_KEY_FILE_DESKTOP_GROUP,
+                              G_KEY_FILE_DESKTOP_KEY_TYPE,
+                              G_KEY_FILE_DESKTOP_TYPE_APPLICATION);
+       g_key_file_set_string (kf,
+                              G_KEY_FILE_DESKTOP_GROUP,
+                              G_KEY_FILE_DESKTOP_KEY_ICON,
+                              epi_icon);
+       g_key_file_set_string (kf,
+                              G_KEY_FILE_DESKTOP_GROUP,
+                              G_KEY_FILE_DESKTOP_KEY_STARTUP_WM_CLASS,
+                              wmclass);
+
+       /* save keyfile */
+       kf_data = g_key_file_to_data (kf, &kf_length, error);
+       if (kf_data == NULL)
+               return FALSE;
+       epi_desktop = g_strdup_printf ("%s/%s.desktop", epi_dir, wmclass);
+       if (!g_file_set_contents (epi_desktop, kf_data, (gssize) kf_length, error))
+               return FALSE;
+
+       /* symlink it to somewhere the shell will notice */
+       app_desktop = g_build_filename (g_get_user_data_dir (),
+                                       "applications",
+                                       gs_app_get_id (app),
+                                       NULL);
+       symlink_desktop = g_file_new_for_path (app_desktop);
+       ret = g_file_make_symbolic_link (symlink_desktop,
+                                        epi_desktop,
+                                        NULL,
+                                        error);
+       if (!ret) {
+               gs_utils_error_convert_gio (error);
+               return FALSE;
+       }
+
+       /* update state */
+       gs_app_set_state (app, AS_APP_STATE_INSTALLING);
+       gs_app_set_state (app, AS_APP_STATE_INSTALLED);
+       return TRUE;
+}
+
+gboolean
+gs_plugin_app_remove (GsPlugin *plugin, GsApp *app,
+                     GCancellable *cancellable, GError **error)
+{
+       const gchar *epi_desktop;
+       g_autofree gchar *app_desktop = NULL;
+       g_autoptr(GFile) file_epi = NULL;
+       g_autoptr(GFile) file_app = NULL;
+
+       /* only process this app if was created by this plugin */
+       if (g_strcmp0 (gs_app_get_management_plugin (app),
+                      gs_plugin_get_name (plugin)) != 0)
+               return TRUE;
+
+       /* remove the epi 'config' file */
+       gs_app_set_state (app, AS_APP_STATE_REMOVING);
+       epi_desktop = gs_app_get_source_id_default (app);
+       file_epi = g_file_new_for_path (epi_desktop);
+       if (!g_file_delete (file_epi, NULL, error))
+               return FALSE;
+
+       /* remove the shared desktop file */
+       app_desktop = g_build_filename (g_get_user_data_dir (),
+                                       "applications",
+                                       gs_app_get_id (app),
+                                       NULL);
+       file_app = g_file_new_for_path (app_desktop);
+       if (!g_file_delete (file_app, NULL, error)) {
+               gs_utils_error_convert_gio (error);
+               return FALSE;
+       }
+       gs_app_set_state (app, AS_APP_STATE_AVAILABLE);
+       return TRUE;
+}
+
+gboolean
+gs_plugin_refine_app (GsPlugin *plugin,
+                     GsApp *app,
+                     GsPluginRefineFlags flags,
+                     GCancellable *cancellable,
+                     GError **error)
+{
+       const gchar *name;
+       g_autofree gchar *fn = NULL;
+       g_autofree gchar *hash = NULL;
+       g_autofree gchar *id_nonfull = NULL;
+
+       /* only process this app if was created by this plugin */
+       if (g_strcmp0 (gs_app_get_management_plugin (app),
+                      gs_plugin_get_name (plugin)) != 0)
+               return TRUE;
+
+       gs_app_set_size_installed (app, 4096);
+
+       /* i guess this is technically true */
+       gs_app_add_kudo (app, GS_APP_KUDO_SANDBOXED_SECURE);
+
+       name = gs_app_get_name (app);
+       if (name == NULL) {
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_INVALID_FORMAT,
+                            "name unset for %s",
+                            gs_app_get_id (app));
+               return FALSE;
+       }
+       if (gs_app_get_summary (app) == NULL) {
+               g_debug ("faking summary for %s", gs_app_get_id (app));
+               gs_app_set_summary (app, GS_APP_QUALITY_LOWEST,
+                                   "Web Application");
+       }
+       hash = g_compute_checksum_for_string (G_CHECKSUM_SHA1, name, -1);
+       id_nonfull = _gs_app_get_id_nonfull (app);
+       fn = g_strdup_printf ("%s/epiphany/app-%s-%s/%s-%s.desktop",
+                             g_get_user_config_dir (),
+                             id_nonfull,
+                             hash,
+                             id_nonfull,
+                             hash);
+       /* try the new-style location */
+       if (!g_file_test (fn, G_FILE_TEST_EXISTS)) {
+               g_free (fn);
+               fn = g_strdup_printf ("%s/epiphany/app-%s/%s.desktop",
+                                     g_get_user_config_dir (),
+                                     id_nonfull, id_nonfull);
+       }
+       if (g_file_test (fn, G_FILE_TEST_EXISTS)) {
+               gs_app_set_state (app, AS_APP_STATE_INSTALLED);
+               gs_app_add_source_id (app, fn);
+               gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
+               return TRUE;
+       }
+       gs_app_set_state (app, AS_APP_STATE_AVAILABLE);
+       return TRUE;
+}
+
+gboolean
+gs_plugin_launch (GsPlugin *plugin,
+                 GsApp *app,
+                 GCancellable *cancellable,
+                 GError **error)
+{
+       /* only process this app if was created by this plugin */
+       if (g_strcmp0 (gs_app_get_management_plugin (app),
+                      gs_plugin_get_name (plugin)) != 0)
+               return TRUE;
+       return gs_plugin_app_launch (plugin, app, error);
+}
diff --git a/plugins/epiphany/gs-self-test.c b/plugins/epiphany/gs-self-test.c
new file mode 100644
index 000000000..2d2f47888
--- /dev/null
+++ b/plugins/epiphany/gs-self-test.c
@@ -0,0 +1,98 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2013-2017 Richard Hughes <richard hughsie com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "config.h"
+
+#include "gnome-software-private.h"
+
+#include "gs-test.h"
+
+static void
+gs_plugins_epiphany_func (GsPluginLoader *plugin_loader)
+{
+       gboolean ret;
+       g_autoptr(GError) error = NULL;
+       g_autoptr(GsApp) app = NULL;
+       g_autoptr(GsPluginJob) plugin_job = NULL;
+
+       /* no epiphany, abort */
+       if (!gs_plugin_loader_get_enabled (plugin_loader, "epiphany"))
+               return;
+
+       /* a webapp with a local icon */
+       app = gs_app_new ("arachne.desktop");
+       gs_app_set_kind (app, AS_APP_KIND_WEB_APP);
+       plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_REFINE,
+                                        "app", app,
+                                        "refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON,
+                                        NULL);
+       ret = gs_plugin_loader_job_action (plugin_loader, plugin_job, NULL, &error);
+       gs_test_flush_main_context ();
+       g_assert_no_error (error);
+       g_assert (ret);
+
+       g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_AVAILABLE);
+       g_assert (gs_app_get_pixbuf (app) != NULL);
+}
+
+int
+main (int argc, char **argv)
+{
+       gboolean ret;
+       g_autofree gchar *fn = NULL;
+       g_autofree gchar *xml = NULL;
+       g_autoptr(GError) error = NULL;
+       g_autoptr(GsPluginLoader) plugin_loader = NULL;
+       const gchar *whitelist[] = {
+               "appstream",
+               "epiphany",
+               "icons",
+               NULL
+       };
+
+       g_test_init (&argc, &argv, NULL);
+       g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
+       g_setenv ("GS_XMLB_VERBOSE", "1", TRUE);
+
+       fn = gs_test_get_filename (TESTDATADIR, "icons/hicolor/scalable/org.gnome.Software.svg");
+       g_assert (fn != NULL);
+       xml = g_strdup_printf ("<?xml version=\"1.0\"?>\n"
+               "<components version=\"0.9\">\n"
+               "  <component type=\"webapp\">\n"
+               "    <id>arachne.desktop</id>\n"
+               "    <name>test</name>\n"
+               "    <pkgname>test</pkgname>\n"
+               "    <icon type=\"remote\">file://%s</icon>\n"
+               "  </component>\n"
+               "  <info>\n"
+               "    <scope>user</scope>\n"
+               "  </info>\n"
+               "</components>\n", fn);
+       g_setenv ("GS_SELF_TEST_APPSTREAM_XML", xml, TRUE);
+
+       /* only critical and error are fatal */
+       g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
+
+       /* we can only load this once per process */
+       plugin_loader = gs_plugin_loader_new ();
+       gs_plugin_loader_add_location (plugin_loader, LOCALPLUGINDIR);
+       gs_plugin_loader_add_location (plugin_loader, LOCALPLUGINDIR_CORE);
+       ret = gs_plugin_loader_setup (plugin_loader,
+                                     (gchar**) whitelist,
+                                     NULL,
+                                     NULL,
+                                     &error);
+       g_assert_no_error (error);
+       g_assert (ret);
+
+       /* plugin tests go here */
+       g_test_add_data_func ("/gnome-software/plugins/epiphany",
+                             plugin_loader,
+                             (GTestDataFunc) gs_plugins_epiphany_func);
+
+       return g_test_run ();
+}
diff --git a/plugins/epiphany/meson.build b/plugins/epiphany/meson.build
new file mode 100644
index 000000000..9d57c4d16
--- /dev/null
+++ b/plugins/epiphany/meson.build
@@ -0,0 +1,52 @@
+cargs = ['-DG_LOG_DOMAIN="GsPluginEpiphany"']
+
+shared_module(
+  'gs_plugin_epiphany',
+  sources : 'gs-plugin-epiphany.c',
+  include_directories : [
+    include_directories('../..'),
+    include_directories('../../lib'),
+  ],
+  install : true,
+  install_dir: plugin_dir,
+  c_args : cargs,
+  dependencies : plugin_libs,
+  link_with : [
+    libgnomesoftware
+  ]
+)
+metainfo = 'org.gnome.Software.Plugin.Epiphany.metainfo.xml'
+
+i18n.merge_file(
+  input: metainfo + '.in',
+  output: metainfo,
+  type: 'xml',
+  po_dir: join_paths(meson.source_root(), 'po'),
+  install: true,
+  install_dir: join_paths(get_option('datadir'), 'metainfo')
+)
+
+if get_option('tests')
+  cargs += ['-DLOCALPLUGINDIR="' + meson.current_build_dir() + '"']
+  cargs += ['-DLOCALPLUGINDIR_CORE="' + meson.current_build_dir() + '/../core"']
+  cargs += ['-DTESTDATADIR="' + join_paths(meson.current_source_dir(), '..', '..', 'data') + '"']
+  e = executable(
+    'gs-self-test-epiphany',
+    compiled_schemas,
+    sources : [
+      'gs-self-test.c'
+    ],
+    include_directories : [
+      include_directories('../..'),
+      include_directories('../../lib'),
+    ],
+    dependencies : [
+      plugin_libs,
+    ],
+    link_with : [
+      libgnomesoftware
+    ],
+    c_args : cargs,
+  )
+  test('gs-self-test-epiphany', e, suite: ['plugins', 'epiphany'], env: test_env)
+endif
diff --git a/plugins/epiphany/org.gnome.Software.Plugin.Epiphany.metainfo.xml.in 
b/plugins/epiphany/org.gnome.Software.Plugin.Epiphany.metainfo.xml.in
new file mode 100644
index 000000000..626381f90
--- /dev/null
+++ b/plugins/epiphany/org.gnome.Software.Plugin.Epiphany.metainfo.xml.in
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright 2013-2016 Richard Hughes <richard hughsie com> -->
+<component type="addon">
+  <id>org.gnome.Software.Plugin.Epiphany</id>
+  <extends>org.gnome.Software.desktop</extends>
+  <name>Web Apps Support</name>
+  <summary>Run popular web applications in a browser</summary>
+  <metadata_license>CC0-1.0</metadata_license>
+  <project_license>GPL-2.0+</project_license>
+  <update_contact>mwleeds_at_protonmail.com</update_contact>
+</component>
diff --git a/plugins/meson.build b/plugins/meson.build
index 01fc42f17..711b488e2 100644
--- a/plugins/meson.build
+++ b/plugins/meson.build
@@ -38,3 +38,6 @@ endif
 if get_option('snap')
   subdir('snap')
 endif
+if get_option('webapps')
+  subdir('epiphany')
+endif


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