Revert "Get power info from power manager instead of upower"
This reverts commit 33c7e10e16f8b3f25929ab139fb30abc745838a4
Change-Id: I1fcdfab9cbd18c1ae408adba78caacd15c99e34a
Reviewed-on: http://gerrit.chromium.org/gerrit/4747
Reviewed-by: Peter Mayo <petermayo@chromium.org>
Tested-by: Peter Mayo <petermayo@chromium.org>
diff --git a/chromeos_power.cc b/chromeos_power.cc
index d8db165..f4fc024 100644
--- a/chromeos_power.cc
+++ b/chromeos_power.cc
@@ -1,13 +1,9 @@
-// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+// Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos_power.h"
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
-
#include <cstdlib>
#include <cstring>
#include <exception>
@@ -27,62 +23,154 @@
namespace { // NOLINT
-bool GetPowerProperty(const dbus::Proxy& proxy,
- const char *param_name,
- GType data_type,
- void *result) {
- GError* error = NULL;
- // Use a dbus call to read the requested parameter.
- if(!dbus_g_proxy_call(proxy.gproxy(), "GetProperty", &error,
- G_TYPE_STRING, param_name,
- G_TYPE_INVALID,
- data_type, result,
- G_TYPE_INVALID)) {
- LOG(WARNING) << (error->message ? error->message : "GetProperty failed.");
+bool RetrieveBatteryStatus(const glib::ScopedHashTable& table,
+ PowerStatus* status) {
+ bool success = true;
+ success &= table.Retrieve("Energy", &status->battery_energy);
+ success &= table.Retrieve("EnergyRate", &status->battery_energy_rate);
+ success &= table.Retrieve("Voltage", &status->battery_voltage);
+ success &= table.Retrieve("TimeToEmpty", &status->battery_time_to_empty);
+ success &= table.Retrieve("TimeToFull", &status->battery_time_to_full);
+ success &= table.Retrieve("Percentage", &status->battery_percentage);
+ success &= table.Retrieve("IsPresent", &status->battery_is_present);
+
+ ::uint32 state = 0;
+ success &= table.Retrieve("State", &state);
+ status->battery_state = BatteryState(state);
+
+ return success;
+}
+
+// If the battery proxy is empty, then clear the battery status, otherwise
+// retrieve the battery status from the proxy.
+
+bool RetrieveBatteryStatus(const dbus::Proxy& battery,
+ PowerStatus* status) {
+ if (!battery) {
+ // Clear the battery status but don't overwrite the line_power status.
+ const PowerStatus zero_battery = { status->line_power_on };
+ *status = zero_battery;
+ return true;
+ }
+
+ glib::ScopedHashTable table;
+
+ if (!dbus::RetrieveProperties(battery,
+ "org.freedesktop.UPower.Device",
+ &table))
+ return false;
+
+ return RetrieveBatteryStatus(table, status);
+}
+
+bool RetrieveLinePowerStatus(const dbus::Proxy& line_power,
+ PowerStatus* status) {
+ if (!line_power) {
+ status->line_power_on = true;
+ return true;
+ }
+ return dbus::RetrieveProperty(line_power,
+ "org.freedesktop.UPower.Device",
+ "online",
+ &status->line_power_on);
+}
+
+// Will return the battery and line_power proxies if available, otherwise they
+// are left unchanged. An error code is not returned because the devices may
+// not be present (such as within a virtual machine for QE).
+
+bool RetrievePowerDeviceProxies(const dbus::BusConnection& bus,
+ const dbus::Proxy& power,
+ dbus::Proxy* battery,
+ dbus::Proxy* line_power) {
+ typedef glib::ScopedPtrArray<const char*> ScopedPtrArray;
+ typedef ScopedPtrArray::iterator iterator;
+
+ ScopedPtrArray devices;
+
+ if (!dbus::CallPtrArray(power, "EnumerateDevices", &devices)) {
+ DLOG(WARNING) << "Could not enumerate power devices.";
return false;
}
+
+ // Iterate the devices and pull out the first battery and line-power.
+
+ const char* battery_name = NULL;
+ const char* line_power_name = NULL;
+
+ // REVISIT (seanparent) : There is some kind of algorithm here which
+ // splits a sequence to a set of outputs where each output is associated
+ // with a predicate. A from of a multi-out copy_if
+ //
+ // copy_if(range, pred1, out1, pred2, out2, ...)
+
+ for (iterator f = devices.begin(), l = devices.end(); f != l; ++f) {
+ dbus::Proxy proxy(bus,
+ "org.freedesktop.UPower",
+ *f,
+ "org.freedesktop.DBus.Properties");
+ ::uint32 type;
+ if (!dbus::RetrieveProperty(proxy,
+ "org.freedesktop.UPower.Device",
+ "type",
+ &type))
+ return NULL;
+
+ if (!battery_name && type == 2)
+ battery_name = *f;
+ else if (!line_power_name && type == 1)
+ line_power_name = *f;
+ }
+
+ DLOG_IF(WARNING, !battery_name) << "Battery is missing!";
+ DLOG_IF(WARNING, !line_power_name) << "Line power is missing!";
+
+ if (battery_name)
+ *battery = dbus::Proxy(bus,
+ "org.freedesktop.UPower",
+ battery_name,
+ "org.freedesktop.DBus.Properties");
+
+ if (line_power_name)
+ *line_power = dbus::Proxy(bus,
+ "org.freedesktop.UPower",
+ line_power_name,
+ "org.freedesktop.DBus.Properties");
+
return true;
}
-bool RetrievePowerStatus(const dbus::Proxy& proxy, PowerStatus* status) {
-#define GET_PROPERTY(proxy, object, type, property) \
- GetPowerProperty(proxy, #property, type, &(object)->property)
- if (!GET_PROPERTY(proxy, status, G_TYPE_BOOLEAN, line_power_on) ||
- !GET_PROPERTY(proxy, status, G_TYPE_DOUBLE, battery_energy) ||
- !GET_PROPERTY(proxy, status, G_TYPE_DOUBLE, battery_energy_rate) ||
- !GET_PROPERTY(proxy, status, G_TYPE_DOUBLE, battery_voltage) ||
- !GET_PROPERTY(proxy, status, G_TYPE_INT64, battery_time_to_empty) ||
- !GET_PROPERTY(proxy, status, G_TYPE_INT64, battery_time_to_full) ||
- !GET_PROPERTY(proxy, status, G_TYPE_DOUBLE, battery_percentage) ||
- !GET_PROPERTY(proxy, status, G_TYPE_BOOLEAN, battery_is_present) ||
- !GET_PROPERTY(proxy, status, G_TYPE_INT, battery_state)) {
- return false;
- }
-#undef GET_PROPERTY
- return true;
-}
-
-} // namespace
+} // namespace
class OpaquePowerStatusConnection {
public:
typedef dbus::MonitorConnection<void (const char*)>* ConnectionType;
OpaquePowerStatusConnection(const PowerStatus& status,
- const dbus::Proxy& proxy,
+ const dbus::Proxy& battery,
+ const dbus::Proxy& line_power,
const PowerMonitor& monitor,
void* object)
: status_(status),
- proxy_(proxy),
+ battery_(battery),
+ line_power_(line_power),
monitor_(monitor),
object_(object),
connection_(NULL) {
}
- void Run() {
- if (!RetrievePowerStatus(proxy_, &status_))
+ static void Run(void* object, const char* device) {
+ PowerStatusConnection self = static_cast<PowerStatusConnection>(object);
+
+ if (self->battery_ && std::strcmp(device, self->battery_.path()) == 0)
+ RetrieveBatteryStatus(self->battery_, &self->status_);
+ else if (self->line_power_
+ && std::strcmp(device, self->line_power_.path()) == 0)
+ RetrieveLinePowerStatus(self->line_power_, &self->status_);
+ else
return;
- monitor_(object_, status_);
+
+ self->monitor_(self->object_, self->status_);
}
ConnectionType& connection() {
@@ -91,67 +179,45 @@
private:
PowerStatus status_;
- dbus::Proxy proxy_;
+ dbus::Proxy battery_;
+ dbus::Proxy line_power_;
PowerMonitor monitor_;
void* object_;
ConnectionType connection_;
};
-namespace { // NOLINT
-
-DBusHandlerResult DBusMessageHandler(DBusConnection* connection,
- DBusMessage* message,
- void* data) {
- OpaquePowerStatusConnection* power_connection =
- static_cast<OpaquePowerStatusConnection*>(data);
-
- if (dbus_message_is_signal(message, power_manager::kPowerManagerInterface,
- "PowerSupplyPoll")) {
- power_connection->Run();
- return DBUS_HANDLER_RESULT_HANDLED;
- }
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-} // namespace
-
extern "C"
PowerStatusConnection ChromeOSMonitorPowerStatus(PowerMonitor monitor,
void* object) {
-
dbus::BusConnection bus = dbus::GetSystemBusConnection();
+ dbus::Proxy power(bus,
+ "org.freedesktop.UPower",
+ "/org/freedesktop/UPower",
+ "org.freedesktop.UPower");
- dbus::Proxy power_status_proxy(bus,
- power_manager::kPowerManagerServiceName,
- power_manager::kPowerManagerServicePath,
- power_manager::kPowerManagerInterface);
+ dbus::Proxy battery;
+ dbus::Proxy line_power;
+
+
+ if (!RetrievePowerDeviceProxies(bus, power, &battery, &line_power))
+ return NULL;
+
PowerStatus status = { };
- RetrievePowerStatus(power_status_proxy, &status);
+ if (!RetrieveBatteryStatus(battery, &status))
+ return NULL;
+
+ if (!RetrieveLinePowerStatus(line_power, &status))
+ return NULL;
+
monitor(object, status);
- PowerStatusConnection result =
- new OpaquePowerStatusConnection(status,
- power_status_proxy,
- monitor,
- object);
+ PowerStatusConnection result = new OpaquePowerStatusConnection(status,
+ battery, line_power, monitor, object);
- DBusConnection* connection = dbus_g_connection_get_connection(
- bus.g_connection());
- CHECK(connection);
-
- DBusError error;
- dbus_error_init(&error);
- std::string match = StringPrintf("type='signal', interface='%s'",
- power_manager::kPowerManagerInterface);
- dbus_bus_add_match(connection, match.c_str(), &error);
- if (dbus_error_is_set(&error)) {
- LOG(DFATAL) << "Failed to add match \"" << match << "\": "
- << error.name << ", message=" << error.message;
- }
-
- CHECK(dbus_connection_add_filter(connection, &DBusMessageHandler, result,
- NULL));
+ result->connection() = dbus::Monitor(power, "DeviceChanged",
+ &OpaquePowerStatusConnection::Run,
+ result);
return result;
}
@@ -166,9 +232,85 @@
extern "C"
bool ChromeOSRetrievePowerInformation(PowerInformation* info) {
- // Func has been stubbed out because some functions it calls has been removed.
- // It will be removed at a later time.
- return true;
+ dbus::BusConnection bus = dbus::GetSystemBusConnection();
+ dbus::Proxy power(bus,
+ "org.freedesktop.UPower",
+ "/org/freedesktop/UPower",
+ "org.freedesktop.UPower");
+
+ dbus::Proxy battery;
+ dbus::Proxy line_power;
+
+ if (!RetrievePowerDeviceProxies(bus, power, &battery, &line_power))
+ return false;
+
+ glib::ScopedHashTable battery_table;
+ glib::ScopedHashTable line_power_table;
+
+ if (!dbus::RetrieveProperties(battery,
+ "org.freedesktop.UPower.Device",
+ &battery_table))
+ return false;
+
+ if (!dbus::RetrieveProperties(line_power,
+ "org.freedesktop.UPower.Device",
+ &line_power_table))
+ return false;
+
+ // NOTE (seanparent) : If this code needs to be made thread safe in the
+ // future then the info_g should be moved to thread local storage.
+
+ static bool init = false;
+ static PowerInformation info_g = {};
+
+ bool success = true;
+
+ if (!init) {
+ success &= battery_table.Retrieve("EnergyEmpty",
+ &info_g.battery_energy_empty);
+ success &= battery_table.Retrieve("EnergyFull",
+ &info_g.battery_energy_full);
+ success &= battery_table.Retrieve("EnergyFullDesign",
+ &info_g.battery_energy_full_design);
+ success &= battery_table.Retrieve("IsRechargable",
+ &info_g.battery_is_rechargeable);
+
+ ::uint32 technology = 0;
+ success &= battery_table.Retrieve("Technology", &technology);
+ info_g.battery_technology = BatteryTechnology(technology);
+
+ // We malloc space for the strings and simply leak them.
+ const char* tmp = "";
+
+ success &= battery_table.Retrieve("Vendor", &tmp);
+ info_g.battery_vendor = NewStringCopy(tmp);
+
+ success &= battery_table.Retrieve("Model", &tmp);
+ info_g.battery_model = NewStringCopy(tmp);
+
+ success &= battery_table.Retrieve("Serial", &tmp);
+ info_g.battery_serial = NewStringCopy(tmp);
+
+ success &= line_power_table.Retrieve("Vendor", &tmp);
+ info_g.line_power_vendor = NewStringCopy(tmp);
+
+ success &= line_power_table.Retrieve("Model", &tmp);
+ info_g.line_power_model = NewStringCopy(tmp);
+
+ success &= line_power_table.Retrieve("Serial", &tmp);
+ info_g.line_power_serial = NewStringCopy(tmp);
+
+ init = success;
+ }
+
+ *info = info_g;
+
+ success &= RetrieveBatteryStatus(battery_table,
+ &info->power_status);
+ success &= line_power_table.Retrieve("Online",
+ &info->power_status.line_power_on);
+
+ return success;
}
extern "C"