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

Side by Side Diff: chrome/browser/memory/tab_manager_delegate_chromeos_unittest.cc

Issue 2095413002: TabManagerDelegate: Better prioritize ARC processes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: minor fixes Created 4 years, 5 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 (c) 2012 The Chromium Authors. All rights reserved. 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 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/memory/tab_manager_delegate_chromeos.h" 5 #include "chrome/browser/memory/tab_manager_delegate_chromeos.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
(...skipping 10 matching lines...) Expand all
21 #include "components/arc/common/process.mojom.h" 21 #include "components/arc/common/process.mojom.h"
22 #include "components/arc/test/fake_arc_bridge_service.h" 22 #include "components/arc/test/fake_arc_bridge_service.h"
23 #include "components/exo/shell_surface.h" 23 #include "components/exo/shell_surface.h"
24 #include "testing/gtest/include/gtest/gtest.h" 24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "ui/aura/window.h" 25 #include "ui/aura/window.h"
26 #include "ui/wm/public/activation_client.h" 26 #include "ui/wm/public/activation_client.h"
27 #include "url/gurl.h" 27 #include "url/gurl.h"
28 28
29 namespace memory { 29 namespace memory {
30 30
31 typedef testing::Test TabManagerDelegateTest;
Yusuke Sato 2016/07/15 00:55:06 using
cylee1 2016/07/15 17:31:13 Done.
32
31 namespace { 33 namespace {
32 34 bool IS_FOCUSED = true;
Yusuke Sato 2016/07/15 00:55:05 constexpr bool kIsFocused = true;
cylee1 2016/07/15 17:31:13 Done.
33 const char kExoShellSurfaceWindowName[] = "ExoShellSurface"; 35 bool NOT_FOCUSED = false;
Yusuke Sato 2016/07/15 00:55:06 same
cylee1 2016/07/15 17:31:13 Done.
34 const char kArcProcessNamePrefix[] = "org.chromium.arc.";
35
36 } // namespace 36 } // namespace
37 37
38 class TabManagerDelegateTest : public ash::test::AshTestBase {
39 public:
40 TabManagerDelegateTest() : application_id_(kArcProcessNamePrefix) {}
41 ~TabManagerDelegateTest() override {}
42
43 void SetUp() override {
44 AshTestBase::SetUp();
45
46 arc_window_ = CreateTestWindowInShellWithId(0);
47 arc_window_->SetName(kExoShellSurfaceWindowName);
48 exo::ShellSurface::SetApplicationId(arc_window_,
49 &application_id_);
50 }
51
52 protected:
53 void ActivateArcWindow() {
54 GetActivationClient()->ActivateWindow(arc_window_);
55 }
56 void DeactivateArcWindow() {
57 GetActivationClient()->DeactivateWindow(arc_window_);
58 }
59
60 private:
61 aura::client::ActivationClient* GetActivationClient() {
62 return aura::client::GetActivationClient(
63 ash::Shell::GetPrimaryRootWindow());
64 }
65
66 aura::Window* arc_window_;
67 std::string application_id_;
68 };
69
70 TEST_F(TabManagerDelegateTest, CandidatesSorted) { 38 TEST_F(TabManagerDelegateTest, CandidatesSorted) {
71 std::vector<arc::ArcProcess> arc_processes; 39 std::vector<arc::ArcProcess> arc_processes;
72 arc_processes.emplace_back(1, 10, "top", arc::mojom::ProcessState::TOP); 40 arc_processes.emplace_back(1, 10, "focused", arc::mojom::ProcessState::TOP,
73 arc_processes.emplace_back(2, 20, "foreground", 41 IS_FOCUSED, 100);
74 arc::mojom::ProcessState::FOREGROUND_SERVICE); 42 arc_processes.emplace_back(2, 20, "visible1",
43 arc::mojom::ProcessState::TOP,
44 NOT_FOCUSED, 200);
75 arc_processes.emplace_back(3, 30, "service", 45 arc_processes.emplace_back(3, 30, "service",
76 arc::mojom::ProcessState::SERVICE); 46 arc::mojom::ProcessState::SERVICE,
47 NOT_FOCUSED, 500);
48 arc_processes.emplace_back(4, 40, "visible2",
49 arc::mojom::ProcessState::TOP,
50 NOT_FOCUSED, 150);
51
77 52
78 TabStats tab1, tab2, tab3, tab4, tab5; 53 TabStats tab1, tab2, tab3, tab4, tab5;
79 tab1.tab_contents_id = 100; 54 tab1.tab_contents_id = 100;
80 tab1.is_pinned = true; 55 tab1.is_pinned = true;
81 56
82 tab2.tab_contents_id = 200; 57 tab2.tab_contents_id = 200;
83 tab2.is_internal_page = true; 58 tab2.is_internal_page = true;
84 59
85 tab3.tab_contents_id = 300; 60 tab3.tab_contents_id = 300;
86 tab3.is_pinned = true; 61 tab3.is_pinned = true;
87 tab3.is_media = true; 62 tab3.is_media = true;
88 63
89 tab4.tab_contents_id = 400; 64 tab4.tab_contents_id = 400;
90 tab4.is_media = true; 65 tab4.is_media = true;
91 66
92 tab5.tab_contents_id = 500; 67 tab5.tab_contents_id = 500;
93 tab5.is_app = true; 68 tab5.is_app = true;
94 TabStatsList tab_list = { 69 TabStatsList tab_list = {
95 tab1, tab2, tab3, tab4, tab5 70 tab1, tab2, tab3, tab4, tab5
96 }; 71 };
97 72
98 std::vector<TabManagerDelegate::Candidate> candidates; 73 std::vector<TabManagerDelegate::Candidate> candidates;
99 74
100 // Case 1: ARC window in the foreground.
101 ActivateArcWindow();
102 candidates = TabManagerDelegate::GetSortedCandidates( 75 candidates = TabManagerDelegate::GetSortedCandidates(
103 tab_list, arc_processes); 76 tab_list, arc_processes);
104 EXPECT_EQ(8U, candidates.size()); 77 EXPECT_EQ(9U, candidates.size());
105 78
106 EXPECT_EQ("service", candidates[0].app->process_name()); 79 // focused app.
107 EXPECT_EQ("foreground", candidates[1].app->process_name()); 80 EXPECT_EQ("focused", candidates[0].app()->process_name());
81 // visible app 1, last_activity_time larger than visible app 2.
82 EXPECT_EQ("visible1", candidates[1].app()->process_name());
83 // visible app 2, last_activity_time less than visible app 1.
84 EXPECT_EQ("visible2", candidates[2].app()->process_name());
85 // pinned and media.
86 EXPECT_EQ(300, candidates[3].tab()->tab_contents_id);
87 // media.
88 EXPECT_EQ(400, candidates[4].tab()->tab_contents_id);
89 // pinned.
90 EXPECT_EQ(100, candidates[5].tab()->tab_contents_id);
91 // chrome app.
92 EXPECT_EQ(500, candidates[6].tab()->tab_contents_id);
108 // internal page. 93 // internal page.
109 EXPECT_EQ(200, candidates[2].tab->tab_contents_id); 94 EXPECT_EQ(200, candidates[7].tab()->tab_contents_id);
110 // chrome app. 95 // background service.
111 EXPECT_EQ(500, candidates[3].tab->tab_contents_id); 96 EXPECT_EQ("service", candidates[8].app()->process_name());
112 // pinned.
113 EXPECT_EQ(100, candidates[4].tab->tab_contents_id);
114 // media.
115 EXPECT_EQ(400, candidates[5].tab->tab_contents_id);
116 // pinned and media.
117 EXPECT_EQ(300, candidates[6].tab->tab_contents_id);
118 // ARC window is the active window, so top app has highest priority.
119 EXPECT_EQ("top", candidates[7].app->process_name());
120
121 // Case 2: ARC window in the background.
122 DeactivateArcWindow();
123 candidates = TabManagerDelegate::GetSortedCandidates(
124 tab_list, arc_processes);
125 EXPECT_EQ(8U, candidates.size());
126
127 EXPECT_EQ("service", candidates[0].app->process_name());
128 EXPECT_EQ("foreground", candidates[1].app->process_name());
129 // internal page.
130 EXPECT_EQ(200, candidates[2].tab->tab_contents_id);
131
132 // Chrome app and android app are tied, so both orders are correct.
133 if (candidates[3].is_arc_app) {
134 EXPECT_EQ("top", candidates[3].app->process_name());
135 // chrome app.
136 EXPECT_EQ(500, candidates[4].tab->tab_contents_id);
137 } else {
138 // chrome app.
139 EXPECT_EQ(500, candidates[3].tab->tab_contents_id);
140 EXPECT_EQ("top", candidates[4].app->process_name());
141 }
142
143 // pinned.
144 EXPECT_EQ(100, candidates[5].tab->tab_contents_id);
145 // media.
146 EXPECT_EQ(400, candidates[6].tab->tab_contents_id);
147 // pinned and media.
148 EXPECT_EQ(300, candidates[7].tab->tab_contents_id);
149 } 97 }
150 98
151 class MockTabManagerDelegate : public TabManagerDelegate { 99 class MockTabManagerDelegate : public TabManagerDelegate {
152 public: 100 public:
153 MockTabManagerDelegate(): TabManagerDelegate(nullptr) { 101 MockTabManagerDelegate(): TabManagerDelegate(nullptr) {
154 } 102 }
155 103
156 explicit MockTabManagerDelegate(TabManagerDelegate::MemoryStat* mem_stat) 104 explicit MockTabManagerDelegate(TabManagerDelegate::MemoryStat* mem_stat)
157 : TabManagerDelegate(nullptr, mem_stat) { 105 : TabManagerDelegate(nullptr, mem_stat) {
158 } 106 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 167
220 private: 168 private:
221 int target_memory_to_free_kb_; 169 int target_memory_to_free_kb_;
222 std::map<base::ProcessHandle, int> process_pss_; 170 std::map<base::ProcessHandle, int> process_pss_;
223 }; 171 };
224 172
225 TEST_F(TabManagerDelegateTest, SetOomScoreAdj) { 173 TEST_F(TabManagerDelegateTest, SetOomScoreAdj) {
226 arc::FakeArcBridgeService fake_arc_bridge_service; 174 arc::FakeArcBridgeService fake_arc_bridge_service;
227 MockTabManagerDelegate tab_manager_delegate; 175 MockTabManagerDelegate tab_manager_delegate;
228 176
229 ActivateArcWindow();
230 std::vector<arc::ArcProcess> arc_processes; 177 std::vector<arc::ArcProcess> arc_processes;
231 arc_processes.emplace_back(1, 10, "top", arc::mojom::ProcessState::TOP); 178 arc_processes.emplace_back(1, 10, "focused", arc::mojom::ProcessState::TOP,
232 arc_processes.emplace_back(2, 20, "foreground", 179 IS_FOCUSED, 100);
233 arc::mojom::ProcessState::FOREGROUND_SERVICE); 180 arc_processes.emplace_back(2, 20, "visible1",
181 arc::mojom::ProcessState::TOP,
182 NOT_FOCUSED, 200);
234 arc_processes.emplace_back(3, 30, "service", 183 arc_processes.emplace_back(3, 30, "service",
235 arc::mojom::ProcessState::SERVICE); 184 arc::mojom::ProcessState::SERVICE,
185 NOT_FOCUSED, 500);
186 arc_processes.emplace_back(4, 40, "visible2",
187 arc::mojom::ProcessState::TOP,
188 NOT_FOCUSED, 150);
189
236 190
237 TabStats tab1, tab2, tab3, tab4, tab5; 191 TabStats tab1, tab2, tab3, tab4, tab5;
238 tab1.is_pinned = true; 192 tab1.is_pinned = true;
239 tab1.renderer_handle = 11; 193 tab1.renderer_handle = 11;
240 194
241 tab2.is_internal_page = true; 195 tab2.is_internal_page = true;
242 tab2.renderer_handle = 11; 196 tab2.renderer_handle = 11;
243 197
244 tab3.is_pinned = true; 198 tab3.is_pinned = true;
245 tab3.is_media = true; 199 tab3.is_media = true;
246 tab3.renderer_handle = 12; 200 tab3.renderer_handle = 12;
247 201
248 tab4.is_media = true; 202 tab4.is_media = true;
249 tab4.renderer_handle = 12; 203 tab4.renderer_handle = 12;
250 204
251 tab5.is_app = true; 205 tab5.is_app = true;
252 tab5.renderer_handle = 12; 206 tab5.renderer_handle = 12;
253 TabStatsList tab_list = {tab1, tab2, tab3, tab4, tab5}; 207 TabStatsList tab_list = {tab1, tab2, tab3, tab4, tab5};
254 208
255 // Sorted order: 209 // Sorted order:
256 // app "service" pid: 30 oom_socre_adj: 825 210 // app "focused" pid: 10
257 // app "foreground" pid: 20 oom_score_adj: 650 211 // app "visible1" pid: 20
258 // tab2 pid: 11 oom_socre_adj: 417 212 // app "visible2" pid: 40
259 // tab5 pid: 12 oom_score_adj: 358 213 // tab3 pid: 12
260 // tab1 pid: 11 oom_socre_adj: 417 214 // tab4 pid: 12
261 // tab4 pid: 12 oom_socre_adj: 358 215 // tab1 pid: 11
262 // tab3 pid: 12 oom_score_adj: 358 216 // tab5 pid: 12
263 // app "top" pid: 10 oom_score_adj: 300 217 // tab2 pid: 11
218 // app "service" pid: 30
264 tab_manager_delegate.AdjustOomPrioritiesImpl(tab_list, arc_processes); 219 tab_manager_delegate.AdjustOomPrioritiesImpl(tab_list, arc_processes);
265 auto& oom_score_map = tab_manager_delegate.oom_score_map_; 220 auto& oom_score_map = tab_manager_delegate.oom_score_map_;
266 221
267 EXPECT_EQ(5U, oom_score_map.size()); 222 EXPECT_EQ(6U, oom_score_map.size());
268 223
269 // Higher priority part. 224 // Higher priority part.
270 EXPECT_EQ(300, oom_score_map[10]); 225 EXPECT_EQ(300, oom_score_map[10]);
271 EXPECT_EQ(358, oom_score_map[12]); 226 EXPECT_EQ(344, oom_score_map[20]);
272 EXPECT_EQ(417, oom_score_map[11]); 227 EXPECT_EQ(388, oom_score_map[40]);
228 EXPECT_EQ(431, oom_score_map[12]);
229 EXPECT_EQ(475, oom_score_map[11]);
273 230
274 // Lower priority part. 231 // Lower priority part.
275 EXPECT_EQ(650, oom_score_map[20]); 232 EXPECT_EQ(650, oom_score_map[30]);
276 EXPECT_EQ(825, oom_score_map[30]);
277 } 233 }
278 234
279 TEST_F(TabManagerDelegateTest, KillMultipleProcesses) { 235 TEST_F(TabManagerDelegateTest, KillMultipleProcesses) {
280 arc::FakeArcBridgeService fake_arc_bridge_service; 236 arc::FakeArcBridgeService fake_arc_bridge_service;
281 237
282 // Not owned. 238 // Not owned.
283 MockMemoryStat* memory_stat = new MockMemoryStat(); 239 MockMemoryStat* memory_stat = new MockMemoryStat();
284 240
285 // Instantiate the mock instance. 241 // Instantiate the mock instance.
286 MockTabManagerDelegate tab_manager_delegate(memory_stat); 242 MockTabManagerDelegate tab_manager_delegate(memory_stat);
287 243
288 ActivateArcWindow();
289
290 std::vector<arc::ArcProcess> arc_processes; 244 std::vector<arc::ArcProcess> arc_processes;
291 arc_processes.emplace_back(10001, 100, "top", arc::mojom::ProcessState::TOP); 245 arc_processes.emplace_back(1, 10, "focused", arc::mojom::ProcessState::TOP,
292 arc_processes.emplace_back(10002, 200, "foreground", 246 IS_FOCUSED, 100);
293 arc::mojom::ProcessState::FOREGROUND_SERVICE); 247 arc_processes.emplace_back(2, 20, "visible1",
294 arc_processes.emplace_back(10003, 300, "service", 248 arc::mojom::ProcessState::TOP,
295 arc::mojom::ProcessState::SERVICE); 249 NOT_FOCUSED, 200);
250 arc_processes.emplace_back(3, 30, "service",
251 arc::mojom::ProcessState::SERVICE,
252 NOT_FOCUSED, 500);
253 arc_processes.emplace_back(4, 40, "visible2",
254 arc::mojom::ProcessState::TOP,
255 NOT_FOCUSED, 150);
296 256
297 TabStats tab1, tab2, tab3, tab4, tab5; 257 TabStats tab1, tab2, tab3, tab4, tab5;
298 tab1.is_pinned = true; 258 tab1.is_pinned = true;
299 tab1.renderer_handle = 11; 259 tab1.renderer_handle = 11;
300 tab1.tab_contents_id = 1; 260 tab1.tab_contents_id = 1;
301 261
302 tab2.is_internal_page = true; 262 tab2.is_internal_page = true;
303 tab2.renderer_handle = 11; 263 tab2.renderer_handle = 11;
304 tab2.tab_contents_id = 2; 264 tab2.tab_contents_id = 2;
305 265
306 tab3.is_pinned = true; 266 tab3.is_pinned = true;
307 tab3.is_media = true; 267 tab3.is_media = true;
308 tab3.renderer_handle = 12; 268 tab3.renderer_handle = 12;
309 tab3.tab_contents_id = 3; 269 tab3.tab_contents_id = 3;
310 270
311 tab4.is_media = true; 271 tab4.is_media = true;
312 tab4.renderer_handle = 12; 272 tab4.renderer_handle = 12;
313 tab4.tab_contents_id = 4; 273 tab4.tab_contents_id = 4;
314 274
315 tab5.is_app = true; 275 tab5.is_app = true;
316 tab5.renderer_handle = 12; 276 tab5.renderer_handle = 12;
317 tab5.tab_contents_id = 5; 277 tab5.tab_contents_id = 5;
318 TabStatsList tab_list = {tab1, tab2, tab3, tab4, tab5}; 278 TabStatsList tab_list = {tab1, tab2, tab3, tab4, tab5};
319 279
320 // Sorted order: 280 // Sorted order:
321 // app "service" pid: 30 281 // app "focused" pid: 10 nspid 1
322 // app "foreground" pid: 20 282 // app "visible1" pid: 20 nspid 2
323 // tab2 pid: 11 283 // app "visible2" pid: 40 nspid 4
324 // tab5 pid: 12 284 // tab3 pid: 12 tab_contents_id 3
325 // tab1 pid: 11 285 // tab4 pid: 12 tab_contents_id 4
326 // tab4 pid: 12 286 // tab1 pid: 11 tab_contents_id 1
327 // tab3 pid: 12 287 // tab5 pid: 12 tab_contents_id 5
328 // app "top" pid: 10 288 // tab2 pid: 11 tab_contents_id 2
289 // app "service" pid: 30 nspid 3
329 memory_stat->SetTargetMemoryToFreeKB(250000); 290 memory_stat->SetTargetMemoryToFreeKB(250000);
330 // The 3 entities to be killed. 291 // Entities to be killed.
331 memory_stat->SetProcessPss(300, 10000); 292 memory_stat->SetProcessPss(30, 10000);
332 memory_stat->SetProcessPss(200, 200000); 293 memory_stat->SetProcessPss(11, 200000);
333 memory_stat->SetProcessPss(11, 50000); 294 memory_stat->SetProcessPss(12, 30000);
334 // Should not be used. 295 // Should not be used.
335 memory_stat->SetProcessPss(100, 30000); 296 memory_stat->SetProcessPss(40, 50000);
336 memory_stat->SetProcessPss(12, 100000); 297 memory_stat->SetProcessPss(20, 30000);
298 memory_stat->SetProcessPss(10, 100000);
337 299
338 tab_manager_delegate.LowMemoryKillImpl(tab_list, arc_processes); 300 tab_manager_delegate.LowMemoryKillImpl(tab_list, arc_processes);
339 301
340 auto killed_arc_processes = tab_manager_delegate.GetKilledArcProcesses(); 302 auto killed_arc_processes = tab_manager_delegate.GetKilledArcProcesses();
341 auto killed_tabs = tab_manager_delegate.GetKilledTabs(); 303 auto killed_tabs = tab_manager_delegate.GetKilledTabs();
342 304
343 EXPECT_EQ(2U, killed_arc_processes.size()); 305 // Killed apps and their nspid.
344 EXPECT_EQ(1U, killed_tabs.size()); 306 EXPECT_EQ(1U, killed_arc_processes.size());
345 307 EXPECT_EQ(3, killed_arc_processes[0]);
346 // nspid. 308 // Killed tabs and their content id.
347 EXPECT_EQ(10003, killed_arc_processes[0]); 309 // Note that process with pid 11 is counted twice. But so far I don't have a
348 EXPECT_EQ(10002, killed_arc_processes[1]); 310 // good way to estimate the memory freed if multiple tabs share one process.
349 // tab content id. 311 EXPECT_EQ(3U, killed_tabs.size());
350 EXPECT_EQ(2, killed_tabs[0]); 312 EXPECT_EQ(2, killed_tabs[0]);
313 EXPECT_EQ(5, killed_tabs[1]);
314 EXPECT_EQ(1, killed_tabs[2]);
351 } 315 }
352 316
353 } // namespace memory 317 } // namespace memory
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698