diff options
Diffstat (limited to 'hal/cocoa/CocoaBattery.cpp')
-rw-r--r-- | hal/cocoa/CocoaBattery.cpp | 325 |
1 files changed, 0 insertions, 325 deletions
diff --git a/hal/cocoa/CocoaBattery.cpp b/hal/cocoa/CocoaBattery.cpp deleted file mode 100644 index 6f1b7b1dc..000000000 --- a/hal/cocoa/CocoaBattery.cpp +++ /dev/null @@ -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 |