remote-access-controller: Allow inhibiting remote access

Inhibiting remote access means any current remote access session is
terminated, and no new ones can be created, until remote access is
uninhibited. The inhibitation is ref counted, meaning there can be more
than one inhibitor.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1212
This commit is contained in:
Jonas Ådahl 2020-04-21 15:44:32 +02:00
parent d26dc4ae44
commit 4300f1f91d
9 changed files with 143 additions and 2 deletions

View File

@ -49,6 +49,7 @@ typedef struct _MetaTileInfo MetaTileInfo;
typedef struct _MetaRenderer MetaRenderer; typedef struct _MetaRenderer MetaRenderer;
typedef struct _MetaRendererView MetaRendererView; typedef struct _MetaRendererView MetaRendererView;
typedef struct _MetaRemoteDesktop MetaRemoteDesktop;
typedef struct _MetaScreenCast MetaScreenCast; typedef struct _MetaScreenCast MetaScreenCast;
typedef struct _MetaScreenCastSession MetaScreenCastSession; typedef struct _MetaScreenCastSession MetaScreenCastSession;
typedef struct _MetaScreenCastStream MetaScreenCastStream; typedef struct _MetaScreenCastStream MetaScreenCastStream;

View File

@ -552,12 +552,12 @@ meta_backend_real_post_init (MetaBackend *backend)
} }
#ifdef HAVE_REMOTE_DESKTOP #ifdef HAVE_REMOTE_DESKTOP
priv->remote_access_controller =
g_object_new (META_TYPE_REMOTE_ACCESS_CONTROLLER, NULL);
priv->dbus_session_watcher = g_object_new (META_TYPE_DBUS_SESSION_WATCHER, NULL); priv->dbus_session_watcher = g_object_new (META_TYPE_DBUS_SESSION_WATCHER, NULL);
priv->screen_cast = meta_screen_cast_new (backend, priv->screen_cast = meta_screen_cast_new (backend,
priv->dbus_session_watcher); priv->dbus_session_watcher);
priv->remote_desktop = meta_remote_desktop_new (priv->dbus_session_watcher); priv->remote_desktop = meta_remote_desktop_new (priv->dbus_session_watcher);
priv->remote_access_controller =
meta_remote_access_controller_new (priv->remote_desktop, priv->screen_cast);
#endif /* HAVE_REMOTE_DESKTOP */ #endif /* HAVE_REMOTE_DESKTOP */
if (!meta_monitor_manager_is_headless (priv->monitor_manager)) if (!meta_monitor_manager_is_headless (priv->monitor_manager))

View File

@ -21,8 +21,12 @@
#ifndef META_REMOTE_ACCESS_CONTROLLER_PRIVATE_H #ifndef META_REMOTE_ACCESS_CONTROLLER_PRIVATE_H
#define META_REMOTE_ACCESS_CONTROLLER_PRIVATE_H #define META_REMOTE_ACCESS_CONTROLLER_PRIVATE_H
#include "backends/meta-backend-types.h"
#include "meta/meta-remote-access-controller.h" #include "meta/meta-remote-access-controller.h"
MetaRemoteAccessController * meta_remote_access_controller_new (MetaRemoteDesktop *remote_desktop,
MetaScreenCast *screen_cast);
void meta_remote_access_controller_notify_new_handle (MetaRemoteAccessController *controller, void meta_remote_access_controller_notify_new_handle (MetaRemoteAccessController *controller,
MetaRemoteAccessHandle *handle); MetaRemoteAccessHandle *handle);

View File

