// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/chromeos/cros/power_library.h" #include "base/message_loop.h" #include "base/string_util.h" #include "chrome/browser/chromeos/cros/cros_library.h" #include "content/browser/browser_thread.h" #include "third_party/cros/chromeos_resume.h" namespace chromeos { class PowerLibraryImpl : public PowerLibrary { public: PowerLibraryImpl() : power_status_connection_(NULL), resume_status_connection_(NULL), status_(chromeos::PowerStatus()) { if (CrosLibrary::Get()->EnsureLoaded()) { Init(); } } ~PowerLibraryImpl() { if (power_status_connection_) { chromeos::DisconnectPowerStatus(power_status_connection_); power_status_connection_ = NULL; } if (resume_status_connection_) { chromeos::DisconnectResume(resume_status_connection_); resume_status_connection_ = NULL; } } void AddObserver(Observer* observer) { observers_.AddObserver(observer); } void RemoveObserver(Observer* observer) { observers_.RemoveObserver(observer); } bool line_power_on() const { return status_.line_power_on; } bool battery_is_present() const { return status_.battery_is_present; } bool battery_fully_charged() const { return status_.battery_state == chromeos::BATTERY_STATE_FULLY_CHARGED; } double battery_percentage() const { return status_.battery_percentage; } base::TimeDelta battery_time_to_empty() const { return base::TimeDelta::FromSeconds(status_.battery_time_to_empty); } base::TimeDelta battery_time_to_full() const { return base::TimeDelta::FromSeconds(status_.battery_time_to_full); } virtual void EnableScreenLock(bool enable) { if (!CrosLibrary::Get()->EnsureLoaded()) return; // Make sure we run on FILE thread becuase chromeos::EnableScreenLock // would write power manager config file to disk. if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) { BrowserThread::PostTask( BrowserThread::FILE, FROM_HERE, NewRunnableMethod(this, &PowerLibraryImpl::EnableScreenLock, enable)); return; } chromeos::EnableScreenLock(enable); } virtual void RequestRestart() { if (!CrosLibrary::Get()->EnsureLoaded()) return; chromeos::RequestRestart(); } virtual void RequestShutdown() { if (!CrosLibrary::Get()->EnsureLoaded()) return; chromeos::RequestShutdown(); } private: static void PowerStatusChangedHandler(void* object, const chromeos::PowerStatus& status) { PowerLibraryImpl* power = static_cast<PowerLibraryImpl*>(object); power->UpdatePowerStatus(status); } static void SystemResumedHandler(void* object) { PowerLibraryImpl* power = static_cast<PowerLibraryImpl*>(object); power->SystemResumed(); } void Init() { power_status_connection_ = chromeos::MonitorPowerStatus( &PowerStatusChangedHandler, this); resume_status_connection_ = chromeos::MonitorResume(&SystemResumedHandler, this); } void UpdatePowerStatus(const chromeos::PowerStatus& status) { // Make sure we run on UI thread. if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, NewRunnableMethod( this, &PowerLibraryImpl::UpdatePowerStatus, status)); return; } DVLOG(1) << "Power lpo=" << status.line_power_on << " sta=" << status.battery_state << " per=" << status.battery_percentage << " tte=" << status.battery_time_to_empty << " ttf=" << status.battery_time_to_full; status_ = status; FOR_EACH_OBSERVER(Observer, observers_, PowerChanged(this)); } void SystemResumed() { // Make sure we run on the UI thread. if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, NewRunnableMethod(this, &PowerLibraryImpl::SystemResumed)); return; } FOR_EACH_OBSERVER(Observer, observers_, SystemResumed()); } ObserverList<Observer> observers_; // A reference to the battery power api, to allow callbacks when the battery // status changes. chromeos::PowerStatusConnection power_status_connection_; // A reference to the resume alerts. chromeos::ResumeConnection resume_status_connection_; // The latest power status. chromeos::PowerStatus status_; DISALLOW_COPY_AND_ASSIGN(PowerLibraryImpl); }; class PowerLibraryStubImpl : public PowerLibrary { public: PowerLibraryStubImpl() {} ~PowerLibraryStubImpl() {} void AddObserver(Observer* observer) {} void RemoveObserver(Observer* observer) {} bool line_power_on() const { return false; } bool battery_is_present() const { return true; } bool battery_fully_charged() const { return false; } double battery_percentage() const { return 50.0; } base::TimeDelta battery_time_to_empty() const { return base::TimeDelta::FromSeconds(10 * 60); } base::TimeDelta battery_time_to_full() const { return base::TimeDelta::FromSeconds(0); } virtual void EnableScreenLock(bool enable) {} virtual void RequestRestart() {} virtual void RequestShutdown() {} }; // static PowerLibrary* PowerLibrary::GetImpl(bool stub) { if (stub) return new PowerLibraryStubImpl(); else return new PowerLibraryImpl(); } } // namespace chromeos // Allows InvokeLater without adding refcounting. This class is a Singleton and // won't be deleted until it's last InvokeLater is run. DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::PowerLibraryImpl);