Home | History | Annotate | Download | only in cros
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/chromeos/cros/power_library.h"
      6 
      7 #include "base/message_loop.h"
      8 #include "base/string_util.h"
      9 #include "chrome/browser/chromeos/cros/cros_library.h"
     10 #include "content/browser/browser_thread.h"
     11 #include "third_party/cros/chromeos_resume.h"
     12 
     13 namespace chromeos {
     14 
     15 class PowerLibraryImpl : public PowerLibrary {
     16  public:
     17   PowerLibraryImpl()
     18       : power_status_connection_(NULL),
     19         resume_status_connection_(NULL),
     20         status_(chromeos::PowerStatus()) {
     21     if (CrosLibrary::Get()->EnsureLoaded()) {
     22       Init();
     23     }
     24   }
     25 
     26   ~PowerLibraryImpl() {
     27     if (power_status_connection_) {
     28       chromeos::DisconnectPowerStatus(power_status_connection_);
     29       power_status_connection_ = NULL;
     30     }
     31     if (resume_status_connection_) {
     32       chromeos::DisconnectResume(resume_status_connection_);
     33       resume_status_connection_ = NULL;
     34     }
     35   }
     36 
     37   void AddObserver(Observer* observer) {
     38     observers_.AddObserver(observer);
     39   }
     40 
     41   void RemoveObserver(Observer* observer) {
     42     observers_.RemoveObserver(observer);
     43   }
     44 
     45   bool line_power_on() const {
     46     return status_.line_power_on;
     47   }
     48 
     49   bool battery_is_present() const {
     50     return status_.battery_is_present;
     51   }
     52 
     53   bool battery_fully_charged() const {
     54     return status_.battery_state == chromeos::BATTERY_STATE_FULLY_CHARGED;
     55   }
     56 
     57   double battery_percentage() const {
     58     return status_.battery_percentage;
     59   }
     60 
     61   base::TimeDelta battery_time_to_empty() const {
     62     return base::TimeDelta::FromSeconds(status_.battery_time_to_empty);
     63   }
     64 
     65   base::TimeDelta battery_time_to_full() const {
     66     return base::TimeDelta::FromSeconds(status_.battery_time_to_full);
     67   }
     68 
     69   virtual void EnableScreenLock(bool enable) {
     70     if (!CrosLibrary::Get()->EnsureLoaded())
     71       return;
     72 
     73     // Make sure we run on FILE thread becuase chromeos::EnableScreenLock
     74     // would write power manager config file to disk.
     75     if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) {
     76       BrowserThread::PostTask(
     77           BrowserThread::FILE, FROM_HERE,
     78           NewRunnableMethod(this, &PowerLibraryImpl::EnableScreenLock, enable));
     79       return;
     80     }
     81 
     82     chromeos::EnableScreenLock(enable);
     83   }
     84 
     85   virtual void RequestRestart() {
     86     if (!CrosLibrary::Get()->EnsureLoaded())
     87       return;
     88     chromeos::RequestRestart();
     89   }
     90 
     91   virtual void RequestShutdown() {
     92     if (!CrosLibrary::Get()->EnsureLoaded())
     93       return;
     94     chromeos::RequestShutdown();
     95   }
     96 
     97  private:
     98   static void PowerStatusChangedHandler(void* object,
     99       const chromeos::PowerStatus& status) {
    100     PowerLibraryImpl* power = static_cast<PowerLibraryImpl*>(object);
    101     power->UpdatePowerStatus(status);
    102   }
    103 
    104   static void SystemResumedHandler(void* object) {
    105     PowerLibraryImpl* power = static_cast<PowerLibraryImpl*>(object);
    106     power->SystemResumed();
    107   }
    108 
    109   void Init() {
    110     power_status_connection_ = chromeos::MonitorPowerStatus(
    111         &PowerStatusChangedHandler, this);
    112     resume_status_connection_ =
    113         chromeos::MonitorResume(&SystemResumedHandler, this);
    114   }
    115 
    116   void UpdatePowerStatus(const chromeos::PowerStatus& status) {
    117     // Make sure we run on UI thread.
    118     if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
    119       BrowserThread::PostTask(
    120           BrowserThread::UI, FROM_HERE,
    121           NewRunnableMethod(
    122               this, &PowerLibraryImpl::UpdatePowerStatus, status));
    123       return;
    124     }
    125 
    126     DVLOG(1) << "Power lpo=" << status.line_power_on
    127              << " sta=" << status.battery_state
    128              << " per=" << status.battery_percentage
    129              << " tte=" << status.battery_time_to_empty
    130              << " ttf=" << status.battery_time_to_full;
    131     status_ = status;
    132     FOR_EACH_OBSERVER(Observer, observers_, PowerChanged(this));
    133   }
    134 
    135   void SystemResumed() {
    136     // Make sure we run on the UI thread.
    137     if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
    138       BrowserThread::PostTask(
    139           BrowserThread::UI, FROM_HERE,
    140           NewRunnableMethod(this, &PowerLibraryImpl::SystemResumed));
    141       return;
    142     }
    143 
    144     FOR_EACH_OBSERVER(Observer, observers_, SystemResumed());
    145   }
    146 
    147   ObserverList<Observer> observers_;
    148 
    149   // A reference to the battery power api, to allow callbacks when the battery
    150   // status changes.
    151   chromeos::PowerStatusConnection power_status_connection_;
    152 
    153   // A reference to the resume alerts.
    154   chromeos::ResumeConnection resume_status_connection_;
    155 
    156   // The latest power status.
    157   chromeos::PowerStatus status_;
    158 
    159   DISALLOW_COPY_AND_ASSIGN(PowerLibraryImpl);
    160 };
    161 
    162 class PowerLibraryStubImpl : public PowerLibrary {
    163  public:
    164   PowerLibraryStubImpl() {}
    165   ~PowerLibraryStubImpl() {}
    166   void AddObserver(Observer* observer) {}
    167   void RemoveObserver(Observer* observer) {}
    168   bool line_power_on() const { return false; }
    169   bool battery_is_present() const { return true; }
    170   bool battery_fully_charged() const { return false; }
    171   double battery_percentage() const { return 50.0; }
    172   base::TimeDelta battery_time_to_empty() const {
    173     return base::TimeDelta::FromSeconds(10 * 60);
    174   }
    175   base::TimeDelta battery_time_to_full() const {
    176     return base::TimeDelta::FromSeconds(0);
    177   }
    178   virtual void EnableScreenLock(bool enable) {}
    179   virtual void RequestRestart() {}
    180   virtual void RequestShutdown() {}
    181 };
    182 
    183 // static
    184 PowerLibrary* PowerLibrary::GetImpl(bool stub) {
    185   if (stub)
    186     return new PowerLibraryStubImpl();
    187   else
    188     return new PowerLibraryImpl();
    189 }
    190 
    191 }  // namespace chromeos
    192 
    193 // Allows InvokeLater without adding refcounting. This class is a Singleton and
    194 // won't be deleted until it's last InvokeLater is run.
    195 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::PowerLibraryImpl);
    196