Branch data Line data Source code
1 : : /* GIO - GLib Input, Output and Streaming Library
2 : : *
3 : : * Copyright 2019 Red Hat, Inc.
4 : : * Copyrgith 2021 Igalia S.L.
5 : : *
6 : : * SPDX-License-Identifier: LGPL-2.1-or-later
7 : : *
8 : : * This library is free software; you can redistribute it and/or
9 : : * modify it under the terms of the GNU Lesser General Public
10 : : * License as published by the Free Software Foundation; either
11 : : * version 2.1 of the License, or (at your option) any later version.
12 : : *
13 : : * This library is distributed in the hope that it will be useful,
14 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : : * Lesser General Public License for more details.
17 : : *
18 : : * You should have received a copy of the GNU Lesser General
19 : : * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 : : */
21 : :
22 : : #include "config.h"
23 : :
24 : : #include "gpowerprofilemonitor.h"
25 : : #include "gpowerprofilemonitordbus.h"
26 : : #include "gioerror.h"
27 : : #include "ginitable.h"
28 : : #include "giomodule-priv.h"
29 : : #include "glibintl.h"
30 : : #include "glib/gstdio.h"
31 : : #include "gcancellable.h"
32 : : #include "gdbusproxy.h"
33 : : #include "gdbusnamewatching.h"
34 : :
35 : : #define G_POWER_PROFILE_MONITOR_DBUS_GET_INITABLE_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_INITABLE, GInitable))
36 : :
37 : : static void g_power_profile_monitor_dbus_iface_init (GPowerProfileMonitorInterface *iface);
38 : : static void g_power_profile_monitor_dbus_initable_iface_init (GInitableIface *iface);
39 : :
40 : : struct _GPowerProfileMonitorDBus
41 : : {
42 : : GObject parent_instance;
43 : :
44 : : guint watch_id;
45 : : GCancellable *cancellable;
46 : : GDBusProxy *proxy;
47 : : gulong signal_id;
48 : :
49 : : gboolean power_saver_enabled;
50 : : };
51 : :
52 : : typedef enum
53 : : {
54 : : PROP_POWER_SAVER_ENABLED = 1,
55 : : } GPowerProfileMonitorDBusProperty;
56 : :
57 : : #define POWERPROFILES_DBUS_NAME "net.hadess.PowerProfiles"
58 : : #define POWERPROFILES_DBUS_IFACE "net.hadess.PowerProfiles"
59 : : #define POWERPROFILES_DBUS_PATH "/net/hadess/PowerProfiles"
60 : :
61 : 240 : G_DEFINE_TYPE_WITH_CODE (GPowerProfileMonitorDBus, g_power_profile_monitor_dbus, G_TYPE_OBJECT,
62 : : G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
63 : : g_power_profile_monitor_dbus_initable_iface_init)
64 : : G_IMPLEMENT_INTERFACE (G_TYPE_POWER_PROFILE_MONITOR,
65 : : g_power_profile_monitor_dbus_iface_init)
66 : : _g_io_modules_ensure_extension_points_registered ();
67 : : g_io_extension_point_implement (G_POWER_PROFILE_MONITOR_EXTENSION_POINT_NAME,
68 : : g_define_type_id,
69 : : "dbus",
70 : : 30))
71 : :
72 : : static void
73 : 1 : g_power_profile_monitor_dbus_init (GPowerProfileMonitorDBus *dbus)
74 : : {
75 : 1 : dbus->power_saver_enabled = FALSE;
76 : 1 : }
77 : :
78 : : static void
79 : 0 : ppd_properties_changed_cb (GDBusProxy *proxy,
80 : : GVariant *changed_properties,
81 : : GStrv *invalidated_properties,
82 : : gpointer user_data)
83 : : {
84 : 0 : GPowerProfileMonitorDBus *dbus = user_data;
85 : : const char *active_profile;
86 : : gboolean enabled;
87 : :
88 : 0 : if (!g_variant_lookup (changed_properties, "ActiveProfile", "&s", &active_profile))
89 : 0 : return;
90 : :
91 : 0 : enabled = g_strcmp0 (active_profile, "power-saver") == 0;
92 : 0 : if (enabled == dbus->power_saver_enabled)
93 : 0 : return;
94 : :
95 : 0 : dbus->power_saver_enabled = enabled;
96 : 0 : g_object_notify (G_OBJECT (dbus), "power-saver-enabled");
97 : : }
98 : :
99 : : static void
100 : 0 : ppd_proxy_cb (GObject *source_object,
101 : : GAsyncResult *res,
102 : : gpointer user_data)
103 : : {
104 : 0 : GPowerProfileMonitorDBus *dbus = user_data;
105 : : GVariant *active_profile_variant;
106 : : GDBusProxy *proxy;
107 : 0 : GError *error = NULL;
108 : : const char *active_profile;
109 : : gboolean power_saver_enabled;
110 : :
111 : 0 : proxy = g_dbus_proxy_new_finish (res, &error);
112 : 0 : if (!proxy)
113 : : {
114 : 0 : g_debug ("GPowerProfileMonitorDBus: Failed to create PowerProfiles D-Bus proxy: %s",
115 : : error->message);
116 : 0 : g_error_free (error);
117 : 0 : return;
118 : : }
119 : :
120 : 0 : active_profile_variant = g_dbus_proxy_get_cached_property (proxy, "ActiveProfile");
121 : 0 : if (active_profile_variant != NULL &&
122 : 0 : g_variant_is_of_type (active_profile_variant, G_VARIANT_TYPE_STRING))
123 : : {
124 : 0 : active_profile = g_variant_get_string (active_profile_variant, NULL);
125 : 0 : power_saver_enabled = g_strcmp0 (active_profile, "power-saver") == 0;
126 : 0 : if (power_saver_enabled != dbus->power_saver_enabled)
127 : : {
128 : 0 : dbus->power_saver_enabled = power_saver_enabled;
129 : 0 : g_object_notify (G_OBJECT (dbus), "power-saver-enabled");
130 : : }
131 : : }
132 : 0 : g_clear_pointer (&active_profile_variant, g_variant_unref);
133 : :
134 : 0 : dbus->signal_id = g_signal_connect (G_OBJECT (proxy), "g-properties-changed",
135 : : G_CALLBACK (ppd_properties_changed_cb), dbus);
136 : 0 : dbus->proxy = g_steal_pointer (&proxy);
137 : : }
138 : :
139 : : static void
140 : 0 : ppd_appeared_cb (GDBusConnection *connection,
141 : : const gchar *name,
142 : : const gchar *name_owner,
143 : : gpointer user_data)
144 : : {
145 : 0 : GPowerProfileMonitorDBus *dbus = user_data;
146 : :
147 : 0 : g_dbus_proxy_new (connection,
148 : : G_DBUS_PROXY_FLAGS_NONE,
149 : : NULL,
150 : : POWERPROFILES_DBUS_NAME,
151 : : POWERPROFILES_DBUS_PATH,
152 : : POWERPROFILES_DBUS_IFACE,
153 : : dbus->cancellable,
154 : : ppd_proxy_cb,
155 : : dbus);
156 : 0 : }
157 : :
158 : : static void
159 : 0 : ppd_vanished_cb (GDBusConnection *connection,
160 : : const gchar *name,
161 : : gpointer user_data)
162 : : {
163 : 0 : GPowerProfileMonitorDBus *dbus = user_data;
164 : :
165 : 0 : g_clear_signal_handler (&dbus->signal_id, dbus->proxy);
166 : 0 : g_clear_object (&dbus->proxy);
167 : :
168 : 0 : dbus->power_saver_enabled = FALSE;
169 : 0 : g_object_notify (G_OBJECT (dbus), "power-saver-enabled");
170 : 0 : }
171 : :
172 : : static void
173 : 0 : g_power_profile_monitor_dbus_get_property (GObject *object,
174 : : guint prop_id,
175 : : GValue *value,
176 : : GParamSpec *pspec)
177 : : {
178 : 0 : GPowerProfileMonitorDBus *dbus = G_POWER_PROFILE_MONITOR_DBUS (object);
179 : :
180 : 0 : switch ((GPowerProfileMonitorDBusProperty) prop_id)
181 : : {
182 : 0 : case PROP_POWER_SAVER_ENABLED:
183 : 0 : g_value_set_boolean (value, dbus->power_saver_enabled);
184 : 0 : break;
185 : :
186 : 0 : default:
187 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
188 : : }
189 : 0 : }
190 : :
191 : : static gboolean
192 : 1 : g_power_profile_monitor_dbus_initable_init (GInitable *initable,
193 : : GCancellable *cancellable,
194 : : GError **error)
195 : : {
196 : 1 : GPowerProfileMonitorDBus *dbus = G_POWER_PROFILE_MONITOR_DBUS (initable);
197 : :
198 : 1 : dbus->cancellable = g_cancellable_new ();
199 : 1 : dbus->watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
200 : : POWERPROFILES_DBUS_NAME,
201 : : G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
202 : : ppd_appeared_cb,
203 : : ppd_vanished_cb,
204 : : dbus,
205 : : NULL);
206 : :
207 : 1 : return TRUE;
208 : : }
209 : :
210 : : static void
211 : 0 : g_power_profile_monitor_dbus_finalize (GObject *object)
212 : : {
213 : 0 : GPowerProfileMonitorDBus *dbus = G_POWER_PROFILE_MONITOR_DBUS (object);
214 : :
215 : 0 : g_cancellable_cancel (dbus->cancellable);
216 : 0 : g_clear_object (&dbus->cancellable);
217 : 0 : g_clear_signal_handler (&dbus->signal_id, dbus->proxy);
218 : 0 : g_clear_object (&dbus->proxy);
219 : 0 : g_clear_handle_id (&dbus->watch_id, g_bus_unwatch_name);
220 : :
221 : 0 : G_OBJECT_CLASS (g_power_profile_monitor_dbus_parent_class)->finalize (object);
222 : 0 : }
223 : :
224 : : static void
225 : 1 : g_power_profile_monitor_dbus_class_init (GPowerProfileMonitorDBusClass *nl_class)
226 : : {
227 : 1 : GObjectClass *gobject_class = G_OBJECT_CLASS (nl_class);
228 : :
229 : 1 : gobject_class->get_property = g_power_profile_monitor_dbus_get_property;
230 : 1 : gobject_class->finalize = g_power_profile_monitor_dbus_finalize;
231 : :
232 : 1 : g_object_class_override_property (gobject_class, PROP_POWER_SAVER_ENABLED, "power-saver-enabled");
233 : 1 : }
234 : :
235 : : static void
236 : 1 : g_power_profile_monitor_dbus_iface_init (GPowerProfileMonitorInterface *monitor_iface)
237 : : {
238 : 1 : }
239 : :
240 : : static void
241 : 1 : g_power_profile_monitor_dbus_initable_iface_init (GInitableIface *iface)
242 : : {
243 : 1 : iface->init = g_power_profile_monitor_dbus_initable_init;
244 : 1 : }
|