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