Skip to content

Commit afacda5

Browse files
committed
XdpRequestFuture
1 parent ed9973c commit afacda5

File tree

8 files changed

+488
-95
lines changed

8 files changed

+488
-95
lines changed

src/email.c

Lines changed: 50 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright © 2017 Red Hat, Inc
2+
* Copyright © 2025 Red Hat, Inc
33
*
44
* SPDX-License-Identifier: LGPL-2.1-or-later
55
*
@@ -15,9 +15,6 @@
1515
*
1616
* You should have received a copy of the GNU Lesser General Public
1717
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
18-
*
19-
* Authors:
20-
* Matthias Clasen <[email protected]>
2118
*/
2219

2320
#include "config.h"
@@ -38,6 +35,7 @@
3835
#include "xdp-impl-dbus.h"
3936
#include "xdp-portal-config.h"
4037
#include "xdp-request.h"
38+
#include "xdp-request-future.h"
4139
#include "xdp-utils.h"
4240

4341
#include "email.h"
@@ -46,6 +44,7 @@ struct _XdpEmail
4644
{
4745
XdpDbusEmailSkeleton parent_instance;
4846

47+
XdpContext *context;
4948
XdpDbusImplEmail *impl;
5049
};
5150

@@ -237,28 +236,11 @@ handle_compose_email (XdpDbusEmail *object,
237236
GVariant *arg_options)
238237
{
239238
XdpEmail *email = XDP_EMAIL (object);
240-
XdpRequest *request = xdp_request_from_invocation (invocation);
241-
XdpAppInfo *app_info = request->app_info;
242-
g_autoptr(XdpDbusImplRequest) impl_request = NULL;
239+
g_autoptr(XdpRequestFuture) request = NULL;
240+
XdpAppInfo *app_info = xdp_invocation_get_app_info (invocation);
243241
g_autoptr(GVariant) options = NULL;
244-
g_autoptr(XdpDbusImplEmailComposeEmailResult) result = NULL;
245-
XdgDesktopPortalResponseEnum response = XDG_DESKTOP_PORTAL_RESPONSE_OTHER;
246242
g_autoptr(GError) error = NULL;
247243

248-
impl_request = dex_await_object (xdp_dbus_impl_request_proxy_new_future (
249-
g_dbus_proxy_get_connection (G_DBUS_PROXY (email->impl)),
250-
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
251-
g_dbus_proxy_get_name (G_DBUS_PROXY (email->impl)),
252-
request->id),
253-
&error);
254-
255-
if (!impl_request)
256-
{
257-
g_dbus_method_invocation_return_gerror (g_steal_pointer (&invocation),
258-
error);
259-
return G_DBUS_METHOD_INVOCATION_HANDLED;
260-
}
261-
262244
options = compose_email_validate_options (app_info,
263245
fd_list,
264246
arg_options,
@@ -270,51 +252,53 @@ handle_compose_email (XdpDbusEmail *object,
270252
return G_DBUS_METHOD_INVOCATION_HANDLED;
271253
}
272254

273-
{
274-
REQUEST_AUTOLOCK (request);
275-
276-
xdp_request_set_impl_request (request, impl_request);
277-
xdp_request_export (request, g_dbus_method_invocation_get_connection (invocation));
278-
}
255+
request = dex_await_object (xdp_request_future_new (email->context,
256+
app_info,
257+
G_DBUS_INTERFACE_SKELETON (object),
258+
G_DBUS_PROXY (email->impl),
259+
arg_options),
260+
&error);
261+
if (!request)
262+
{
263+
g_dbus_method_invocation_return_gerror (g_steal_pointer (&invocation),
264+
error);
265+
return G_DBUS_METHOD_INVOCATION_HANDLED;
266+
}
279267

280268
xdp_dbus_email_complete_compose_email (object,
281269
g_steal_pointer (&invocation),
282270
NULL,
283-
request->id);
284-
285-
result = dex_await_boxed (xdp_dbus_impl_email_call_compose_email_future (
286-
email->impl,
287-
request->id,
288-
xdp_app_info_get_id (app_info),
289-
arg_parent_window,
290-
options),
291-
&error);
292-
293-
if (result)
294-
{
295-
response = result->response;
296-
}
297-
else
298-
{
299-
g_dbus_error_strip_remote_error (error);
300-
g_warning ("Backend call failed: %s", error->message);
301-
302-
response = XDG_DESKTOP_PORTAL_RESPONSE_OTHER;
303-
}
271+
xdp_request_future_get_object_path (request));
304272

305273
{
306-
REQUEST_AUTOLOCK (request);
307-
308-
if (request->exported)
274+
g_autoptr(XdpDbusImplEmailComposeEmailResult) result = NULL;
275+
XdgDesktopPortalResponseEnum response;
276+
g_auto(GVariantBuilder) new_results =
277+
G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_VARDICT);
278+
279+
result = dex_await_boxed (xdp_dbus_impl_email_call_compose_email_future (
280+
email->impl,
281+
xdp_request_future_get_object_path (request),
282+
xdp_app_info_get_id (app_info),
283+
arg_parent_window,
284+
options),
285+
&error);
286+
287+
if (result)
288+
{
289+
response = result->response;
290+
}
291+
else
309292
{
310-
g_auto(GVariantBuilder) new_results =
311-
G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_VARDICT);
293+
g_dbus_error_strip_remote_error (error);
294+
g_warning ("Backend call failed: %s", error->message);
312295

313-
xdp_dbus_request_emit_response (XDP_DBUS_REQUEST (request),
314-
response,
315-
g_variant_builder_end (&new_results));
316-
xdp_request_unexport (request);
296+
response = XDG_DESKTOP_PORTAL_RESPONSE_OTHER;
317297
}
298+
299+
xdp_request_future_emit_response (request,
300+
response,
301+
g_variant_builder_end (&new_results));
318302
}
319303

