afakhry | 5448575 | 2015-07-06 17:39:16 | [diff] [blame] | 1 | // 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 | |
avi | 24d693f | 2016-08-06 18:03:52 | [diff] [blame] | 5 | #include "chrome/browser/task_manager/task_manager_interface.h" |
afakhry | 5448575 | 2015-07-06 17:39:16 | [diff] [blame] | 6 | |
afakhry | 17406972 | 2016-05-24 19:16:16 | [diff] [blame] | 7 | #include "chrome/browser/browser_process.h" |
avi | 24d693f | 2016-08-06 18:03:52 | [diff] [blame] | 8 | #include "chrome/browser/task_manager/sampling/task_manager_impl.h" |
| 9 | #include "chrome/browser/task_manager/sampling/task_manager_io_thread_helper.h" |
afakhry | 0501503 | 2015-08-14 01:09:56 | [diff] [blame] | 10 | #include "chrome/common/chrome_switches.h" |
afakhry | 17406972 | 2016-05-24 19:16:16 | [diff] [blame] | 11 | #include "chrome/common/pref_names.h" |
| 12 | #include "components/prefs/pref_registry_simple.h" |
| 13 | #include "components/prefs/pref_service.h" |
afakhry | 0501503 | 2015-08-14 01:09:56 | [diff] [blame] | 14 | #include "content/public/browser/browser_thread.h" |
cburn | c0a5953 | 2017-07-06 17:34:39 | [diff] [blame] | 15 | #include "content/public/browser/resource_request_info.h" |
John Abd-El-Malek | 2791e09 | 2018-01-08 15:35:20 | [diff] [blame] | 16 | #include "content/public/common/child_process_host.h" |
afakhry | 0501503 | 2015-08-14 01:09:56 | [diff] [blame] | 17 | |
afakhry | 17406972 | 2016-05-24 19:16:16 | [diff] [blame] | 18 | #if defined(OS_MACOSX) |
| 19 | #include "chrome/browser/ui/browser_dialogs.h" |
| 20 | #endif // defined(OS_MACOSX) |
| 21 | |
avi | 24d693f | 2016-08-06 18:03:52 | [diff] [blame] | 22 | namespace task_manager { |
afakhry | 5448575 | 2015-07-06 17:39:16 | [diff] [blame] | 23 | |
cburn | c0a5953 | 2017-07-06 17:34:39 | [diff] [blame] | 24 | namespace { |
| 25 | BytesTransferredKey KeyForRequest(const net::URLRequest& request) { |
| 26 | // Only net::URLRequestJob instances created by the ResourceDispatcherHost |
| 27 | // have an associated ResourceRequestInfo and a render frame associated. |
cburn | c0a5953 | 2017-07-06 17:34:39 | [diff] [blame] | 28 | const content::ResourceRequestInfo* info = |
| 29 | content::ResourceRequestInfo::ForRequest(&request); |
cburn | c0a5953 | 2017-07-06 17:34:39 | [diff] [blame] | 30 | |
Nick Carter | 074b520 | 2017-11-29 00:44:25 | [diff] [blame] | 31 | // Requests without ResourceRequestInfo are attributed to the browser process. |
| 32 | if (!info) |
| 33 | return {content::ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE}; |
cburn | c0a5953 | 2017-07-06 17:34:39 | [diff] [blame] | 34 | |
Nick Carter | 074b520 | 2017-11-29 00:44:25 | [diff] [blame] | 35 | // 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()}; |
cburn | c0a5953 | 2017-07-06 17:34:39 | [diff] [blame] | 43 | } |
| 44 | } // namespace |
| 45 | |
afakhry | 0501503 | 2015-08-14 01:09:56 | [diff] [blame] | 46 | // static |
afakhry | 17406972 | 2016-05-24 19:16:16 | [diff] [blame] | 47 | void TaskManagerInterface::RegisterPrefs(PrefRegistrySimple* registry) { |
| 48 | registry->RegisterDictionaryPref(prefs::kTaskManagerWindowPlacement); |
| 49 | registry->RegisterDictionaryPref(prefs::kTaskManagerColumnVisibility); |
| 50 | registry->RegisterBooleanPref(prefs::kTaskManagerEndProcessEnabled, true); |
| 51 | } |
| 52 | |
| 53 | // static |
| 54 | bool TaskManagerInterface::IsEndProcessEnabled() { |
| 55 | PrefService* state = g_browser_process->local_state(); |
| 56 | return !state || state->GetBoolean(prefs::kTaskManagerEndProcessEnabled); |
| 57 | } |
| 58 | |
afakhry | 17406972 | 2016-05-24 19:16:16 | [diff] [blame] | 59 | // static |
afakhry | 0501503 | 2015-08-14 01:09:56 | [diff] [blame] | 60 | TaskManagerInterface* TaskManagerInterface::GetTaskManager() { |
| 61 | DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 62 | |
| 63 | return TaskManagerImpl::GetInstance(); |
| 64 | } |
| 65 | |
| 66 | // static |
| 67 | void TaskManagerInterface::OnRawBytesRead(const net::URLRequest& request, |
sclittle | ce72c48 | 2015-08-24 20:20:59 | [diff] [blame] | 68 | int64_t bytes_read) { |
afakhry | 0501503 | 2015-08-14 01:09:56 | [diff] [blame] | 69 | DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
cburn | c0a5953 | 2017-07-06 17:34:39 | [diff] [blame] | 70 | BytesTransferredKey key = KeyForRequest(request); |
| 71 | TaskManagerIoThreadHelper::OnRawBytesTransferred(key, bytes_read, |
| 72 | 0 /*bytes_sent*/); |
afakhry | 0501503 | 2015-08-14 01:09:56 | [diff] [blame] | 73 | } |
| 74 | |
cburn | e9d2f361 | 2017-06-20 22:15:03 | [diff] [blame] | 75 | // static |
| 76 | void TaskManagerInterface::OnRawBytesSent(const net::URLRequest& request, |
| 77 | int64_t bytes_sent) { |
| 78 | DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
cburn | c0a5953 | 2017-07-06 17:34:39 | [diff] [blame] | 79 | BytesTransferredKey key = KeyForRequest(request); |
| 80 | TaskManagerIoThreadHelper::OnRawBytesTransferred(key, 0 /*bytes_read*/, |
| 81 | bytes_sent); |
cburn | e9d2f361 | 2017-06-20 22:15:03 | [diff] [blame] | 82 | } |
| 83 | |
afakhry | 5448575 | 2015-07-06 17:39:16 | [diff] [blame] | 84 | void TaskManagerInterface::AddObserver(TaskManagerObserver* observer) { |
| 85 | observers_.AddObserver(observer); |
afakhry | 0501503 | 2015-08-14 01:09:56 | [diff] [blame] | 86 | observer->observed_task_manager_ = this; |
afakhry | 5448575 | 2015-07-06 17:39:16 | [diff] [blame] | 87 | |
| 88 | ResourceFlagsAdded(observer->desired_resources_flags()); |
| 89 | |
afakhry | 0501503 | 2015-08-14 01:09:56 | [diff] [blame] | 90 | 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) |
afakhry | 5448575 | 2015-07-06 17:39:16 | [diff] [blame] | 97 | 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 | |
| 106 | void TaskManagerInterface::RemoveObserver(TaskManagerObserver* observer) { |
| 107 | observers_.RemoveObserver(observer); |
afakhry | 0501503 | 2015-08-14 01:09:56 | [diff] [blame] | 108 | observer->observed_task_manager_ = nullptr; |
afakhry | 5448575 | 2015-07-06 17:39:16 | [diff] [blame] | 109 | |
| 110 | // Recalculate the minimum refresh rate and the enabled resource flags. |
avi | 664c07b | 2015-12-26 02:18:31 | [diff] [blame] | 111 | int64_t flags = 0; |
afakhry | 5448575 | 2015-07-06 17:39:16 | [diff] [blame] | 112 | base::TimeDelta min_time = base::TimeDelta::Max(); |
dcheng | ea68766 | 2016-10-13 16:59:52 | [diff] [blame] | 113 | for (auto& observer : observers_) { |
| 114 | if (observer.desired_refresh_time() < min_time) |
| 115 | min_time = observer.desired_refresh_time(); |
afakhry | 5448575 | 2015-07-06 17:39:16 | [diff] [blame] | 116 | |
dcheng | ea68766 | 2016-10-13 16:59:52 | [diff] [blame] | 117 | flags |= observer.desired_resources_flags(); |
afakhry | 5448575 | 2015-07-06 17:39:16 | [diff] [blame] | 118 | } |
| 119 | |
| 120 | if (min_time == base::TimeDelta::Max()) { |
afakhry | 0501503 | 2015-08-14 01:09:56 | [diff] [blame] | 121 | // This is the last observer to be removed. Stop updating. |
afakhry | 5448575 | 2015-07-06 17:39:16 | [diff] [blame] | 122 | SetEnabledResourceFlags(0); |
| 123 | refresh_timer_->Stop(); |
afakhry | 0501503 | 2015-08-14 01:09:56 | [diff] [blame] | 124 | StopUpdating(); |
afakhry | 5448575 | 2015-07-06 17:39:16 | [diff] [blame] | 125 | } else { |
| 126 | SetEnabledResourceFlags(flags); |
| 127 | ScheduleRefresh(min_time); |
| 128 | } |
| 129 | } |
| 130 | |
afakhry | 0501503 | 2015-08-14 01:09:56 | [diff] [blame] | 131 | void TaskManagerInterface::RecalculateRefreshFlags() { |
avi | 664c07b | 2015-12-26 02:18:31 | [diff] [blame] | 132 | int64_t flags = 0; |
dcheng | ea68766 | 2016-10-13 16:59:52 | [diff] [blame] | 133 | for (auto& observer : observers_) |
| 134 | flags |= observer.desired_resources_flags(); |
afakhry | 0501503 | 2015-08-14 01:09:56 | [diff] [blame] | 135 | |
| 136 | SetEnabledResourceFlags(flags); |
| 137 | } |
| 138 | |
afakhry | 9824183 | 2016-03-11 19:27:47 | [diff] [blame] | 139 | bool TaskManagerInterface::IsResourceRefreshEnabled(RefreshType type) const { |
afakhry | 5448575 | 2015-07-06 17:39:16 | [diff] [blame] | 140 | return (enabled_resources_flags_ & type) != 0; |
| 141 | } |
| 142 | |
| 143 | TaskManagerInterface::TaskManagerInterface() |
tzik | 550a880d | 2018-07-12 21:29:13 | [diff] [blame^] | 144 | : refresh_timer_(new base::RepeatingTimer()), enabled_resources_flags_(0) {} |
afakhry | 5448575 | 2015-07-06 17:39:16 | [diff] [blame] | 145 | |
| 146 | TaskManagerInterface::~TaskManagerInterface() { |
| 147 | } |
| 148 | |
| 149 | void TaskManagerInterface::NotifyObserversOnTaskAdded(TaskId id) { |
ericwilligers | 58b0e16 | 2016-10-21 07:15:56 | [diff] [blame] | 150 | for (TaskManagerObserver& observer : observers_) |
| 151 | observer.OnTaskAdded(id); |
afakhry | 5448575 | 2015-07-06 17:39:16 | [diff] [blame] | 152 | } |
| 153 | |
| 154 | void TaskManagerInterface::NotifyObserversOnTaskToBeRemoved(TaskId id) { |
ericwilligers | 58b0e16 | 2016-10-21 07:15:56 | [diff] [blame] | 155 | for (TaskManagerObserver& observer : observers_) |
| 156 | observer.OnTaskToBeRemoved(id); |
afakhry | 5448575 | 2015-07-06 17:39:16 | [diff] [blame] | 157 | } |
| 158 | |
| 159 | void TaskManagerInterface::NotifyObserversOnRefresh( |
| 160 | const TaskIdList& task_ids) { |
ericwilligers | 58b0e16 | 2016-10-21 07:15:56 | [diff] [blame] | 161 | for (TaskManagerObserver& observer : observers_) |
| 162 | observer.OnTasksRefreshed(task_ids); |
afakhry | 5448575 | 2015-07-06 17:39:16 | [diff] [blame] | 163 | } |
| 164 | |
afakhry | 9824183 | 2016-03-11 19:27:47 | [diff] [blame] | 165 | void TaskManagerInterface::NotifyObserversOnRefreshWithBackgroundCalculations( |
| 166 | const TaskIdList& task_ids) { |
ericwilligers | 58b0e16 | 2016-10-21 07:15:56 | [diff] [blame] | 167 | for (TaskManagerObserver& observer : observers_) |
| 168 | observer.OnTasksRefreshedWithBackgroundCalculations(task_ids); |
afakhry | 9824183 | 2016-03-11 19:27:47 | [diff] [blame] | 169 | } |
| 170 | |
| 171 | void TaskManagerInterface::NotifyObserversOnTaskUnresponsive(TaskId id) { |
ericwilligers | 58b0e16 | 2016-10-21 07:15:56 | [diff] [blame] | 172 | for (TaskManagerObserver& observer : observers_) |
| 173 | observer.OnTaskUnresponsive(id); |
afakhry | 9824183 | 2016-03-11 19:27:47 | [diff] [blame] | 174 | } |
| 175 | |
afakhry | 5448575 | 2015-07-06 17:39:16 | [diff] [blame] | 176 | base::TimeDelta TaskManagerInterface::GetCurrentRefreshTime() const { |
| 177 | return refresh_timer_->IsRunning() ? refresh_timer_->GetCurrentDelay() |
| 178 | : base::TimeDelta::Max(); |
| 179 | } |
| 180 | |
avi | 664c07b | 2015-12-26 02:18:31 | [diff] [blame] | 181 | void TaskManagerInterface::ResourceFlagsAdded(int64_t flags) { |
afakhry | 5448575 | 2015-07-06 17:39:16 | [diff] [blame] | 182 | enabled_resources_flags_ |= flags; |
| 183 | } |
| 184 | |
avi | 664c07b | 2015-12-26 02:18:31 | [diff] [blame] | 185 | void TaskManagerInterface::SetEnabledResourceFlags(int64_t flags) { |
afakhry | 5448575 | 2015-07-06 17:39:16 | [diff] [blame] | 186 | enabled_resources_flags_ = flags; |
| 187 | } |
| 188 | |
| 189 | void 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 | |
avi | 24d693f | 2016-08-06 18:03:52 | [diff] [blame] | 196 | } // namespace task_manager |