Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(131)

Side by Side Diff: chrome/browser/ui/views/new_task_manager_view.cc

Issue 1367673003: Expose all reusable task manager view code so it can be used by Mac (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/new_task_manager_view.h" 5 #include "chrome/browser/ui/views/new_task_manager_view.h"
6 6
7 #include <map>
8
9 #include "base/i18n/number_formatting.h"
10 #include "base/prefs/pref_service.h" 7 #include "base/prefs/pref_service.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/browser_process.h" 8 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/profiles/profile_manager.h" 9 #include "chrome/browser/profiles/profile_manager.h"
16 #include "chrome/browser/profiles/profile_window.h" 10 #include "chrome/browser/profiles/profile_window.h"
17 #include "chrome/browser/task_management/task_manager_interface.h"
18 #include "chrome/browser/task_management/task_manager_observer.h" 11 #include "chrome/browser/task_management/task_manager_observer.h"
12 #include "chrome/browser/ui/task_manager/task_manager_columns.h"
13 #include "chrome/browser/ui/task_manager/task_manager_table_model.h"
19 #include "chrome/browser/ui/user_manager.h" 14 #include "chrome/browser/ui/user_manager.h"
20 #include "chrome/common/pref_names.h" 15 #include "chrome/common/pref_names.h"
21 #include "chrome/common/url_constants.h" 16 #include "chrome/common/url_constants.h"
22 #include "chrome/grit/chromium_strings.h" 17 #include "chrome/grit/chromium_strings.h"
23 #include "chrome/grit/generated_resources.h" 18 #include "chrome/grit/generated_resources.h"
24 #include "components/nacl/browser/nacl_browser.h"
25 #include "content/public/common/result_codes.h"
26 #include "third_party/WebKit/public/web/WebCache.h"
27 #include "ui/base/l10n/l10n_util.h" 19 #include "ui/base/l10n/l10n_util.h"
28 #include "ui/base/models/table_model_observer.h" 20 #include "ui/base/models/table_model_observer.h"
29 #include "ui/base/text/bytes_formatting.h"
30 #include "ui/views/controls/label.h" 21 #include "ui/views/controls/label.h"
31 #include "ui/views/controls/link.h" 22 #include "ui/views/controls/link.h"
32 #include "ui/views/controls/table/table_grouper.h"
33 #include "ui/views/controls/table/table_view.h" 23 #include "ui/views/controls/table/table_view.h"
34 #include "ui/views/layout/layout_constants.h" 24 #include "ui/views/layout/layout_constants.h"
35 #include "ui/views/view.h" 25 #include "ui/views/view.h"
36 #include "ui/views/widget/widget.h" 26 #include "ui/views/widget/widget.h"
37 27
38 #if defined(USE_ASH) 28 #if defined(USE_ASH)
39 #include "ash/shelf/shelf_util.h" 29 #include "ash/shelf/shelf_util.h"
40 #include "ash/wm/window_util.h" 30 #include "ash/wm/window_util.h"
41 #include "grit/ash_resources.h" 31 #include "grit/ash_resources.h"
42 #endif // defined(USE_ASH) 32 #endif // defined(USE_ASH)
43 33
44 #if defined(OS_WIN) 34 #if defined(OS_WIN)
45 #include "chrome/browser/shell_integration.h" 35 #include "chrome/browser/shell_integration.h"
46 #include "ui/base/win/shell.h" 36 #include "ui/base/win/shell.h"
47 #include "ui/views/win/hwnd_util.h" 37 #include "ui/views/win/hwnd_util.h"
48 #endif // defined(OS_WIN) 38 #endif // defined(OS_WIN)
49 39
50 namespace task_management { 40 namespace task_management {
51 41
52 namespace { 42 namespace {
53 43
54 NewTaskManagerView* g_task_manager_view = nullptr; 44 NewTaskManagerView* g_task_manager_view = nullptr;
55 45
56 #if defined(OS_MACOSX)
57 // Match Activity Monitor's default refresh rate.
58 const int64 kRefreshTimeMS = 2000;
59
60 // Activity Monitor shows %cpu with one decimal digit -- be consistent with
61 // that.
62 const char kCpuTextFormatString[] = "%.1f";
63 #else
64 const int64 kRefreshTimeMS = 1000;
65 const char kCpuTextFormatString[] = "%.0f";
66 #endif // defined(OS_MACOSX)
67
68 // The columns that are shared by a group will show the value of the column
69 // only once per group.
70 bool IsSharedByGroup(int column_id) {
71 switch (column_id) {
72 case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN:
73 case IDS_TASK_MANAGER_SHARED_MEM_COLUMN:
74 case IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN:
75 case IDS_TASK_MANAGER_CPU_COLUMN:
76 case IDS_TASK_MANAGER_PROCESS_ID_COLUMN:
77 case IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN:
78 case IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN:
79 case IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN:
80 case IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN:
81 case IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN:
82 case IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN:
83 case IDS_TASK_MANAGER_NACL_DEBUG_STUB_PORT_COLUMN:
84 return true;
85 default:
86 return false;
87 }
88 }
89
90 // Opens the "about:memory" for the "stats for nerds" link. 46 // Opens the "about:memory" for the "stats for nerds" link.
91 void OpenAboutMemory(chrome::HostDesktopType desktop_type) { 47 void OpenAboutMemory(chrome::HostDesktopType desktop_type) {
92 Profile* profile = ProfileManager::GetLastUsedProfileAllowedByPolicy(); 48 Profile* profile = ProfileManager::GetLastUsedProfileAllowedByPolicy();
93 if (profile->IsGuestSession() && 49 if (profile->IsGuestSession() &&
94 !g_browser_process->local_state()->GetBoolean( 50 !g_browser_process->local_state()->GetBoolean(
95 prefs::kBrowserGuestModeEnabled)) { 51 prefs::kBrowserGuestModeEnabled)) {
96 UserManager::Show(base::FilePath(), 52 UserManager::Show(base::FilePath(),
97 profiles::USER_MANAGER_NO_TUTORIAL, 53 profiles::USER_MANAGER_NO_TUTORIAL,
98 profiles::USER_MANAGER_SELECT_PROFILE_CHROME_MEMORY); 54 profiles::USER_MANAGER_SELECT_PROFILE_CHROME_MEMORY);
99 return; 55 return;
100 } 56 }
101 57
102 chrome::NavigateParams params(profile, 58 chrome::NavigateParams params(profile,
103 GURL(chrome::kChromeUIMemoryURL), 59 GURL(chrome::kChromeUIMemoryURL),
104 ui::PAGE_TRANSITION_LINK); 60 ui::PAGE_TRANSITION_LINK);
105 params.disposition = NEW_FOREGROUND_TAB; 61 params.disposition = NEW_FOREGROUND_TAB;
106 params.host_desktop_type = desktop_type; 62 params.host_desktop_type = desktop_type;
107 chrome::Navigate(&params); 63 chrome::Navigate(&params);
108 } 64 }
109 65
110 // Used to sort various column values. 66 } // namespace
111 template <class T> 67
112 int ValueCompare(T value1, T value2) { 68 // The Aura views TableView delegate of the TaskManagerTableModel.
113 if (value1 == value2) 69 class NewTaskManagerView::ViewsTableDelegate : public TableViewDelegate {
Lei Zhang 2015/09/24 05:33:58 Can NewTaskManagerView itself implement the TableV
afakhry 2015/09/25 16:39:49 Done.
114 return 0; 70 public:
115 return value1 < value2 ? -1 : 1; 71 explicit ViewsTableDelegate(views::TableView* table);
72 ~ViewsTableDelegate() override;
73
74 // task_management::TableViewDelegate:
75 bool IsColumnVisible(int column_id) const override;
76 void SetColumnVisibility(int column_id, bool new_visibility) override;
77 bool IsTableSorted() const override;
78 TableSortDescriptor GetSortDescriptor() const override;
79 void ToggleSortOrder(int visible_column_index) override;
80
81 private:
82 views::TableView* table_;
83
84 DISALLOW_COPY_AND_ASSIGN(ViewsTableDelegate);
85 };
86
87 ////////////////////////////////////////////////////////////////////////////////
88 // ViewsTableDelegate Implementation:
89 ////////////////////////////////////////////////////////////////////////////////
90
91 NewTaskManagerView::ViewsTableDelegate::ViewsTableDelegate(
92 views::TableView* table) : table_(table) {
93 DCHECK(table);
116 } 94 }
117 95
118 // Used when one or both of the results to compare are unavailable. 96 NewTaskManagerView::ViewsTableDelegate::~ViewsTableDelegate() {
119 int OrderUnavailableValue(bool v1, bool v2) {
120 if (!v1 && !v2)
121 return 0;
122 return v1 ? 1 : -1;
123 } 97 }
124 98
125 // A class to stringify the task manager's values into string16s and to 99 // task_management::TableViewDelegate:
126 // cache the common strings that will be reused many times like "N/A" and so on. 100 bool NewTaskManagerView::ViewsTableDelegate::IsColumnVisible(
127 class TaskManagerValuesStringifier { 101 int column_id) const {
128 public: 102 return table_->IsColumnVisible(column_id);
129 TaskManagerValuesStringifier() 103 }
130 : n_a_string_(l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT)),
131 zero_string_(base::ASCIIToUTF16("0")),
132 asterisk_string_(base::ASCIIToUTF16("*")),
133 unknown_string_(l10n_util::GetStringUTF16(
134 IDS_TASK_MANAGER_UNKNOWN_VALUE_TEXT)) {
135 }
136 104
137 ~TaskManagerValuesStringifier() {} 105 void NewTaskManagerView::ViewsTableDelegate::SetColumnVisibility(
106 int column_id,
107 bool new_visibility) {
108 table_->SetColumnVisibility(column_id, new_visibility);
109 }
138 110
139 base::string16 GetCpuUsageText(double cpu_usage) { 111 bool NewTaskManagerView::ViewsTableDelegate::IsTableSorted() const {
140 return base::UTF8ToUTF16(base::StringPrintf(kCpuTextFormatString, 112 return table_->is_sorted();
141 cpu_usage)); 113 }
142 }
143 114
144 base::string16 GetMemoryUsageText(int64 memory_usage, bool has_duplicates) { 115 TableSortDescriptor
145 if (memory_usage == -1) 116 NewTaskManagerView::ViewsTableDelegate::GetSortDescriptor() const {
146 return n_a_string_; 117 if (!IsTableSorted())
118 return TableSortDescriptor();
147 119
148 #if defined(OS_MACOSX) 120 const auto& descriptor = table_->sort_descriptors().front();
149 // System expectation is to show "100 kB", "200 MB", etc. 121 return TableSortDescriptor(descriptor.column_id, descriptor.ascending);
150 // TODO(thakis): [This TODO has been taken as is from the old task manager]: 122 }
151 // Switch to metric units (as opposed to powers of two).
152 base::string16 memory_text = ui::FormatBytes(memory_usage);
153 #else
154 base::string16 memory_text = base::FormatNumber(memory_usage / 1024);
155 // Adjust number string if necessary.
156 base::i18n::AdjustStringForLocaleDirection(&memory_text);
157 memory_text = l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_MEM_CELL_TEXT,
158 memory_text);
159 #endif // defined(OS_MACOSX)
160 123
161 if (has_duplicates) 124 void NewTaskManagerView::ViewsTableDelegate::ToggleSortOrder(
162 memory_text += asterisk_string_; 125 int visible_column_index) {
163 126 table_->ToggleSortOrder(visible_column_index);
164 return memory_text;
165 }
166
167 base::string16 GetIdleWakeupsText(int idle_wakeups) {
168 if (idle_wakeups == -1)
169 return n_a_string_;
170
171 return base::FormatNumber(idle_wakeups);
172 }
173
174 base::string16 GetNaClPortText(int nacl_port) {
175 if (nacl_port == nacl::kGdbDebugStubPortUnused)
176 return n_a_string_;
177
178 if (nacl_port == nacl::kGdbDebugStubPortUnknown)
179 return unknown_string_;
180
181 return base::IntToString16(nacl_port);
182 }
183
184 base::string16 GetWindowsHandlesText(int64 current, int64 peak) {
185 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_HANDLES_CELL_TEXT,
186 base::Int64ToString16(current),
187 base::Int64ToString16(peak));
188 }
189
190 base::string16 GetNetworkUsageText(int64 network_usage) {
191 if (network_usage == -1)
192 return n_a_string_;
193
194 if (network_usage == 0)
195 return zero_string_;
196
197 base::string16 net_byte = ui::FormatSpeed(network_usage);
198 // Force number string to have LTR directionality.
199 return base::i18n::GetDisplayStringInLTRDirectionality(net_byte);
200 }
201
202 base::string16 GetProcessIdText(base::ProcessId proc_id) {
203 return base::IntToString16(proc_id);
204 }
205
206 base::string16 FormatAllocatedAndUsedMemory(int64 allocated, int64 used) {
207 return l10n_util::GetStringFUTF16(
208 IDS_TASK_MANAGER_CACHE_SIZE_CELL_TEXT,
209 ui::FormatBytesWithUnits(allocated, ui::DATA_UNITS_KIBIBYTE, false),
210 ui::FormatBytesWithUnits(used, ui::DATA_UNITS_KIBIBYTE, false));
211 }
212
213 base::string16 GetWebCacheStatText(
214 const blink::WebCache::ResourceTypeStat& stat) {
215 return FormatAllocatedAndUsedMemory(stat.size, stat.liveSize);
216 }
217
218 const base::string16& n_a_string() const { return n_a_string_; }
219 const base::string16& zero_string() const { return zero_string_; }
220 const base::string16& asterisk_string() const { return asterisk_string_; }
221 const base::string16& unknown_string() const { return unknown_string_; }
222
223 private:
224 // The localized string "N/A".
225 const base::string16 n_a_string_;
226
227 // The value 0 as a string "0".
228 const base::string16 zero_string_;
229
230 // The string "*" that is used to show that there exists duplicates in the
231 // GPU memory.
232 const base::string16 asterisk_string_;
233
234 // The string "Unknown".
235 const base::string16 unknown_string_;
236
237 DISALLOW_COPY_AND_ASSIGN(TaskManagerValuesStringifier);
238 };
239
240 } // namespace
241
242 ////////////////////////////////////////////////////////////////////////////////
243
244 // IMPORTANT: Do NOT change the below list without changing the COLUMN_LIST
245 // macro below.
246 const TableColumnData kColumns[] = {
247 { IDS_TASK_MANAGER_TASK_COLUMN, ui::TableColumn::LEFT, -1, 1, true, true,
248 true },
249 { IDS_TASK_MANAGER_PROFILE_NAME_COLUMN, ui::TableColumn::LEFT, -1, 0, true,
250 true, false },
251 { IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN, ui::TableColumn::RIGHT, -1, 0, true,
252 false, true },
253 { IDS_TASK_MANAGER_SHARED_MEM_COLUMN, ui::TableColumn::RIGHT, -1, 0, true,
254 false, false },
255 { IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN, ui::TableColumn::RIGHT, -1, 0, true,
256 false, false },
257 { IDS_TASK_MANAGER_CPU_COLUMN, ui::TableColumn::RIGHT, -1, 0, true, false,
258 true },
259 { IDS_TASK_MANAGER_NET_COLUMN, ui::TableColumn::RIGHT, -1, 0, true, false,
260 true },
261 { IDS_TASK_MANAGER_PROCESS_ID_COLUMN, ui::TableColumn::RIGHT, -1, 0, true,
262 true, true },
263
264 #if defined(OS_WIN)
265 { IDS_TASK_MANAGER_GDI_HANDLES_COLUMN, ui::TableColumn::RIGHT, -1, 0, true,
266 false, false },
267 { IDS_TASK_MANAGER_USER_HANDLES_COLUMN, ui::TableColumn::RIGHT, -1, 0, true,
268 false, false },
269 #endif
270
271 { IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN, ui::TableColumn::RIGHT, -1, 0,
272 true, false, false },
273 { IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN, ui::TableColumn::RIGHT, -1,
274 0, true, false, false },
275 { IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN, ui::TableColumn::RIGHT, -1, 0,
276 true, false, false },
277 { IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN, ui::TableColumn::RIGHT, -1, 0, true,
278 false, false },
279 { IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN, ui::TableColumn::RIGHT, -1, 0,
280 true, false, false },
281
282 #if !defined(DISABLE_NACL)
283 { IDS_TASK_MANAGER_NACL_DEBUG_STUB_PORT_COLUMN, ui::TableColumn::RIGHT, -1, 0,
284 true, true, false },
285 #endif // !defined(DISABLE_NACL)
286
287 { IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN, ui::TableColumn::RIGHT,
288 -1, 0, true, false, false },
289
290 #if defined(OS_MACOSX) || defined(OS_LINUX)
291 // TODO(port): Port the idle wakeups per second to platforms other than Linux
292 // and MacOS (http://crbug.com/120488).
293 { IDS_TASK_MANAGER_IDLE_WAKEUPS_COLUMN, ui::TableColumn::RIGHT, -1, 0, true,
294 false, false },
295 #endif // defined(OS_MACOSX) || defined(OS_LINUX)
296 };
297
298 const size_t kColumnsSize = arraysize(kColumns);
299
300 const char kSortColumnIdKey[] = "sort_column_id";
301 const char kSortIsAscendingKey[] = "sort_is_ascending";
302
303 // We can't use the integer IDs of the columns converted to strings as session
304 // restore keys. These integer values can change from one build to another as
305 // they are generated. Instead we use the literal string value of the column
306 // ID symbol (i.e. for the ID IDS_TASK_MANAGER_TASK_COLUMN, we use the literal
307 // string "IDS_TASK_MANAGER_TASK_COLUMN". The following macros help us
308 // efficiently get the literal ID for the integer value.
309 #define COLUMNS_LITS(def) \
310 def(IDS_TASK_MANAGER_TASK_COLUMN) \
311 def(IDS_TASK_MANAGER_PROFILE_NAME_COLUMN) \
312 def(IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN) \
313 def(IDS_TASK_MANAGER_SHARED_MEM_COLUMN) \
314 def(IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN) \
315 def(IDS_TASK_MANAGER_CPU_COLUMN) \
316 def(IDS_TASK_MANAGER_NET_COLUMN) \
317 def(IDS_TASK_MANAGER_PROCESS_ID_COLUMN) \
318 def(IDS_TASK_MANAGER_GDI_HANDLES_COLUMN) \
319 def(IDS_TASK_MANAGER_USER_HANDLES_COLUMN) \
320 def(IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN) \
321 def(IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN) \
322 def(IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN) \
323 def(IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN) \
324 def(IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN) \
325 def(IDS_TASK_MANAGER_NACL_DEBUG_STUB_PORT_COLUMN) \
326 def(IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN) \
327 def(IDS_TASK_MANAGER_IDLE_WAKEUPS_COLUMN)
328 // Add to the above list in the macro any new IDs added in the future. Also
329 // remove the removed ones.
330
331 #define COLUMN_ID_AS_STRING(col_id) case col_id: return std::string(#col_id);
332
333 std::string GetColumnIdAsString(int column_id) {
334 switch (column_id) {
335 COLUMNS_LITS(COLUMN_ID_AS_STRING)
336 default:
337 NOTREACHED();
338 return std::string();
339 }
340 } 127 }
341 128
342 //////////////////////////////////////////////////////////////////////////////// 129 ////////////////////////////////////////////////////////////////////////////////
343
344 // The table model of the task manager table view that will observe the
345 // task manager backend and adapt its interface to match the requirements of the
346 // TableView.
347 class NewTaskManagerView::TableModel
348 : public TaskManagerObserver,
349 public ui::TableModel,
350 public views::TableGrouper {
351 public:
352 explicit TableModel(int64 refresh_flags);
353 ~TableModel() override;
354
355 // ui::TableModel:
356 int RowCount() override;
357 base::string16 GetText(int row, int column) override;
358 gfx::ImageSkia GetIcon(int row) override;
359 void SetObserver(ui::TableModelObserver* observer) override;
360 int CompareValues(int row1, int row2, int column_id) override;
361
362 // views::TableGrouper:
363 void GetGroupRange(int model_index, views::GroupRange* range) override;
364
365 // task_management::TaskManagerObserver:
366 void OnTaskAdded(TaskId id) override;
367 void OnTaskToBeRemoved(TaskId id) override;
368 void OnTasksRefreshed(const TaskIdList& task_ids) override;
369
370 // Start / stop observing the task manager.
371 void StartUpdating();
372 void StopUpdating();
373
374 // Activates the browser tab associated with the process in the specified
375 // |row_index|.
376 void ActivateTask(int row_index);
377
378 // Kills the process on which the task at |row_index| is running.
379 void KillTask(int row_index);
380
381 // Based on the given |visibility| and the |column_id|, a particular refresh
382 // type will be enabled or disabled. Multiple columns can map to the same
383 // refresh type, for that we need |table| to determine if any is visible.
384 void UpdateRefreshTypes(views::TableView* table,
385 int column_id,
386 bool visibility);
387
388
389 // Checks if the task at |row_index| is running on the browser process.
390 bool IsBrowserProcess(int row_index) const;
391
392 private:
393 void OnRefresh();
394
395 // Checks whether the task at |row_index| is the first task in its process
396 // group of tasks.
397 bool IsTaskFirstInGroup(int row_index) const;
398
399 // The table model observer that will be set by the table view of the task
400 // manager.
401 ui::TableModelObserver* table_model_observer_;
402
403 // The sorted list of task IDs by process ID then by task ID.
404 std::vector<TaskId> tasks_;
405
406 // The owned task manager values stringifier that will be used to convert the
407 // values to string16.
408 TaskManagerValuesStringifier stringifier_;
409
410 DISALLOW_COPY_AND_ASSIGN(TableModel);
411 };
412
413 ////////////////////////////////////////////////////////////////////////////////
414 // NewTaskManagerView::TableModel Implementation:
415 ////////////////////////////////////////////////////////////////////////////////
416
417 NewTaskManagerView::TableModel::TableModel(int64 refresh_flags)
418 : TaskManagerObserver(base::TimeDelta::FromMilliseconds(kRefreshTimeMS),
419 refresh_flags),
420 table_model_observer_(nullptr) {
421 }
422
423 NewTaskManagerView::TableModel::~TableModel() {
424 }
425
426 int NewTaskManagerView::TableModel::RowCount() {
427 return static_cast<int>(tasks_.size());
428 }
429
430 base::string16 NewTaskManagerView::TableModel::GetText(int row, int column) {
431 if (IsSharedByGroup(column) && !IsTaskFirstInGroup(row))
432 return base::string16();
433
434 switch (column) {
435 case IDS_TASK_MANAGER_TASK_COLUMN:
436 return observed_task_manager()->GetTitle(tasks_[row]);
437
438 case IDS_TASK_MANAGER_PROFILE_NAME_COLUMN:
439 return observed_task_manager()->GetProfileName(tasks_[row]);
440
441 case IDS_TASK_MANAGER_NET_COLUMN:
442 return stringifier_.GetNetworkUsageText(
443 observed_task_manager()->GetNetworkUsage(tasks_[row]));
444
445 case IDS_TASK_MANAGER_CPU_COLUMN:
446 return stringifier_.GetCpuUsageText(
447 observed_task_manager()->GetCpuUsage(tasks_[row]));
448
449 case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN:
450 return stringifier_.GetMemoryUsageText(
451 observed_task_manager()->GetPrivateMemoryUsage(tasks_[row]), false);
452
453 case IDS_TASK_MANAGER_SHARED_MEM_COLUMN:
454 return stringifier_.GetMemoryUsageText(
455 observed_task_manager()->GetSharedMemoryUsage(tasks_[row]), false);
456
457 case IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN:
458 return stringifier_.GetMemoryUsageText(
459 observed_task_manager()->GetPhysicalMemoryUsage(tasks_[row]), false);
460
461 case IDS_TASK_MANAGER_PROCESS_ID_COLUMN:
462 return stringifier_.GetProcessIdText(
463 observed_task_manager()->GetProcessId(tasks_[row]));
464
465 case IDS_TASK_MANAGER_GDI_HANDLES_COLUMN: {
466 int64 current, peak;
467 observed_task_manager()->GetGDIHandles(tasks_[row], &current, &peak);
468 return stringifier_.GetWindowsHandlesText(current, peak);
469 }
470
471 case IDS_TASK_MANAGER_USER_HANDLES_COLUMN: {
472 int64 current, peak;
473 observed_task_manager()->GetUSERHandles(tasks_[row], &current, &peak);
474 return stringifier_.GetWindowsHandlesText(current, peak);
475 }
476
477 case IDS_TASK_MANAGER_IDLE_WAKEUPS_COLUMN:
478 return stringifier_.GetIdleWakeupsText(
479 observed_task_manager()->GetIdleWakeupsPerSecond(tasks_[row]));
480
481 case IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN: {
482 blink::WebCache::ResourceTypeStats stats;
483 if (observed_task_manager()->GetWebCacheStats(tasks_[row], &stats))
484 return stringifier_.GetWebCacheStatText(stats.images);
485 return stringifier_.n_a_string();
486 }
487
488 case IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN: {
489 blink::WebCache::ResourceTypeStats stats;
490 if (observed_task_manager()->GetWebCacheStats(tasks_[row], &stats))
491 return stringifier_.GetWebCacheStatText(stats.scripts);
492 return stringifier_.n_a_string();
493 }
494
495 case IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN: {
496 blink::WebCache::ResourceTypeStats stats;
497 if (observed_task_manager()->GetWebCacheStats(tasks_[row], &stats))
498 return stringifier_.GetWebCacheStatText(stats.cssStyleSheets);
499 return stringifier_.n_a_string();
500 }
501
502 case IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN: {
503 bool has_duplicates = false;
504 return stringifier_.GetMemoryUsageText(
505 observed_task_manager()->GetGpuMemoryUsage(tasks_[row],
506 &has_duplicates),
507 has_duplicates);
508 }
509
510 case IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN:
511 return stringifier_.GetMemoryUsageText(
512 observed_task_manager()->GetSqliteMemoryUsed(tasks_[row]), false);
513
514 case IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN: {
515 int64 v8_allocated, v8_used;
516 if (observed_task_manager()->GetV8Memory(tasks_[row],
517 &v8_allocated,
518 &v8_used)) {
519 return stringifier_.FormatAllocatedAndUsedMemory(v8_allocated,
520 v8_used);
521 }
522 return stringifier_.n_a_string();
523 }
524
525 case IDS_TASK_MANAGER_NACL_DEBUG_STUB_PORT_COLUMN:
526 return stringifier_.GetNaClPortText(
527 observed_task_manager()->GetNaClDebugStubPort(tasks_[row]));
528
529 default:
530 NOTREACHED();
531 return base::string16();
532 }
533 }
534
535 gfx::ImageSkia NewTaskManagerView::TableModel::GetIcon(int row) {
536 return observed_task_manager()->GetIcon(tasks_[row]);
537 }
538
539 void NewTaskManagerView::TableModel::SetObserver(
540 ui::TableModelObserver* observer) {
541 table_model_observer_ = observer;
542 }
543
544 int NewTaskManagerView::TableModel::CompareValues(int row1,
545 int row2,
546 int column_id) {
547 switch (column_id) {
548 case IDS_TASK_MANAGER_TASK_COLUMN:
549 case IDS_TASK_MANAGER_PROFILE_NAME_COLUMN:
550 return ui::TableModel::CompareValues(row1, row2, column_id);
551
552 case IDS_TASK_MANAGER_NET_COLUMN:
553 return ValueCompare(
554 observed_task_manager()->GetNetworkUsage(tasks_[row1]),
555 observed_task_manager()->GetNetworkUsage(tasks_[row2]));
556
557 case IDS_TASK_MANAGER_CPU_COLUMN:
558 return ValueCompare(observed_task_manager()->GetCpuUsage(tasks_[row1]),
559 observed_task_manager()->GetCpuUsage(tasks_[row2]));
560
561 case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN:
562 return ValueCompare(
563 observed_task_manager()->GetPrivateMemoryUsage(tasks_[row1]),
564 observed_task_manager()->GetPrivateMemoryUsage(tasks_[row2]));
565
566 case IDS_TASK_MANAGER_SHARED_MEM_COLUMN:
567 return ValueCompare(
568 observed_task_manager()->GetSharedMemoryUsage(tasks_[row1]),
569 observed_task_manager()->GetSharedMemoryUsage(tasks_[row2]));
570
571 case IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN:
572 return ValueCompare(
573 observed_task_manager()->GetPhysicalMemoryUsage(tasks_[row1]),
574 observed_task_manager()->GetPhysicalMemoryUsage(tasks_[row2]));
575
576 case IDS_TASK_MANAGER_NACL_DEBUG_STUB_PORT_COLUMN:
577 return ValueCompare(
578 observed_task_manager()->GetNaClDebugStubPort(tasks_[row1]),
579 observed_task_manager()->GetNaClDebugStubPort(tasks_[row2]));
580
581 case IDS_TASK_MANAGER_PROCESS_ID_COLUMN:
582 return ValueCompare(observed_task_manager()->GetProcessId(tasks_[row1]),
583 observed_task_manager()->GetProcessId(tasks_[row2]));
584
585 case IDS_TASK_MANAGER_GDI_HANDLES_COLUMN: {
586 int64 current1, peak1, current2, peak2;
587 observed_task_manager()->GetGDIHandles(tasks_[row1], &current1, &peak1);
588 observed_task_manager()->GetGDIHandles(tasks_[row2], &current2, &peak2);
589 return ValueCompare(current1, current2);
590 }
591
592 case IDS_TASK_MANAGER_USER_HANDLES_COLUMN: {
593 int64 current1, peak1, current2, peak2;
594 observed_task_manager()->GetUSERHandles(tasks_[row1], &current1, &peak1);
595 observed_task_manager()->GetUSERHandles(tasks_[row2], &current2, &peak2);
596 return ValueCompare(current1, current2);
597 }
598
599 case IDS_TASK_MANAGER_IDLE_WAKEUPS_COLUMN:
600 return ValueCompare(
601 observed_task_manager()->GetIdleWakeupsPerSecond(tasks_[row1]),
602 observed_task_manager()->GetIdleWakeupsPerSecond(tasks_[row2]));
603
604 case IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN:
605 case IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN:
606 case IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN: {
607 blink::WebCache::ResourceTypeStats stats1;
608 blink::WebCache::ResourceTypeStats stats2;
609 bool row1_stats_valid =
610 observed_task_manager()->GetWebCacheStats(tasks_[row1], &stats1);
611 bool row2_stats_valid =
612 observed_task_manager()->GetWebCacheStats(tasks_[row2], &stats2);
613 if (!row1_stats_valid || !row2_stats_valid)
614 return OrderUnavailableValue(row1_stats_valid, row2_stats_valid);
615
616 switch (column_id) {
617 case IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN:
618 return ValueCompare(stats1.images.size, stats2.images.size);
619 case IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN:
620 return ValueCompare(stats1.scripts.size, stats2.scripts.size);
621 case IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN:
622 return ValueCompare(stats1.cssStyleSheets.size,
623 stats2.cssStyleSheets.size);
624 default:
625 NOTREACHED();
626 return 0;
627 }
628 }
629
630 case IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN: {
631 bool has_duplicates;
632 return ValueCompare(
633 observed_task_manager()->GetGpuMemoryUsage(tasks_[row1],
634 &has_duplicates),
635 observed_task_manager()->GetGpuMemoryUsage(tasks_[row2],
636 &has_duplicates));
637 }
638
639 case IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN: {
640 int64 allocated1, allocated2, used1, used2;
641 observed_task_manager()->GetV8Memory(tasks_[row1], &allocated1, &used1);
642 observed_task_manager()->GetV8Memory(tasks_[row2], &allocated2, &used2);
643 return ValueCompare(allocated1, allocated2);
644 }
645
646 case IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN:
647 return ValueCompare(
648 observed_task_manager()->GetSqliteMemoryUsed(tasks_[row1]),
649 observed_task_manager()->GetSqliteMemoryUsed(tasks_[row2]));
650
651 default:
652 NOTREACHED();
653 return 0;
654 }
655 }
656
657 void NewTaskManagerView::TableModel::GetGroupRange(int model_index,
658 views::GroupRange* range) {
659 int i = model_index;
660 for ( ; i >= 0; --i) {
661 if (IsTaskFirstInGroup(i))
662 break;
663 }
664
665 CHECK_GE(i, 0);
666
667 range->start = i;
668 range->length = observed_task_manager()->GetNumberOfTasksOnSameProcess(
669 tasks_[model_index]);
670 }
671
672 void NewTaskManagerView::TableModel::OnTaskAdded(TaskId id) {
673 // For the table view scrollbar to behave correctly we must inform it that
674 // a new task has been added.
675
676 // We will get a newly sorted list from the task manager as opposed to just
677 // adding |id| to |tasks_| because we want to keep |tasks_| sorted by proc IDs
678 // and then by Task IDs.
679 tasks_ = observed_task_manager()->GetTaskIdsList();
680 if (table_model_observer_)
681 table_model_observer_->OnItemsAdded(RowCount() - 1, 1);
682 }
683
684 void NewTaskManagerView::TableModel::OnTaskToBeRemoved(TaskId id) {
685 auto index = std::find(tasks_.begin(), tasks_.end(), id);
686 if (index == tasks_.end())
687 return;
688 auto removed_index = index - tasks_.begin();
689 tasks_.erase(index);
690 if (table_model_observer_)
691 table_model_observer_->OnItemsRemoved(removed_index, 1);
692 }
693
694 void NewTaskManagerView::TableModel::OnTasksRefreshed(
695 const TaskIdList& task_ids) {
696 tasks_ = task_ids;
697 OnRefresh();
698 }
699
700 void NewTaskManagerView::TableModel::StartUpdating() {
701 TaskManagerInterface::GetTaskManager()->AddObserver(this);
702 tasks_ = observed_task_manager()->GetTaskIdsList();
703 OnRefresh();
704 }
705
706 void NewTaskManagerView::TableModel::StopUpdating() {
707 observed_task_manager()->RemoveObserver(this);
708 }
709
710 void NewTaskManagerView::TableModel::ActivateTask(int row_index) {
711 observed_task_manager()->ActivateTask(tasks_[row_index]);
712 }
713
714 void NewTaskManagerView::TableModel::KillTask(int row_index) {
715 base::ProcessId proc_id = observed_task_manager()->GetProcessId(
716 tasks_[row_index]);
717
718 DCHECK_NE(proc_id, base::GetCurrentProcId());
719
720 base::Process process = base::Process::Open(proc_id);
721 process.Terminate(content::RESULT_CODE_KILLED, false);
722 }
723
724 void NewTaskManagerView::TableModel::UpdateRefreshTypes(views::TableView* table,
725 int column_id,
726 bool visibility) {
727 bool new_visibility = visibility;
728 RefreshType type = REFRESH_TYPE_NONE;
729 switch (column_id) {
730 case IDS_TASK_MANAGER_PROFILE_NAME_COLUMN:
731 case IDS_TASK_MANAGER_TASK_COLUMN:
732 case IDS_TASK_MANAGER_PROCESS_ID_COLUMN:
733 return; // The data is these columns do not change.
734
735 case IDS_TASK_MANAGER_NET_COLUMN:
736 type = REFRESH_TYPE_NETWORK_USAGE;
737 break;
738
739 case IDS_TASK_MANAGER_CPU_COLUMN:
740 type = REFRESH_TYPE_CPU;
741 break;
742
743 case IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN:
744 case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN:
745 case IDS_TASK_MANAGER_SHARED_MEM_COLUMN:
746 type = REFRESH_TYPE_MEMORY;
747 if (table->IsColumnVisible(IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN) ||
748 table->IsColumnVisible(IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN) ||
749 table->IsColumnVisible(IDS_TASK_MANAGER_SHARED_MEM_COLUMN)) {
750 new_visibility = true;
751 }
752 break;
753
754 case IDS_TASK_MANAGER_GDI_HANDLES_COLUMN:
755 case IDS_TASK_MANAGER_USER_HANDLES_COLUMN:
756 type = REFRESH_TYPE_HANDLES;
757 if (table->IsColumnVisible(IDS_TASK_MANAGER_GDI_HANDLES_COLUMN) ||
758 table->IsColumnVisible(IDS_TASK_MANAGER_USER_HANDLES_COLUMN)) {
759 new_visibility = true;
760 }
761 break;
762
763 case IDS_TASK_MANAGER_IDLE_WAKEUPS_COLUMN:
764 type = REFRESH_TYPE_IDLE_WAKEUPS;
765 break;
766
767 case IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN:
768 case IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN:
769 case IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN:
770 type = REFRESH_TYPE_WEBCACHE_STATS;
771 if (table->IsColumnVisible(IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN) ||
772 table->IsColumnVisible(
773 IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN) ||
774 table->IsColumnVisible(IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN)) {
775 new_visibility = true;
776 }
777 break;
778
779 case IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN:
780 type = REFRESH_TYPE_GPU_MEMORY;
781 break;
782
783 case IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN:
784 type = REFRESH_TYPE_SQLITE_MEMORY;
785 break;
786
787 case IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN:
788 type = REFRESH_TYPE_V8_MEMORY;
789 break;
790
791 case IDS_TASK_MANAGER_NACL_DEBUG_STUB_PORT_COLUMN:
792 type = REFRESH_TYPE_NACL;
793 break;
794
795 default:
796 NOTREACHED();
797 return;
798 }
799
800 if (new_visibility)
801 AddRefreshType(type);
802 else
803 RemoveRefreshType(type);
804 }
805
806 bool NewTaskManagerView::TableModel::IsBrowserProcess(int row_index) const {
807 return observed_task_manager()->GetProcessId(tasks_[row_index]) ==
808 base::GetCurrentProcId();
809 }
810
811 void NewTaskManagerView::TableModel::OnRefresh() {
812 if (table_model_observer_)
813 table_model_observer_->OnItemsChanged(0, RowCount());
814 }
815
816 bool NewTaskManagerView::TableModel::IsTaskFirstInGroup(int row_index) const {
817 if (row_index == 0)
818 return true;
819
820 return observed_task_manager()->GetProcessId(tasks_[row_index - 1]) !=
821 observed_task_manager()->GetProcessId(tasks_[row_index]);
822 }
823
824 ////////////////////////////////////////////////////////////////////////////////
825 // NewTaskManagerView Implementation: 130 // NewTaskManagerView Implementation:
826 //////////////////////////////////////////////////////////////////////////////// 131 ////////////////////////////////////////////////////////////////////////////////
827 132
828 NewTaskManagerView::~NewTaskManagerView() { 133 NewTaskManagerView::~NewTaskManagerView() {
829 // Delete child views now, while our table model still exists. 134 // Delete child views now, while our table model still exists.
830 RemoveAllChildViews(true); 135 RemoveAllChildViews(true);
831 } 136 }
832 137
833 // static 138 // static
834 void NewTaskManagerView::Show(Browser* browser) { 139 void NewTaskManagerView::Show(Browser* browser) {
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 296
992 void NewTaskManagerView::WindowClosing() { 297 void NewTaskManagerView::WindowClosing() {
993 // Now that the window is closed, we can allow a new one to be opened. 298 // Now that the window is closed, we can allow a new one to be opened.
994 // (WindowClosing comes in asynchronously from the call to Close() and we 299 // (WindowClosing comes in asynchronously from the call to Close() and we
995 // may have already opened a new instance). 300 // may have already opened a new instance).
996 if (g_task_manager_view == this) { 301 if (g_task_manager_view == this) {
997 // We don't have to delete |g_task_manager_view| as we don't own it. It's 302 // We don't have to delete |g_task_manager_view| as we don't own it. It's
998 // owned by the Views hierarchy. 303 // owned by the Views hierarchy.
999 g_task_manager_view = nullptr; 304 g_task_manager_view = nullptr;
1000 } 305 }
1001 StoreColumnsSettings(); 306 table_model_->StoreColumnsSettings();
1002 table_model_->StopUpdating(); 307 table_model_->StopUpdating();
1003 } 308 }
1004 309
1005 bool NewTaskManagerView::UseNewStyleForThisDialog() const { 310 bool NewTaskManagerView::UseNewStyleForThisDialog() const {
1006 return false; 311 return false;
1007 } 312 }
1008 313
314 void NewTaskManagerView::GetGroupRange(int model_index,
315 views::GroupRange* range) {
316 table_model_->GetRowsGroupRange(model_index, &range->start, &range->length);
317 }
318
1009 void NewTaskManagerView::OnSelectionChanged() { 319 void NewTaskManagerView::OnSelectionChanged() {
1010 const ui::ListSelectionModel::SelectedIndices& selections( 320 const ui::ListSelectionModel::SelectedIndices& selections(
1011 tab_table_->selection_model().selected_indices()); 321 tab_table_->selection_model().selected_indices());
1012 bool selection_contains_browser_process = false; 322 bool selection_contains_browser_process = false;
1013 for (const auto& selection : selections) { 323 for (const auto& selection : selections) {
1014 if (table_model_->IsBrowserProcess(selection)) { 324 if (table_model_->IsBrowserProcess(selection)) {
1015 selection_contains_browser_process = true; 325 selection_contains_browser_process = true;
1016 break; 326 break;
1017 } 327 }
1018 } 328 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1066 return true; 376 return true;
1067 } 377 }
1068 378
1069 bool NewTaskManagerView::GetAcceleratorForCommandId( 379 bool NewTaskManagerView::GetAcceleratorForCommandId(
1070 int command_id, 380 int command_id,
1071 ui::Accelerator* accelerator) { 381 ui::Accelerator* accelerator) {
1072 return false; 382 return false;
1073 } 383 }
1074 384
1075 void NewTaskManagerView::ExecuteCommand(int id, int event_flags) { 385 void NewTaskManagerView::ExecuteCommand(int id, int event_flags) {
1076 ToggleColumnVisibility(id); 386 table_model_->ToggleColumnVisibility(id);
1077 } 387 }
1078 388
1079 NewTaskManagerView::NewTaskManagerView(chrome::HostDesktopType desktop_type) 389 NewTaskManagerView::NewTaskManagerView(chrome::HostDesktopType desktop_type)
1080 : table_model_( 390 : kill_button_(nullptr),
1081 new NewTaskManagerView::TableModel(REFRESH_TYPE_CPU |
1082 REFRESH_TYPE_MEMORY |
1083 REFRESH_TYPE_NETWORK_USAGE)),
1084 kill_button_(nullptr),
1085 about_memory_link_(nullptr), 391 about_memory_link_(nullptr),
1086 tab_table_(nullptr), 392 tab_table_(nullptr),
1087 tab_table_parent_(nullptr), 393 tab_table_parent_(nullptr),
1088 desktop_type_(desktop_type), 394 desktop_type_(desktop_type),
1089 is_always_on_top_(false) { 395 is_always_on_top_(false) {
1090 Init(); 396 Init();
1091 } 397 }
1092 398
1093 // static 399 // static
1094 NewTaskManagerView* NewTaskManagerView::GetInstanceForTests() { 400 NewTaskManagerView* NewTaskManagerView::GetInstanceForTests() {
1095 return g_task_manager_view; 401 return g_task_manager_view;
1096 } 402 }
1097 403
1098 void NewTaskManagerView::Init() { 404 void NewTaskManagerView::Init() {
1099 columns_settings_.reset(new base::DictionaryValue);
1100
1101 // Create the table columns. 405 // Create the table columns.
1102 for (size_t i = 0; i < kColumnsSize; ++i) { 406 for (size_t i = 0; i < kColumnsSize; ++i) {
1103 const auto& col_data = kColumns[i]; 407 const auto& col_data = kColumns[i];
1104 columns_.push_back(ui::TableColumn(col_data.id, col_data.align, 408 columns_.push_back(ui::TableColumn(col_data.id, col_data.align,
1105 col_data.width, col_data.percent)); 409 col_data.width, col_data.percent));
1106 columns_.back().sortable = col_data.sortable; 410 columns_.back().sortable = col_data.sortable;
1107 columns_.back().initial_sort_is_ascending = 411 columns_.back().initial_sort_is_ascending =
1108 col_data.initial_sort_is_ascending; 412 col_data.initial_sort_is_ascending;
1109 } 413 }
1110 414
1111 // Create the table view. 415 // Create in this order: the table view, the table delegate, the table model.
1112 tab_table_ = new views::TableView( 416 tab_table_ = new views::TableView(nullptr, columns_, views::ICON_AND_TEXT,
1113 table_model_.get(), columns_, views::ICON_AND_TEXT, false); 417 false);
1114 tab_table_->SetGrouper(table_model_.get()); 418 table_delegate_.reset(new ViewsTableDelegate(tab_table_));
419 table_model_.reset(new TaskManagerTableModel(REFRESH_TYPE_CPU |
420 REFRESH_TYPE_MEMORY |
421 REFRESH_TYPE_NETWORK_USAGE,
422 table_delegate_.get()));
423 tab_table_->SetModel(table_model_.get());
424 tab_table_->SetGrouper(this);
1115 tab_table_->SetObserver(this); 425 tab_table_->SetObserver(this);
1116 tab_table_->set_context_menu_controller(this); 426 tab_table_->set_context_menu_controller(this);
1117 set_context_menu_controller(this); 427 set_context_menu_controller(this);
1118 428
1119 RetrieveSavedColumnsSettingsAndUpdateTable(); 429 table_model_->RetrieveSavedColumnsSettingsAndUpdateTable();
1120 430
1121 kill_button_ = new views::LabelButton(this, 431 kill_button_ = new views::LabelButton(this,
1122 l10n_util::GetStringUTF16(IDS_TASK_MANAGER_KILL)); 432 l10n_util::GetStringUTF16(IDS_TASK_MANAGER_KILL));
1123 kill_button_->SetStyle(views::Button::STYLE_BUTTON); 433 kill_button_->SetStyle(views::Button::STYLE_BUTTON);
1124 434
1125 about_memory_link_ = new views::Link( 435 about_memory_link_ = new views::Link(
1126 l10n_util::GetStringUTF16(IDS_TASK_MANAGER_ABOUT_MEMORY_LINK)); 436 l10n_util::GetStringUTF16(IDS_TASK_MANAGER_ABOUT_MEMORY_LINK));
1127 about_memory_link_->set_listener(this); 437 about_memory_link_->set_listener(this);
1128 438
1129 // Makes sure our state is consistent. 439 // Makes sure our state is consistent.
(...skipping 18 matching lines...) Expand all
1148 458
1149 if (!g_browser_process->local_state()) 459 if (!g_browser_process->local_state())
1150 return; 460 return;
1151 461
1152 const base::DictionaryValue* dictionary = 462 const base::DictionaryValue* dictionary =
1153 g_browser_process->local_state()->GetDictionary(GetWindowName()); 463 g_browser_process->local_state()->GetDictionary(GetWindowName());
1154 if (dictionary) 464 if (dictionary)
1155 dictionary->GetBoolean("always_on_top", &is_always_on_top_); 465 dictionary->GetBoolean("always_on_top", &is_always_on_top_);
1156 } 466 }
1157 467
1158 void NewTaskManagerView::RetrieveSavedColumnsSettingsAndUpdateTable() {
1159 if (!g_browser_process->local_state())
1160 return;
1161
1162 const base::DictionaryValue* dictionary =
1163 g_browser_process->local_state()->GetDictionary(
1164 prefs::kTaskManagerColumnVisibility);
1165 if (!dictionary)
1166 return;
1167
1168 // Do a best effort of retrieving the correct settings from the local state.
1169 // Use the default settings of the value if it fails to be retrieved.
1170 std::string sorted_col_id;
1171 bool sort_is_ascending = true;
1172 dictionary->GetString(kSortColumnIdKey, &sorted_col_id);
1173 dictionary->GetBoolean(kSortIsAscendingKey, &sort_is_ascending);
1174
1175 int current_visible_column_index = 0;
1176 for (size_t i = 0; i < kColumnsSize; ++i) {
1177 const int col_id = kColumns[i].id;
1178 const std::string col_id_key(GetColumnIdAsString(col_id));
1179
1180 if (col_id_key.empty())
1181 continue;
1182
1183 bool col_visibility = kColumns[i].default_visibility;
1184 dictionary->GetBoolean(col_id_key, &col_visibility);
1185
1186 // If the above GetBoolean() fails, the |col_visibility| remains at the
1187 // default visibility.
1188 columns_settings_->SetBoolean(col_id_key, col_visibility);
1189 tab_table_->SetColumnVisibility(col_id, col_visibility);
1190 table_model_->UpdateRefreshTypes(tab_table_, col_id, col_visibility);
1191
1192 if (col_visibility) {
1193 if (sorted_col_id == col_id_key) {
1194 if (sort_is_ascending == kColumns[i].initial_sort_is_ascending) {
1195 tab_table_->ToggleSortOrder(current_visible_column_index);
1196 } else {
1197 // Unfortunately the API of ui::TableView doesn't provide a clean way
1198 // to sort by a particular column ID and a sort direction. If the
1199 // retrieved sort direction is different than the initial one, we have
1200 // to toggle the sort order twice!
1201 // Note that the function takes the visible_column_index rather than
1202 // a column ID.
1203 tab_table_->ToggleSortOrder(current_visible_column_index);
1204 tab_table_->ToggleSortOrder(current_visible_column_index);
1205 }
1206 }
1207
1208 ++current_visible_column_index;
1209 }
1210 }
1211 }
1212
1213 void NewTaskManagerView::StoreColumnsSettings() {
1214 PrefService* local_state = g_browser_process->local_state();
1215 if (!local_state)
1216 return;
1217
1218 DictionaryPrefUpdate dict_update(local_state,
1219 prefs::kTaskManagerColumnVisibility);
1220
1221 base::DictionaryValue::Iterator it(*columns_settings_);
1222 while (!it.IsAtEnd()) {
1223 dict_update->Set(it.key(), it.value().CreateDeepCopy());
1224 it.Advance();
1225 }
1226
1227 // Store the current sort status to be restored again at startup.
1228 if (tab_table_->sort_descriptors().empty()) {
1229 dict_update->SetString(kSortColumnIdKey, "");
1230 } else {
1231 const auto& sort_descriptor = tab_table_->sort_descriptors().front();
1232 dict_update->SetString(kSortColumnIdKey,
1233 GetColumnIdAsString(sort_descriptor.column_id));
1234 dict_update->SetBoolean(kSortIsAscendingKey, sort_descriptor.ascending);
1235 }
1236 }
1237
1238 void NewTaskManagerView::ToggleColumnVisibility(int column_id) {
1239 bool new_visibility = !tab_table_->IsColumnVisible(column_id);
1240 tab_table_->SetColumnVisibility(column_id, new_visibility);
1241 columns_settings_->SetBoolean(GetColumnIdAsString(column_id), new_visibility);
1242 table_model_->UpdateRefreshTypes(tab_table_, column_id, new_visibility);
1243 }
1244
1245 } // namespace task_management 468 } // namespace task_management
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698