|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include <limits> |
|
7 #include "BatteryManager.h" |
|
8 #include "Constants.h" |
|
9 #include "mozilla/DOMEventTargetHelper.h" |
|
10 #include "mozilla/Hal.h" |
|
11 #include "mozilla/Preferences.h" |
|
12 #include "mozilla/dom/BatteryManagerBinding.h" |
|
13 #include "nsIDOMClassInfo.h" |
|
14 |
|
15 /** |
|
16 * We have to use macros here because our leak analysis tool things we are |
|
17 * leaking strings when we have |static const nsString|. Sad :( |
|
18 */ |
|
19 #define LEVELCHANGE_EVENT_NAME NS_LITERAL_STRING("levelchange") |
|
20 #define CHARGINGCHANGE_EVENT_NAME NS_LITERAL_STRING("chargingchange") |
|
21 #define DISCHARGINGTIMECHANGE_EVENT_NAME NS_LITERAL_STRING("dischargingtimechange") |
|
22 #define CHARGINGTIMECHANGE_EVENT_NAME NS_LITERAL_STRING("chargingtimechange") |
|
23 |
|
24 namespace mozilla { |
|
25 namespace dom { |
|
26 namespace battery { |
|
27 |
|
28 BatteryManager::BatteryManager(nsPIDOMWindow* aWindow) |
|
29 : DOMEventTargetHelper(aWindow) |
|
30 , mLevel(kDefaultLevel) |
|
31 , mCharging(kDefaultCharging) |
|
32 , mRemainingTime(kDefaultRemainingTime) |
|
33 { |
|
34 } |
|
35 |
|
36 void |
|
37 BatteryManager::Init() |
|
38 { |
|
39 hal::RegisterBatteryObserver(this); |
|
40 |
|
41 hal::BatteryInformation batteryInfo; |
|
42 hal::GetCurrentBatteryInformation(&batteryInfo); |
|
43 |
|
44 UpdateFromBatteryInfo(batteryInfo); |
|
45 } |
|
46 |
|
47 void |
|
48 BatteryManager::Shutdown() |
|
49 { |
|
50 hal::UnregisterBatteryObserver(this); |
|
51 } |
|
52 |
|
53 JSObject* |
|
54 BatteryManager::WrapObject(JSContext* aCx) |
|
55 { |
|
56 return BatteryManagerBinding::Wrap(aCx, this); |
|
57 } |
|
58 |
|
59 double |
|
60 BatteryManager::DischargingTime() const |
|
61 { |
|
62 if (mCharging || mRemainingTime == kUnknownRemainingTime) { |
|
63 return std::numeric_limits<double>::infinity(); |
|
64 } |
|
65 |
|
66 return mRemainingTime; |
|
67 } |
|
68 |
|
69 double |
|
70 BatteryManager::ChargingTime() const |
|
71 { |
|
72 if (!mCharging || mRemainingTime == kUnknownRemainingTime) { |
|
73 return std::numeric_limits<double>::infinity(); |
|
74 } |
|
75 |
|
76 return mRemainingTime; |
|
77 } |
|
78 |
|
79 void |
|
80 BatteryManager::UpdateFromBatteryInfo(const hal::BatteryInformation& aBatteryInfo) |
|
81 { |
|
82 mLevel = aBatteryInfo.level(); |
|
83 mCharging = aBatteryInfo.charging(); |
|
84 mRemainingTime = aBatteryInfo.remainingTime(); |
|
85 |
|
86 // Add some guards to make sure the values are coherent. |
|
87 if (mLevel == 1.0 && mCharging == true && |
|
88 mRemainingTime != kDefaultRemainingTime) { |
|
89 mRemainingTime = kDefaultRemainingTime; |
|
90 NS_ERROR("Battery API: When charging and level at 1.0, remaining time " |
|
91 "should be 0. Please fix your backend!"); |
|
92 } |
|
93 } |
|
94 |
|
95 void |
|
96 BatteryManager::Notify(const hal::BatteryInformation& aBatteryInfo) |
|
97 { |
|
98 double previousLevel = mLevel; |
|
99 bool previousCharging = mCharging; |
|
100 double previousRemainingTime = mRemainingTime; |
|
101 |
|
102 UpdateFromBatteryInfo(aBatteryInfo); |
|
103 |
|
104 if (previousCharging != mCharging) { |
|
105 DispatchTrustedEvent(CHARGINGCHANGE_EVENT_NAME); |
|
106 } |
|
107 |
|
108 if (previousLevel != mLevel) { |
|
109 DispatchTrustedEvent(LEVELCHANGE_EVENT_NAME); |
|
110 } |
|
111 |
|
112 /* |
|
113 * There are a few situations that could happen here: |
|
114 * 1. Charging state changed: |
|
115 * a. Previous remaining time wasn't unkwonw, we have to fire an event for |
|
116 * the change. |
|
117 * b. New remaining time isn't unkwonw, we have to fire an event for it. |
|
118 * 2. Charging state didn't change but remainingTime did, we have to fire |
|
119 * the event that correspond to the current charging state. |
|
120 */ |
|
121 if (mCharging != previousCharging) { |
|
122 if (previousRemainingTime != kUnknownRemainingTime) { |
|
123 DispatchTrustedEvent(previousCharging ? CHARGINGTIMECHANGE_EVENT_NAME |
|
124 : DISCHARGINGTIMECHANGE_EVENT_NAME); |
|
125 } |
|
126 if (mRemainingTime != kUnknownRemainingTime) { |
|
127 DispatchTrustedEvent(mCharging ? CHARGINGTIMECHANGE_EVENT_NAME |
|
128 : DISCHARGINGTIMECHANGE_EVENT_NAME); |
|
129 } |
|
130 } else if (previousRemainingTime != mRemainingTime) { |
|
131 DispatchTrustedEvent(mCharging ? CHARGINGTIMECHANGE_EVENT_NAME |
|
132 : DISCHARGINGTIMECHANGE_EVENT_NAME); |
|
133 } |
|
134 } |
|
135 |
|
136 /* static */ bool |
|
137 BatteryManager::HasSupport() |
|
138 { |
|
139 return Preferences::GetBool("dom.battery.enabled", true); |
|
140 } |
|
141 |
|
142 } // namespace battery |
|
143 } // namespace dom |
|
144 } // namespace mozilla |