perf_provider_chromeos.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind_helpers.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/callback.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/compiler_specific.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/metrics/histogram.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/process_util.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/sequenced_worker_pool.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/metrics/perf_provider_chromeos.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_list.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_list_observer.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_switches.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/dbus/debug_daemon_client.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Default time in seconds between invocations of perf. 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This period is roughly 6.5 hours. 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This is chosen to be relatively prime with the number of seconds in: 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - one minute (60) 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - one hour (3600) 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - one day (86400) 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const unsigned kPerfCommandIntervalDefaultSeconds = 23093; 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Default time in seconds perf is run for. 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const unsigned kPerfCommandDurationDefaultSeconds = 2; 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace metrics { 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This class must be created and used on the UI thread. It watches for any 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// incognito window being opened from the time it is instantiated to the time it 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// is destroyed. 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WindowedIncognitoObserver : public chrome::BrowserListObserver { 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WindowedIncognitoObserver() : incognito_launched_(false) { 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserList::AddObserver(this); 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~WindowedIncognitoObserver() { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserList::RemoveObserver(this); 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This method can be checked to see whether any incognito window has been 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // opened since the time this object was created. 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool incognito_launched() { 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return incognito_launched_; 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // chrome::BrowserListObserver implementation. 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnBrowserAdded(Browser* browser) OVERRIDE { 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (browser->profile()->IsOffTheRecord()) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) incognito_launched_ = true; 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool incognito_launched_; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PerfProvider::PerfProvider() 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : state_(READY_TO_COLLECT), 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this) { 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScheduleCollection(); 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PerfProvider::~PerfProvider() {} 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PerfProvider::GetPerfData(PerfDataProto* perf_data_proto) { 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (state_ != READY_TO_UPLOAD) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *perf_data_proto = perf_data_proto_; 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_ = READY_TO_COLLECT; 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PerfProvider::ScheduleCollection() { 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (timer_.IsRunning()) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta collection_interval = base::TimeDelta::FromSeconds( 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kPerfCommandIntervalDefaultSeconds); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) timer_.Start(FROM_HERE, collection_interval, this, 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &PerfProvider::CollectIfNecessary); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PerfProvider::CollectIfNecessary() { 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (state_ != READY_TO_COLLECT) 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For privacy reasons, Chrome should only collect perf data if there is no 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // incognito session active (or gets spawned during the collection). 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (BrowserList::IsOffTheRecordSessionActive()) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<WindowedIncognitoObserver> incognito_observer( 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new WindowedIncognitoObserver); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chromeos::DebugDaemonClient* client = 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta collection_duration = base::TimeDelta::FromSeconds( 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kPerfCommandDurationDefaultSeconds); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client->GetPerfData(collection_duration.InSeconds(), 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&PerfProvider::ParseProtoIfValid, 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_factory_.GetWeakPtr(), 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&incognito_observer))); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PerfProvider::ParseProtoIfValid( 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<WindowedIncognitoObserver> incognito_observer, 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<uint8>& data) { 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (incognito_observer->incognito_launched()) 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!perf_data_proto_.ParseFromArray(data.data(), data.size())) { 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) perf_data_proto_.Clear(); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_ = READY_TO_UPLOAD; 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace metrics 145