1/* 2 * Copyright (C) 2012 Samsung Electronics 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 */ 19 20#include "config.h" 21#include "BatteryProviderEfl.h" 22 23#if ENABLE(BATTERY_STATUS) 24 25#include "BatteryProviderEflClient.h" 26#include "EventNames.h" 27#include <E_Ukit.h> 28#include <limits> 29 30namespace WebCore { 31 32BatteryProviderEfl::BatteryProviderEfl(BatteryProviderEflClient* client) 33 : m_client(client) 34 , m_timer(this, &BatteryProviderEfl::timerFired) 35 , m_batteryStatusRefreshInterval(1.0) 36{ 37} 38 39BatteryStatus* BatteryProviderEfl::batteryStatus() const 40{ 41 return m_batteryStatus.get(); 42} 43 44void BatteryProviderEfl::startUpdating() 45{ 46 if (m_timer.isActive()) 47 return; 48 49 if (!e_dbus_init()) 50 return; 51 52 if (!e_ukit_init()) { 53 e_dbus_shutdown(); 54 return; 55 } 56 57 m_timer.startRepeating(m_batteryStatusRefreshInterval); 58} 59 60void BatteryProviderEfl::stopUpdating() 61{ 62 if (!m_timer.isActive()) 63 return; 64 65 m_timer.stop(); 66 e_ukit_shutdown(); 67 e_dbus_shutdown(); 68} 69 70void BatteryProviderEfl::setBatteryStatus(const AtomicString& eventType, PassRefPtr<BatteryStatus> batteryStatus) 71{ 72 m_batteryStatus = batteryStatus; 73 m_client->didChangeBatteryStatus(eventType, m_batteryStatus); 74} 75 76void BatteryProviderEfl::timerFired(Timer<BatteryProviderEfl>* timer) 77{ 78 ASSERT_UNUSED(timer, timer == &m_timer); 79 E_DBus_Connection* edbusConnection = e_dbus_bus_get(DBUS_BUS_SYSTEM); 80 if (edbusConnection) 81 e_upower_get_all_devices(edbusConnection, getBatteryStatus, static_cast<void*>(this)); 82} 83 84void BatteryProviderEfl::getBatteryStatus(void* data, void* replyData, DBusError* dBusError) 85{ 86 E_Ukit_Get_All_Devices_Return* eukitDeviceNames = static_cast<E_Ukit_Get_All_Devices_Return*>(replyData); 87 if (!eukitDeviceNames || !eukitDeviceNames->strings || dbus_error_is_set(dBusError)) { 88 dbus_error_free(dBusError); 89 return; 90 } 91 92 E_DBus_Connection* edbusConnection = e_dbus_bus_get(DBUS_BUS_SYSTEM); 93 Eina_List* list; 94 void* deviceName; 95 EINA_LIST_FOREACH(eukitDeviceNames->strings, list, deviceName) 96 e_upower_get_all_properties(edbusConnection, static_cast<char*>(deviceName), setBatteryClient, data); 97} 98 99void BatteryProviderEfl::setBatteryClient(void* data, void* replyData, DBusError* dBusError) 100{ 101 E_Ukit_Get_All_Properties_Return* eukitPropertyNames = static_cast<E_Ukit_Get_All_Properties_Return*>(replyData); 102 103 if (!eukitPropertyNames || dbus_error_is_set(dBusError)) { 104 dbus_error_free(dBusError); 105 return; 106 } 107 108 if (!eukitPropertyNames->properties) 109 return; 110 111 E_Ukit_Property* property = static_cast<E_Ukit_Property*>(eina_hash_find(eukitPropertyNames->properties, "Type")); 112 if (!property || property->val.u != E_UPOWER_SOURCE_BATTERY) 113 return; 114 115 BatteryProviderEfl* client = static_cast<BatteryProviderEfl*>(data); 116 BatteryStatus* clientBatteryStatus = client->batteryStatus(); 117 bool charging = false; 118 bool chargingChanged = false; 119 static unsigned chargingState = 0; 120 121 property = static_cast<E_Ukit_Property*>(eina_hash_find(eukitPropertyNames->properties, "State")); 122 if (!property) 123 return; 124 if (!clientBatteryStatus || chargingState != property->val.u) { 125 chargingChanged = true; 126 chargingState = property->val.u; 127 (chargingState == E_UPOWER_STATE_FULL || chargingState == E_UPOWER_STATE_CHARGING) ? charging = true : charging = false; 128 } else 129 charging = clientBatteryStatus->charging(); 130 131 bool chargingTimeChanged = false; 132 bool dischargingTimeChanged = false; 133 double chargingTime = std::numeric_limits<double>::infinity(); 134 double dischargingTime = std::numeric_limits<double>::infinity(); 135 136 if (charging) { 137 if (!clientBatteryStatus || clientBatteryStatus->dischargingTime() != std::numeric_limits<double>::infinity()) 138 dischargingTimeChanged = true; 139 dischargingTime = std::numeric_limits<double>::infinity(); 140 property = static_cast<E_Ukit_Property*>(eina_hash_find(eukitPropertyNames->properties, "TimeToFull")); 141 if (!property) 142 return; 143 if (!clientBatteryStatus || clientBatteryStatus->chargingTime() != property->val.x) 144 chargingTimeChanged = true; 145 chargingTime = property->val.x; 146 } else { 147 if (!clientBatteryStatus || clientBatteryStatus->chargingTime() != std::numeric_limits<double>::infinity()) 148 chargingTimeChanged = true; 149 chargingTime = std::numeric_limits<double>::infinity(); 150 property = static_cast<E_Ukit_Property*>(eina_hash_find(eukitPropertyNames->properties, "TimeToEmpty")); 151 if (!property) 152 return; 153 if (!clientBatteryStatus || clientBatteryStatus->dischargingTime() != property->val.x) 154 dischargingTimeChanged = true; 155 dischargingTime = property->val.x; 156 } 157 158 bool levelChanged = false; 159 property = static_cast<E_Ukit_Property*>(eina_hash_find(eukitPropertyNames->properties, "Percentage")); 160 if (!property) 161 return; 162 163 double level = property->val.d / 100; 164 if (!clientBatteryStatus || clientBatteryStatus->level() != level) 165 levelChanged = true; 166 167 WTF::RefPtr<BatteryStatus> batteryStatus = BatteryStatus::create(charging, chargingTime, dischargingTime, level); 168 if (chargingChanged) 169 client->setBatteryStatus(eventNames().chargingchangeEvent, batteryStatus); 170 if (chargingTimeChanged) 171 client->setBatteryStatus(eventNames().chargingtimechangeEvent, batteryStatus); 172 if (dischargingTimeChanged) 173 client->setBatteryStatus(eventNames().dischargingtimechangeEvent, batteryStatus); 174 if (levelChanged) 175 client->setBatteryStatus(eventNames().levelchangeEvent, batteryStatus); 176} 177 178} 179 180#endif // BATTERY_STATUS 181 182