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 
5 #include "chrome/browser/task_manager/task_manager_interface.h"
6 
7 #include "base/bind.h"
8 #include "chrome/browser/browser_process.h"
9 #include "chrome/browser/task_manager/sampling/task_manager_impl.h"
10 #include "chrome/common/chrome_switches.h"
11 #include "chrome/common/pref_names.h"
12 #include "components/prefs/pref_registry_simple.h"
13 #include "components/prefs/pref_service.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/common/child_process_host.h"
16 
17 #if defined(OS_MAC)
18 #include "chrome/browser/ui/browser_dialogs.h"
19 #endif  // defined(OS_MAC)
20 
21 namespace task_manager {
22 
23 // static
RegisterPrefs(PrefRegistrySimple * registry)24 void TaskManagerInterface::RegisterPrefs(PrefRegistrySimple* registry) {
25   registry->RegisterDictionaryPref(prefs::kTaskManagerWindowPlacement);
26   registry->RegisterDictionaryPref(prefs::kTaskManagerColumnVisibility);
27   registry->RegisterBooleanPref(prefs::kTaskManagerEndProcessEnabled, true);
28 }
29 
30 // static
IsEndProcessEnabled()31 bool TaskManagerInterface::IsEndProcessEnabled() {
32   PrefService* state = g_browser_process->local_state();
33   return !state || state->GetBoolean(prefs::kTaskManagerEndProcessEnabled);
34 }
35 
36 // static
GetTaskManager()37 TaskManagerInterface* TaskManagerInterface::GetTaskManager() {
38   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
39 
40   return TaskManagerImpl::GetInstance();
41 }
42 
AddObserver(TaskManagerObserver * observer)43 void TaskManagerInterface::AddObserver(TaskManagerObserver* observer) {
44   observers_.AddObserver(observer);
45   observer->observed_task_manager_ = this;
46 
47   ResourceFlagsAdded(observer->desired_resources_flags());
48 
49   base::TimeDelta current_refresh_time = GetCurrentRefreshTime();
50   if (current_refresh_time == base::TimeDelta::Max()) {
51     // This is the first observer to be added. Start updating.
52     StartUpdating();
53   }
54 
55   if (observer->desired_refresh_time() > current_refresh_time)
56     return;
57 
58   // Reached here, then this is EITHER (not the first observer to be added AND
59   // it requires a more frequent refresh rate) OR (it's the very first observer
60   // to be added).
61   // Reset the refresh timer.
62   ScheduleRefresh(observer->desired_refresh_time());
63 }
64 
RemoveObserver(TaskManagerObserver * observer)65 void TaskManagerInterface::RemoveObserver(TaskManagerObserver* observer) {
66   observers_.RemoveObserver(observer);
67   observer->observed_task_manager_ = nullptr;
68 
69   // Recalculate the minimum refresh rate and the enabled resource flags.
70   int64_t flags = 0;
71   base::TimeDelta min_time = base::TimeDelta::Max();
72   for (auto& observer : observers_) {
73     if (observer.desired_refresh_time() < min_time)
74       min_time = observer.desired_refresh_time();
75 
76     flags |= observer.desired_resources_flags();
77   }
78 
79   if (min_time == base::TimeDelta::Max()) {
80     // This is the last observer to be removed. Stop updating.
81     SetEnabledResourceFlags(0);
82     refresh_timer_->Stop();
83     StopUpdating();
84   } else {
85     SetEnabledResourceFlags(flags);
86     ScheduleRefresh(min_time);
87   }
88 }
89 
RecalculateRefreshFlags()90 void TaskManagerInterface::RecalculateRefreshFlags() {
91   int64_t flags = 0;
92   for (auto& observer : observers_)
93     flags |= observer.desired_resources_flags();
94 
95   SetEnabledResourceFlags(flags);
96 }
97 
IsResourceRefreshEnabled(RefreshType type) const98 bool TaskManagerInterface::IsResourceRefreshEnabled(RefreshType type) const {
99   return (enabled_resources_flags_ & type) != 0;
100 }
101 
TaskManagerInterface()102 TaskManagerInterface::TaskManagerInterface()
103     : refresh_timer_(new base::RepeatingTimer()), enabled_resources_flags_(0) {}
104 
~TaskManagerInterface()105 TaskManagerInterface::~TaskManagerInterface() {
106 }
107 
NotifyObserversOnTaskAdded(TaskId id)108 void TaskManagerInterface::NotifyObserversOnTaskAdded(TaskId id) {
109   for (TaskManagerObserver& observer : observers_)
110     observer.OnTaskAdded(id);
111 }
112 
NotifyObserversOnTaskToBeRemoved(TaskId id)113 void TaskManagerInterface::NotifyObserversOnTaskToBeRemoved(TaskId id) {
114   for (TaskManagerObserver& observer : observers_)
115     observer.OnTaskToBeRemoved(id);
116 }
117 
NotifyObserversOnRefresh(const TaskIdList & task_ids)118 void TaskManagerInterface::NotifyObserversOnRefresh(
119     const TaskIdList& task_ids) {
120   for (TaskManagerObserver& observer : observers_)
121     observer.OnTasksRefreshed(task_ids);
122 }
123 
NotifyObserversOnRefreshWithBackgroundCalculations(const TaskIdList & task_ids)124 void TaskManagerInterface::NotifyObserversOnRefreshWithBackgroundCalculations(
125       const TaskIdList& task_ids) {
126   for (TaskManagerObserver& observer : observers_)
127     observer.OnTasksRefreshedWithBackgroundCalculations(task_ids);
128 }
129 
NotifyObserversOnTaskUnresponsive(TaskId id)130 void TaskManagerInterface::NotifyObserversOnTaskUnresponsive(TaskId id) {
131   for (TaskManagerObserver& observer : observers_)
132     observer.OnTaskUnresponsive(id);
133 }
134 
GetCurrentRefreshTime() const135 base::TimeDelta TaskManagerInterface::GetCurrentRefreshTime() const {
136   return refresh_timer_->IsRunning() ? refresh_timer_->GetCurrentDelay()
137                                      : base::TimeDelta::Max();
138 }
139 
ResourceFlagsAdded(int64_t flags)140 void TaskManagerInterface::ResourceFlagsAdded(int64_t flags) {
141   enabled_resources_flags_ |= flags;
142 }
143 
SetEnabledResourceFlags(int64_t flags)144 void TaskManagerInterface::SetEnabledResourceFlags(int64_t flags) {
145   enabled_resources_flags_ = flags;
146 }
147 
ScheduleRefresh(base::TimeDelta refresh_time)148 void TaskManagerInterface::ScheduleRefresh(base::TimeDelta refresh_time) {
149   refresh_timer_->Start(FROM_HERE, refresh_time,
150                         base::BindRepeating(&TaskManagerInterface::Refresh,
151                                             base::Unretained(this)));
152 }
153 
154 }  // namespace task_manager
155