1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/battery/BatteryManager.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,144 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include <limits> 1.10 +#include "BatteryManager.h" 1.11 +#include "Constants.h" 1.12 +#include "mozilla/DOMEventTargetHelper.h" 1.13 +#include "mozilla/Hal.h" 1.14 +#include "mozilla/Preferences.h" 1.15 +#include "mozilla/dom/BatteryManagerBinding.h" 1.16 +#include "nsIDOMClassInfo.h" 1.17 + 1.18 +/** 1.19 + * We have to use macros here because our leak analysis tool things we are 1.20 + * leaking strings when we have |static const nsString|. Sad :( 1.21 + */ 1.22 +#define LEVELCHANGE_EVENT_NAME NS_LITERAL_STRING("levelchange") 1.23 +#define CHARGINGCHANGE_EVENT_NAME NS_LITERAL_STRING("chargingchange") 1.24 +#define DISCHARGINGTIMECHANGE_EVENT_NAME NS_LITERAL_STRING("dischargingtimechange") 1.25 +#define CHARGINGTIMECHANGE_EVENT_NAME NS_LITERAL_STRING("chargingtimechange") 1.26 + 1.27 +namespace mozilla { 1.28 +namespace dom { 1.29 +namespace battery { 1.30 + 1.31 +BatteryManager::BatteryManager(nsPIDOMWindow* aWindow) 1.32 + : DOMEventTargetHelper(aWindow) 1.33 + , mLevel(kDefaultLevel) 1.34 + , mCharging(kDefaultCharging) 1.35 + , mRemainingTime(kDefaultRemainingTime) 1.36 +{ 1.37 +} 1.38 + 1.39 +void 1.40 +BatteryManager::Init() 1.41 +{ 1.42 + hal::RegisterBatteryObserver(this); 1.43 + 1.44 + hal::BatteryInformation batteryInfo; 1.45 + hal::GetCurrentBatteryInformation(&batteryInfo); 1.46 + 1.47 + UpdateFromBatteryInfo(batteryInfo); 1.48 +} 1.49 + 1.50 +void 1.51 +BatteryManager::Shutdown() 1.52 +{ 1.53 + hal::UnregisterBatteryObserver(this); 1.54 +} 1.55 + 1.56 +JSObject* 1.57 +BatteryManager::WrapObject(JSContext* aCx) 1.58 +{ 1.59 + return BatteryManagerBinding::Wrap(aCx, this); 1.60 +} 1.61 + 1.62 +double 1.63 +BatteryManager::DischargingTime() const 1.64 +{ 1.65 + if (mCharging || mRemainingTime == kUnknownRemainingTime) { 1.66 + return std::numeric_limits<double>::infinity(); 1.67 + } 1.68 + 1.69 + return mRemainingTime; 1.70 +} 1.71 + 1.72 +double 1.73 +BatteryManager::ChargingTime() const 1.74 +{ 1.75 + if (!mCharging || mRemainingTime == kUnknownRemainingTime) { 1.76 + return std::numeric_limits<double>::infinity(); 1.77 + } 1.78 + 1.79 + return mRemainingTime; 1.80 +} 1.81 + 1.82 +void 1.83 +BatteryManager::UpdateFromBatteryInfo(const hal::BatteryInformation& aBatteryInfo) 1.84 +{ 1.85 + mLevel = aBatteryInfo.level(); 1.86 + mCharging = aBatteryInfo.charging(); 1.87 + mRemainingTime = aBatteryInfo.remainingTime(); 1.88 + 1.89 + // Add some guards to make sure the values are coherent. 1.90 + if (mLevel == 1.0 && mCharging == true && 1.91 + mRemainingTime != kDefaultRemainingTime) { 1.92 + mRemainingTime = kDefaultRemainingTime; 1.93 + NS_ERROR("Battery API: When charging and level at 1.0, remaining time " 1.94 + "should be 0. Please fix your backend!"); 1.95 + } 1.96 +} 1.97 + 1.98 +void 1.99 +BatteryManager::Notify(const hal::BatteryInformation& aBatteryInfo) 1.100 +{ 1.101 + double previousLevel = mLevel; 1.102 + bool previousCharging = mCharging; 1.103 + double previousRemainingTime = mRemainingTime; 1.104 + 1.105 + UpdateFromBatteryInfo(aBatteryInfo); 1.106 + 1.107 + if (previousCharging != mCharging) { 1.108 + DispatchTrustedEvent(CHARGINGCHANGE_EVENT_NAME); 1.109 + } 1.110 + 1.111 + if (previousLevel != mLevel) { 1.112 + DispatchTrustedEvent(LEVELCHANGE_EVENT_NAME); 1.113 + } 1.114 + 1.115 + /* 1.116 + * There are a few situations that could happen here: 1.117 + * 1. Charging state changed: 1.118 + * a. Previous remaining time wasn't unkwonw, we have to fire an event for 1.119 + * the change. 1.120 + * b. New remaining time isn't unkwonw, we have to fire an event for it. 1.121 + * 2. Charging state didn't change but remainingTime did, we have to fire 1.122 + * the event that correspond to the current charging state. 1.123 + */ 1.124 + if (mCharging != previousCharging) { 1.125 + if (previousRemainingTime != kUnknownRemainingTime) { 1.126 + DispatchTrustedEvent(previousCharging ? CHARGINGTIMECHANGE_EVENT_NAME 1.127 + : DISCHARGINGTIMECHANGE_EVENT_NAME); 1.128 + } 1.129 + if (mRemainingTime != kUnknownRemainingTime) { 1.130 + DispatchTrustedEvent(mCharging ? CHARGINGTIMECHANGE_EVENT_NAME 1.131 + : DISCHARGINGTIMECHANGE_EVENT_NAME); 1.132 + } 1.133 + } else if (previousRemainingTime != mRemainingTime) { 1.134 + DispatchTrustedEvent(mCharging ? CHARGINGTIMECHANGE_EVENT_NAME 1.135 + : DISCHARGINGTIMECHANGE_EVENT_NAME); 1.136 + } 1.137 +} 1.138 + 1.139 +/* static */ bool 1.140 +BatteryManager::HasSupport() 1.141 +{ 1.142 + return Preferences::GetBool("dom.battery.enabled", true); 1.143 +} 1.144 + 1.145 +} // namespace battery 1.146 +} // namespace dom 1.147 +} // namespace mozilla