Source/WebCore/ChangeLog

 12021-10-19 Patrick Griffis <pgriffis@igalia.com>
 2
 3 [GTK] Rewrite LowPowerModeNotifier to use GPowerProfileMonitor
 4 https://bugs.webkit.org/show_bug.cgi?id=231958
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 This replaces the previous direct use of UPower with some advantages:
 9
 10 - Fixes support while being sandboxed without UPower DBus access
 11 - Respects a system-wide low power mode rather than only being
 12 enabled when the battery is low
 13
 14 I decided to remove the old behavior entirely as it is a very
 15 different behavior than the new one and subjectively worse.
 16
 17 * platform/LowPowerModeNotifier.h:
 18 * platform/glib/LowPowerModeNotifierGLib.cpp:
 19 (WebCore::LowPowerModeNotifier::LowPowerModeNotifier):
 20 (WebCore::LowPowerModeNotifier::powerSaverEnabledNotifyCallback):
 21 (WebCore::LowPowerModeNotifier::~LowPowerModeNotifier):
 22
1232021-10-19 Tyler Wilcock <tyler_w@apple.com>
224
325 AX: Fix broken spec links in AccessibilityObject.cpp and AccessibilityTree.cpp

Source/WebCore/platform/LowPowerModeNotifier.h

@@OBJC_CLASS WebLowPowerModeObserver;
3333#endif
3434
3535#if USE(GLIB)
 36#include <gio/gio.h>
3637#include <wtf/glib/GRefPtr.h>
37 typedef struct _GDBusProxy GDBusProxy;
3838#endif
3939
4040namespace WebCore {

@@private:
5656 RetainPtr<WebLowPowerModeObserver> m_observer;
5757 LowPowerModeChangeCallback m_callback;
5858#elif USE(GLIB)
59  void updateWarningLevel();
60  void warningLevelChanged();
61  static void gPropertiesChangedCallback(LowPowerModeNotifier*, GVariant* changedProperties);
62 
63  GRefPtr<GDBusProxy> m_displayDeviceProxy;
64  GRefPtr<GCancellable> m_cancellable;
 59#if GLIB_CHECK_VERSION(2, 69, 1)
6560 LowPowerModeChangeCallback m_callback;
66  bool m_lowPowerModeEnabled { false };
 61 GRefPtr<GPowerProfileMonitor> m_powerProfileMonitor;
 62#endif
6763#endif
6864};
6965

Source/WebCore/platform/glib/LowPowerModeNotifierGLib.cpp

2626
2727namespace WebCore {
2828
29 static const char kWarningLevel[] = "WarningLevel";
3029
3130LowPowerModeNotifier::LowPowerModeNotifier(LowPowerModeChangeCallback&& callback)
32  : m_cancellable(adoptGRef(g_cancellable_new()))
33  , m_callback(WTFMove(callback))
 31 : m_callback(WTFMove(callback))
 32#if GLIB_CHECK_VERSION(2, 69, 1)
 33 , m_powerProfileMonitor(adoptGRef(g_power_profile_monitor_dup_default()))
 34#endif
3435{
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;
 36 m_callback(isLowPowerModeEnabled());
4237
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  }
 38#if GLIB_CHECK_VERSION(2, 69, 1)
 39 g_signal_connect_swapped(m_powerProfileMonitor.get(), "notify::power-saver-enabled", G_CALLBACK(+[] (LowPowerModeNotifier* self, GParamSpec*, GPowerProfileMonitor*) {
 40 self->m_callback(self->isLowPowerModeEnabled());
 41 }), this);
 42#endif
9643}
9744
9845LowPowerModeNotifier::~LowPowerModeNotifier()
9946{
100  g_cancellable_cancel(m_cancellable.get());
 47#if GLIB_CHECK_VERSION(2, 69, 1)
 48 g_signal_handlers_disconnect_by_data(m_powerProfileMonitor.get(), this);
 49#endif
10150}
10251
10352bool LowPowerModeNotifier::isLowPowerModeEnabled() const
10453{
105  return m_lowPowerModeEnabled;
 54#if GLIB_CHECK_VERSION(2, 69, 1)
 55 return g_power_profile_monitor_get_power_saver_enabled(m_powerProfileMonitor.get());
 56#else
 57 return false;
 58#endif
10659}
10760
10861} // namespace WebCore