- add sources.
[platform/framework/web/crosswalk.git] / src / content / browser / profiler_controller_impl.cc
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/profiler_controller_impl.h"
6
7 #include "base/bind.h"
8 #include "base/command_line.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"
16 #include "content/public/common/content_switches.h"
17
18 namespace content {
19
20 ProfilerController* ProfilerController::GetInstance() {
21   return ProfilerControllerImpl::GetInstance();
22 }
23
24 ProfilerControllerImpl* ProfilerControllerImpl::GetInstance() {
25   return Singleton<ProfilerControllerImpl>::get();
26 }
27
28 ProfilerControllerImpl::ProfilerControllerImpl() : subscriber_(NULL) {
29 }
30
31 ProfilerControllerImpl::~ProfilerControllerImpl() {
32 }
33
34 void ProfilerControllerImpl::OnPendingProcesses(int sequence_number,
35                                                 int pending_processes,
36                                                 bool end) {
37   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
38   if (subscriber_)
39     subscriber_->OnPendingProcesses(sequence_number, pending_processes, end);
40 }
41
42 void ProfilerControllerImpl::OnProfilerDataCollected(
43     int sequence_number,
44     const tracked_objects::ProcessDataSnapshot& profiler_data,
45     int process_type) {
46   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
47     BrowserThread::PostTask(
48         BrowserThread::UI, FROM_HERE,
49         base::Bind(&ProfilerControllerImpl::OnProfilerDataCollected,
50                    base::Unretained(this),
51                    sequence_number,
52                    profiler_data,
53                    process_type));
54     return;
55   }
56
57   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
58   if (subscriber_) {
59     subscriber_->OnProfilerDataCollected(sequence_number, profiler_data,
60                                          process_type);
61   }
62 }
63
64 void ProfilerControllerImpl::Register(ProfilerSubscriber* subscriber) {
65   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
66   DCHECK(!subscriber_);
67   subscriber_ = subscriber;
68 }
69
70 void ProfilerControllerImpl::Unregister(const ProfilerSubscriber* subscriber) {
71   DCHECK_EQ(subscriber_, subscriber);
72   subscriber_ = NULL;
73 }
74
75 void ProfilerControllerImpl::GetProfilerDataFromChildProcesses(
76     int sequence_number) {
77   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
78
79   int pending_processes = 0;
80   for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) {
81     // Skips requesting profiler data from the "GPU Process" if we are using in
82     // process GPU. Those stats should be in the Browser-process's GPU thread.
83     if (iter.GetData().process_type == PROCESS_TYPE_GPU &&
84         CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU)) {
85       continue;
86     }
87
88     ++pending_processes;
89     if (!iter.Send(new ChildProcessMsg_GetChildProfilerData(sequence_number)))
90       --pending_processes;
91   }
92
93   BrowserThread::PostTask(
94       BrowserThread::UI,
95       FROM_HERE,
96       base::Bind(
97           &ProfilerControllerImpl::OnPendingProcesses,
98           base::Unretained(this),
99           sequence_number,
100           pending_processes,
101           true));
102 }
103
104 void ProfilerControllerImpl::GetProfilerData(int sequence_number) {
105   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
106
107   int pending_processes = 0;
108   for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
109        !it.IsAtEnd(); it.Advance()) {
110     ++pending_processes;
111     if (!it.GetCurrentValue()->Send(
112             new ChildProcessMsg_GetChildProfilerData(sequence_number))) {
113       --pending_processes;
114     }
115   }
116   OnPendingProcesses(sequence_number, pending_processes, false);
117
118   BrowserThread::PostTask(
119       BrowserThread::IO,
120       FROM_HERE,
121       base::Bind(&ProfilerControllerImpl::GetProfilerDataFromChildProcesses,
122                  base::Unretained(this),
123                  sequence_number));
124 }
125
126 }  // namespace content