1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "config.h" 6 #include "modules/battery/BatteryManager.h" 7 8 #include "modules/battery/BatteryDispatcher.h" 9 #include "modules/battery/BatteryStatus.h" 10 #include "platform/RuntimeEnabledFeatures.h" 11 12 namespace WebCore { 13 14 PassRefPtrWillBeRawPtr<BatteryManager> BatteryManager::create(ExecutionContext* context) 15 { 16 RefPtrWillBeRawPtr<BatteryManager> batteryManager(adoptRefWillBeRefCountedGarbageCollected(new BatteryManager(context))); 17 batteryManager->suspendIfNeeded(); 18 return batteryManager.release(); 19 } 20 21 BatteryManager::~BatteryManager() 22 { 23 stopUpdating(); 24 } 25 26 BatteryManager::BatteryManager(ExecutionContext* context) 27 : ActiveDOMObject(context) 28 , DeviceEventControllerBase(toDocument(context)->page()) 29 , m_batteryStatus(BatteryStatus::create()) 30 , m_state(NotStarted) 31 { 32 } 33 34 ScriptPromise BatteryManager::startRequest(ScriptState* scriptState) 35 { 36 if (m_state == Pending) 37 return m_resolver->promise(); 38 39 m_resolver = ScriptPromiseResolverWithContext::create(scriptState); 40 ScriptPromise promise = m_resolver->promise(); 41 42 if (m_state == Resolved) { 43 // FIXME: Consider returning the same promise in this case. See crbug.com/385025. 44 m_resolver->resolve(this); 45 } else if (m_state == NotStarted) { 46 m_state = Pending; 47 m_hasEventListener = true; 48 startUpdating(); 49 } 50 51 return promise; 52 } 53 54 bool BatteryManager::charging() 55 { 56 return m_batteryStatus->charging(); 57 } 58 59 double BatteryManager::chargingTime() 60 { 61 return m_batteryStatus->chargingTime(); 62 } 63 64 double BatteryManager::dischargingTime() 65 { 66 return m_batteryStatus->dischargingTime(); 67 } 68 69 double BatteryManager::level() 70 { 71 return m_batteryStatus->level(); 72 } 73 74 void BatteryManager::didUpdateData() 75 { 76 ASSERT(RuntimeEnabledFeatures::batteryStatusEnabled()); 77 ASSERT(m_state != NotStarted); 78 79 RefPtrWillBeRawPtr<BatteryStatus> oldStatus = m_batteryStatus; 80 m_batteryStatus = BatteryDispatcher::instance().latestData(); 81 82 #if !ENABLE(OILPAN) 83 // BatteryDispatcher also holds a reference to m_batteryStatus. 84 ASSERT(m_batteryStatus->refCount() > 1); 85 #endif 86 87 if (m_state == Pending) { 88 ASSERT(m_resolver); 89 m_state = Resolved; 90 m_resolver->resolve(this); 91 return; 92 } 93 94 Document* document = toDocument(executionContext()); 95 if (document->activeDOMObjectsAreSuspended() || document->activeDOMObjectsAreStopped()) 96 return; 97 98 ASSERT(oldStatus); 99 100 if (m_batteryStatus->charging() != oldStatus->charging()) 101 dispatchEvent(Event::create(EventTypeNames::chargingchange)); 102 if (m_batteryStatus->chargingTime() != oldStatus->chargingTime()) 103 dispatchEvent(Event::create(EventTypeNames::chargingtimechange)); 104 if (m_batteryStatus->dischargingTime() != oldStatus->dischargingTime()) 105 dispatchEvent(Event::create(EventTypeNames::dischargingtimechange)); 106 if (m_batteryStatus->level() != oldStatus->level()) 107 dispatchEvent(Event::create(EventTypeNames::levelchange)); 108 } 109 110 void BatteryManager::registerWithDispatcher() 111 { 112 BatteryDispatcher::instance().addController(this); 113 } 114 115 void BatteryManager::unregisterWithDispatcher() 116 { 117 BatteryDispatcher::instance().removeController(this); 118 } 119 120 bool BatteryManager::hasLastData() 121 { 122 return BatteryDispatcher::instance().latestData(); 123 } 124 125 void BatteryManager::suspend() 126 { 127 m_hasEventListener = false; 128 stopUpdating(); 129 } 130 131 void BatteryManager::resume() 132 { 133 m_hasEventListener = true; 134 startUpdating(); 135 } 136 137 void BatteryManager::stop() 138 { 139 m_hasEventListener = false; 140 stopUpdating(); 141 } 142 143 void BatteryManager::trace(Visitor* visitor) 144 { 145 visitor->trace(m_batteryStatus); 146 EventTargetWithInlineData::trace(visitor); 147 } 148 149 } // namespace WebCore 150