15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/power_manager_client.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/command_line.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/format_macros.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 159ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/observer_list.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/platform_thread.h" 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h" 217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chromeos/chromeos_switches.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/dbus/power_manager/input_event.pb.h" 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/power_manager/peripheral_battery_status.pb.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/dbus/power_manager/policy.pb.h" 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/power_manager/power_supply_properties.pb.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/dbus/power_manager/suspend.pb.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/bus.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/message.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_path.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_proxy.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Maximum amount of time that the power manager will wait for Chrome to 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// say that it's ready for the system to be suspended, in milliseconds. 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kSuspendDelayTimeoutMs = 5000; 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Human-readable description of Chrome's suspend delay. 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kSuspendDelayDescription[] = "chrome"; 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The PowerManagerClient implementation used in production. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PowerManagerClientImpl : public PowerManagerClient { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit PowerManagerClientImpl(dbus::Bus* bus) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : origin_thread_id_(base::PlatformThread::CurrentId()), 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager_proxy_(NULL), 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) suspend_delay_id_(-1), 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) has_suspend_delay_id_(false), 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_suspend_id_(-1), 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) suspend_is_pending_(false), 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_pending_suspend_readiness_callbacks_(0), 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) last_is_projecting_(false), 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_(this) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager_proxy_ = bus->GetObjectProxy( 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kPowerManagerServiceName, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::ObjectPath(power_manager::kPowerManagerServicePath)); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager_proxy_->SetNameOwnerChangedCallback( 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&PowerManagerClientImpl::NameOwnerChangedReceived, 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Monitor the D-Bus signal for brightness changes. Only the power 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // manager knows the actual brightness level. We don't cache the 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // brightness level in Chrome as it'll make things less reliable. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager_proxy_->ConnectToSignal( 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kPowerManagerInterface, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kBrightnessChangedSignal, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PowerManagerClientImpl::BrightnessChangedReceived, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PowerManagerClientImpl::SignalConnected, 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager_proxy_->ConnectToSignal( 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kPowerManagerInterface, 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) power_manager::kPeripheralBatteryStatusSignal, 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&PowerManagerClientImpl::PeripheralBatteryStatusReceived, 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PowerManagerClientImpl::SignalConnected, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager_proxy_->ConnectToSignal( 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kPowerManagerInterface, 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) power_manager::kPowerSupplyPollSignal, 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&PowerManagerClientImpl::PowerSupplyPollReceived, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PowerManagerClientImpl::SignalConnected, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager_proxy_->ConnectToSignal( 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kPowerManagerInterface, 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) power_manager::kIdleNotifySignal, 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&PowerManagerClientImpl::IdleNotifySignalReceived, 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PowerManagerClientImpl::SignalConnected, 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager_proxy_->ConnectToSignal( 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kPowerManagerInterface, 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager::kInputEventSignal, 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&PowerManagerClientImpl::InputEventReceived, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PowerManagerClientImpl::SignalConnected, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager_proxy_->ConnectToSignal( 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kPowerManagerInterface, 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager::kSuspendStateChangedSignal, 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&PowerManagerClientImpl::SuspendStateChangedReceived, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PowerManagerClientImpl::SignalConnected, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager_proxy_->ConnectToSignal( 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kPowerManagerInterface, 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager::kSuspendImminentSignal, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind( 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &PowerManagerClientImpl::SuspendImminentReceived, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PowerManagerClientImpl::SignalConnected, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager_proxy_->ConnectToSignal( 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager::kPowerManagerInterface, 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager::kIdleActionImminentSignal, 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind( 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &PowerManagerClientImpl::IdleActionImminentReceived, 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&PowerManagerClientImpl::SignalConnected, 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager_proxy_->ConnectToSignal( 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager::kPowerManagerInterface, 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager::kIdleActionDeferredSignal, 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind( 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &PowerManagerClientImpl::IdleActionDeferredReceived, 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&PowerManagerClientImpl::SignalConnected, 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RegisterSuspendDelay(); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~PowerManagerClientImpl() { 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Here we should unregister suspend notifications from powerd, 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // however: 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - The lifetime of the PowerManagerClientImpl can extend past that of 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the objectproxy, 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // - power_manager can already detect that the client is gone and 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // unregister our suspend delay. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // PowerManagerClient overrides: 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AddObserver(Observer* observer) OVERRIDE { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(observer); // http://crbug.com/119976 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.AddObserver(observer); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RemoveObserver(Observer* observer) OVERRIDE { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.RemoveObserver(observer); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool HasObserver(Observer* observer) OVERRIDE { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return observers_.HasObserver(observer); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DecreaseScreenBrightness(bool allow_off) OVERRIDE { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MethodCall method_call( 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kPowerManagerInterface, 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kDecreaseScreenBrightness); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MessageWriter writer(&method_call); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writer.AppendBool(allow_off); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager_proxy_->CallMethod( 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &method_call, 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::ObjectProxy::EmptyResponseCallback()); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void IncreaseScreenBrightness() OVERRIDE { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SimpleMethodCallToPowerManager(power_manager::kIncreaseScreenBrightness); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DecreaseKeyboardBrightness() OVERRIDE { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SimpleMethodCallToPowerManager(power_manager::kDecreaseKeyboardBrightness); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void IncreaseKeyboardBrightness() OVERRIDE { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SimpleMethodCallToPowerManager(power_manager::kIncreaseKeyboardBrightness); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetScreenBrightnessPercent(double percent, 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool gradual) OVERRIDE { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MethodCall method_call( 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kPowerManagerInterface, 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kSetScreenBrightnessPercent); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MessageWriter writer(&method_call); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writer.AppendDouble(percent); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writer.AppendInt32( 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gradual ? 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kBrightnessTransitionGradual : 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kBrightnessTransitionInstant); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager_proxy_->CallMethod( 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &method_call, 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::ObjectProxy::EmptyResponseCallback()); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void GetScreenBrightnessPercent( 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GetScreenBrightnessPercentCallback& callback) OVERRIDE { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MethodCall method_call(power_manager::kPowerManagerInterface, 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kGetScreenBrightnessPercent); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager_proxy_->CallMethod( 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &method_call, 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PowerManagerClientImpl::OnGetScreenBrightnessPercent, 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), callback)); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void RequestStatusUpdate() OVERRIDE { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MethodCall method_call( 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kPowerManagerInterface, 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kGetPowerSupplyPropertiesMethod); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager_proxy_->CallMethod( 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &method_call, 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PowerManagerClientImpl::OnGetPowerSupplyPropertiesMethod, 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RequestRestart() OVERRIDE { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SimpleMethodCallToPowerManager(power_manager::kRequestRestartMethod); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RequestShutdown() OVERRIDE { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SimpleMethodCallToPowerManager(power_manager::kRequestShutdownMethod); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RequestIdleNotification(int64 threshold) OVERRIDE { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MethodCall method_call(power_manager::kPowerManagerInterface, 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kRequestIdleNotification); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MessageWriter writer(&method_call); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writer.AppendInt64(threshold); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager_proxy_->CallMethod( 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &method_call, 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::ObjectProxy::EmptyResponseCallback()); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual void NotifyUserActivity( 2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch power_manager::UserActivityType type) OVERRIDE { 2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dbus::MethodCall method_call( 2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch power_manager::kPowerManagerInterface, 2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch power_manager::kHandleUserActivityMethod); 2557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dbus::MessageWriter writer(&method_call); 2567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch writer.AppendInt32(type); 2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch power_manager_proxy_->CallMethod( 2597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch &method_call, 2607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 2617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dbus::ObjectProxy::EmptyResponseCallback()); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void NotifyVideoActivity(bool is_fullscreen) OVERRIDE { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MethodCall method_call( 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kPowerManagerInterface, 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kHandleVideoActivityMethod); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MessageWriter writer(&method_call); 269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch writer.AppendBool(is_fullscreen); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager_proxy_->CallMethod( 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &method_call, 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::ObjectProxy::EmptyResponseCallback()); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void SetPolicy( 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const power_manager::PowerManagementPolicy& policy) OVERRIDE { 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dbus::MethodCall method_call( 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager::kPowerManagerInterface, 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager::kSetPolicyMethod); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MessageWriter writer(&method_call); 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!writer.AppendProtoAsArrayOfBytes(policy)) { 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Error calling " << power_manager::kSetPolicyMethod; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager_proxy_->CallMethod( 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &method_call, 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::ObjectProxy::EmptyResponseCallback()); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetIsProjecting(bool is_projecting) OVERRIDE { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MethodCall method_call( 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kPowerManagerInterface, 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager::kSetIsProjectingMethod); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MessageWriter writer(&method_call); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writer.AppendBool(is_projecting); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager_proxy_->CallMethod( 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &method_call, 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::ObjectProxy::EmptyResponseCallback()); 30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) last_is_projecting_ = is_projecting; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual base::Closure GetSuspendReadinessCallback() OVERRIDE { 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(OnOriginThread()); 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(suspend_is_pending_); 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_pending_suspend_readiness_callbacks_++; 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::Bind(&PowerManagerClientImpl::HandleObserverSuspendReadiness, 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), pending_suspend_id_); 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Returns true if the current thread is the origin thread. 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool OnOriginThread() { 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::PlatformThread::CurrentId() == origin_thread_id_; 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when a dbus signal is initially connected. 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SignalConnected(const std::string& interface_name, 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& signal_name, 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG_IF(WARNING, !success) << "Failed to connect to signal " 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << signal_name << "."; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make a method call to power manager with no arguments and no response. 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SimpleMethodCallToPowerManager(const std::string& method_name) { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MethodCall method_call(power_manager::kPowerManagerInterface, 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method_name); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_manager_proxy_->CallMethod( 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &method_call, 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::ObjectProxy::EmptyResponseCallback()); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void NameOwnerChangedReceived(dbus::Signal* signal) { 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Power manager restarted"; 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RegisterSuspendDelay(); 34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetIsProjecting(last_is_projecting_); 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, PowerManagerRestarted()); 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void BrightnessChangedReceived(dbus::Signal* signal) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MessageReader reader(signal); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 brightness_level = 0; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool user_initiated = 0; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(reader.PopInt32(&brightness_level) && 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reader.PopBool(&user_initiated))) { 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Brightness changed signal had incorrect parameters: " 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << signal->ToString(); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Brightness changed to " << brightness_level 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ": user initiated " << user_initiated; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrightnessChanged(brightness_level, user_initiated)); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void PeripheralBatteryStatusReceived(dbus::Signal* signal) { 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dbus::MessageReader reader(signal); 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) power_manager::PeripheralBatteryStatus protobuf_status; 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!reader.PopArrayOfBytesAsProto(&protobuf_status)) { 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Unable to decode protocol buffer from " 366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << power_manager::kPeripheralBatteryStatusSignal << " signal"; 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string path = protobuf_status.path(); 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string name = protobuf_status.name(); 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int level = protobuf_status.has_level() ? protobuf_status.level() : -1; 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << "Device battery status received " << level 375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << " for " << name << " at " << path; 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PeripheralBatteryStatusReceived(path, name, level)); 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void PowerSupplyPollReceived(dbus::Signal* signal) { 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Received power supply poll signal."; 383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) dbus::MessageReader reader(signal); 384868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) power_manager::PowerSupplyProperties protobuf; 385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (reader.PopArrayOfBytesAsProto(&protobuf)) { 386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FOR_EACH_OBSERVER(Observer, observers_, PowerChanged(protobuf)); 387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LOG(ERROR) << "Unable to decode " 389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << power_manager::kPowerSupplyPollSignal << "signal"; 390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnGetPowerSupplyPropertiesMethod(dbus::Response* response) { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response) { 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Error calling " 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << power_manager::kGetPowerSupplyPropertiesMethod; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MessageReader reader(response); 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) power_manager::PowerSupplyProperties protobuf; 402868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (reader.PopArrayOfBytesAsProto(&protobuf)) { 403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FOR_EACH_OBSERVER(Observer, observers_, PowerChanged(protobuf)); 404868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 405868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LOG(ERROR) << "Unable to decode " 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << power_manager::kGetPowerSupplyPropertiesMethod 407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << " response"; 40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void OnGetScreenBrightnessPercent( 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetScreenBrightnessPercentCallback& callback, 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dbus::Response* response) { 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response) { 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Error calling " 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << power_manager::kGetScreenBrightnessPercent; 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MessageReader reader(response); 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) double percent = 0.0; 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!reader.PopDouble(&percent)) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Error reading response from powerd: " 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << response->ToString(); 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(percent); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void OnRegisterSuspendDelayReply(dbus::Response* response) { 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response) { 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Error calling " 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << power_manager::kRegisterSuspendDelayMethod; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MessageReader reader(response); 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager::RegisterSuspendDelayReply protobuf; 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!reader.PopArrayOfBytesAsProto(&protobuf)) { 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Unable to parse reply from " 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << power_manager::kRegisterSuspendDelayMethod; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) suspend_delay_id_ = protobuf.delay_id(); 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) has_suspend_delay_id_ = true; 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Registered suspend delay " << suspend_delay_id_; 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void IdleNotifySignalReceived(dbus::Signal* signal) { 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::MessageReader reader(signal); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 threshold = 0; 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!reader.PopInt64(&threshold)) { 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Idle Notify signal had incorrect parameters: " 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << signal->ToString(); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(threshold, 0); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Idle Notify: " << threshold; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, IdleNotify(threshold)); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SuspendImminentReceived(dbus::Signal* signal) { 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!has_suspend_delay_id_) { 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Received unrequested " 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << power_manager::kSuspendImminentSignal << " signal"; 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dbus::MessageReader reader(signal); 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager::SuspendImminent protobuf_imminent; 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!reader.PopArrayOfBytesAsProto(&protobuf_imminent)) { 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Unable to decode protocol buffer from " 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << power_manager::kSuspendImminentSignal << " signal"; 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (suspend_is_pending_) { 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(WARNING) << "Got " << power_manager::kSuspendImminentSignal 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " signal about pending suspend attempt " 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << protobuf_imminent.suspend_id() << " while still waiting " 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "on attempt " << pending_suspend_id_; 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_suspend_id_ = protobuf_imminent.suspend_id(); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) suspend_is_pending_ = true; 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_pending_suspend_readiness_callbacks_ = 0; 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, SuspendImminent()); 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MaybeReportSuspendReadiness(); 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void IdleActionImminentReceived(dbus::Signal* signal) { 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, IdleActionImminent()); 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void IdleActionDeferredReceived(dbus::Signal* signal) { 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, IdleActionDeferred()); 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void InputEventReceived(dbus::Signal* signal) { 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dbus::MessageReader reader(signal); 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager::InputEvent proto; 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!reader.PopArrayOfBytesAsProto(&proto)) { 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Unable to decode protocol buffer from " 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << power_manager::kInputEventSignal << " signal"; 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks timestamp = 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks::FromInternalValue(proto.timestamp()); 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Got " << power_manager::kInputEventSignal << " signal:" 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " type=" << proto.type() << " timestamp=" << proto.timestamp(); 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (proto.type()) { 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case power_manager::InputEvent_Type_POWER_BUTTON_DOWN: 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case power_manager::InputEvent_Type_POWER_BUTTON_UP: { 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool down = 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (proto.type() == power_manager::InputEvent_Type_POWER_BUTTON_DOWN); 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER(PowerManagerClient::Observer, observers_, 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PowerButtonEventReceived(down, timestamp)); 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case power_manager::InputEvent_Type_LID_OPEN: 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case power_manager::InputEvent_Type_LID_CLOSED: { 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool open = 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (proto.type() == power_manager::InputEvent_Type_LID_OPEN); 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER(PowerManagerClient::Observer, observers_, 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LidEventReceived(open, timestamp)); 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SuspendStateChangedReceived(dbus::Signal* signal) { 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dbus::MessageReader reader(signal); 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager::SuspendState proto; 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!reader.PopArrayOfBytesAsProto(&proto)) { 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Unable to decode protocol buffer from " 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << power_manager::kSuspendStateChangedSignal << " signal"; 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Got " << power_manager::kSuspendStateChangedSignal << " signal:" 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " type=" << proto.type() << " wall_time=" << proto.wall_time(); 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time wall_time = 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time::FromInternalValue(proto.wall_time()); 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (proto.type()) { 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case power_manager::SuspendState_Type_SUSPEND_TO_MEMORY: 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_suspend_wall_time_ = wall_time; 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case power_manager::SuspendState_Type_RESUME: 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER( 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PowerManagerClient::Observer, observers_, 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SystemResumed(wall_time - last_suspend_wall_time_)); 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Registers a suspend delay with the power manager. This is usually 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // only called at startup, but if the power manager restarts, we need to 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // create a new delay. 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void RegisterSuspendDelay() { 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Throw out any old delay that was registered. 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) suspend_delay_id_ = -1; 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) has_suspend_delay_id_ = false; 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dbus::MethodCall method_call( 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager::kPowerManagerInterface, 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager::kRegisterSuspendDelayMethod); 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dbus::MessageWriter writer(&method_call); 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager::RegisterSuspendDelayRequest protobuf_request; 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta timeout = 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromMilliseconds(kSuspendDelayTimeoutMs); 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protobuf_request.set_timeout(timeout.ToInternalValue()); 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protobuf_request.set_description(kSuspendDelayDescription); 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!writer.AppendProtoAsArrayOfBytes(protobuf_request)) { 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Error constructing message for " 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << power_manager::kRegisterSuspendDelayMethod; 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager_proxy_->CallMethod( 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &method_call, 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind( 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &PowerManagerClientImpl::OnRegisterSuspendDelayReply, 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Records the fact that an observer has finished doing asynchronous work 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that was blocking a pending suspend attempt and possibly reports 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // suspend readiness to powerd. Called by callbacks returned via 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // GetSuspendReadinessCallback(). 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void HandleObserverSuspendReadiness(int32 suspend_id) { 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(OnOriginThread()); 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!suspend_is_pending_ || suspend_id != pending_suspend_id_) 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_pending_suspend_readiness_callbacks_--; 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MaybeReportSuspendReadiness(); 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Reports suspend readiness to powerd if no observers are still holding 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // suspend readiness callbacks. 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void MaybeReportSuspendReadiness() { 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!suspend_is_pending_ || num_pending_suspend_readiness_callbacks_ > 0) 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dbus::MethodCall method_call( 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager::kPowerManagerInterface, 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager::kHandleSuspendReadinessMethod); 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dbus::MessageWriter writer(&method_call); 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager::SuspendReadinessInfo protobuf_request; 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protobuf_request.set_delay_id(suspend_delay_id_); 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protobuf_request.set_suspend_id(pending_suspend_id_); 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_suspend_id_ = -1; 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) suspend_is_pending_ = false; 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!writer.AppendProtoAsArrayOfBytes(protobuf_request)) { 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Error constructing message for " 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << power_manager::kHandleSuspendReadinessMethod; 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_manager_proxy_->CallMethod( 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &method_call, 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dbus::ObjectProxy::EmptyResponseCallback()); 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Origin thread (i.e. the UI thread in production). 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::PlatformThreadId origin_thread_id_; 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::ObjectProxy* power_manager_proxy_; 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ObserverList<Observer> observers_; 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The delay_id_ obtained from the RegisterSuspendDelay request. 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32 suspend_delay_id_; 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool has_suspend_delay_id_; 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // powerd-supplied ID corresponding to an imminent suspend attempt that is 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // currently being delayed. 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32 pending_suspend_id_; 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool suspend_is_pending_; 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Number of callbacks that have been returned by 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // GetSuspendReadinessCallback() during the currently-pending suspend 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // attempt but have not yet been called. 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_pending_suspend_readiness_callbacks_; 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Wall time from the latest signal telling us that the system was about to 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // suspend to memory. 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time last_suspend_wall_time_; 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 65490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Last state passed to SetIsProjecting(). 65590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool last_is_projecting_; 65690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: This should remain the last member so it'll be destroyed and 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // invalidate its weak pointers before any other members are destroyed. 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtrFactory<PowerManagerClientImpl> weak_ptr_factory_; 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PowerManagerClientImpl); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The PowerManagerClient implementation used on Linux desktop, 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which does nothing. 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PowerManagerClientStubImpl : public PowerManagerClient { 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PowerManagerClientStubImpl() 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : discharging_(true), 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) battery_percentage_(40), 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) brightness_(50.0), 672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pause_count_(2), 673868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) cycle_count_(0), 674868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) weak_ptr_factory_(this) { 6757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (CommandLine::ForCurrentProcess()->HasSwitch( 6767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch chromeos::switches::kEnableStubInteractive)) { 6777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const int kStatusUpdateMs = 1000; 6787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch update_timer_.Start(FROM_HERE, 6797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::TimeDelta::FromMilliseconds(kStatusUpdateMs), this, 6807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch &PowerManagerClientStubImpl::UpdateStatus); 6817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~PowerManagerClientStubImpl() {} 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // PowerManagerClient overrides: 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AddObserver(Observer* observer) OVERRIDE { 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.AddObserver(observer); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RemoveObserver(Observer* observer) OVERRIDE { 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.RemoveObserver(observer); 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool HasObserver(Observer* observer) OVERRIDE { 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return observers_.HasObserver(observer); 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DecreaseScreenBrightness(bool allow_off) OVERRIDE { 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Requested to descrease screen brightness"; 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetBrightness(brightness_ - 5.0, true); 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void IncreaseScreenBrightness() OVERRIDE { 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Requested to increase screen brightness"; 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetBrightness(brightness_ + 5.0, true); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetScreenBrightnessPercent(double percent, 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool gradual) OVERRIDE { 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Requested to set screen brightness to " << percent << "% " 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << (gradual ? "gradually" : "instantaneously"); 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetBrightness(percent, false); 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void GetScreenBrightnessPercent( 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GetScreenBrightnessPercentCallback& callback) OVERRIDE { 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(brightness_); 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DecreaseKeyboardBrightness() OVERRIDE { 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Requested to descrease keyboard brightness"; 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void IncreaseKeyboardBrightness() OVERRIDE { 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Requested to increase keyboard brightness"; 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 730868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void RequestStatusUpdate() OVERRIDE { 731868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::MessageLoop::current()->PostTask(FROM_HERE, 732868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&PowerManagerClientStubImpl::UpdateStatus, 733868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RequestRestart() OVERRIDE {} 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RequestShutdown() OVERRIDE {} 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void RequestIdleNotification(int64 threshold) OVERRIDE { 740868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&PowerManagerClientStubImpl::TriggerIdleNotify, 743868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), threshold), 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromMilliseconds(threshold)); 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual void NotifyUserActivity( 7487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch power_manager::UserActivityType type) OVERRIDE {} 749eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void NotifyVideoActivity(bool is_fullscreen) OVERRIDE {} 7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void SetPolicy( 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const power_manager::PowerManagementPolicy& policy) OVERRIDE {} 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetIsProjecting(bool is_projecting) OVERRIDE {} 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual base::Closure GetSuspendReadinessCallback() OVERRIDE { 7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::Closure(); 7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 758868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void UpdateStatus() { 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pause_count_ > 0) { 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pause_count_--; 761eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (pause_count_ == 2) 762eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch discharging_ = !discharging_; 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 764eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (discharging_) 765eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch battery_percentage_ -= (battery_percentage_ <= 10 ? 1 : 10); 766eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch else 767eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch battery_percentage_ += (battery_percentage_ >= 10 ? 10 : 1); 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) battery_percentage_ = std::min(std::max(battery_percentage_, 0), 100); 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We pause at 0 and 100% so that it's easier to check those conditions. 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (battery_percentage_ == 0 || battery_percentage_ == 100) { 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pause_count_ = 4; 772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (battery_percentage_ == 100) 773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cycle_count_ = (cycle_count_ + 1) % 3; 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 777eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int kSecondsToEmptyFullBattery = 3 * 60 * 60; // 3 hours. 778a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) int64 remaining_battery_time = 779a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) std::max(1, battery_percentage_ * kSecondsToEmptyFullBattery / 100); 780eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 781eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch props_.Clear(); 782eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 783eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch switch (cycle_count_) { 784eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case 0: 785eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Say that the system is charging with AC connected and 786eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // discharging without any charger connected. 787eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch props_.set_external_power(discharging_ ? 788eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch power_manager::PowerSupplyProperties_ExternalPower_DISCONNECTED : 789eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch power_manager::PowerSupplyProperties_ExternalPower_AC); 790eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 791eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case 1: 792eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Say that the system is both charging and discharging on USB 793eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // (i.e. a low-power charger). 794eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch props_.set_external_power( 795eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch power_manager::PowerSupplyProperties_ExternalPower_USB); 796eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 797eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case 2: 798eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Say that the system is both charging and discharging on AC. 799eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch props_.set_external_power( 800eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch power_manager::PowerSupplyProperties_ExternalPower_AC); 801eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 802eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch default: 803eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NOTREACHED() << "Unhandled cycle " << cycle_count_; 804eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 805eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 806eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (battery_percentage_ == 100 && !discharging_) { 807eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch props_.set_battery_state( 808eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch power_manager::PowerSupplyProperties_BatteryState_FULL); 809eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if (!discharging_) { 810eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch props_.set_battery_state( 811eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch power_manager::PowerSupplyProperties_BatteryState_CHARGING); 812eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch props_.set_battery_time_to_full_sec(std::max(static_cast<int64>(1), 813eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kSecondsToEmptyFullBattery - remaining_battery_time)); 814eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 815eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch props_.set_battery_state( 816eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch power_manager::PowerSupplyProperties_BatteryState_DISCHARGING); 817eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch props_.set_battery_time_to_empty_sec(remaining_battery_time); 818eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 819eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 820eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch props_.set_battery_percent(battery_percentage_); 821eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch props_.set_is_calculating_battery_time(pause_count_ > 1); 822eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 823eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FOR_EACH_OBSERVER(Observer, observers_, PowerChanged(props_)); 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetBrightness(double percent, bool user_initiated) { 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) brightness_ = std::min(std::max(0.0, percent), 100.0); 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int brightness_level = static_cast<int>(brightness_); 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrightnessChanged(brightness_level, user_initiated)); 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void TriggerIdleNotify(int64 threshold) { 8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, IdleNotify(threshold)); 8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool discharging_; 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int battery_percentage_; 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double brightness_; 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pause_count_; 841c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int cycle_count_; 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ObserverList<Observer> observers_; 843868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::RepeatingTimer<PowerManagerClientStubImpl> update_timer_; 844eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch power_manager::PowerSupplyProperties props_; 845868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 846868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Note: This should remain the last member so it'll be destroyed and 847868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // invalidate its weak pointers before any other members are destroyed. 848868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::WeakPtrFactory<PowerManagerClientStubImpl> weak_ptr_factory_; 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PowerManagerClient::PowerManagerClient() { 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PowerManagerClient::~PowerManagerClient() { 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PowerManagerClient* PowerManagerClient::Create( 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusClientImplementationType type, 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus::Bus* bus) { 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new PowerManagerClientImpl(bus); 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new PowerManagerClientStubImpl(); 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace chromeos 868