/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/** * This is the declaration of UPowerClient class. This class is listening and * communicating to upower daemon through DBus. * There is no header file because this class shouldn't be public.
*/ class UPowerClient { public: static UPowerClient* GetInstance();
/** * Update the currently tracked device.
*/ void UpdateTrackedDevices();
/** * Update the battery info.
*/ bool GetBatteryInfo();
/** * Watch battery device for status
*/ bool AddTrackedDevice(constchar* devicePath);
/** * Callback used by 'DeviceChanged' signal.
*/ staticvoid DeviceChanged(GDBusProxy* aProxy, gchar* aSenderName,
gchar* aSignalName, GVariant* aParameters,
UPowerClient* aListener);
/** * Callback used by 'PropertiesChanged' signal. * This method is called when the the battery level changes. * (Only with upower >= 0.99)
*/ staticvoid DevicePropertiesChanged(GDBusProxy* aProxy, gchar* aSenderName,
gchar* aSignalName, GVariant* aParameters,
UPowerClient* aListener);
RefPtr<GCancellable> mCancellable;
// The DBus proxy object to upower.
RefPtr<GDBusProxy> mUPowerProxy;
// The path of the tracked device.
GUniquePtr<gchar> mTrackedDevice;
// The DBusGProxy for the tracked device.
RefPtr<GDBusProxy> mTrackedDeviceProxy;
UPowerClient::~UPowerClient() {
NS_ASSERTION(
!mUPowerProxy && !mTrackedDevice && !mTrackedDeviceProxy && !mCancellable, "The observers have not been correctly removed! " "(StopListening should have been called)");
}
// We should now show the default values, not the latest we got.
mLevel = kDefaultLevel;
mCharging = kDefaultCharging;
mRemainingTime = kDefaultRemainingTime;
}
DBusProxyCall(mUPowerProxy, "EnumerateDevices", nullptr,
G_DBUS_CALL_FLAGS_NONE, -1, mCancellable)
->Then(
GetCurrentSerialEventTarget(), __func__, // It's safe to capture this as we use mCancellable to stop // listening.
[this](RefPtr<GVariant>&& aResult) {
RefPtr<GVariant> variant =
dont_AddRef(g_variant_get_child_value(aResult.get(), 0)); if (!variant || !g_variant_is_of_type(
variant, G_VARIANT_TYPE_OBJECT_PATH_ARRAY)) {
g_warning( "Failed to enumerate devices of org.freedesktop.UPower: " "wrong param %s\n",
g_variant_get_type_string(aResult.get())); return;
}
gsize num = g_variant_n_children(variant); for (gsize i = 0; i < num; i++) { constchar* devicePath = g_variant_get_string(
g_variant_get_child_value(variant, i), nullptr); if (!devicePath) {
g_warning( "Failed to enumerate devices of org.freedesktop.UPower: " "missing device?\n"); return;
} /* * We are looking for the first device that is a battery. * TODO: we could try to combine more than one battery.
*/ if (AddTrackedDevice(devicePath)) { break;
}
}
g_signal_connect(mUPowerProxy, "g-signal",
G_CALLBACK(DeviceChanged), this);
},
[this](GUniquePtr<GError>&& aError) { if (!g_error_matches(aError.get(), G_IO_ERROR,
G_IO_ERROR_CANCELLED)) {
g_warning( "Failed to enumerate devices of org.freedesktop.UPower: %s\n",
aError->message);
}
g_signal_connect(mUPowerProxy, "g-signal",
G_CALLBACK(DeviceChanged), this);
});
}
/* static */ void UPowerClient::DeviceChanged(GDBusProxy* aProxy, gchar* aSenderName,
gchar* aSignalName, GVariant* aParameters,
UPowerClient* aListener) { // Added new device. Act only if we're missing any tracked device if (!g_strcmp0(aSignalName, "DeviceAdded")) { if (aListener->mTrackedDevice) { return;
}
} elseif (!g_strcmp0(aSignalName, "DeviceRemoved")) { if (g_strcmp0(aSenderName, aListener->mTrackedDevice.get())) { return;
}
}
aListener->UpdateTrackedDevices();
}
/* * State values are confusing... * First of all, after looking at upower sources (0.9.13), it seems that * PendingDischarge and PendingCharge are not used. * In addition, FullyCharged and Empty states are not clear because we do not * know if the battery is actually charging or not. Those values come directly * from sysfs (in the Linux kernel) which have four states: "Empty", "Full", * "Charging" and "Discharging". In sysfs, "Empty" and "Full" are also only * related to the level, not to the charging state. * In this code, we are going to assume that Full means charging and Empty * means discharging because if that is not the case, the state should not * last a long time (actually, it should disappear at the following update). * It might be even very hard to see real cases where the state is Empty and * the battery is charging or the state is Full and the battery is discharging * given that plugging/unplugging the battery should have an impact on the * level.
*/
if (!mTrackedDeviceProxy) { returnfalse;
}
RefPtr<GVariant> value = dont_AddRef(
g_dbus_proxy_get_cached_property(mTrackedDeviceProxy, "State")); if (NS_WARN_IF(!value ||
!g_variant_is_of_type(value, G_VARIANT_TYPE_UINT32))) { returnfalse;
}
switch (g_variant_get_uint32(value)) { case eState_Unknown:
mCharging = kDefaultCharging; break; case eState_FullyCharged:
isFull = true;
[[fallthrough]]; case eState_Charging: case eState_PendingCharge:
mCharging = true; break; case eState_Discharging: case eState_Empty: case eState_PendingDischarge:
mCharging = false; break;
}
/* * The battery level might be very close to 100% (like 99%) without * increasing. It seems that upower sets the battery state as 'full' in that * case so we should trust it and not even try to get the value.
*/ if (isFull) {
mLevel = 1.0;
} else {
value = dont_AddRef(
g_dbus_proxy_get_cached_property(mTrackedDeviceProxy, "Percentage")); if (NS_WARN_IF(!value ||
!g_variant_is_of_type(value, G_VARIANT_TYPE_DOUBLE))) { returnfalse;
}
mLevel = round(g_variant_get_double(value)) * 0.01;
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.15Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.