mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-30 04:17:31 +09:00
Issue #1391 - Remove the DOM battery API
This commit is contained in:
parent
d97bcfb97a
commit
b33e80b186
30 changed files with 0 additions and 1833 deletions
53
hal/Hal.cpp
53
hal/Hal.cpp
|
|
@ -264,30 +264,6 @@ private:
|
|||
bool mHasValidCache;
|
||||
};
|
||||
|
||||
class BatteryObserversManager : public CachingObserversManager<BatteryInformation>
|
||||
{
|
||||
protected:
|
||||
void EnableNotifications() {
|
||||
PROXY_IF_SANDBOXED(EnableBatteryNotifications());
|
||||
}
|
||||
|
||||
void DisableNotifications() {
|
||||
PROXY_IF_SANDBOXED(DisableBatteryNotifications());
|
||||
}
|
||||
|
||||
void GetCurrentInformationInternal(BatteryInformation* aInfo) {
|
||||
PROXY_IF_SANDBOXED(GetCurrentBatteryInformation(aInfo));
|
||||
}
|
||||
};
|
||||
|
||||
static BatteryObserversManager&
|
||||
BatteryObservers()
|
||||
{
|
||||
static BatteryObserversManager sBatteryObservers;
|
||||
AssertMainThread();
|
||||
return sBatteryObservers;
|
||||
}
|
||||
|
||||
class NetworkObserversManager : public CachingObserversManager<NetworkInformation>
|
||||
{
|
||||
protected:
|
||||
|
|
@ -356,35 +332,6 @@ ScreenConfigurationObservers()
|
|||
return sScreenConfigurationObservers;
|
||||
}
|
||||
|
||||
void
|
||||
RegisterBatteryObserver(BatteryObserver* aObserver)
|
||||
{
|
||||
AssertMainThread();
|
||||
BatteryObservers().AddObserver(aObserver);
|
||||
}
|
||||
|
||||
void
|
||||
UnregisterBatteryObserver(BatteryObserver* aObserver)
|
||||
{
|
||||
AssertMainThread();
|
||||
BatteryObservers().RemoveObserver(aObserver);
|
||||
}
|
||||
|
||||
void
|
||||
GetCurrentBatteryInformation(BatteryInformation* aInfo)
|
||||
{
|
||||
AssertMainThread();
|
||||
*aInfo = BatteryObservers().GetCurrentInformation();
|
||||
}
|
||||
|
||||
void
|
||||
NotifyBatteryChange(const BatteryInformation& aInfo)
|
||||
{
|
||||
AssertMainThread();
|
||||
BatteryObservers().CacheInformation(aInfo);
|
||||
BatteryObservers().BroadcastCachedInformation();
|
||||
}
|
||||
|
||||
bool GetScreenEnabled()
|
||||
{
|
||||
AssertMainThread();
|
||||
|
|
|
|||
24
hal/Hal.h
24
hal/Hal.h
|
|
@ -10,7 +10,6 @@
|
|||
#include "base/basictypes.h"
|
||||
#include "base/platform_thread.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/dom/battery/Types.h"
|
||||
#include "mozilla/dom/MozPowerManagerBinding.h"
|
||||
#include "mozilla/dom/network/Types.h"
|
||||
#include "mozilla/dom/power/Types.h"
|
||||
|
|
@ -87,29 +86,6 @@ void Vibrate(const nsTArray<uint32_t>& pattern,
|
|||
void CancelVibrate(nsPIDOMWindowInner* aWindow);
|
||||
void CancelVibrate(const hal::WindowIdentifier &id);
|
||||
|
||||
/**
|
||||
* Inform the battery backend there is a new battery observer.
|
||||
* @param aBatteryObserver The observer that should be added.
|
||||
*/
|
||||
void RegisterBatteryObserver(BatteryObserver* aBatteryObserver);
|
||||
|
||||
/**
|
||||
* Inform the battery backend a battery observer unregistered.
|
||||
* @param aBatteryObserver The observer that should be removed.
|
||||
*/
|
||||
void UnregisterBatteryObserver(BatteryObserver* aBatteryObserver);
|
||||
|
||||
/**
|
||||
* Returns the current battery information.
|
||||
*/
|
||||
void GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo);
|
||||
|
||||
/**
|
||||
* Notify of a change in the battery state.
|
||||
* @param aBatteryInfo The new battery information.
|
||||
*/
|
||||
void NotifyBatteryChange(const hal::BatteryInformation& aBatteryInfo);
|
||||
|
||||
/**
|
||||
* Determine whether the device's screen is currently enabled.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,325 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim set: sw=2 ts=2 et lcs=trail\:.,tab\:>~ : */
|
||||
/* 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/. */
|
||||
|
||||
#import <CoreFoundation/CoreFoundation.h>
|
||||
#import <IOKit/ps/IOPowerSources.h>
|
||||
#import <IOKit/ps/IOPSKeys.h>
|
||||
|
||||
#include <mozilla/Hal.h>
|
||||
#include <mozilla/dom/battery/Constants.h>
|
||||
#include <mozilla/Services.h>
|
||||
|
||||
#include <nsIObserverService.h>
|
||||
#include <nsIObserver.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#define IOKIT_FRAMEWORK_PATH "/System/Library/Frameworks/IOKit.framework/IOKit"
|
||||
|
||||
#ifndef kIOPSTimeRemainingUnknown
|
||||
#define kIOPSTimeRemainingUnknown ((CFTimeInterval)-1.0)
|
||||
#endif
|
||||
#ifndef kIOPSTimeRemainingUnlimited
|
||||
#define kIOPSTimeRemainingUnlimited ((CFTimeInterval)-2.0)
|
||||
#endif
|
||||
|
||||
using namespace mozilla::dom::battery;
|
||||
|
||||
namespace mozilla {
|
||||
namespace hal_impl {
|
||||
|
||||
typedef CFTimeInterval (*IOPSGetTimeRemainingEstimateFunc)(void);
|
||||
|
||||
class MacPowerInformationService
|
||||
{
|
||||
public:
|
||||
static MacPowerInformationService* GetInstance();
|
||||
static void Shutdown();
|
||||
static bool IsShuttingDown();
|
||||
|
||||
void BeginListening();
|
||||
void StopListening();
|
||||
|
||||
static void HandleChange(void *aContext);
|
||||
|
||||
~MacPowerInformationService();
|
||||
|
||||
private:
|
||||
MacPowerInformationService();
|
||||
|
||||
// The reference to the runloop that is notified of power changes.
|
||||
CFRunLoopSourceRef mRunLoopSource;
|
||||
|
||||
double mLevel;
|
||||
bool mCharging;
|
||||
double mRemainingTime;
|
||||
bool mShouldNotify;
|
||||
|
||||
friend void GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo);
|
||||
|
||||
static MacPowerInformationService* sInstance;
|
||||
static bool sShuttingDown;
|
||||
|
||||
static void* sIOKitFramework;
|
||||
static IOPSGetTimeRemainingEstimateFunc sIOPSGetTimeRemainingEstimate;
|
||||
};
|
||||
|
||||
void* MacPowerInformationService::sIOKitFramework;
|
||||
IOPSGetTimeRemainingEstimateFunc MacPowerInformationService::sIOPSGetTimeRemainingEstimate;
|
||||
|
||||
/*
|
||||
* Implementation of mozilla::hal_impl::EnableBatteryNotifications,
|
||||
* mozilla::hal_impl::DisableBatteryNotifications,
|
||||
* and mozilla::hal_impl::GetCurrentBatteryInformation.
|
||||
*/
|
||||
|
||||
void
|
||||
EnableBatteryNotifications()
|
||||
{
|
||||
if (!MacPowerInformationService::IsShuttingDown()) {
|
||||
MacPowerInformationService::GetInstance()->BeginListening();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DisableBatteryNotifications()
|
||||
{
|
||||
if (!MacPowerInformationService::IsShuttingDown()) {
|
||||
MacPowerInformationService::GetInstance()->StopListening();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo)
|
||||
{
|
||||
MacPowerInformationService* powerService = MacPowerInformationService::GetInstance();
|
||||
|
||||
aBatteryInfo->level() = powerService->mLevel;
|
||||
aBatteryInfo->charging() = powerService->mCharging;
|
||||
aBatteryInfo->remainingTime() = powerService->mRemainingTime;
|
||||
}
|
||||
|
||||
bool MacPowerInformationService::sShuttingDown = false;
|
||||
|
||||
/*
|
||||
* Following is the implementation of MacPowerInformationService.
|
||||
*/
|
||||
|
||||
MacPowerInformationService* MacPowerInformationService::sInstance = nullptr;
|
||||
|
||||
namespace {
|
||||
struct SingletonDestroyer final : public nsIObserver
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
private:
|
||||
~SingletonDestroyer() {}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(SingletonDestroyer, nsIObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
SingletonDestroyer::Observe(nsISupports*, const char* aTopic, const char16_t*)
|
||||
{
|
||||
MOZ_ASSERT(!strcmp(aTopic, "xpcom-shutdown"));
|
||||
MacPowerInformationService::Shutdown();
|
||||
return NS_OK;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
/* static */ MacPowerInformationService*
|
||||
MacPowerInformationService::GetInstance()
|
||||
{
|
||||
if (sInstance) {
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
sInstance = new MacPowerInformationService();
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->AddObserver(new SingletonDestroyer(), "xpcom-shutdown", false);
|
||||
}
|
||||
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
bool
|
||||
MacPowerInformationService::IsShuttingDown()
|
||||
{
|
||||
return sShuttingDown;
|
||||
}
|
||||
|
||||
void
|
||||
MacPowerInformationService::Shutdown()
|
||||
{
|
||||
sShuttingDown = true;
|
||||
delete sInstance;
|
||||
sInstance = nullptr;
|
||||
}
|
||||
|
||||
MacPowerInformationService::MacPowerInformationService()
|
||||
: mRunLoopSource(nullptr)
|
||||
, mLevel(kDefaultLevel)
|
||||
, mCharging(kDefaultCharging)
|
||||
, mRemainingTime(kDefaultRemainingTime)
|
||||
, mShouldNotify(false)
|
||||
{
|
||||
// IOPSGetTimeRemainingEstimate (and the related constants) are only available
|
||||
// on 10.7, so we test for their presence at runtime.
|
||||
sIOKitFramework = dlopen(IOKIT_FRAMEWORK_PATH, RTLD_LAZY | RTLD_LOCAL);
|
||||
if (sIOKitFramework) {
|
||||
sIOPSGetTimeRemainingEstimate =
|
||||
(IOPSGetTimeRemainingEstimateFunc)dlsym(sIOKitFramework, "IOPSGetTimeRemainingEstimate");
|
||||
} else {
|
||||
sIOPSGetTimeRemainingEstimate = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
MacPowerInformationService::~MacPowerInformationService()
|
||||
{
|
||||
MOZ_ASSERT(!mRunLoopSource,
|
||||
"The observers have not been correctly removed! "
|
||||
"(StopListening should have been called)");
|
||||
|
||||
if (sIOKitFramework) {
|
||||
dlclose(sIOKitFramework);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacPowerInformationService::BeginListening()
|
||||
{
|
||||
// Set ourselves up to be notified about changes.
|
||||
MOZ_ASSERT(!mRunLoopSource, "IOPS Notification Loop Source already set up. "
|
||||
"(StopListening should have been called)");
|
||||
|
||||
mRunLoopSource = ::IOPSNotificationCreateRunLoopSource(HandleChange, this);
|
||||
if (mRunLoopSource) {
|
||||
::CFRunLoopAddSource(::CFRunLoopGetCurrent(), mRunLoopSource,
|
||||
kCFRunLoopDefaultMode);
|
||||
|
||||
// Invoke our callback now so we have data if GetCurrentBatteryInformation is
|
||||
// called before a change happens.
|
||||
HandleChange(this);
|
||||
mShouldNotify = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacPowerInformationService::StopListening()
|
||||
{
|
||||
MOZ_ASSERT(mRunLoopSource, "IOPS Notification Loop Source not set up. "
|
||||
"(StopListening without BeginListening)");
|
||||
|
||||
::CFRunLoopRemoveSource(::CFRunLoopGetCurrent(), mRunLoopSource,
|
||||
kCFRunLoopDefaultMode);
|
||||
mRunLoopSource = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
MacPowerInformationService::HandleChange(void* aContext) {
|
||||
MacPowerInformationService* power =
|
||||
static_cast<MacPowerInformationService*>(aContext);
|
||||
|
||||
CFTypeRef data = ::IOPSCopyPowerSourcesInfo();
|
||||
if (!data) {
|
||||
::CFRelease(data);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the list of power sources.
|
||||
CFArrayRef list = ::IOPSCopyPowerSourcesList(data);
|
||||
if (!list) {
|
||||
::CFRelease(list);
|
||||
return;
|
||||
}
|
||||
|
||||
// Default values. These will be used if there are 0 sources or we can't find
|
||||
// better information.
|
||||
double level = kDefaultLevel;
|
||||
double charging = kDefaultCharging;
|
||||
double remainingTime = kDefaultRemainingTime;
|
||||
|
||||
// Look for the first battery power source to give us the information we need.
|
||||
// Usually there's only 1 available, depending on current power source.
|
||||
for (CFIndex i = 0; i < ::CFArrayGetCount(list); ++i) {
|
||||
CFTypeRef source = ::CFArrayGetValueAtIndex(list, i);
|
||||
CFDictionaryRef currPowerSourceDesc = ::IOPSGetPowerSourceDescription(data, source);
|
||||
if (!currPowerSourceDesc) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get a battery level estimate. This key is required.
|
||||
int currentCapacity = 0;
|
||||
const void* cfRef = ::CFDictionaryGetValue(currPowerSourceDesc, CFSTR(kIOPSCurrentCapacityKey));
|
||||
::CFNumberGetValue((CFNumberRef)cfRef, kCFNumberSInt32Type, ¤tCapacity);
|
||||
|
||||
// This key is also required.
|
||||
int maxCapacity = 0;
|
||||
cfRef = ::CFDictionaryGetValue(currPowerSourceDesc, CFSTR(kIOPSMaxCapacityKey));
|
||||
::CFNumberGetValue((CFNumberRef)cfRef, kCFNumberSInt32Type, &maxCapacity);
|
||||
|
||||
if (maxCapacity > 0) {
|
||||
level = static_cast<double>(currentCapacity)/static_cast<double>(maxCapacity);
|
||||
}
|
||||
|
||||
// Find out if we're charging.
|
||||
// This key is optional, we fallback to kDefaultCharging if the current power
|
||||
// source doesn't have that info.
|
||||
if(::CFDictionaryGetValueIfPresent(currPowerSourceDesc, CFSTR(kIOPSIsChargingKey), &cfRef)) {
|
||||
charging = ::CFBooleanGetValue((CFBooleanRef)cfRef);
|
||||
|
||||
// Get an estimate of how long it's going to take until we're fully charged.
|
||||
// This key is optional.
|
||||
if (charging) {
|
||||
// Default value that will be changed if we happen to find the actual
|
||||
// remaining time.
|
||||
remainingTime = level == 1.0 ? kDefaultRemainingTime : kUnknownRemainingTime;
|
||||
|
||||
if (::CFDictionaryGetValueIfPresent(currPowerSourceDesc,
|
||||
CFSTR(kIOPSTimeToFullChargeKey), &cfRef)) {
|
||||
int timeToCharge;
|
||||
::CFNumberGetValue((CFNumberRef)cfRef, kCFNumberIntType, &timeToCharge);
|
||||
if (timeToCharge != kIOPSTimeRemainingUnknown) {
|
||||
remainingTime = timeToCharge*60;
|
||||
}
|
||||
}
|
||||
} else if (sIOPSGetTimeRemainingEstimate) { // not charging
|
||||
// See if we can get a time estimate.
|
||||
CFTimeInterval estimate = sIOPSGetTimeRemainingEstimate();
|
||||
if (estimate == kIOPSTimeRemainingUnlimited || estimate == kIOPSTimeRemainingUnknown) {
|
||||
remainingTime = kUnknownRemainingTime;
|
||||
} else {
|
||||
remainingTime = estimate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
bool isNewData = level != power->mLevel || charging != power->mCharging ||
|
||||
remainingTime != power->mRemainingTime;
|
||||
|
||||
power->mRemainingTime = remainingTime;
|
||||
power->mCharging = charging;
|
||||
power->mLevel = level;
|
||||
|
||||
// Notify the observers if stuff changed.
|
||||
if (power->mShouldNotify && isNewData) {
|
||||
hal::NotifyBatteryChange(hal::BatteryInformation(power->mLevel,
|
||||
power->mCharging,
|
||||
power->mRemainingTime));
|
||||
}
|
||||
|
||||
::CFRelease(data);
|
||||
::CFRelease(list);
|
||||
}
|
||||
|
||||
} // namespace hal_impl
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et ft=cpp : */
|
||||
/* 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/. */
|
||||
|
||||
#include "Hal.h"
|
||||
#include "mozilla/dom/battery/Constants.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace hal_impl {
|
||||
|
||||
void
|
||||
EnableBatteryNotifications()
|
||||
{}
|
||||
|
||||
void
|
||||
DisableBatteryNotifications()
|
||||
{}
|
||||
|
||||
void
|
||||
GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo)
|
||||
{
|
||||
aBatteryInfo->level() = dom::battery::kDefaultLevel;
|
||||
aBatteryInfo->charging() = dom::battery::kDefaultCharging;
|
||||
aBatteryInfo->remainingTime() = dom::battery::kDefaultRemainingTime;
|
||||
}
|
||||
|
||||
} // hal_impl
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,508 +0,0 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#include "Hal.h"
|
||||
#include "HalLog.h"
|
||||
#include <dbus/dbus-glib.h>
|
||||
#include <dbus/dbus-glib-lowlevel.h>
|
||||
#include <mozilla/Attributes.h>
|
||||
#include <mozilla/dom/battery/Constants.h>
|
||||
#include "nsAutoRef.h"
|
||||
#include <cmath>
|
||||
|
||||
/*
|
||||
* Helper that manages the destruction of glib objects as soon as they leave
|
||||
* the current scope.
|
||||
*
|
||||
* We are specializing nsAutoRef class.
|
||||
*/
|
||||
|
||||
template <>
|
||||
class nsAutoRefTraits<GHashTable> : public nsPointerRefTraits<GHashTable>
|
||||
{
|
||||
public:
|
||||
static void Release(GHashTable* ptr) { g_hash_table_unref(ptr); }
|
||||
};
|
||||
|
||||
using namespace mozilla::dom::battery;
|
||||
|
||||
namespace mozilla {
|
||||
namespace hal_impl {
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
void BeginListening();
|
||||
void StopListening();
|
||||
|
||||
double GetLevel();
|
||||
bool IsCharging();
|
||||
double GetRemainingTime();
|
||||
|
||||
~UPowerClient();
|
||||
|
||||
private:
|
||||
UPowerClient();
|
||||
|
||||
enum States {
|
||||
eState_Unknown = 0,
|
||||
eState_Charging,
|
||||
eState_Discharging,
|
||||
eState_Empty,
|
||||
eState_FullyCharged,
|
||||
eState_PendingCharge,
|
||||
eState_PendingDischarge
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the currently tracked device.
|
||||
* @return whether everything went ok.
|
||||
*/
|
||||
void UpdateTrackedDeviceSync();
|
||||
|
||||
/**
|
||||
* Returns a hash table with the properties of aDevice.
|
||||
* Note: the caller has to unref the hash table.
|
||||
*/
|
||||
GHashTable* GetDevicePropertiesSync(DBusGProxy* aProxy);
|
||||
void GetDevicePropertiesAsync(DBusGProxy* aProxy);
|
||||
static void GetDevicePropertiesCallback(DBusGProxy* aProxy,
|
||||
DBusGProxyCall* aCall,
|
||||
void* aData);
|
||||
|
||||
/**
|
||||
* Using the device properties (aHashTable), this method updates the member
|
||||
* variable storing the values we care about.
|
||||
*/
|
||||
void UpdateSavedInfo(GHashTable* aHashTable);
|
||||
|
||||
/**
|
||||
* Callback used by 'DeviceChanged' signal.
|
||||
*/
|
||||
static void DeviceChanged(DBusGProxy* aProxy, const gchar* aObjectPath,
|
||||
UPowerClient* aListener);
|
||||
|
||||
/**
|
||||
* Callback used by 'PropertiesChanged' signal.
|
||||
* This method is called when the the battery level changes.
|
||||
* (Only with upower >= 0.99)
|
||||
*/
|
||||
static void PropertiesChanged(DBusGProxy* aProxy, const gchar*,
|
||||
GHashTable*, char**,
|
||||
UPowerClient* aListener);
|
||||
|
||||
/**
|
||||
* Callback called when mDBusConnection gets a signal.
|
||||
*/
|
||||
static DBusHandlerResult ConnectionSignalFilter(DBusConnection* aConnection,
|
||||
DBusMessage* aMessage,
|
||||
void* aData);
|
||||
|
||||
// The DBus connection object.
|
||||
DBusGConnection* mDBusConnection;
|
||||
|
||||
// The DBus proxy object to upower.
|
||||
DBusGProxy* mUPowerProxy;
|
||||
|
||||
// The path of the tracked device.
|
||||
gchar* mTrackedDevice;
|
||||
|
||||
// The DBusGProxy for the tracked device.
|
||||
DBusGProxy* mTrackedDeviceProxy;
|
||||
|
||||
double mLevel;
|
||||
bool mCharging;
|
||||
double mRemainingTime;
|
||||
|
||||
static UPowerClient* sInstance;
|
||||
|
||||
static const guint sDeviceTypeBattery = 2;
|
||||
static const guint64 kUPowerUnknownRemainingTime = 0;
|
||||
};
|
||||
|
||||
/*
|
||||
* Implementation of mozilla::hal_impl::EnableBatteryNotifications,
|
||||
* mozilla::hal_impl::DisableBatteryNotifications,
|
||||
* and mozilla::hal_impl::GetCurrentBatteryInformation.
|
||||
*/
|
||||
|
||||
void
|
||||
EnableBatteryNotifications()
|
||||
{
|
||||
UPowerClient::GetInstance()->BeginListening();
|
||||
}
|
||||
|
||||
void
|
||||
DisableBatteryNotifications()
|
||||
{
|
||||
UPowerClient::GetInstance()->StopListening();
|
||||
}
|
||||
|
||||
void
|
||||
GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo)
|
||||
{
|
||||
UPowerClient* upowerClient = UPowerClient::GetInstance();
|
||||
|
||||
aBatteryInfo->level() = upowerClient->GetLevel();
|
||||
aBatteryInfo->charging() = upowerClient->IsCharging();
|
||||
aBatteryInfo->remainingTime() = upowerClient->GetRemainingTime();
|
||||
}
|
||||
|
||||
/*
|
||||
* Following is the implementation of UPowerClient.
|
||||
*/
|
||||
|
||||
UPowerClient* UPowerClient::sInstance = nullptr;
|
||||
|
||||
/* static */ UPowerClient*
|
||||
UPowerClient::GetInstance()
|
||||
{
|
||||
if (!sInstance) {
|
||||
sInstance = new UPowerClient();
|
||||
}
|
||||
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
UPowerClient::UPowerClient()
|
||||
: mDBusConnection(nullptr)
|
||||
, mUPowerProxy(nullptr)
|
||||
, mTrackedDevice(nullptr)
|
||||
, mTrackedDeviceProxy(nullptr)
|
||||
, mLevel(kDefaultLevel)
|
||||
, mCharging(kDefaultCharging)
|
||||
, mRemainingTime(kDefaultRemainingTime)
|
||||
{
|
||||
}
|
||||
|
||||
UPowerClient::~UPowerClient()
|
||||
{
|
||||
NS_ASSERTION(!mDBusConnection && !mUPowerProxy && !mTrackedDevice && !mTrackedDeviceProxy,
|
||||
"The observers have not been correctly removed! "
|
||||
"(StopListening should have been called)");
|
||||
}
|
||||
|
||||
void
|
||||
UPowerClient::BeginListening()
|
||||
{
|
||||
GError* error = nullptr;
|
||||
mDBusConnection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
|
||||
|
||||
if (!mDBusConnection) {
|
||||
HAL_LOG("Failed to open connection to bus: %s\n", error->message);
|
||||
g_error_free(error);
|
||||
return;
|
||||
}
|
||||
|
||||
DBusConnection* dbusConnection =
|
||||
dbus_g_connection_get_connection(mDBusConnection);
|
||||
|
||||
// Make sure we do not exit the entire program if DBus connection get lost.
|
||||
dbus_connection_set_exit_on_disconnect(dbusConnection, false);
|
||||
|
||||
// Listening to signals the DBus connection is going to get so we will know
|
||||
// when it is lost and we will be able to disconnect cleanly.
|
||||
dbus_connection_add_filter(dbusConnection, ConnectionSignalFilter, this,
|
||||
nullptr);
|
||||
|
||||
mUPowerProxy = dbus_g_proxy_new_for_name(mDBusConnection,
|
||||
"org.freedesktop.UPower",
|
||||
"/org/freedesktop/UPower",
|
||||
"org.freedesktop.UPower");
|
||||
|
||||
UpdateTrackedDeviceSync();
|
||||
|
||||
/*
|
||||
* TODO: we should probably listen to DeviceAdded and DeviceRemoved signals.
|
||||
* If we do that, we would have to disconnect from those in StopListening.
|
||||
* It's not yet implemented because it requires testing hot plugging and
|
||||
* removal of a battery.
|
||||
*/
|
||||
dbus_g_proxy_add_signal(mUPowerProxy, "DeviceChanged", G_TYPE_STRING,
|
||||
G_TYPE_INVALID);
|
||||
dbus_g_proxy_connect_signal(mUPowerProxy, "DeviceChanged",
|
||||
G_CALLBACK (DeviceChanged), this, nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
UPowerClient::StopListening()
|
||||
{
|
||||
// If mDBusConnection isn't initialized, that means we are not really listening.
|
||||
if (!mDBusConnection) {
|
||||
return;
|
||||
}
|
||||
|
||||
dbus_connection_remove_filter(
|
||||
dbus_g_connection_get_connection(mDBusConnection),
|
||||
ConnectionSignalFilter, this);
|
||||
|
||||
dbus_g_proxy_disconnect_signal(mUPowerProxy, "DeviceChanged",
|
||||
G_CALLBACK (DeviceChanged), this);
|
||||
|
||||
g_free(mTrackedDevice);
|
||||
mTrackedDevice = nullptr;
|
||||
|
||||
if (mTrackedDeviceProxy) {
|
||||
dbus_g_proxy_disconnect_signal(mTrackedDeviceProxy, "PropertiesChanged",
|
||||
G_CALLBACK (PropertiesChanged), this);
|
||||
|
||||
g_object_unref(mTrackedDeviceProxy);
|
||||
mTrackedDeviceProxy = nullptr;
|
||||
}
|
||||
|
||||
g_object_unref(mUPowerProxy);
|
||||
mUPowerProxy = nullptr;
|
||||
|
||||
dbus_g_connection_unref(mDBusConnection);
|
||||
mDBusConnection = nullptr;
|
||||
|
||||
// We should now show the default values, not the latest we got.
|
||||
mLevel = kDefaultLevel;
|
||||
mCharging = kDefaultCharging;
|
||||
mRemainingTime = kDefaultRemainingTime;
|
||||
}
|
||||
|
||||
void
|
||||
UPowerClient::UpdateTrackedDeviceSync()
|
||||
{
|
||||
GType typeGPtrArray = dbus_g_type_get_collection("GPtrArray",
|
||||
DBUS_TYPE_G_OBJECT_PATH);
|
||||
GPtrArray* devices = nullptr;
|
||||
GError* error = nullptr;
|
||||
|
||||
// Reset the current tracked device:
|
||||
g_free(mTrackedDevice);
|
||||
mTrackedDevice = nullptr;
|
||||
|
||||
// Reset the current tracked device proxy:
|
||||
if (mTrackedDeviceProxy) {
|
||||
dbus_g_proxy_disconnect_signal(mTrackedDeviceProxy, "PropertiesChanged",
|
||||
G_CALLBACK (PropertiesChanged), this);
|
||||
|
||||
g_object_unref(mTrackedDeviceProxy);
|
||||
mTrackedDeviceProxy = nullptr;
|
||||
}
|
||||
|
||||
// If that fails, that likely means upower isn't installed.
|
||||
if (!dbus_g_proxy_call(mUPowerProxy, "EnumerateDevices", &error, G_TYPE_INVALID,
|
||||
typeGPtrArray, &devices, G_TYPE_INVALID)) {
|
||||
HAL_LOG("Error: %s\n", error->message);
|
||||
g_error_free(error);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* We are looking for the first device that is a battery.
|
||||
* TODO: we could try to combine more than one battery.
|
||||
*/
|
||||
for (guint i=0; i<devices->len; ++i) {
|
||||
gchar* devicePath = static_cast<gchar*>(g_ptr_array_index(devices, i));
|
||||
|
||||
DBusGProxy* proxy = dbus_g_proxy_new_from_proxy(mUPowerProxy,
|
||||
"org.freedesktop.DBus.Properties",
|
||||
devicePath);
|
||||
|
||||
nsAutoRef<GHashTable> hashTable(GetDevicePropertiesSync(proxy));
|
||||
|
||||
if (g_value_get_uint(static_cast<const GValue*>(g_hash_table_lookup(hashTable, "Type"))) == sDeviceTypeBattery) {
|
||||
UpdateSavedInfo(hashTable);
|
||||
mTrackedDevice = devicePath;
|
||||
mTrackedDeviceProxy = proxy;
|
||||
break;
|
||||
}
|
||||
|
||||
g_object_unref(proxy);
|
||||
g_free(devicePath);
|
||||
}
|
||||
|
||||
if (mTrackedDeviceProxy) {
|
||||
dbus_g_proxy_add_signal(mTrackedDeviceProxy, "PropertiesChanged",
|
||||
G_TYPE_STRING,
|
||||
dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
|
||||
G_TYPE_VALUE),
|
||||
G_TYPE_STRV, G_TYPE_INVALID);
|
||||
dbus_g_proxy_connect_signal(mTrackedDeviceProxy, "PropertiesChanged",
|
||||
G_CALLBACK (PropertiesChanged), this, nullptr);
|
||||
}
|
||||
|
||||
g_ptr_array_free(devices, true);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
UPowerClient::DeviceChanged(DBusGProxy* aProxy, const gchar* aObjectPath,
|
||||
UPowerClient* aListener)
|
||||
{
|
||||
if (!aListener->mTrackedDevice) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if GLIB_MAJOR_VERSION >= 2 && GLIB_MINOR_VERSION >= 16
|
||||
if (g_strcmp0(aObjectPath, aListener->mTrackedDevice)) {
|
||||
#else
|
||||
if (g_ascii_strcasecmp(aObjectPath, aListener->mTrackedDevice)) {
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
aListener->GetDevicePropertiesAsync(aListener->mTrackedDeviceProxy);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
UPowerClient::PropertiesChanged(DBusGProxy* aProxy, const gchar*, GHashTable*,
|
||||
char**, UPowerClient* aListener)
|
||||
{
|
||||
aListener->GetDevicePropertiesAsync(aListener->mTrackedDeviceProxy);
|
||||
}
|
||||
|
||||
/* static */ DBusHandlerResult
|
||||
UPowerClient::ConnectionSignalFilter(DBusConnection* aConnection,
|
||||
DBusMessage* aMessage, void* aData)
|
||||
{
|
||||
if (dbus_message_is_signal(aMessage, DBUS_INTERFACE_LOCAL, "Disconnected")) {
|
||||
static_cast<UPowerClient*>(aData)->StopListening();
|
||||
// We do not return DBUS_HANDLER_RESULT_HANDLED here because the connection
|
||||
// might be shared and some other filters might want to do something.
|
||||
}
|
||||
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
|
||||
GHashTable*
|
||||
UPowerClient::GetDevicePropertiesSync(DBusGProxy* aProxy)
|
||||
{
|
||||
GError* error = nullptr;
|
||||
GHashTable* hashTable = nullptr;
|
||||
GType typeGHashTable = dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
|
||||
G_TYPE_VALUE);
|
||||
if (!dbus_g_proxy_call(aProxy, "GetAll", &error, G_TYPE_STRING,
|
||||
"org.freedesktop.UPower.Device", G_TYPE_INVALID,
|
||||
typeGHashTable, &hashTable, G_TYPE_INVALID)) {
|
||||
HAL_LOG("Error: %s\n", error->message);
|
||||
g_error_free(error);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return hashTable;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
UPowerClient::GetDevicePropertiesCallback(DBusGProxy* aProxy,
|
||||
DBusGProxyCall* aCall, void* aData)
|
||||
{
|
||||
GError* error = nullptr;
|
||||
GHashTable* hashTable = nullptr;
|
||||
GType typeGHashTable = dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
|
||||
G_TYPE_VALUE);
|
||||
if (!dbus_g_proxy_end_call(aProxy, aCall, &error, typeGHashTable,
|
||||
&hashTable, G_TYPE_INVALID)) {
|
||||
HAL_LOG("Error: %s\n", error->message);
|
||||
g_error_free(error);
|
||||
} else {
|
||||
sInstance->UpdateSavedInfo(hashTable);
|
||||
hal::NotifyBatteryChange(hal::BatteryInformation(sInstance->mLevel,
|
||||
sInstance->mCharging,
|
||||
sInstance->mRemainingTime));
|
||||
g_hash_table_unref(hashTable);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UPowerClient::GetDevicePropertiesAsync(DBusGProxy* aProxy)
|
||||
{
|
||||
dbus_g_proxy_begin_call(aProxy, "GetAll", GetDevicePropertiesCallback, nullptr,
|
||||
nullptr, G_TYPE_STRING,
|
||||
"org.freedesktop.UPower.Device", G_TYPE_INVALID);
|
||||
}
|
||||
|
||||
void
|
||||
UPowerClient::UpdateSavedInfo(GHashTable* aHashTable)
|
||||
{
|
||||
bool isFull = false;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
switch (g_value_get_uint(static_cast<const GValue*>(g_hash_table_lookup(aHashTable, "State")))) {
|
||||
case eState_Unknown:
|
||||
mCharging = kDefaultCharging;
|
||||
break;
|
||||
case eState_FullyCharged:
|
||||
isFull = true;
|
||||
MOZ_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 {
|
||||
mLevel = round(g_value_get_double(static_cast<const GValue*>(g_hash_table_lookup(aHashTable, "Percentage"))))*0.01;
|
||||
}
|
||||
|
||||
if (isFull) {
|
||||
mRemainingTime = 0;
|
||||
} else {
|
||||
mRemainingTime = mCharging ? g_value_get_int64(static_cast<const GValue*>(g_hash_table_lookup(aHashTable, "TimeToFull")))
|
||||
: g_value_get_int64(static_cast<const GValue*>(g_hash_table_lookup(aHashTable, "TimeToEmpty")));
|
||||
|
||||
if (mRemainingTime == kUPowerUnknownRemainingTime) {
|
||||
mRemainingTime = kUnknownRemainingTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
UPowerClient::GetLevel()
|
||||
{
|
||||
return mLevel;
|
||||
}
|
||||
|
||||
bool
|
||||
UPowerClient::IsCharging()
|
||||
{
|
||||
return mCharging;
|
||||
}
|
||||
|
||||
double
|
||||
UPowerClient::GetRemainingTime()
|
||||
{
|
||||
return mRemainingTime;
|
||||
}
|
||||
|
||||
} // namespace hal_impl
|
||||
} // namespace mozilla
|
||||
|
|
@ -34,14 +34,6 @@ if CONFIG['OS_TARGET'] == 'Linux':
|
|||
'linux/LinuxMemory.cpp',
|
||||
'linux/LinuxPower.cpp',
|
||||
]
|
||||
if CONFIG['MOZ_ENABLE_DBUS']:
|
||||
UNIFIED_SOURCES += [
|
||||
'linux/UPowerClient.cpp',
|
||||
]
|
||||
else:
|
||||
UNIFIED_SOURCES += [
|
||||
'fallback/FallbackBattery.cpp',
|
||||
]
|
||||
elif CONFIG['OS_TARGET'] == 'WINNT':
|
||||
UNIFIED_SOURCES += [
|
||||
'fallback/FallbackAlarm.cpp',
|
||||
|
|
@ -51,13 +43,8 @@ elif CONFIG['OS_TARGET'] == 'WINNT':
|
|||
'fallback/FallbackVibration.cpp',
|
||||
'windows/WindowsSensor.cpp',
|
||||
]
|
||||
# WindowsBattery.cpp cannot be built in unified mode because it relies on HalImpl.h.
|
||||
SOURCES += [
|
||||
'windows/WindowsBattery.cpp',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
UNIFIED_SOURCES += [
|
||||
'cocoa/CocoaBattery.cpp',
|
||||
'fallback/FallbackAlarm.cpp',
|
||||
'fallback/FallbackMemory.cpp',
|
||||
'fallback/FallbackPower.cpp',
|
||||
|
|
@ -73,18 +60,9 @@ elif CONFIG['OS_TARGET'] in ('OpenBSD', 'NetBSD', 'FreeBSD', 'DragonFly'):
|
|||
'fallback/FallbackSensor.cpp',
|
||||
'fallback/FallbackVibration.cpp',
|
||||
]
|
||||
if CONFIG['MOZ_ENABLE_DBUS']:
|
||||
UNIFIED_SOURCES += [
|
||||
'linux/UPowerClient.cpp',
|
||||
]
|
||||
else:
|
||||
UNIFIED_SOURCES += [
|
||||
'fallback/FallbackBattery.cpp',
|
||||
]
|
||||
else:
|
||||
UNIFIED_SOURCES += [
|
||||
'fallback/FallbackAlarm.cpp',
|
||||
'fallback/FallbackBattery.cpp',
|
||||
'fallback/FallbackMemory.cpp',
|
||||
'fallback/FallbackPower.cpp',
|
||||
'fallback/FallbackScreenConfiguration.cpp',
|
||||
|
|
|
|||
|
|
@ -20,12 +20,6 @@ using PRTime from "prtime.h";
|
|||
namespace mozilla {
|
||||
|
||||
namespace hal {
|
||||
struct BatteryInformation {
|
||||
double level;
|
||||
bool charging;
|
||||
double remainingTime;
|
||||
};
|
||||
|
||||
struct SensorData {
|
||||
SensorType sensor;
|
||||
PRTime timestamp;
|
||||
|
|
@ -69,7 +63,6 @@ nested(upto inside_cpow) sync protocol PHal {
|
|||
manager PContent;
|
||||
|
||||
child:
|
||||
async NotifyBatteryChange(BatteryInformation aBatteryInfo);
|
||||
async NotifyNetworkChange(NetworkInformation aNetworkInfo);
|
||||
async NotifyWakeLockChange(WakeLockInformation aWakeLockInfo);
|
||||
async NotifyScreenConfigurationChange(ScreenConfiguration aScreenOrientation);
|
||||
|
|
@ -80,11 +73,6 @@ parent:
|
|||
async Vibrate(uint32_t[] pattern, uint64_t[] id, PBrowser browser);
|
||||
async CancelVibrate(uint64_t[] id, PBrowser browser);
|
||||
|
||||
async EnableBatteryNotifications();
|
||||
async DisableBatteryNotifications();
|
||||
sync GetCurrentBatteryInformation()
|
||||
returns (BatteryInformation aBatteryInfo);
|
||||
|
||||
async EnableNetworkNotifications();
|
||||
async DisableNetworkNotifications();
|
||||
sync GetCurrentNetworkInformation()
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
#include "mozilla/hal_sandbox/PHalParent.h"
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
#include "mozilla/dom/battery/Types.h"
|
||||
#include "mozilla/dom/network/Types.h"
|
||||
#include "mozilla/dom/ScreenOrientation.h"
|
||||
#include "mozilla/EnumeratedRange.h"
|
||||
|
|
@ -69,24 +68,6 @@ CancelVibrate(const WindowIdentifier &id)
|
|||
Hal()->SendCancelVibrate(newID.AsArray(), TabChild::GetFrom(newID.GetWindow()));
|
||||
}
|
||||
|
||||
void
|
||||
EnableBatteryNotifications()
|
||||
{
|
||||
Hal()->SendEnableBatteryNotifications();
|
||||
}
|
||||
|
||||
void
|
||||
DisableBatteryNotifications()
|
||||
{
|
||||
Hal()->SendDisableBatteryNotifications();
|
||||
}
|
||||
|
||||
void
|
||||
GetCurrentBatteryInformation(BatteryInformation* aBatteryInfo)
|
||||
{
|
||||
Hal()->SendGetCurrentBatteryInformation(aBatteryInfo);
|
||||
}
|
||||
|
||||
void
|
||||
EnableNetworkNotifications()
|
||||
{
|
||||
|
|
@ -376,7 +357,6 @@ bool SystemServiceIsRunning(const char* aSvcName)
|
|||
}
|
||||
|
||||
class HalParent : public PHalParent
|
||||
, public BatteryObserver
|
||||
, public NetworkObserver
|
||||
, public ISensorObserver
|
||||
, public WakeLockObserver
|
||||
|
|
@ -390,7 +370,6 @@ public:
|
|||
{
|
||||
// NB: you *must* unconditionally unregister your observer here,
|
||||
// if it *may* be registered below.
|
||||
hal::UnregisterBatteryObserver(this);
|
||||
hal::UnregisterNetworkObserver(this);
|
||||
hal::UnregisterScreenConfigurationObserver(this);
|
||||
for (auto sensor : MakeEnumeratedRange(NUM_SENSOR_TYPE)) {
|
||||
|
|
@ -431,30 +410,6 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
RecvEnableBatteryNotifications() override {
|
||||
// We give all content battery-status permission.
|
||||
hal::RegisterBatteryObserver(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
RecvDisableBatteryNotifications() override {
|
||||
hal::UnregisterBatteryObserver(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
RecvGetCurrentBatteryInformation(BatteryInformation* aBatteryInfo) override {
|
||||
// We give all content battery-status permission.
|
||||
hal::GetCurrentBatteryInformation(aBatteryInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Notify(const BatteryInformation& aBatteryInfo) override {
|
||||
Unused << SendNotifyBatteryChange(aBatteryInfo);
|
||||
}
|
||||
|
||||
virtual bool
|
||||
RecvEnableNetworkNotifications() override {
|
||||
// We give all content access to this network-status information.
|
||||
|
|
@ -768,12 +723,6 @@ public:
|
|||
sHalChildDestroyed = true;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
RecvNotifyBatteryChange(const BatteryInformation& aBatteryInfo) override {
|
||||
hal::NotifyBatteryChange(aBatteryInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
RecvNotifySensorChange(const hal::SensorData &aSensorData) override;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,190 +0,0 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#include "Hal.h"
|
||||
#include "HalImpl.h"
|
||||
#include "nsITimer.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/battery/Constants.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
|
||||
using namespace mozilla::dom::battery;
|
||||
|
||||
namespace mozilla {
|
||||
namespace hal_impl {
|
||||
|
||||
static nsCOMPtr<nsITimer> sUpdateTimer;
|
||||
|
||||
/* Power Event API is Vista or later */
|
||||
static decltype(RegisterPowerSettingNotification)* sRegisterPowerSettingNotification = nullptr;
|
||||
static decltype(UnregisterPowerSettingNotification)* sUnregisterPowerSettingNotification = nullptr;
|
||||
static HPOWERNOTIFY sPowerHandle = nullptr;
|
||||
static HPOWERNOTIFY sCapacityHandle = nullptr;
|
||||
static HWND sHWnd = nullptr;
|
||||
|
||||
static void
|
||||
UpdateHandler(nsITimer* aTimer, void* aClosure) {
|
||||
NS_ASSERTION(!IsVistaOrLater(),
|
||||
"We shouldn't call this function for Vista or later version!");
|
||||
|
||||
static hal::BatteryInformation sLastInfo;
|
||||
hal::BatteryInformation currentInfo;
|
||||
|
||||
hal_impl::GetCurrentBatteryInformation(¤tInfo);
|
||||
if (sLastInfo.level() != currentInfo.level() ||
|
||||
sLastInfo.charging() != currentInfo.charging() ||
|
||||
sLastInfo.remainingTime() != currentInfo.remainingTime()) {
|
||||
hal::NotifyBatteryChange(currentInfo);
|
||||
sLastInfo = currentInfo;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
LRESULT CALLBACK
|
||||
BatteryWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
if (msg != WM_POWERBROADCAST || wParam != PBT_POWERSETTINGCHANGE) {
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
hal::BatteryInformation currentInfo;
|
||||
|
||||
// Since we need update remainingTime, we cannot use LPARAM.
|
||||
hal_impl::GetCurrentBatteryInformation(¤tInfo);
|
||||
|
||||
hal::NotifyBatteryChange(currentInfo);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
EnableBatteryNotifications()
|
||||
{
|
||||
if (IsVistaOrLater()) {
|
||||
// RegisterPowerSettingNotification is from Vista or later.
|
||||
// Use this API if available.
|
||||
HMODULE hUser32 = GetModuleHandleW(L"USER32.DLL");
|
||||
if (!sRegisterPowerSettingNotification)
|
||||
sRegisterPowerSettingNotification = (decltype(RegisterPowerSettingNotification)*)
|
||||
GetProcAddress(hUser32, "RegisterPowerSettingNotification");
|
||||
if (!sUnregisterPowerSettingNotification)
|
||||
sUnregisterPowerSettingNotification = (decltype(UnregisterPowerSettingNotification)*)
|
||||
GetProcAddress(hUser32, "UnregisterPowerSettingNotification");
|
||||
|
||||
if (!sRegisterPowerSettingNotification ||
|
||||
!sUnregisterPowerSettingNotification) {
|
||||
NS_ASSERTION(false, "Canot find PowerSettingNotification functions.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create custom window to watch battery event
|
||||
// If we can get Gecko's window handle, this is unnecessary.
|
||||
|
||||
if (sHWnd == nullptr) {
|
||||
WNDCLASSW wc;
|
||||
HMODULE hSelf = GetModuleHandle(nullptr);
|
||||
|
||||
if (!GetClassInfoW(hSelf, L"MozillaBatteryClass", &wc)) {
|
||||
ZeroMemory(&wc, sizeof(WNDCLASSW));
|
||||
wc.hInstance = hSelf;
|
||||
wc.lpfnWndProc = BatteryWindowProc;
|
||||
wc.lpszClassName = L"MozillaBatteryClass";
|
||||
RegisterClassW(&wc);
|
||||
}
|
||||
|
||||
sHWnd = CreateWindowW(L"MozillaBatteryClass", L"Battery Watcher",
|
||||
0, 0, 0, 0, 0,
|
||||
nullptr, nullptr, hSelf, nullptr);
|
||||
}
|
||||
|
||||
if (sHWnd == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
sPowerHandle =
|
||||
sRegisterPowerSettingNotification(sHWnd,
|
||||
&GUID_ACDC_POWER_SOURCE,
|
||||
DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
sCapacityHandle =
|
||||
sRegisterPowerSettingNotification(sHWnd,
|
||||
&GUID_BATTERY_PERCENTAGE_REMAINING,
|
||||
DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
} else
|
||||
{
|
||||
// for Windows XP. If we remove Windows XP support,
|
||||
// we should remove timer-based power notification
|
||||
sUpdateTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
if (sUpdateTimer) {
|
||||
sUpdateTimer->InitWithFuncCallback(UpdateHandler,
|
||||
nullptr,
|
||||
Preferences::GetInt("dom.battery.timer",
|
||||
30000 /* 30s */),
|
||||
nsITimer::TYPE_REPEATING_SLACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DisableBatteryNotifications()
|
||||
{
|
||||
if (IsVistaOrLater()) {
|
||||
if (sPowerHandle) {
|
||||
sUnregisterPowerSettingNotification(sPowerHandle);
|
||||
sPowerHandle = nullptr;
|
||||
}
|
||||
|
||||
if (sCapacityHandle) {
|
||||
sUnregisterPowerSettingNotification(sCapacityHandle);
|
||||
sCapacityHandle = nullptr;
|
||||
}
|
||||
|
||||
if (sHWnd) {
|
||||
DestroyWindow(sHWnd);
|
||||
sHWnd = nullptr;
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (sUpdateTimer) {
|
||||
sUpdateTimer->Cancel();
|
||||
sUpdateTimer = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo)
|
||||
{
|
||||
SYSTEM_POWER_STATUS status;
|
||||
if (!GetSystemPowerStatus(&status)) {
|
||||
aBatteryInfo->level() = kDefaultLevel;
|
||||
aBatteryInfo->charging() = kDefaultCharging;
|
||||
aBatteryInfo->remainingTime() = kDefaultRemainingTime;
|
||||
return;
|
||||
}
|
||||
|
||||
aBatteryInfo->level() =
|
||||
status.BatteryLifePercent == 255 ? kDefaultLevel
|
||||
: ((double)status.BatteryLifePercent) / 100.0;
|
||||
aBatteryInfo->charging() = (status.ACLineStatus != 0);
|
||||
if (status.ACLineStatus != 0) {
|
||||
if (aBatteryInfo->level() == 1.0) {
|
||||
// GetSystemPowerStatus API may returns -1 for BatteryFullLifeTime.
|
||||
// So, if battery is 100%, set kDefaultRemainingTime at force.
|
||||
aBatteryInfo->remainingTime() = kDefaultRemainingTime;
|
||||
} else {
|
||||
aBatteryInfo->remainingTime() =
|
||||
status.BatteryFullLifeTime == (DWORD)-1 ? kUnknownRemainingTime
|
||||
: status.BatteryFullLifeTime;
|
||||
}
|
||||
} else {
|
||||
aBatteryInfo->remainingTime() =
|
||||
status.BatteryLifeTime == (DWORD)-1 ? kUnknownRemainingTime
|
||||
: status.BatteryLifeTime;
|
||||
}
|
||||
}
|
||||
|
||||
} // hal_impl
|
||||
} // mozilla
|
||||
Loading…
Add table
Add a link
Reference in a new issue