Supervised user import: Listen for profile creation/deletion
[chromium-blink-merge.git] / content / browser / profiler_controller_impl.cc
blob7427d15f68684ff4d1d8397f1ae9497b6438f56e
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.
5 #include "content/browser/profiler_controller_impl.h"
7 #include "base/bind.h"
8 #include "base/process/process_handle.h"
9 #include "base/tracked_objects.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/profiler_subscriber.h"
15 #include "content/public/browser/render_process_host.h"
17 namespace content {
19 ProfilerController* ProfilerController::GetInstance() {
20 return ProfilerControllerImpl::GetInstance();
23 ProfilerControllerImpl* ProfilerControllerImpl::GetInstance() {
24 return Singleton<ProfilerControllerImpl>::get();
27 ProfilerControllerImpl::ProfilerControllerImpl() : subscriber_(NULL) {
30 ProfilerControllerImpl::~ProfilerControllerImpl() {
33 void ProfilerControllerImpl::OnPendingProcesses(int sequence_number,
34 int pending_processes,
35 bool end) {
36 DCHECK_CURRENTLY_ON(BrowserThread::UI);
37 if (subscriber_)
38 subscriber_->OnPendingProcesses(sequence_number, pending_processes, end);
41 void ProfilerControllerImpl::OnProfilerDataCollected(
42 int sequence_number,
43 const tracked_objects::ProcessDataSnapshot& profiler_data,
44 content::ProcessType process_type) {
45 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
46 BrowserThread::PostTask(
47 BrowserThread::UI, FROM_HERE,
48 base::Bind(&ProfilerControllerImpl::OnProfilerDataCollected,
49 base::Unretained(this),
50 sequence_number,
51 profiler_data,
52 process_type));
53 return;
56 DCHECK_CURRENTLY_ON(BrowserThread::UI);
57 if (subscriber_) {
58 subscriber_->OnProfilerDataCollected(sequence_number, profiler_data,
59 process_type);
63 void ProfilerControllerImpl::Register(ProfilerSubscriber* subscriber) {
64 DCHECK_CURRENTLY_ON(BrowserThread::UI);
65 DCHECK(!subscriber_);
66 subscriber_ = subscriber;
69 void ProfilerControllerImpl::Unregister(const ProfilerSubscriber* subscriber) {
70 DCHECK_EQ(subscriber_, subscriber);
71 subscriber_ = NULL;
74 void ProfilerControllerImpl::GetProfilerDataFromChildProcesses(
75 int sequence_number,
76 int current_profiling_phase) {
77 DCHECK_CURRENTLY_ON(BrowserThread::IO);
79 int pending_processes = 0;
80 for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) {
81 // In some cases, there may be no child process of the given type (for
82 // example, the GPU process may not exist and there may instead just be a
83 // GPU thread in the browser process). If that's the case, then the process
84 // handle will be base::kNullProcessHandle and we shouldn't ask it for data.
85 if (iter.GetData().handle == base::kNullProcessHandle)
86 continue;
88 ++pending_processes;
89 if (!iter.Send(new ChildProcessMsg_GetChildProfilerData(
90 sequence_number, current_profiling_phase))) {
91 --pending_processes;
95 BrowserThread::PostTask(
96 BrowserThread::UI,
97 FROM_HERE,
98 base::Bind(
99 &ProfilerControllerImpl::OnPendingProcesses,
100 base::Unretained(this),
101 sequence_number,
102 pending_processes,
103 true));
106 // static
107 void ProfilerControllerImpl::NotifyChildProcessesOfProfilingPhaseCompletion(
108 int profiling_phase) {
109 DCHECK_CURRENTLY_ON(BrowserThread::IO);
111 for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) {
112 // In some cases, there may be no child process of the given type (for
113 // example, the GPU process may not exist and there may instead just be a
114 // GPU thread in the browser process). If that's the case, then the process
115 // handle will be base::kNullProcessHandle and we shouldn't send it a
116 // message.
117 if (iter.GetData().handle == base::kNullProcessHandle)
118 continue;
120 iter.Send(new ChildProcessMsg_ProfilingPhaseCompleted(profiling_phase));
124 void ProfilerControllerImpl::GetProfilerData(int sequence_number,
125 int current_profiling_phase) {
126 DCHECK_CURRENTLY_ON(BrowserThread::UI);
128 // Iterates through renderers in UI thread, and through other child processes
129 // in IO thread, and send them GetChildProfilerData message. Renderers have to
130 // be contacted from UI thread, and other processes - from IO thread.
131 int pending_processes = 0;
132 for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
133 !it.IsAtEnd(); it.Advance()) {
134 ++pending_processes;
135 if (!it.GetCurrentValue()->Send(new ChildProcessMsg_GetChildProfilerData(
136 sequence_number, current_profiling_phase))) {
137 --pending_processes;
140 OnPendingProcesses(sequence_number, pending_processes, false);
142 BrowserThread::PostTask(
143 BrowserThread::IO, FROM_HERE,
144 base::Bind(&ProfilerControllerImpl::GetProfilerDataFromChildProcesses,
145 base::Unretained(this), sequence_number,
146 current_profiling_phase));
149 void ProfilerControllerImpl::OnProfilingPhaseCompleted(int profiling_phase) {
150 DCHECK_CURRENTLY_ON(BrowserThread::UI);
152 // Iterates through renderers in UI thread, and through other child processes
153 // in IO thread, and send them OnProfilingPhase message. Renderers have to be
154 // contacted from UI thread, and other processes - from IO thread.
155 for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
156 !it.IsAtEnd(); it.Advance()) {
157 it.GetCurrentValue()->Send(
158 new ChildProcessMsg_ProfilingPhaseCompleted(profiling_phase));
161 BrowserThread::PostTask(
162 BrowserThread::IO, FROM_HERE,
163 base::Bind(&ProfilerControllerImpl::
164 NotifyChildProcessesOfProfilingPhaseCompletion,
165 profiling_phase));
168 } // namespace content