Home | History | Annotate | Download | only in browser
      1 // Copyright (c) 2012 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/histogram_controller.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/metrics/histogram.h"
      9 #include "content/browser/histogram_subscriber.h"
     10 #include "content/common/child_process_messages.h"
     11 #include "content/public/browser/browser_child_process_host_iterator.h"
     12 #include "content/public/browser/browser_thread.h"
     13 #include "content/public/browser/child_process_data.h"
     14 #include "content/public/browser/render_process_host.h"
     15 #include "content/public/common/process_type.h"
     16 
     17 namespace content {
     18 
     19 HistogramController* HistogramController::GetInstance() {
     20   return Singleton<HistogramController>::get();
     21 }
     22 
     23 HistogramController::HistogramController() : subscriber_(NULL) {
     24 }
     25 
     26 HistogramController::~HistogramController() {
     27 }
     28 
     29 void HistogramController::OnPendingProcesses(int sequence_number,
     30                                              int pending_processes,
     31                                              bool end) {
     32   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     33   if (subscriber_)
     34     subscriber_->OnPendingProcesses(sequence_number, pending_processes, end);
     35 }
     36 
     37 void HistogramController::OnHistogramDataCollected(
     38     int sequence_number,
     39     const std::vector<std::string>& pickled_histograms) {
     40   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
     41     BrowserThread::PostTask(
     42         BrowserThread::UI, FROM_HERE,
     43         base::Bind(&HistogramController::OnHistogramDataCollected,
     44                    base::Unretained(this),
     45                    sequence_number,
     46                    pickled_histograms));
     47     return;
     48   }
     49 
     50   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     51   if (subscriber_) {
     52     subscriber_->OnHistogramDataCollected(sequence_number,
     53                                           pickled_histograms);
     54   }
     55 }
     56 
     57 void HistogramController::Register(HistogramSubscriber* subscriber) {
     58   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     59   DCHECK(!subscriber_);
     60   subscriber_ = subscriber;
     61 }
     62 
     63 void HistogramController::Unregister(
     64     const HistogramSubscriber* subscriber) {
     65   DCHECK_EQ(subscriber_, subscriber);
     66   subscriber_ = NULL;
     67 }
     68 
     69 void HistogramController::GetHistogramDataFromChildProcesses(
     70     int sequence_number) {
     71   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
     72 
     73   int pending_processes = 0;
     74   for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) {
     75     int type = iter.GetData().process_type;
     76     if (type != PROCESS_TYPE_PLUGIN &&
     77         type != PROCESS_TYPE_GPU &&
     78         type != PROCESS_TYPE_PPAPI_PLUGIN &&
     79         type != PROCESS_TYPE_PPAPI_BROKER) {
     80       continue;
     81     }
     82 
     83     ++pending_processes;
     84     if (!iter.Send(new ChildProcessMsg_GetChildHistogramData(sequence_number)))
     85       --pending_processes;
     86   }
     87 
     88   BrowserThread::PostTask(
     89       BrowserThread::UI,
     90       FROM_HERE,
     91       base::Bind(
     92           &HistogramController::OnPendingProcesses,
     93           base::Unretained(this),
     94           sequence_number,
     95           pending_processes,
     96           true));
     97 }
     98 
     99 void HistogramController::GetHistogramData(int sequence_number) {
    100   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    101 
    102   int pending_processes = 0;
    103   for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
    104        !it.IsAtEnd(); it.Advance()) {
    105     ++pending_processes;
    106     if (!it.GetCurrentValue()->Send(
    107             new ChildProcessMsg_GetChildHistogramData(sequence_number))) {
    108       --pending_processes;
    109     }
    110   }
    111   OnPendingProcesses(sequence_number, pending_processes, false);
    112 
    113   BrowserThread::PostTask(
    114       BrowserThread::IO,
    115       FROM_HERE,
    116       base::Bind(&HistogramController::GetHistogramDataFromChildProcesses,
    117                  base::Unretained(this),
    118                  sequence_number));
    119 }
    120 
    121 }  // namespace content
    122