Home | History | Annotate | Download | only in power_profiler
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/browser/power_profiler/power_profiler_service.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "base/threading/sequenced_worker_pool.h"
     10 #include "content/public/browser/browser_thread.h"
     11 
     12 namespace content {
     13 
     14 PowerProfilerService::PowerProfilerService()
     15     : status_(UNINITIALIZED),
     16       data_provider_(PowerDataProvider::Create()) {
     17   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     18 
     19   // No provider supported for current platform.
     20   if (!data_provider_.get())
     21     return;
     22   sample_period_ = data_provider_->GetSamplingRate();
     23   status_ = INITIALIZED;
     24   task_runner_ = BrowserThread::GetBlockingPool()->GetSequencedTaskRunner(
     25       BrowserThread::GetBlockingPool()->GetSequenceToken());
     26 }
     27 
     28 PowerProfilerService::PowerProfilerService(
     29     scoped_ptr<PowerDataProvider> provider,
     30     scoped_refptr<base::TaskRunner> task_runner,
     31     const base::TimeDelta& sample_period)
     32     : task_runner_(task_runner),
     33       status_(UNINITIALIZED),
     34       sample_period_(sample_period),
     35       data_provider_(provider.Pass()) {
     36   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     37 
     38   if (data_provider_.get())
     39       status_ = INITIALIZED;
     40 }
     41 
     42 PowerProfilerService::~PowerProfilerService() {
     43 }
     44 
     45 bool PowerProfilerService::IsAvailable() const {
     46   return status_ !=  UNINITIALIZED;
     47 }
     48 
     49 std::string PowerProfilerService::GetAccuracyLevel() const {
     50   DCHECK(IsAvailable());
     51   switch (data_provider_->GetAccuracyLevel()) {
     52     case PowerDataProvider::High:
     53       return "High";
     54     case PowerDataProvider::Moderate:
     55       return "Moderate";
     56     case PowerDataProvider::Low:
     57       return "Low";
     58   }
     59   return "";
     60 }
     61 
     62 PowerProfilerService* PowerProfilerService::GetInstance() {
     63   return Singleton<PowerProfilerService>::get();
     64 }
     65 
     66 void PowerProfilerService::AddObserver(PowerProfilerObserver* observer) {
     67   if (status_ == UNINITIALIZED)
     68     return;
     69 
     70   observers_.AddObserver(observer);
     71   if (status_ != PROFILING)
     72     Start();
     73 }
     74 
     75 void PowerProfilerService::RemoveObserver(PowerProfilerObserver* observer) {
     76   observers_.RemoveObserver(observer);
     77 
     78   if (status_ == PROFILING && !observers_.might_have_observers())
     79     Stop();
     80 }
     81 
     82 void PowerProfilerService::Start() {
     83   DCHECK(status_ == INITIALIZED);
     84   status_ = PROFILING;
     85 
     86   // Send out power events immediately.
     87   QueryData();
     88 
     89   query_power_timer_.Start(FROM_HERE,
     90       sample_period_, this, &PowerProfilerService::QueryData);
     91 }
     92 
     93 void PowerProfilerService::Stop() {
     94   DCHECK(status_ == PROFILING);
     95 
     96   query_power_timer_.Stop();
     97   status_ = INITIALIZED;
     98 }
     99 
    100 void PowerProfilerService::QueryData() {
    101   task_runner_->PostTask(
    102       FROM_HERE, base::Bind(&PowerProfilerService::QueryDataOnTaskRunner,
    103                             base::Unretained(this)));
    104 }
    105 
    106 void PowerProfilerService::Notify(const PowerEventVector& events) {
    107   FOR_EACH_OBSERVER(PowerProfilerObserver, observers_, OnPowerEvent(events));
    108 }
    109 
    110 void PowerProfilerService::QueryDataOnTaskRunner() {
    111   DCHECK(task_runner_->RunsTasksOnCurrentThread());
    112   DCHECK(status_ == PROFILING);
    113 
    114   // Get data and notify.
    115   PowerEventVector events = data_provider_->GetData();
    116   if (events.size() != 0) {
    117     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
    118         &PowerProfilerService::Notify, base::Unretained(this), events));
    119   }
    120 }
    121 
    122 }  // namespace content
    123