[GTK] Add a UPower-based BatteryProvider
authorzandobersek@gmail.com <zandobersek@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 11 Dec 2013 18:16:48 +0000 (18:16 +0000)
committerzandobersek@gmail.com <zandobersek@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 11 Dec 2013 18:16:48 +0000 (18:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=115719

Reviewed by Martin Robinson.

Source/Platform:

* GNUmakefile.am: Add the Source/WebCore/platform/glib directory to the list of directories searched
for header inclusion. Add the upower-glib dependency CFLAGS to the list of libPlatform's CPPFLAGS.

Source/WebCore:

Introduce the BatteryProviderUPower, a provider of the system's battery status that produces the information
using the upower-glib library.

The BatteryProviderUPower creates a new UPower client when the provider should start emitting updates and hooks
up to device alteration signals. These only fire recalculation of the battery status when a battery device is altered.

When recalculating, every battery device is taken into account, accumulating the energy capacities when both empty
and full, the current rate of energy charging/discharging, and the battery status (whether the device is charging or
discharging). This gives a set of data that covers the overall battery status of the system.

This data is then used to calculate the battery status as perceived by the WebCore implementation. Charging is determined
by examining the integral sign of the current combined energy rate. Charging and discharging times are calculated, when
appropriate, by dividing the chargable/dischargable capacity with the current combined energy rate. The battery level is
calculated by dividing the current energy capacity with the full energy capacity (i.e. the combined capacity of all
the batteries that the system possesses). The status is (indirectly) passed onto BatteryManager by invoking the
updateBatteryStatus method on the client, with the first parameter representing the battery charging/discharging state,
the second parameter representing the time left until the battery is fully charged (when charging) or fully
depleted (when discharging), and the third parameter representing the current battery level.

Whenever the implementation cannot provide any information about the battery status of the system, the client's
updateBatteryStatus method is invoked with the first parameter reporting the unavailability of any information
about the battery status. The other two parameters can be omitted as they default to 0 when not given and are neither
available nor useful in such circumstances. The client should handle such an update by reporting the 'default' battery
status - charging, the battery level being at 1.0 and both the charging and discharging time having the value of
the positive infinity (as per the Battery Status API specification).

The implementation is heavily inspired by a similar approach to calculating battery status in GNOME Settings Daemon.

No new tests - no new functionality. The feature is not yet enabled. When enabled, the relevant tests pass.

* GNUmakefile.list.am: Add the BatteryProviderUPower(Client) build targets.
* platform/glib/BatteryProviderUPower.cpp: Added.
(powerDeviceAlterationCallback):
(BatteryProviderUPower::BatteryProviderUPower):
(BatteryProviderUPower::startUpdating):
(BatteryProviderUPower::stopUpdating):
(BatteryProviderUPower::updateBatteryStatus):
* platform/glib/BatteryProviderUPower.h: Added.
(WebCore):
(BatteryProviderUPower):
* platform/glib/BatteryProviderUPowerClient.h: Added.
(WebCore):
(BatteryProviderUPowerClient):

Source/WebKit/gtk:

* GNUmakefile.am: Link the libwebkigtk library against the upower-glib library.

Source/WebKit2:

* GNUmakefile.am: Link the libwebkit2gtk library against the upower-glib library.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@160444 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/Platform/ChangeLog
Source/Platform/GNUmakefile.am
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/platform/glib/BatteryProviderUPower.cpp [new file with mode: 0644]
Source/WebCore/platform/glib/BatteryProviderUPower.h [new file with mode: 0644]
Source/WebCore/platform/glib/BatteryProviderUPowerClient.h [new file with mode: 0644]
Source/WebKit/gtk/ChangeLog
Source/WebKit/gtk/GNUmakefile.am
Source/WebKit2/ChangeLog
Source/WebKit2/GNUmakefile.am

index f16fd14..12e59e7 100644 (file)
@@ -1,3 +1,13 @@
+2013-12-11  José Dapena Paz  <jdapena@igalia.com> and Zan Dobersek  <zdobersek@igalia.com>
+
+        [GTK] Add a UPower-based BatteryProvider
+        https://bugs.webkit.org/show_bug.cgi?id=115719
+
+        Reviewed by Martin Robinson.
+
+        * GNUmakefile.am: Add the Source/WebCore/platform/glib directory to the list of directories searched
+        for header inclusion. Add the upower-glib dependency CFLAGS to the list of libPlatform's CPPFLAGS.
+
 2013-12-02  Thiago de Barros Lacerda  <thiago.lacerda@openbossa.org>
 
         Nix Upstream: Updating Platform files
index bdff28e..78e8c4b 100644 (file)
@@ -28,6 +28,7 @@ platform_webcore_cppflags += \
        -I$(srcdir)/Source/WebCore/platform/audio \
        -I$(srcdir)/Source/WebCore/platform/cairo \
        -I$(srcdir)/Source/WebCore/platform/geoclue \
+       -I$(srcdir)/Source/WebCore/platform/glib \
        -I$(srcdir)/Source/WebCore/platform/graphics \
        -I$(srcdir)/Source/WebCore/platform/graphics/cairo \
        -I$(srcdir)/Source/WebCore/platform/graphics/cpu/arm \
@@ -95,7 +96,8 @@ libPlatform_la_CPPFLAGS = \
        $(FREETYPE_CFLAGS) \
        $(GEOCLUE_CFLAGS) \
        $(GSTREAMER_CFLAGS) \
-       $(LIBSOUP_CFLAGS)
+       $(LIBSOUP_CFLAGS) \
+       $(UPOWER_GLIB_CFLAGS)
 
 libPlatformGtk_la_SOURCES = \
        $(platformgtk_sources)
index 9bbeefe..28a2c03 100644 (file)
@@ -1,3 +1,54 @@
+2013-12-11  José Dapena Paz  <jdapena@igalia.com> and Zan Dobersek  <zdobersek@igalia.com>
+
+        [GTK] Add a UPower-based BatteryProvider
+        https://bugs.webkit.org/show_bug.cgi?id=115719
+
+        Reviewed by Martin Robinson.
+
+        Introduce the BatteryProviderUPower, a provider of the system's battery status that produces the information
+        using the upower-glib library.
+
+        The BatteryProviderUPower creates a new UPower client when the provider should start emitting updates and hooks
+        up to device alteration signals. These only fire recalculation of the battery status when a battery device is altered.
+
+        When recalculating, every battery device is taken into account, accumulating the energy capacities when both empty
+        and full, the current rate of energy charging/discharging, and the battery status (whether the device is charging or
+        discharging). This gives a set of data that covers the overall battery status of the system.
+
+        This data is then used to calculate the battery status as perceived by the WebCore implementation. Charging is determined
+        by examining the integral sign of the current combined energy rate. Charging and discharging times are calculated, when
+        appropriate, by dividing the chargable/dischargable capacity with the current combined energy rate. The battery level is
+        calculated by dividing the current energy capacity with the full energy capacity (i.e. the combined capacity of all
+        the batteries that the system possesses). The status is (indirectly) passed onto BatteryManager by invoking the
+        updateBatteryStatus method on the client, with the first parameter representing the battery charging/discharging state,
+        the second parameter representing the time left until the battery is fully charged (when charging) or fully
+        depleted (when discharging), and the third parameter representing the current battery level.
+
+        Whenever the implementation cannot provide any information about the battery status of the system, the client's
+        updateBatteryStatus method is invoked with the first parameter reporting the unavailability of any information
+        about the battery status. The other two parameters can be omitted as they default to 0 when not given and are neither
+        available nor useful in such circumstances. The client should handle such an update by reporting the 'default' battery
+        status - charging, the battery level being at 1.0 and both the charging and discharging time having the value of
+        the positive infinity (as per the Battery Status API specification).
+
+        The implementation is heavily inspired by a similar approach to calculating battery status in GNOME Settings Daemon.
+
+        No new tests - no new functionality. The feature is not yet enabled. When enabled, the relevant tests pass.
+
+        * GNUmakefile.list.am: Add the BatteryProviderUPower(Client) build targets.
+        * platform/glib/BatteryProviderUPower.cpp: Added.
+        (powerDeviceAlterationCallback):
+        (BatteryProviderUPower::BatteryProviderUPower):
+        (BatteryProviderUPower::startUpdating):
+        (BatteryProviderUPower::stopUpdating):
+        (BatteryProviderUPower::updateBatteryStatus):
+        * platform/glib/BatteryProviderUPower.h: Added.
+        (WebCore):
+        (BatteryProviderUPower):
+        * platform/glib/BatteryProviderUPowerClient.h: Added.
+        (WebCore):
+        (BatteryProviderUPowerClient):
+
 2013-12-11  Thiago de Barros Lacerda  <thiago.lacerda@openbossa.org>
 
         Improving createOffer and createAnswer LayoutTests
index c9a2dfa..d99f7ab 100644 (file)
@@ -5585,6 +5585,9 @@ platform_sources += \
        Source/WebCore/platform/geoclue/GeolocationProviderGeoclue.h \
        Source/WebCore/platform/geoclue/GeolocationProviderGeoclue.cpp \
        Source/WebCore/platform/geoclue/GeolocationProviderGeoclueClient.h \
+       Source/WebCore/platform/glib/BatteryProviderUPowerClient.h \
+       Source/WebCore/platform/glib/BatteryProviderUPower.cpp \
+       Source/WebCore/platform/glib/BatteryProviderUPower.h \
        Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp \
        Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp \
        Source/WebCore/platform/graphics/cairo/CairoUtilities.h \
diff --git a/Source/WebCore/platform/glib/BatteryProviderUPower.cpp b/Source/WebCore/platform/glib/BatteryProviderUPower.cpp
new file mode 100644 (file)
index 0000000..6a9f1bf
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2013 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "BatteryProviderUPower.h"
+
+#if ENABLE(BATTERY_STATUS)
+
+#include "BatteryProviderUPowerClient.h"
+#include <cmath>
+#include <limits>
+#include <wtf/gobject/GOwnPtr.h>
+
+using namespace WebCore;
+
+static void powerDeviceAlterationCallback(UpClient* upowerClient, UpDevice* upowerDevice, BatteryProviderUPower* provider)
+{
+    UpDeviceKind deviceKind;
+    g_object_get(upowerDevice, "kind", &deviceKind, nullptr);
+    if (deviceKind != UP_DEVICE_KIND_BATTERY)
+        return;
+
+    provider->updateBatteryStatus();
+}
+
+BatteryProviderUPower::BatteryProviderUPower(BatteryProviderUPowerClient* client)
+    : m_client(client)
+    , m_isUpdating(false)
+{
+    ASSERT(m_client);
+}
+
+void BatteryProviderUPower::startUpdating()
+{
+    ASSERT(!m_upowerClient);
+    m_upowerClient = adoptGRef(up_client_new());
+
+    GOwnPtr<GError> error;
+    if (!up_client_enumerate_devices_sync(m_upowerClient.get(), 0, &error.outPtr())) {
+        m_client->updateBatteryStatus(NotAvailable);
+        return;
+    }
+
+    g_signal_connect(m_upowerClient.get(), "device-changed", G_CALLBACK(powerDeviceAlterationCallback), this);
+    g_signal_connect(m_upowerClient.get(), "device-added", G_CALLBACK(powerDeviceAlterationCallback), this);
+    g_signal_connect(m_upowerClient.get(), "device-removed", G_CALLBACK(powerDeviceAlterationCallback), this);
+
+    m_isUpdating = true;
+    updateBatteryStatus();
+}
+
+void BatteryProviderUPower::stopUpdating()
+{
+    m_upowerClient.clear();
+    m_isUpdating = false;
+}
+
+void BatteryProviderUPower::updateBatteryStatus()
+{
+    if (!m_isUpdating)
+        return;
+
+    GPtrArray* devices = up_client_get_devices(m_upowerClient.get());
+    if (!devices) {
+        m_client->updateBatteryStatus(NotAvailable);
+        return;
+    }
+
+    unsigned numOfBatteryDevices = 0;
+    double combinedEnergyCapacityCurrent = 0, combinedEnergyCapacityFull = 0, combinedEnergyRate = 0;
+
+    for (unsigned i = 0; i < devices->len; i++) {
+        UpDevice* device = static_cast<UpDevice*>(g_ptr_array_index(devices, i));
+        UpDeviceKind deviceKind;
+        UpDeviceState deviceState;
+        bool isPresent;
+        double energyCapacityCurrent = 0, energyCapacityEmpty = 0, energyCapacityFull = 0, energyRate = 0;
+
+        g_object_get(device,
+            "energy", &energyCapacityCurrent,
+            "energy-empty", &energyCapacityEmpty,
+            "energy-full", &energyCapacityFull,
+            "energy-rate", &energyRate,
+            "is-present", &isPresent,
+            "kind", &deviceKind,
+            "state", &deviceState,
+            nullptr);
+
+        if (deviceKind != UP_DEVICE_KIND_BATTERY || !isPresent)
+            continue;
+
+        numOfBatteryDevices++;
+        combinedEnergyCapacityCurrent += energyCapacityCurrent - energyCapacityEmpty;
+        combinedEnergyCapacityFull += energyCapacityFull;
+        // Added energy rate should be signed according to the charging/discharging state.
+        combinedEnergyRate += deviceState == UP_DEVICE_STATE_DISCHARGING ? -energyRate : energyRate;
+    }
+
+    g_ptr_array_unref(devices);
+
+    if (!numOfBatteryDevices) {
+        m_client->updateBatteryStatus(NotAvailable);
+        return;
+    }
+
+    double level = 0;
+    if (combinedEnergyCapacityFull > 0)
+        level = combinedEnergyCapacityCurrent / combinedEnergyCapacityFull;
+
+    if (combinedEnergyRate >= 0) {
+        double chargingTime = std::numeric_limits<double>::infinity();
+        if (combinedEnergyRate)
+            chargingTime = 3600 * (combinedEnergyCapacityFull - combinedEnergyCapacityCurrent) / combinedEnergyRate;
+        m_client->updateBatteryStatus(Charging, chargingTime, level);
+    } else {
+        double dischargingTime = 3600 * combinedEnergyCapacityCurrent / std::abs(combinedEnergyRate);
+        m_client->updateBatteryStatus(Discharging, dischargingTime, level);
+    }
+}
+
+#endif // ENABLE(BATTERY_STATUS)
diff --git a/Source/WebCore/platform/glib/BatteryProviderUPower.h b/Source/WebCore/platform/glib/BatteryProviderUPower.h
new file mode 100644 (file)
index 0000000..d1609bb
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2013 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef BatteryProviderUPower_h
+#define BatteryProviderUPower_h
+
+#if ENABLE(BATTERY_STATUS)
+
+#include <libupower-glib/upower.h>
+#include <wtf/gobject/GRefPtr.h>
+
+namespace WebCore {
+
+class BatteryProviderUPowerClient;
+
+class BatteryProviderUPower {
+public:
+    BatteryProviderUPower(BatteryProviderUPowerClient*);
+
+    void startUpdating();
+    void stopUpdating();
+
+    void updateBatteryStatus();
+
+private:
+    BatteryProviderUPowerClient* m_client;
+
+    GRefPtr<UpClient> m_upowerClient;
+
+    bool m_isUpdating;
+};
+
+}
+
+#endif // ENABLE(BATTERY_STATUS)
+
+#endif // BatteryProviderUPower_h
diff --git a/Source/WebCore/platform/glib/BatteryProviderUPowerClient.h b/Source/WebCore/platform/glib/BatteryProviderUPowerClient.h
new file mode 100644 (file)
index 0000000..6ea81f2
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2013 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef BatteryProviderUPowerClient_h
+#define BatteryProviderUPowerClient_h
+
+#if ENABLE(BATTERY_STATUS)
+
+namespace WebCore {
+
+enum BatteryProviderUPowerStatus {
+    NotAvailable = 0,
+    Charging,
+    Discharging,
+};
+
+class BatteryProviderUPowerClient {
+public:
+    virtual void updateBatteryStatus(BatteryProviderUPowerStatus, double secondsRemaining = 0, double batteryLevel = 0) = 0;
+};
+
+}
+
+#endif // ENABLE(BATTERY_STATUS)
+
+#endif // BatteryProviderUPowerClient_h
index d553c65..33aefcb 100644 (file)
@@ -1,5 +1,14 @@
 2013-12-11  José Dapena Paz  <jdapena@igalia.com> and Zan Dobersek  <zdobersek@igalia.com>
 
+        [GTK] Add a UPower-based BatteryProvider
+        https://bugs.webkit.org/show_bug.cgi?id=115719
+
+        Reviewed by Martin Robinson.
+
+        * GNUmakefile.am: Link the libwebkigtk library against the upower-glib library.
+
+2013-12-11  José Dapena Paz  <jdapena@igalia.com> and Zan Dobersek  <zdobersek@igalia.com>
+
         [GTK][WK1] Add an empty BatteryClientGtk
         https://bugs.webkit.org/show_bug.cgi?id=115628
 
index 3c81104..09d3831 100644 (file)
@@ -126,6 +126,7 @@ libwebkitgtk_@WEBKITGTK_API_MAJOR_VERSION@_@WEBKITGTK_API_MINOR_VERSION@_la_LIBA
        $(PNG_LIBS) \
        $(SQLITE3_LIBS) \
        $(UNICODE_LIBS) \
+       $(UPOWER_GLIB_LIBS) \
        $(WEBP_LIBS) \
        $(XCOMPOSITE_LIBS) \
        $(XDAMAGE_LIBS) \
index 0ea34df..2835e46 100644 (file)
@@ -1,3 +1,12 @@
+2013-12-11  José Dapena Paz  <jdapena@igalia.com> and Zan Dobersek  <zdobersek@igalia.com>
+
+        [GTK] Add a UPower-based BatteryProvider
+        https://bugs.webkit.org/show_bug.cgi?id=115719
+
+        Reviewed by Martin Robinson.
+
+        * GNUmakefile.am: Link the libwebkit2gtk library against the upower-glib library.
+
 2013-12-11  Gustavo Noronha Silva  <gns@gnome.org>
 
         [GTK] Support right-side attachment of the inspector
index 18177c3..5f07b73 100644 (file)
@@ -285,6 +285,7 @@ libwebkit2gtk_@WEBKITGTK_API_MAJOR_VERSION@_@WEBKITGTK_API_MINOR_VERSION@_la_LIB
        $(PNG_LIBS) \
        $(SQLITE3_LIBS) \
        $(UNICODE_LIBS) \
+       $(UPOWER_GLIB_LIBS) \
        $(WEBP_LIBS) \
        $(XRENDER_LIBS) \
        $(XCOMPOSITE_LIBS) \