(root)/
glib-2.79.0/
gio/
gmemorymonitorportal.c
       1  /* GIO - GLib Input, Output and Streaming Library
       2   *
       3   * Copyright 2019 Red Hat, Inc.
       4   *
       5   * SPDX-License-Identifier: LGPL-2.1-or-later
       6   *
       7   * This library is free software; you can redistribute it and/or
       8   * modify it under the terms of the GNU Lesser General Public
       9   * License as published by the Free Software Foundation; either
      10   * version 2.1 of the License, or (at your option) any later version.
      11   *
      12   * This library is distributed in the hope that it will be useful,
      13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15   * Lesser General Public License for more details.
      16   *
      17   * You should have received a copy of the GNU Lesser General
      18   * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
      19   */
      20  
      21  #include "config.h"
      22  
      23  #include "gmemorymonitor.h"
      24  #include "gmemorymonitorportal.h"
      25  #include "ginitable.h"
      26  #include "giomodule-priv.h"
      27  #include "xdp-dbus.h"
      28  #include "gportalsupport.h"
      29  
      30  #define G_MEMORY_MONITOR_PORTAL_GET_INITABLE_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_INITABLE, GInitable))
      31  
      32  static void g_memory_monitor_portal_iface_init (GMemoryMonitorInterface *iface);
      33  static void g_memory_monitor_portal_initable_iface_init (GInitableIface *iface);
      34  
      35  struct _GMemoryMonitorPortal
      36  {
      37    GObject parent_instance;
      38  
      39    GDBusProxy *proxy;
      40    gulong signal_id;
      41  };
      42  
      43  G_DEFINE_TYPE_WITH_CODE (GMemoryMonitorPortal, g_memory_monitor_portal, G_TYPE_OBJECT,
      44                           G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
      45                                                  g_memory_monitor_portal_initable_iface_init)
      46                           G_IMPLEMENT_INTERFACE (G_TYPE_MEMORY_MONITOR,
      47                                                  g_memory_monitor_portal_iface_init)
      48                           _g_io_modules_ensure_extension_points_registered ();
      49                           g_io_extension_point_implement (G_MEMORY_MONITOR_EXTENSION_POINT_NAME,
      50                                                           g_define_type_id,
      51                                                           "portal",
      52                                                           40))
      53  
      54  static void
      55  g_memory_monitor_portal_init (GMemoryMonitorPortal *portal)
      56  {
      57  }
      58  
      59  static void
      60  proxy_signal (GDBusProxy            *proxy,
      61                const char            *sender,
      62                const char            *signal,
      63                GVariant              *parameters,
      64                GMemoryMonitorPortal *portal)
      65  {
      66    guint8 level;
      67  
      68    if (strcmp (signal, "LowMemoryWarning") != 0)
      69      return;
      70    if (!parameters)
      71      return;
      72  
      73    g_variant_get (parameters, "(y)", &level);
      74    g_signal_emit_by_name (portal, "low-memory-warning", level);
      75  }
      76  
      77  static gboolean
      78  g_memory_monitor_portal_initable_init (GInitable     *initable,
      79                                          GCancellable  *cancellable,
      80                                          GError       **error)
      81  {
      82    GMemoryMonitorPortal *portal = G_MEMORY_MONITOR_PORTAL (initable);
      83    GDBusProxy *proxy;
      84    gchar *name_owner = NULL;
      85  
      86    if (!glib_should_use_portal ())
      87      {
      88        g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Not using portals");
      89        return FALSE;
      90      }
      91  
      92    proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
      93                                           G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
      94                                           NULL,
      95                                           "org.freedesktop.portal.Desktop",
      96                                           "/org/freedesktop/portal/desktop",
      97                                           "org.freedesktop.portal.MemoryMonitor",
      98                                           cancellable,
      99                                           error);
     100    if (!proxy)
     101      return FALSE;
     102  
     103    name_owner = g_dbus_proxy_get_name_owner (proxy);
     104  
     105    if (name_owner == NULL)
     106      {
     107        g_object_unref (proxy);
     108        g_set_error (error,
     109                     G_DBUS_ERROR,
     110                     G_DBUS_ERROR_NAME_HAS_NO_OWNER,
     111                     "Desktop portal not found");
     112        return FALSE;
     113      }
     114  
     115    g_free (name_owner);
     116  
     117    portal->signal_id = g_signal_connect (proxy, "g-signal",
     118                                          G_CALLBACK (proxy_signal), portal);
     119  
     120    portal->proxy = proxy;
     121  
     122    return TRUE;
     123  }
     124  
     125  static void
     126  g_memory_monitor_portal_finalize (GObject *object)
     127  {
     128    GMemoryMonitorPortal *portal = G_MEMORY_MONITOR_PORTAL (object);
     129  
     130    if (portal->proxy != NULL)
     131      g_clear_signal_handler (&portal->signal_id, portal->proxy);
     132    g_clear_object (&portal->proxy);
     133  
     134    G_OBJECT_CLASS (g_memory_monitor_portal_parent_class)->finalize (object);
     135  }
     136  
     137  static void
     138  g_memory_monitor_portal_class_init (GMemoryMonitorPortalClass *nl_class)
     139  {
     140    GObjectClass *gobject_class = G_OBJECT_CLASS (nl_class);
     141  
     142    gobject_class->finalize  = g_memory_monitor_portal_finalize;
     143  }
     144  
     145  static void
     146  g_memory_monitor_portal_iface_init (GMemoryMonitorInterface *monitor_iface)
     147  {
     148  }
     149  
     150  static void
     151  g_memory_monitor_portal_initable_iface_init (GInitableIface *iface)
     152  {
     153    iface->init = g_memory_monitor_portal_initable_init;
     154  }