320304
return G_DBUS_METHOD_INVOCATION_HANDLED;
@@ -350,11 +334,13 @@ xdp_email_class_init (XdpEmailClass *klass)
350334
}
351335

352336
static XdpEmail *
353-
xdp_email_new (XdpDbusImplEmail *impl)
337+
xdp_email_new (XdpContext *context,
338+
XdpDbusImplEmail *impl)
354339
{
355340
XdpEmail *email;
356341

357342
email = g_object_new (xdp_email_get_type (), NULL);
343+
email->context = context; // FIXME there might be problems with the context lifetime
358344
email->impl = g_object_ref (impl);
359345

360346
g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (email->impl), G_MAXINT);
@@ -364,10 +350,10 @@ xdp_email_new (XdpDbusImplEmail *impl)
364350
return email;
365351
}
366352

367-
static DexFuture *
368-
run_email_fiber (gpointer user_data)
353+
DexFuture *
354+
init_email (gpointer user_data)
369355
{
370-
XdpContext *context = user_data;
356+
XdpContext *context = XDP_CONTEXT (user_data);
371357
g_autoptr(XdpEmail) email = NULL;
372358
GDBusConnection *connection = xdp_context_get_connection (context);
373359
XdpPortalConfig *config = xdp_context_get_config (context);
@@ -391,24 +377,10 @@ run_email_fiber (gpointer user_data)
391377
return dex_future_new_false ();
392378
}
393379

394-
email = xdp_email_new (impl);
380+
email = xdp_email_new (context, impl);
395381

396382
xdp_context_take_and_export_portal (context,
397383
G_DBUS_INTERFACE_SKELETON (g_steal_pointer (&email)),
398384
XDP_CONTEXT_EXPORT_FLAGS_RUN_IN_FIBER);
399385
return dex_future_new_true ();
400386
}
401-
402-
void
403-
init_email (XdpContext *context,
404-
GCancellable *cancellable)
405-
{
406-
DexFuture *f;
407-
408-
f = dex_future_first (dex_scheduler_spawn (NULL, 0,
409-
run_email_fiber,
410-
context, NULL),
411-
dex_cancellable_new_from_cancellable (cancellable),
412-
NULL);
413-
dex_future_disown (f);
414-
}

src/email.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,4 @@
2424

2525
#include "xdp-types.h"
2626

27-
void init_email (XdpContext *context,
28-
GCancellable *cancellable);
27+
DexFuture * init_email (gpointer user_data);

src/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ xdg_desktop_portal_sources = files(
126126
'xdp-permissions.c',
127127
'xdp-portal-config.c',
128128
'xdp-request.c',
129+
'xdp-request-future.c',
129130
'xdp-session.c',
130131
'xdp-session-persistence.c',
131132
)

src/xdp-context.c

Lines changed: 79 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@
6262

6363
#include "xdp-context.h"
6464

65+
enum
66+
{
67+
PEER_DISCONNECT,
68+
N_SIGNALS,
69+
};
70+
71+
static guint signals[N_SIGNALS] = { 0 };
72+
6573
struct _XdpContext
6674
{
6775
GObject parent_instance;
@@ -114,6 +122,14 @@ xdp_context_class_init (XdpContextClass *klass)
114122
GObjectClass *object_class = G_OBJECT_CLASS (klass);
115123

116124
object_class->dispose = xdp_context_dispose;
125+
126+
signals[PEER_DISCONNECT] =
127+
g_signal_new ("peer-disconnect",
128+
G_TYPE_FROM_CLASS (object_class),
129+
G_SIGNAL_RUN_LAST,
130+
0, NULL, NULL, NULL,
131+
G_TYPE_NONE, 1,
132+
G_TYPE_STRING);
117133
}
118134

119135
static void
@@ -193,9 +209,9 @@ method_needs_request (GDBusMethodInvocation *invocation)
193209
}
194210

