// Copyright (c) 2012 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 "content/browser/histogram_controller.h"
#include "base/bind.h"
#include "base/metrics/histogram.h"
#include "content/browser/histogram_subscriber.h"
#include "content/common/child_process_messages.h"
#include "content/public/browser/browser_child_process_host_iterator.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/process_type.h"
namespace content {
HistogramController* HistogramController::GetInstance() {
return Singleton<HistogramController>::get();
}
HistogramController::HistogramController() : subscriber_(NULL) {
}
HistogramController::~HistogramController() {
}
void HistogramController::OnPendingProcesses(int sequence_number,
int pending_processes,
bool end) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (subscriber_)
subscriber_->OnPendingProcesses(sequence_number, pending_processes, end);
}
void HistogramController::OnHistogramDataCollected(
int sequence_number,
const std::vector<std::string>& pickled_histograms) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&HistogramController::OnHistogramDataCollected,
base::Unretained(this),
sequence_number,
pickled_histograms));
return;
}
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (subscriber_) {
subscriber_->OnHistogramDataCollected(sequence_number,
pickled_histograms);
}
}
void HistogramController::Register(HistogramSubscriber* subscriber) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(!subscriber_);
subscriber_ = subscriber;
}
void HistogramController::Unregister(
const HistogramSubscriber* subscriber) {
DCHECK_EQ(subscriber_, subscriber);
subscriber_ = NULL;
}
void HistogramController::GetHistogramDataFromChildProcesses(
int sequence_number) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
int pending_processes = 0;
for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) {
int type = iter.GetData().process_type;
if (type != PROCESS_TYPE_PLUGIN &&
type != PROCESS_TYPE_GPU &&
type != PROCESS_TYPE_PPAPI_PLUGIN &&
type != PROCESS_TYPE_PPAPI_BROKER) {
continue;
}
++pending_processes;
if (!iter.Send(new ChildProcessMsg_GetChildHistogramData(sequence_number)))
--pending_processes;
}
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
base::Bind(
&HistogramController::OnPendingProcesses,
base::Unretained(this),
sequence_number,
pending_processes,
true));
}
void HistogramController::GetHistogramData(int sequence_number) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
int pending_processes = 0;
for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
!it.IsAtEnd(); it.Advance()) {
++pending_processes;
if (!it.GetCurrentValue()->Send(
new ChildProcessMsg_GetChildHistogramData(sequence_number))) {
--pending_processes;
}
}
OnPendingProcesses(sequence_number, pending_processes, false);
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
base::Bind(&HistogramController::GetHistogramDataFromChildProcesses,
base::Unretained(this),
sequence_number));
}
} // namespace content