blob: c4a9993740a311753d9193ff239ef0c313c7bf36 [file] [log] [blame]
afakhry54485752015-07-06 17:39:161// Copyright 2015 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
avi24d693f2016-08-06 18:03:525#include "chrome/browser/task_manager/task_manager_interface.h"
afakhry54485752015-07-06 17:39:166
afakhry174069722016-05-24 19:16:167#include "chrome/browser/browser_process.h"
avi24d693f2016-08-06 18:03:528#include "chrome/browser/task_manager/sampling/task_manager_impl.h"
9#include "chrome/browser/task_manager/sampling/task_manager_io_thread_helper.h"
afakhry05015032015-08-14 01:09:5610#include "chrome/common/chrome_switches.h"
afakhry174069722016-05-24 19:16:1611#include "chrome/common/pref_names.h"
12#include "components/prefs/pref_registry_simple.h"
13#include "components/prefs/pref_service.h"
afakhry05015032015-08-14 01:09:5614#include "content/public/browser/browser_thread.h"
cburnc0a59532017-07-06 17:34:3915#include "content/public/browser/resource_request_info.h"
John Abd-El-Malek2791e092018-01-08 15:35:2016#include "content/public/common/child_process_host.h"
afakhry05015032015-08-14 01:09:5617
afakhry174069722016-05-24 19:16:1618#if defined(OS_MACOSX)
19#include "chrome/browser/ui/browser_dialogs.h"
20#endif // defined(OS_MACOSX)
21
avi24d693f2016-08-06 18:03:5222namespace task_manager {
afakhry54485752015-07-06 17:39:1623
cburnc0a59532017-07-06 17:34:3924namespace {
25BytesTransferredKey KeyForRequest(const net::URLRequest& request) {
26 // Only net::URLRequestJob instances created by the ResourceDispatcherHost
27 // have an associated ResourceRequestInfo and a render frame associated.
cburnc0a59532017-07-06 17:34:3928 const content::ResourceRequestInfo* info =
29 content::ResourceRequestInfo::ForRequest(&request);
cburnc0a59532017-07-06 17:34:3930
Nick Carter074b5202017-11-29 00:44:2531 // Requests without ResourceRequestInfo are attributed to the browser process.
32 if (!info)
33 return {content::ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE};
cburnc0a59532017-07-06 17:34:3934
Nick Carter074b5202017-11-29 00:44:2535 // Requests from PPAPI instances are proxied through the renderer, and specify
36 // the plugin_child_id of the plugin process.
37 if (info->GetPluginChildID() != content::ChildProcessHost::kInvalidUniqueID)
38 return {info->GetPluginChildID(), MSG_ROUTING_NONE};
39
40 // Other requests are associated with the child process (and frame, if
41 // originating from a renderer process).
42 return {info->GetChildID(), info->GetRenderFrameID()};
cburnc0a59532017-07-06 17:34:3943}
44} // namespace
45
afakhry05015032015-08-14 01:09:5646// static
afakhry174069722016-05-24 19:16:1647void TaskManagerInterface::RegisterPrefs(PrefRegistrySimple* registry) {
48 registry->RegisterDictionaryPref(prefs::kTaskManagerWindowPlacement);
49 registry->RegisterDictionaryPref(prefs::kTaskManagerColumnVisibility);
50 registry->RegisterBooleanPref(prefs::kTaskManagerEndProcessEnabled, true);
51}
52
53// static
54bool TaskManagerInterface::IsEndProcessEnabled() {
55 PrefService* state = g_browser_process->local_state();
56 return !state || state->GetBoolean(prefs::kTaskManagerEndProcessEnabled);
57}
58
afakhry174069722016-05-24 19:16:1659// static
afakhry05015032015-08-14 01:09:5660TaskManagerInterface* TaskManagerInterface::GetTaskManager() {
61 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
62
63 return TaskManagerImpl::GetInstance();
64}
65
66// static
67void TaskManagerInterface::OnRawBytesRead(const net::URLRequest& request,
sclittlece72c482015-08-24 20:20:5968 int64_t bytes_read) {
afakhry05015032015-08-14 01:09:5669 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
cburnc0a59532017-07-06 17:34:3970 BytesTransferredKey key = KeyForRequest(request);
71 TaskManagerIoThreadHelper::OnRawBytesTransferred(key, bytes_read,
72 0 /*bytes_sent*/);
afakhry05015032015-08-14 01:09:5673}
74
cburne9d2f3612017-06-20 22:15:0375// static
76void TaskManagerInterface::OnRawBytesSent(const net::URLRequest& request,
77 int64_t bytes_sent) {
78 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
cburnc0a59532017-07-06 17:34:3979 BytesTransferredKey key = KeyForRequest(request);
80 TaskManagerIoThreadHelper::OnRawBytesTransferred(key, 0 /*bytes_read*/,
81 bytes_sent);
cburne9d2f3612017-06-20 22:15:0382}
83
afakhry54485752015-07-06 17:39:1684void TaskManagerInterface::AddObserver(TaskManagerObserver* observer) {
85 observers_.AddObserver(observer);
afakhry05015032015-08-14 01:09:5686 observer->observed_task_manager_ = this;
afakhry54485752015-07-06 17:39:1687
88 ResourceFlagsAdded(observer->desired_resources_flags());
89
afakhry05015032015-08-14 01:09:5690 base::TimeDelta current_refresh_time = GetCurrentRefreshTime();
91 if (current_refresh_time == base::TimeDelta::Max()) {
92 // This is the first observer to be added. Start updating.
93 StartUpdating();
94 }
95
96 if (observer->desired_refresh_time() > current_refresh_time)
afakhry54485752015-07-06 17:39:1697 return;
98
99 // Reached here, then this is EITHER (not the first observer to be added AND
100 // it requires a more frequent refresh rate) OR (it's the very first observer
101 // to be added).
102 // Reset the refresh timer.
103 ScheduleRefresh(observer->desired_refresh_time());
104}
105
106void TaskManagerInterface::RemoveObserver(TaskManagerObserver* observer) {
107 observers_.RemoveObserver(observer);
afakhry05015032015-08-14 01:09:56108 observer->observed_task_manager_ = nullptr;
afakhry54485752015-07-06 17:39:16109
110 // Recalculate the minimum refresh rate and the enabled resource flags.
avi664c07b2015-12-26 02:18:31111 int64_t flags = 0;
afakhry54485752015-07-06 17:39:16112 base::TimeDelta min_time = base::TimeDelta::Max();
dchengea687662016-10-13 16:59:52113 for (auto& observer : observers_) {
114 if (observer.desired_refresh_time() < min_time)
115 min_time = observer.desired_refresh_time();
afakhry54485752015-07-06 17:39:16116
dchengea687662016-10-13 16:59:52117 flags |= observer.desired_resources_flags();
afakhry54485752015-07-06 17:39:16118 }
119
120 if (min_time == base::TimeDelta::Max()) {
afakhry05015032015-08-14 01:09:56121 // This is the last observer to be removed. Stop updating.
afakhry54485752015-07-06 17:39:16122 SetEnabledResourceFlags(0);
123 refresh_timer_->Stop();
afakhry05015032015-08-14 01:09:56124 StopUpdating();
afakhry54485752015-07-06 17:39:16125 } else {
126 SetEnabledResourceFlags(flags);
127 ScheduleRefresh(min_time);
128 }
129}
130
afakhry05015032015-08-14 01:09:56131void TaskManagerInterface::RecalculateRefreshFlags() {
avi664c07b2015-12-26 02:18:31132 int64_t flags = 0;
dchengea687662016-10-13 16:59:52133 for (auto& observer : observers_)
134 flags |= observer.desired_resources_flags();
afakhry05015032015-08-14 01:09:56135
136 SetEnabledResourceFlags(flags);
137}
138
afakhry98241832016-03-11 19:27:47139bool TaskManagerInterface::IsResourceRefreshEnabled(RefreshType type) const {
afakhry54485752015-07-06 17:39:16140 return (enabled_resources_flags_ & type) != 0;
141}
142
143TaskManagerInterface::TaskManagerInterface()
tzik550a880d2018-07-12 21:29:13144 : refresh_timer_(new base::RepeatingTimer()), enabled_resources_flags_(0) {}
afakhry54485752015-07-06 17:39:16145
146TaskManagerInterface::~TaskManagerInterface() {
147}
148
149void TaskManagerInterface::NotifyObserversOnTaskAdded(TaskId id) {
ericwilligers58b0e162016-10-21 07:15:56150 for (TaskManagerObserver& observer : observers_)
151 observer.OnTaskAdded(id);
afakhry54485752015-07-06 17:39:16152}
153
154void TaskManagerInterface::NotifyObserversOnTaskToBeRemoved(TaskId id) {
ericwilligers58b0e162016-10-21 07:15:56155 for (TaskManagerObserver& observer : observers_)
156 observer.OnTaskToBeRemoved(id);
afakhry54485752015-07-06 17:39:16157}
158
159void TaskManagerInterface::NotifyObserversOnRefresh(
160 const TaskIdList& task_ids) {
ericwilligers58b0e162016-10-21 07:15:56161 for (TaskManagerObserver& observer : observers_)
162 observer.OnTasksRefreshed(task_ids);
afakhry54485752015-07-06 17:39:16163}
164
afakhry98241832016-03-11 19:27:47165void TaskManagerInterface::NotifyObserversOnRefreshWithBackgroundCalculations(
166 const TaskIdList& task_ids) {
ericwilligers58b0e162016-10-21 07:15:56167 for (TaskManagerObserver& observer : observers_)
168 observer.OnTasksRefreshedWithBackgroundCalculations(task_ids);
afakhry98241832016-03-11 19:27:47169}
170
171void TaskManagerInterface::NotifyObserversOnTaskUnresponsive(TaskId id) {
ericwilligers58b0e162016-10-21 07:15:56172 for (TaskManagerObserver& observer : observers_)
173 observer.OnTaskUnresponsive(id);
afakhry98241832016-03-11 19:27:47174}
175
afakhry54485752015-07-06 17:39:16176base::TimeDelta TaskManagerInterface::GetCurrentRefreshTime() const {
177 return refresh_timer_->IsRunning() ? refresh_timer_->GetCurrentDelay()
178 : base::TimeDelta::Max();
179}
180
avi664c07b2015-12-26 02:18:31181void TaskManagerInterface::ResourceFlagsAdded(int64_t flags) {
afakhry54485752015-07-06 17:39:16182 enabled_resources_flags_ |= flags;
183}
184
avi664c07b2015-12-26 02:18:31185void TaskManagerInterface::SetEnabledResourceFlags(int64_t flags) {
afakhry54485752015-07-06 17:39:16186 enabled_resources_flags_ = flags;
187}
188
189void TaskManagerInterface::ScheduleRefresh(base::TimeDelta refresh_time) {
190 refresh_timer_->Start(FROM_HERE,
191 refresh_time,
192 base::Bind(&TaskManagerInterface::Refresh,
193 base::Unretained(this)));
194}
195
avi24d693f2016-08-06 18:03:52196} // namespace task_manager