@ -22,6 +22,9 @@
#include "backends/meta-remote-access-controller-private.h" #include "backends/meta-remote-access-controller-private.h"
#include "backends/meta-remote-desktop.h"
#include "backends/meta-screen-cast.h"
enum enum
{ {
HANDLE_STOPPED, HANDLE_STOPPED,
@ -54,6 +57,9 @@ G_DEFINE_TYPE_WITH_PRIVATE (MetaRemoteAccessHandle,
struct _MetaRemoteAccessController struct _MetaRemoteAccessController
{ {
GObject parent; GObject parent;
MetaRemoteDesktop *remote_desktop;
MetaScreenCast *screen_cast;
}; };
G_DEFINE_TYPE (MetaRemoteAccessController, G_DEFINE_TYPE (MetaRemoteAccessController,
@ -122,6 +128,49 @@ meta_remote_access_controller_notify_new_handle (MetaRemoteAccessController *con
handle); handle);
} }
/**
* meta_remote_access_controller_inhibit_remote_access:
* @controller: a #MetaRemoteAccessController
*
* Inhibits remote access sessions from being created and running. Any active
* remote access session will be terminated.
*/
void
meta_remote_access_controller_inhibit_remote_access (MetaRemoteAccessController *controller)
{
meta_remote_desktop_inhibit (controller->remote_desktop);
meta_screen_cast_inhibit (controller->screen_cast);
}
/**
* meta_remote_access_controller_uninhibit_remote_access:
* @controller: a #MetaRemoteAccessController
*
* Uninhibits remote access sessions from being created and running. If this was
* the last inhibitation that was inhibited, new remote access sessions can now
* be created.
*/
void
meta_remote_access_controller_uninhibit_remote_access (MetaRemoteAccessController *controller)
{
meta_screen_cast_uninhibit (controller->screen_cast);
meta_remote_desktop_uninhibit (controller->remote_desktop);
}
MetaRemoteAccessController *
meta_remote_access_controller_new (MetaRemoteDesktop *remote_desktop,
MetaScreenCast *screen_cast)
{
MetaRemoteAccessController *remote_access_controller;
remote_access_controller = g_object_new (META_TYPE_REMOTE_ACCESS_CONTROLLER,
NULL);
remote_access_controller->remote_desktop = remote_desktop;
remote_access_controller->screen_cast = screen_cast;
return remote_access_controller;
}
static void static void
meta_remote_access_handle_init (MetaRemoteAccessHandle *handle) meta_remote_access_handle_init (MetaRemoteAccessHandle *handle)
{ {

View File

@ -56,6 +56,8 @@ struct _MetaRemoteDesktop
int dbus_name_id; int dbus_name_id;
int inhibit_count;
GHashTable *sessions; GHashTable *sessions;
MetaDbusSessionWatcher *session_watcher; MetaDbusSessionWatcher *session_watcher;
@ -70,6 +72,34 @@ G_DEFINE_TYPE_WITH_CODE (MetaRemoteDesktop,
G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_REMOTE_DESKTOP, G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_REMOTE_DESKTOP,
meta_remote_desktop_init_iface)); meta_remote_desktop_init_iface));
void
meta_remote_desktop_inhibit (MetaRemoteDesktop *remote_desktop)
{
remote_desktop->inhibit_count++;
if (remote_desktop->inhibit_count == 1)
{
GHashTableIter iter;
gpointer key, value;
g_hash_table_iter_init (&iter, remote_desktop->sessions);
while (g_hash_table_iter_next (&iter, &key, &value))
{
MetaRemoteDesktopSession *session = value;
g_hash_table_iter_steal (&iter);
meta_remote_desktop_session_close (session);
}
}
}
void
meta_remote_desktop_uninhibit (MetaRemoteDesktop *remote_desktop)
{
g_return_if_fail (remote_desktop->inhibit_count > 0);
remote_desktop->inhibit_count--;
}
GDBusConnection * GDBusConnection *
meta_remote_desktop_get_connection (MetaRemoteDesktop *remote_desktop) meta_remote_desktop_get_connection (MetaRemoteDesktop *remote_desktop)
{ {
@ -108,6 +138,15 @@ handle_create_session (MetaDBusRemoteDesktop *skeleton,
char *session_path; char *session_path;
const char *client_dbus_name; const char *client_dbus_name;
if (remote_desktop->inhibit_count > 0)
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
"Session creation inhibited");
return TRUE;
}
peer_name = g_dbus_method_invocation_get_sender (invocation); peer_name = g_dbus_method_invocation_get_sender (invocation);
session = meta_remote_desktop_session_new (remote_desktop, session = meta_remote_desktop_session_new (remote_desktop,
peer_name, peer_name,

View File

@ -36,6 +36,10 @@ G_DECLARE_FINAL_TYPE (MetaRemoteDesktop, meta_remote_desktop,
META, REMOTE_DESKTOP, META, REMOTE_DESKTOP,
MetaDBusRemoteDesktopSkeleton) MetaDBusRemoteDesktopSkeleton)
void meta_remote_desktop_inhibit (MetaRemoteDesktop *remote_desktop);
void meta_remote_desktop_uninhibit (MetaRemoteDesktop *remote_desktop);
MetaRemoteDesktopSession * meta_remote_desktop_get_session (MetaRemoteDesktop *remote_desktop, MetaRemoteDesktopSession * meta_remote_desktop_get_session (MetaRemoteDesktop *remote_desktop,
const char *session_id); const char *session_id);

View File

@ -40,6 +40,8 @@ struct _MetaScreenCast
int dbus_name_id; int dbus_name_id;
int inhibit_count;
GList *sessions; GList *sessions;
MetaDbusSessionWatcher *session_watcher; MetaDbusSessionWatcher *session_watcher;
@ -54,6 +56,29 @@ G_DEFINE_TYPE_WITH_CODE (MetaScreenCast, meta_screen_cast,
G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_SCREEN_CAST, G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_SCREEN_CAST,
meta_screen_cast_init_iface)) meta_screen_cast_init_iface))
void
meta_screen_cast_inhibit (MetaScreenCast *screen_cast)
{
screen_cast->inhibit_count++;
if (screen_cast->inhibit_count == 1)
{
while (screen_cast->sessions)
{
MetaScreenCastSession *session = screen_cast->sessions->data;
meta_screen_cast_session_close (session);
}
}
}
void
meta_screen_cast_uninhibit (MetaScreenCast *screen_cast)
{
g_return_if_fail (screen_cast->inhibit_count > 0);
screen_cast->inhibit_count--;
}
GDBusConnection * GDBusConnection *
meta_screen_cast_get_connection (MetaScreenCast *screen_cast) meta_screen_cast_get_connection (MetaScreenCast *screen_cast)
{ {
@ -119,6 +144,15 @@ handle_create_session (MetaDBusScreenCast *skeleton,
gboolean disable_animations; gboolean disable_animations;
MetaScreenCastSessionType session_type; MetaScreenCastSessionType session_type;
if (screen_cast->inhibit_count > 0)
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
"Session creation inhibited");
return TRUE;
}
g_variant_lookup (properties, "remote-desktop-session-id", "s", g_variant_lookup (properties, "remote-desktop-session-id", "s",
&remote_desktop_session_id); &remote_desktop_session_id);

View File

@ -42,6 +42,10 @@ G_DECLARE_FINAL_TYPE (MetaScreenCast, meta_screen_cast,
META, SCREEN_CAST, META, SCREEN_CAST,
MetaDBusScreenCastSkeleton) MetaDBusScreenCastSkeleton)
void meta_screen_cast_inhibit (MetaScreenCast *screen_cast);
void meta_screen_cast_uninhibit (MetaScreenCast *screen_cast);
GDBusConnection * meta_screen_cast_get_connection (MetaScreenCast *screen_cast); GDBusConnection * meta_screen_cast_get_connection (MetaScreenCast *screen_cast);
MetaBackend * meta_screen_cast_get_backend (MetaScreenCast *screen_cast); MetaBackend * meta_screen_cast_get_backend (MetaScreenCast *screen_cast);

View File

@ -54,4 +54,10 @@ G_DECLARE_FINAL_TYPE (MetaRemoteAccessController,
META, REMOTE_ACCESS_CONTROLLER, META, REMOTE_ACCESS_CONTROLLER,
GObject) GObject)
META_EXPORT
void meta_remote_access_controller_inhibit_remote_access (MetaRemoteAccessController *controller);
META_EXPORT
void meta_remote_access_controller_uninhibit_remote_access (MetaRemoteAccessController *controller);
#endif /* META_REMOTE_ACCESS_CONTROLLER_H */ #endif /* META_REMOTE_ACCESS_CONTROLLER_H */