1 | /* |
2 | * Copyright (C) 2017 Collabora Ltd. |
3 | * Copyright (C) 2018 Igalia S.L. |
4 | * |
5 | * This library is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU Lesser General Public |
7 | * License as published by the Free Software Foundation; either |
8 | * version 2 of the License, or (at your option) any later version. |
9 | * |
10 | * This library is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * Lesser General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU Lesser General Public |
16 | * License along with this library; if not, write to the Free Software |
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
18 | */ |
19 | |
20 | #include "config.h" |
21 | #include "LowPowerModeNotifier.h" |
22 | |
23 | #include <cstring> |
24 | #include <gio/gio.h> |
25 | #include <wtf/glib/GUniquePtr.h> |
26 | |
27 | namespace WebCore { |
28 | |
29 | static const char kWarningLevel[] = "WarningLevel" ; |
30 | |
31 | LowPowerModeNotifier::LowPowerModeNotifier(LowPowerModeChangeCallback&& callback) |
32 | : m_cancellable(adoptGRef(g_cancellable_new())) |
33 | , m_callback(WTFMove(callback)) |
34 | { |
35 | g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, static_cast<GDBusProxyFlags>(G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES), |
36 | nullptr, "org.freedesktop.UPower" , "/org/freedesktop/UPower/devices/DisplayDevice" , "org.freedesktop.UPower.Device" , m_cancellable.get(), |
37 | [](GObject*, GAsyncResult* result, gpointer userData) { |
38 | GUniqueOutPtr<GError> error; |
39 | GRefPtr<GDBusProxy> proxy = adoptGRef(g_dbus_proxy_new_for_bus_finish(result, &error.outPtr())); |
40 | if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) |
41 | return; |
42 | |
43 | auto* self = static_cast<LowPowerModeNotifier*>(userData); |
44 | if (proxy) { |
45 | GUniquePtr<char> nameOwner(g_dbus_proxy_get_name_owner(proxy.get())); |
46 | if (nameOwner) { |
47 | self->m_displayDeviceProxy = WTFMove(proxy); |
48 | self->updateWarningLevel(); |
49 | g_signal_connect_swapped(self->m_displayDeviceProxy.get(), "g-properties-changed" , G_CALLBACK(gPropertiesChangedCallback), self); |
50 | return; |
51 | } |
52 | } |
53 | |
54 | // Now, if there is no name owner, it would be good to try to |
55 | // connect to a Flatpak battery status portal instead. |
56 | // Unfortunately, no such portal currently exists. |
57 | self->m_cancellable = nullptr; |
58 | }, this); |
59 | } |
60 | |
61 | void LowPowerModeNotifier::updateWarningLevel() |
62 | { |
63 | GRefPtr<GVariant> variant = adoptGRef(g_dbus_proxy_get_cached_property(m_displayDeviceProxy.get(), kWarningLevel)); |
64 | if (!variant) { |
65 | m_lowPowerModeEnabled = false; |
66 | return; |
67 | } |
68 | |
69 | // 0: Unknown |
70 | // 1: None |
71 | // 2: Discharging (only for universal power supplies) |
72 | // 3: Low |
73 | // 4: Critical |
74 | // 5: Action |
75 | m_lowPowerModeEnabled = g_variant_get_uint32(variant.get()) > 1; |
76 | } |
77 | |
78 | void LowPowerModeNotifier::warningLevelChanged() |
79 | { |
80 | updateWarningLevel(); |
81 | m_callback(m_lowPowerModeEnabled); |
82 | } |
83 | |
84 | void LowPowerModeNotifier::gPropertiesChangedCallback(LowPowerModeNotifier* self, GVariant* changedProperties) |
85 | { |
86 | GUniqueOutPtr<GVariantIter> iter; |
87 | g_variant_get(changedProperties, "a{sv}" , &iter.outPtr()); |
88 | |
89 | const char* propertyName; |
90 | while (g_variant_iter_next(iter.get(), "{&sv}" , &propertyName, nullptr)) { |
91 | if (!strcmp(propertyName, kWarningLevel)) { |
92 | self->warningLevelChanged(); |
93 | break; |
94 | } |
95 | } |
96 | } |
97 | |
98 | LowPowerModeNotifier::~LowPowerModeNotifier() |
99 | { |
100 | g_cancellable_cancel(m_cancellable.get()); |
101 | } |
102 | |
103 | bool LowPowerModeNotifier::isLowPowerModeEnabled() const |
104 | { |
105 | return m_lowPowerModeEnabled; |
106 | } |
107 | |
108 | } // namespace WebCore |
109 | |