Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extension install #11

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/libportal-sections.txt
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ xdp_portal_update_monitor_stop
XdpUpdateInstallFlags
xdp_portal_update_install
xdp_portal_update_install_finish
xdp_portal_update_install_ref
xdp_portal_update_install_ref_finish
</SECTION>

<SECTION>
Expand Down
104 changes: 94 additions & 10 deletions libportal/updates.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ update_progress_received (GDBusConnection *bus,
g_variant_lookup (info, "error", "&s", &error);
g_variant_lookup (info, "error_message", "&s", &error_message);
}
g_print ("update progress received %u/%u %u%% %d\n", op, n_ops, progress, status);

g_signal_emit_by_name (portal, "update-progress",
n_ops,
Expand Down Expand Up @@ -310,6 +309,7 @@ typedef struct {
XdpParent *parent;
char *parent_handle;
GTask *task;
char *ref;
} InstallUpdateCall;

static void
Expand All @@ -324,6 +324,7 @@ install_update_call_free (InstallUpdateCall *call)

g_object_unref (call->portal);
g_object_unref (call->task);
g_free (call->ref);

g_free (call);
}
Expand Down Expand Up @@ -380,15 +381,27 @@ install_update (InstallUpdateCall *call)
cancellable = g_task_get_cancellable (call->task);

g_variant_builder_init (&options, G_VARIANT_TYPE_VARDICT);
g_dbus_connection_call (call->portal->bus,
FLATPAK_PORTAL_BUS_NAME,
call->portal->update_monitor_handle,
UPDATE_MONITOR_INTERFACE,
"Update",
g_variant_new ("(sa{sv})",
call->parent_handle,
&options),
NULL, 0, -1, cancellable, update_started, call);
if (call->ref)
g_dbus_connection_call (call->portal->bus,
FLATPAK_PORTAL_BUS_NAME,
call->portal->update_monitor_handle,
UPDATE_MONITOR_INTERFACE,
"Install",
g_variant_new ("(ssa{sv})",
call->parent_handle,
call->ref,
&options),
NULL, 0, -1, cancellable, update_started, call);
else
g_dbus_connection_call (call->portal->bus,
FLATPAK_PORTAL_BUS_NAME,
call->portal->update_monitor_handle,
UPDATE_MONITOR_INTERFACE,
"Update",
g_variant_new ("(sa{sv})",
call->parent_handle,
&options),
NULL, 0, -1, cancellable, update_started, call);
}

/**
Expand Down Expand Up @@ -458,3 +471,74 @@ xdp_portal_update_install_finish (XdpPortal *portal,

return g_task_propagate_boolean (G_TASK (result), error);
}

/**
* xdp_portal_update_install_ref:
* @portal: a #XdpPortal
* @parent: a #XdpParent
* @ref: the ref to install
* @flags: options for this call
* @cancellable: (nullable): optional #GCancellable
* @callback: (scope async): a callback to call when the request is done
* @data: (closure): data to pass to @callback
*
* Installs an available application or runtime extension of the
* app making this call.
*
* During the installation, the #XdpPortal::update-progress
* signal will be emitted to provide progress information.
*/
void
xdp_portal_update_install_ref (XdpPortal *portal,
XdpParent *parent,
const char *ref,
XdpUpdateInstallFlags flags,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer data)
{
InstallUpdateCall *call;

g_return_if_fail (XDP_IS_PORTAL (portal));
g_return_if_fail (flags == XDP_UPDATE_INSTALL_FLAG_NONE);

call = g_new (InstallUpdateCall, 1);
call->portal = g_object_ref (portal);
if (parent)
call->parent = _xdp_parent_copy (parent);
else
call->parent_handle = g_strdup ("");
call->ref = g_strdup (ref);
call->task = g_task_new (portal, cancellable, callback, data);
g_task_set_source_tag (call->task, xdp_portal_update_install_ref);

install_update (call);
}

/**
* xdp_portal_update_install_ref_finish:
* @portal: a #XdpPortal
* @result: a #GAsyncResult
* @error: return location for an error
*
* Finishes an installation request, and returns
* the result in the form of boolean.
*
* Note that the install may not be completed
* by the time this function is called. You need to
* listen to the #XdpPortal::update-progress signal
* to learn when it is complete.
*
* Returns: %TRUE if the installation was started
*/
gboolean
xdp_portal_update_install_ref_finish (XdpPortal *portal,
GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (XDP_IS_PORTAL (portal), FALSE);
g_return_val_if_fail (g_task_is_valid (result, portal), FALSE);
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == xdp_portal_update_install_ref, FALSE);

