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/child/child_histogram_message_filter.h" 6 7 #include <ctype.h> 8 9 #include "base/bind.h" 10 #include "base/message_loop/message_loop.h" 11 #include "base/metrics/statistics_recorder.h" 12 #include "base/pickle.h" 13 #include "content/child/child_process.h" 14 #include "content/child/child_thread.h" 15 #include "content/common/child_process_messages.h" 16 17 namespace content { 18 19 ChildHistogramMessageFilter::ChildHistogramMessageFilter() 20 : channel_(NULL), 21 io_message_loop_(ChildProcess::current()->io_message_loop_proxy()), 22 histogram_snapshot_manager_(this) { 23 } 24 25 ChildHistogramMessageFilter::~ChildHistogramMessageFilter() { 26 } 27 28 void ChildHistogramMessageFilter::OnFilterAdded(IPC::Channel* channel) { 29 channel_ = channel; 30 } 31 32 void ChildHistogramMessageFilter::OnFilterRemoved() { 33 } 34 35 bool ChildHistogramMessageFilter::OnMessageReceived( 36 const IPC::Message& message) { 37 bool handled = true; 38 IPC_BEGIN_MESSAGE_MAP(ChildHistogramMessageFilter, message) 39 IPC_MESSAGE_HANDLER(ChildProcessMsg_GetChildHistogramData, 40 OnGetChildHistogramData) 41 IPC_MESSAGE_UNHANDLED(handled = false) 42 IPC_END_MESSAGE_MAP() 43 return handled; 44 } 45 46 void ChildHistogramMessageFilter::SendHistograms(int sequence_number) { 47 io_message_loop_->PostTask( 48 FROM_HERE, base::Bind(&ChildHistogramMessageFilter::UploadAllHistograms, 49 this, sequence_number)); 50 } 51 52 void ChildHistogramMessageFilter::OnGetChildHistogramData(int sequence_number) { 53 UploadAllHistograms(sequence_number); 54 } 55 56 void ChildHistogramMessageFilter::UploadAllHistograms(int sequence_number) { 57 DCHECK_EQ(0u, pickled_histograms_.size()); 58 59 // Push snapshots into our pickled_histograms_ vector. 60 // Note: Before serializing, we set the kIPCSerializationSourceFlag for all 61 // the histograms, so that the receiving process can distinguish them from the 62 // local histograms. 63 histogram_snapshot_manager_.PrepareDeltas( 64 base::Histogram::kIPCSerializationSourceFlag, false); 65 66 channel_->Send(new ChildProcessHostMsg_ChildHistogramData( 67 sequence_number, pickled_histograms_)); 68 69 pickled_histograms_.clear(); 70 static int count = 0; 71 count++; 72 DHISTOGRAM_COUNTS("Histogram.ChildProcessHistogramSentCount", count); 73 } 74 75 void ChildHistogramMessageFilter::RecordDelta( 76 const base::HistogramBase& histogram, 77 const base::HistogramSamples& snapshot) { 78 DCHECK_NE(0, snapshot.TotalCount()); 79 80 Pickle pickle; 81 histogram.SerializeInfo(&pickle); 82 snapshot.Serialize(&pickle); 83 84 pickled_histograms_.push_back( 85 std::string(static_cast<const char*>(pickle.data()), pickle.size())); 86 } 87 88 void ChildHistogramMessageFilter::InconsistencyDetected( 89 base::HistogramBase::Inconsistency problem) { 90 UMA_HISTOGRAM_ENUMERATION("Histogram.InconsistenciesChildProcess", 91 problem, base::HistogramBase::NEVER_EXCEEDED_VALUE); 92 } 93 94 void ChildHistogramMessageFilter::UniqueInconsistencyDetected( 95 base::HistogramBase::Inconsistency problem) { 96 UMA_HISTOGRAM_ENUMERATION("Histogram.InconsistenciesChildProcessUnique", 97 problem, base::HistogramBase::NEVER_EXCEEDED_VALUE); 98 } 99 100 void ChildHistogramMessageFilter::InconsistencyDetectedInLoggedCount( 101 int amount) { 102 UMA_HISTOGRAM_COUNTS("Histogram.InconsistentSnapshotChildProcess", 103 std::abs(amount)); 104 } 105 106 } // namespace content 107