195211
static gboolean
196-
authorize_callback (GDBusInterfaceSkeleton *interface,
197-
GDBusMethodInvocation *invocation,
198-
gpointer user_data)
212+
authorize_callback_fiber (GDBusInterfaceSkeleton *interface,
213+
GDBusMethodInvocation *invocation,
214+
gpointer user_data)
199215
{
200216
XdpContext *context = XDP_CONTEXT (user_data);
201217
g_autoptr(XdpAppInfo) app_info = NULL;
@@ -220,6 +236,33 @@ authorize_callback (GDBusInterfaceSkeleton *interface,
220236

221237
g_object_set_data (G_OBJECT (invocation), "xdp-app-info", app_info);
222238

239+
return TRUE;
240+
}
241+
242+
static gboolean
243+
authorize_callback (GDBusInterfaceSkeleton *interface,
244+
GDBusMethodInvocation *invocation,
245+
gpointer user_data)
246+
{
247+
XdpContext *context = XDP_CONTEXT (user_data);
248+
g_autoptr(XdpAppInfo) app_info = NULL;
249+
g_autoptr(GError) error = NULL;
250+
251+
app_info = xdp_app_info_registry_ensure_for_invocation_sync (context->app_info_registry,
252+
invocation,
253+
NULL,
254+
&error);
255+
if (app_info == NULL)
256+
{
257+
g_dbus_method_invocation_return_error (invocation,
258+
G_DBUS_ERROR,
259+
G_DBUS_ERROR_ACCESS_DENIED,
260+
"Portal operation not allowed: %s", error->message);
261+
return FALSE;
262+
}
263+
264+
g_object_set_data (G_OBJECT (invocation), "xdp-app-info", app_info);
265+
223266
if (method_needs_request (invocation))
224267
{
225268
if (!xdp_request_init_invocation (invocation, app_info, &error))
@@ -270,10 +313,20 @@ xdp_context_take_and_export_portal (XdpContext *context,
270313
* method calls must see the modified value.
271314
*/
272315

273-
g_signal_connect_object (skeleton, "g-authorize-method",
274-
G_CALLBACK (authorize_callback),
275-
context,
276-
G_CONNECT_DEFAULT);
316+
if (flags & XDP_CONTEXT_EXPORT_FLAGS_RUN_IN_FIBER)
317+
{
318+
g_signal_connect_object (skeleton, "g-authorize-method",
319+
G_CALLBACK (authorize_callback_fiber),
320+
context,
321+
G_CONNECT_DEFAULT);
322+
}
323+
else
324+
{
325+
g_signal_connect_object (skeleton, "g-authorize-method",
326+
G_CALLBACK (authorize_callback),
327+
context,
328+
G_CONNECT_DEFAULT);
329+
}
277330
}
278331

279332
if (g_dbus_interface_skeleton_export (skeleton,
@@ -304,19 +357,36 @@ on_peer_disconnect (const char *name,
304357

305358
xdp_usb_delete_for_sender (context, name);
306359
notification_delete_for_sender (context, name);
360+
361+
g_signal_emit (context, signals[PEER_DISCONNECT], 0, name);
362+
307363
close_requests_for_sender (name);
308364
close_sessions_for_sender (name);
309365
xdp_session_persistence_delete_transient_permissions_for_sender (name);
310366
xdp_app_info_registry_delete (context->app_info_registry, name);
311367
}
312368

369+
static void
370+
xdp_context_register_portal_fiber (XdpContext *context,
371+
DexFiberFunc portal_init_func)
372+
{
373+
g_autoptr(DexFuture) f = NULL;
374+
GCancellable *cancellable = context->cancellable;
375+
376+
f = dex_future_first (dex_scheduler_spawn (NULL, 0,
377+
portal_init_func,
378+
context, NULL),
379+
dex_cancellable_new_from_cancellable (cancellable),
380+
NULL);
381+
dex_future_disown (g_steal_pointer (&f));
382+
}
383+
313384
gboolean
314385
xdp_context_register (XdpContext *context,
315386
GDBusConnection *connection,
316387
GError **error)
317388
{
318389
XdpPortalConfig *portal_config = context->portal_config;
319-
GCancellable *cancellable = context->cancellable;
320390
XdpImplConfig *lockdown_impl_config;
321391
XdpImplConfig *access_impl_config;
322392
GQuark portal_errors G_GNUC_UNUSED;
@@ -374,6 +444,7 @@ xdp_context_register (XdpContext *context,
374444
G_MAXINT);
375445
}
376446

447+
xdp_context_register_portal_fiber (context, init_email);
377448
init_memory_monitor (context);
378449
init_power_profile_monitor (context);
379450
init_network_monitor (context);
@@ -395,7 +466,6 @@ xdp_context_register (XdpContext *context,
395466
init_background (context);
396467
init_wallpaper (context);
397468
init_account (context);
398-
init_email (context, cancellable);
399469
init_secret (context);
400470
init_global_shortcuts (context);
401471
init_dynamic_launcher (context);

0 commit comments

Comments
 (0)