return g_task_propagate_boolean (G_TASK (result), error);
}
14 changes: 14 additions & 0 deletions libportal/updates.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,18 @@ gboolean xdp_portal_update_install_finish (XdpPortal *porta
GAsyncResult *result,
GError **error);

XDP_PUBLIC
void xdp_portal_update_install_ref (XdpPortal *portal,
XdpParent *parent,
const char *ref,
XdpUpdateInstallFlags flags,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer data);

XDP_PUBLIC
gboolean xdp_portal_update_install_ref_finish (XdpPortal *portal,
GAsyncResult *result,
GError **error);

G_END_DECLS
72 changes: 72 additions & 0 deletions portal-test/portal-test-win.c
Original file line number Diff line number Diff line change
Expand Up @@ -1073,6 +1073,77 @@ set_wallpaper (PortalTestWin *win)
xdp_parent_free (parent);
}

static void
install_debuginfo_called (GObject *source,
GAsyncResult *result,
gpointer data)
{
XdpPortal *portal = XDP_PORTAL (source);
g_autoptr(GError) error = NULL;
gboolean ret;

g_print ("install debuginfo called\n");
ret = xdp_portal_update_install_ref_finish (portal, result, &error);
if (!ret)
{
g_warning ("Install request failed: %s", error ? error->message : "Unknown error");
return;
}

g_message ("Install request successful!");
}

static void
update_progress (XdpPortal *portal,
guint n_ops,
guint op,
guint progress,
XdpUpdateStatus status,
const char *error,
const char *error_message,
gpointer data)
{
g_message ("Installation progress %u/%u %u%%\n", op, n_ops, progress);
if (status != 0)
g_warning ("Installation failed: %s", error_message);

if (progress == 100 && status == 0)
g_message ("Installation completed successfully");

if (status != 0 || progress == 100)
{
g_print ("Stopping the update monitor\n");
g_signal_handlers_disconnect_by_func (portal, update_progress, NULL);
xdp_portal_update_monitor_stop (portal);
}
}

static void
monitor_started_cb (GObject *source,
GAsyncResult *result,
gpointer data)
{
XdpPortal *portal = XDP_PORTAL (source);
g_autoptr(GError) error = NULL;
const char *ref = "runtime/org.gnome.PortalTest.Debug/x86_64/master";

if (!xdp_portal_update_monitor_start_finish (portal, result, &error))
{
g_warning ("Failed to start update monitor: %s", error->message);
return;
}

g_signal_connect (portal, "update-progress", G_CALLBACK (update_progress), NULL);

xdp_portal_update_install_ref (portal, NULL, ref, 0, NULL, install_debuginfo_called, NULL);
}

static void
install_debuginfo (PortalTestWin *win)
{
xdp_portal_update_monitor_start (win->portal, 0, NULL, monitor_started_cb, NULL);
}

static void
portal_test_win_class_init (PortalTestWinClass *class)
{
Expand All @@ -1093,6 +1164,7 @@ portal_test_win_class_init (PortalTestWinClass *class)
gtk_widget_class_bind_template_callback (widget_class, compose_email);
gtk_widget_class_bind_template_callback (widget_class, request_background);
gtk_widget_class_bind_template_callback (widget_class, set_wallpaper);
gtk_widget_class_bind_template_callback (widget_class, install_debuginfo);
gtk_widget_class_bind_template_child (widget_class, PortalTestWin, sandbox_status);
gtk_widget_class_bind_template_child (widget_class, PortalTestWin, network_status);
gtk_widget_class_bind_template_child (widget_class, PortalTestWin, monitor_name);
Expand Down
23 changes: 23 additions & 0 deletions portal-test/portal-test-win.ui
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,29 @@
<property name="top-attach">18</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">1</property>
<property name="halign">end</property>
<property name="label">Extensions</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">19</property>
</packing>
</child>
<child>
<object class="GtkButton">
<property name="visible">1</property>
<property name="xalign">0</property>
<property name="label">Install</property>
<signal name="clicked" handler="install_debuginfo" swapped="yes"/>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">19</property>
</packing>
</child>
</object>
</child>
</template>
Expand Down