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

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: sync to ToT 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 using TabManagerDelegateTest = testing::Test;
32
31 namespace { 33 namespace {
32 34 constexpr bool kIsFocused = true;
33 const char kExoShellSurfaceWindowName[] = "ExoShellSurface"; 35 constexpr bool kNotFocused = false;
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 kIsFocused, 100);
74 arc::mojom::ProcessState::FOREGROUND_SERVICE); 42 arc_processes.emplace_back(2, 20, "visible1", arc::mojom::ProcessState::TOP,
75 arc_processes.emplace_back(3, 30, "service", 43 kNotFocused, 200);
76 arc::mojom::ProcessState::SERVICE); 44 arc_processes.emplace_back(
45 3, 30, "service", arc::mojom::ProcessState::SERVICE, kNotFocused, 500);
46 arc_processes.emplace_back(4, 40, "visible2", arc::mojom::ProcessState::TOP,
47 kNotFocused, 150);
77 48
78 TabStats tab1, tab2, tab3, tab4, tab5; 49 TabStats tab1, tab2, tab3, tab4, tab5;
79 tab1.tab_contents_id = 100; 50 tab1.tab_contents_id = 100;
80 tab1.is_pinned = true; 51 tab1.is_pinned = true;
81 52
82 tab2.tab_contents_id = 200; 53 tab2.tab_contents_id = 200;
83 tab2.is_internal_page = true; 54 tab2.is_internal_page = true;
84 55
85 tab3.tab_contents_id = 300; 56 tab3.tab_contents_id = 300;
86 tab3.is_pinned = true; 57 tab3.is_pinned = true;
87 tab3.is_media = true; 58 tab3.is_media = true;
88 59
89 tab4.tab_contents_id = 400; 60 tab4.tab_contents_id = 400;
90 tab4.is_media = true; 61 tab4.is_media = true;
91 62
92 tab5.tab_contents_id = 500; 63 tab5.tab_contents_id = 500;
93 tab5.is_app = true; 64 tab5.is_app = true;
94 TabStatsList tab_list = { 65 TabStatsList tab_list = {
95 tab1, tab2, tab3, tab4, tab5 66 tab1, tab2, tab3, tab4, tab5
96 }; 67 };
97 68
98 std::vector<TabManagerDelegate::Candidate> candidates; 69 std::vector<TabManagerDelegate::Candidate> candidates;
99 70
100 // Case 1: ARC window in the foreground.
101 ActivateArcWindow();
102 candidates = TabManagerDelegate::GetSortedCandidates( 71 candidates = TabManagerDelegate::GetSortedCandidates(
103 tab_list, arc_processes); 72 tab_list, arc_processes);
104 EXPECT_EQ(8U, candidates.size()); 73 EXPECT_EQ(9U, candidates.size());
105 74
106 EXPECT_EQ("service", candidates[0].app->process_name()); 75 // focused app.
107 EXPECT_EQ("foreground", candidates[1].app->process_name()); 76 EXPECT_EQ("focused", candidates[0].app()->process_name());
77 // visible app 1, last_activity_time larger than visible app 2.
78 EXPECT_EQ("visible1", candidates[1].app()->process_name());
79 // visible app 2, last_activity_time less than visible app 1.
80 EXPECT_EQ("visible2", candidates[2].app()->process_name());
81 // pinned and media.
82 EXPECT_EQ(300, candidates[3].tab()->tab_contents_id);
83 // media.
84 EXPECT_EQ(400, candidates[4].tab()->tab_contents_id);
85 // pinned.
86 EXPECT_EQ(100, candidates[5].tab()->tab_contents_id);
87 // chrome app.
88 EXPECT_EQ(500, candidates[6].tab()->tab_contents_id);
108 // internal page. 89 // internal page.
109 EXPECT_EQ(200, candidates[2].tab->tab_contents_id); 90 EXPECT_EQ(200, candidates[7].tab()->tab_contents_id);
110 // chrome app. 91 // background service.
111 EXPECT_EQ(500, candidates[3].tab->tab_contents_id); 92 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 } 93 }
150 94
151 class MockTabManagerDelegate : public TabManagerDelegate { 95 class MockTabManagerDelegate : public TabManagerDelegate {
152 public: 96 public:
153 MockTabManagerDelegate(): TabManagerDelegate(nullptr) { 97 MockTabManagerDelegate(): TabManagerDelegate(nullptr) {
154 } 98 }
155 99
156 explicit MockTabManagerDelegate(TabManagerDelegate::MemoryStat* mem_stat) 100 explicit MockTabManagerDelegate(TabManagerDelegate::MemoryStat* mem_stat)
157 : TabManagerDelegate(nullptr, mem_stat) { 101 : TabManagerDelegate(nullptr, mem_stat) {
158 } 102 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 163
220 private: 164 private:
221 int target_memory_to_free_kb_; 165 int target_memory_to_free_kb_;
222 std::map<base::ProcessHandle, int> process_pss_; 166 std::map<base::ProcessHandle, int> process_pss_;
223 }; 167 };
224 168
225 TEST_F(TabManagerDelegateTest, SetOomScoreAdj) { 169 TEST_F(TabManagerDelegateTest, SetOomScoreAdj) {
226 arc::FakeArcBridgeService fake_arc_bridge_service; 170 arc::FakeArcBridgeService fake_arc_bridge_service;
227 MockTabManagerDelegate tab_manager_delegate; 171 MockTabManagerDelegate tab_manager_delegate;
228 172
229 ActivateArcWindow();
230 std::vector<arc::ArcProcess> arc_processes; 173 std::vector<arc::ArcProcess> arc_processes;
231 arc_processes.emplace_back(1, 10, "top", arc::mojom::ProcessState::TOP); 174 arc_processes.emplace_back(1, 10, "focused", arc::mojom::ProcessState::TOP,
232 arc_processes.emplace_back(2, 20, "foreground", 175 kIsFocused, 100);
233 arc::mojom::ProcessState::FOREGROUND_SERVICE); 176 arc_processes.emplace_back(2, 20, "visible1", arc::mojom::ProcessState::TOP,
234 arc_processes.emplace_back(3, 30, "service", 177 kNotFocused, 200);
235 arc::mojom::ProcessState::SERVICE); 178 arc_processes.emplace_back(
179 3, 30, "service", arc::mojom::ProcessState::SERVICE, kNotFocused, 500);
180 arc_processes.emplace_back(4, 40, "visible2", arc::mojom::ProcessState::TOP,
181 kNotFocused, 150);
236 182
237 TabStats tab1, tab2, tab3, tab4, tab5; 183 TabStats tab1, tab2, tab3, tab4, tab5;
238 tab1.is_pinned = true; 184 tab1.is_pinned = true;
239 tab1.renderer_handle = 11; 185 tab1.renderer_handle = 11;
240 186
241 tab2.is_internal_page = true; 187 tab2.is_internal_page = true;
242 tab2.renderer_handle = 11; 188 tab2.renderer_handle = 11;
243 189
244 tab3.is_pinned = true; 190 tab3.is_pinned = true;
245 tab3.is_media = true; 191 tab3.is_media = true;
246 tab3.renderer_handle = 12; 192 tab3.renderer_handle = 12;
247 193
248 tab4.is_media = true; 194 tab4.is_media = true;
249 tab4.renderer_handle = 12; 195 tab4.renderer_handle = 12;
250 196
251 tab5.is_app = true; 197 tab5.is_app = true;
252 tab5.renderer_handle = 12; 198 tab5.renderer_handle = 12;
253 TabStatsList tab_list = {tab1, tab2, tab3, tab4, tab5}; 199 TabStatsList tab_list = {tab1, tab2, tab3, tab4, tab5};
254 200
255 // Sorted order: 201 // Sorted order:
256 // app "service" pid: 30 oom_socre_adj: 825 202 // app "focused" pid: 10
257 // app "foreground" pid: 20 oom_score_adj: 650 203 // app "visible1" pid: 20
258 // tab2 pid: 11 oom_socre_adj: 417 204 // app "visible2" pid: 40
259 // tab5 pid: 12 oom_score_adj: 358 205 // tab3 pid: 12
260 // tab1 pid: 11 oom_socre_adj: 417 206 // tab4 pid: 12
261 // tab4 pid: 12 oom_socre_adj: 358 207 // tab1 pid: 11
262 // tab3 pid: 12 oom_score_adj: 358 208 // tab5 pid: 12
263 // app "top" pid: 10 oom_score_adj: 300 209 // tab2 pid: 11
210 // app "service" pid: 30
264 tab_manager_delegate.AdjustOomPrioritiesImpl(tab_list, arc_processes); 211 tab_manager_delegate.AdjustOomPrioritiesImpl(tab_list, arc_processes);
265 auto& oom_score_map = tab_manager_delegate.oom_score_map_; 212 auto& oom_score_map = tab_manager_delegate.oom_score_map_;
266 213
267 EXPECT_EQ(5U, oom_score_map.size()); 214 EXPECT_EQ(6U, oom_score_map.size());
268 215
269 // Higher priority part. 216 // Higher priority part.
270 EXPECT_EQ(300, oom_score_map[10]); 217 EXPECT_EQ(300, oom_score_map[10]);
271 EXPECT_EQ(358, oom_score_map[12]); 218 EXPECT_EQ(344, oom_score_map[20]);
272 EXPECT_EQ(417, oom_score_map[11]); 219 EXPECT_EQ(388, oom_score_map[40]);
220 EXPECT_EQ(431, oom_score_map[12]);
221 EXPECT_EQ(475, oom_score_map[11]);
273 222
274 // Lower priority part. 223 // Lower priority part.
275 EXPECT_EQ(650, oom_score_map[20]); 224 EXPECT_EQ(650, oom_score_map[30]);
276 EXPECT_EQ(825, oom_score_map[30]);
277 } 225 }
278 226
279 TEST_F(TabManagerDelegateTest, KillMultipleProcesses) { 227 TEST_F(TabManagerDelegateTest, KillMultipleProcesses) {
280 arc::FakeArcBridgeService fake_arc_bridge_service; 228 arc::FakeArcBridgeService fake_arc_bridge_service;
281 229
282 // Not owned. 230 // Not owned.
283 MockMemoryStat* memory_stat = new MockMemoryStat(); 231 MockMemoryStat* memory_stat = new MockMemoryStat();
284 232
285 // Instantiate the mock instance. 233 // Instantiate the mock instance.
286 MockTabManagerDelegate tab_manager_delegate(memory_stat); 234 MockTabManagerDelegate tab_manager_delegate(memory_stat);
287 235
288 ActivateArcWindow();
289
290 std::vector<arc::ArcProcess> arc_processes; 236 std::vector<arc::ArcProcess> arc_processes;
291 arc_processes.emplace_back(10001, 100, "top", arc::mojom::ProcessState::TOP); 237 arc_processes.emplace_back(1, 10, "focused", arc::mojom::ProcessState::TOP,
292 arc_processes.emplace_back(10002, 200, "foreground", 238 kIsFocused, 100);
293 arc::mojom::ProcessState::FOREGROUND_SERVICE); 239 arc_processes.emplace_back(2, 20, "visible1", arc::mojom::ProcessState::TOP,
294 arc_processes.emplace_back(10003, 300, "service", 240 kNotFocused, 200);
295 arc::mojom::ProcessState::SERVICE); 241 arc_processes.emplace_back(
242 3, 30, "service", arc::mojom::ProcessState::SERVICE, kNotFocused, 500);
243 arc_processes.emplace_back(4, 40, "visible2", arc::mojom::ProcessState::TOP,
244 kNotFocused, 150);
296 245
297 TabStats tab1, tab2, tab3, tab4, tab5; 246 TabStats tab1, tab2, tab3, tab4, tab5;
298 tab1.is_pinned = true; 247 tab1.is_pinned = true;
299 tab1.renderer_handle = 11; 248 tab1.renderer_handle = 11;
300 tab1.tab_contents_id = 1; 249 tab1.tab_contents_id = 1;
301 250
302 tab2.is_internal_page = true; 251 tab2.is_internal_page = true;
303 tab2.renderer_handle = 11; 252 tab2.renderer_handle = 11;
304 tab2.tab_contents_id = 2; 253 tab2.tab_contents_id = 2;
305 254
306 tab3.is_pinned = true; 255 tab3.is_pinned = true;
307 tab3.is_media = true; 256 tab3.is_media = true;
308 tab3.renderer_handle = 12; 257 tab3.renderer_handle = 12;
309 tab3.tab_contents_id = 3; 258 tab3.tab_contents_id = 3;
310 259
311 tab4.is_media = true; 260 tab4.is_media = true;
312 tab4.renderer_handle = 12; 261 tab4.renderer_handle = 12;
313 tab4.tab_contents_id = 4; 262 tab4.tab_contents_id = 4;
314 263
315 tab5.is_app = true; 264 tab5.is_app = true;
316 tab5.renderer_handle = 12; 265 tab5.renderer_handle = 12;
317 tab5.tab_contents_id = 5; 266 tab5.tab_contents_id = 5;
318 TabStatsList tab_list = {tab1, tab2, tab3, tab4, tab5}; 267 TabStatsList tab_list = {tab1, tab2, tab3, tab4, tab5};
319 268
320 // Sorted order: 269 // Sorted order:
321 // app "service" pid: 30 270 // app "focused" pid: 10 nspid 1
322 // app "foreground" pid: 20 271 // app "visible1" pid: 20 nspid 2
323 // tab2 pid: 11 272 // app "visible2" pid: 40 nspid 4
324 // tab5 pid: 12 273 // tab3 pid: 12 tab_contents_id 3
325 // tab1 pid: 11 274 // tab4 pid: 12 tab_contents_id 4
326 // tab4 pid: 12 275 // tab1 pid: 11 tab_contents_id 1
327 // tab3 pid: 12 276 // tab5 pid: 12 tab_contents_id 5
328 // app "top" pid: 10 277 // tab2 pid: 11 tab_contents_id 2
278 // app "service" pid: 30 nspid 3
329 memory_stat->SetTargetMemoryToFreeKB(250000); 279 memory_stat->SetTargetMemoryToFreeKB(250000);
330 // The 3 entities to be killed. 280 // Entities to be killed.
331 memory_stat->SetProcessPss(300, 10000); 281 memory_stat->SetProcessPss(30, 10000);
332 memory_stat->SetProcessPss(200, 200000); 282 memory_stat->SetProcessPss(11, 200000);
333 memory_stat->SetProcessPss(11, 50000); 283 memory_stat->SetProcessPss(12, 30000);
334 // Should not be used. 284 // Should not be used.
335 memory_stat->SetProcessPss(100, 30000); 285 memory_stat->SetProcessPss(40, 50000);
336 memory_stat->SetProcessPss(12, 100000); 286 memory_stat->SetProcessPss(20, 30000);
287 memory_stat->SetProcessPss(10, 100000);
337 288
338 tab_manager_delegate.LowMemoryKillImpl(tab_list, arc_processes); 289 tab_manager_delegate.LowMemoryKillImpl(tab_list, arc_processes);
339 290
340 auto killed_arc_processes = tab_manager_delegate.GetKilledArcProcesses(); 291 auto killed_arc_processes = tab_manager_delegate.GetKilledArcProcesses();
341 auto killed_tabs = tab_manager_delegate.GetKilledTabs(); 292 auto killed_tabs = tab_manager_delegate.GetKilledTabs();
342 293
343 EXPECT_EQ(2U, killed_arc_processes.size()); 294 // Killed apps and their nspid.
344 EXPECT_EQ(1U, killed_tabs.size()); 295 EXPECT_EQ(1U, killed_arc_processes.size());
345 296 EXPECT_EQ(3, killed_arc_processes[0]);
346 // nspid. 297 // Killed tabs and their content id.
347 EXPECT_EQ(10003, killed_arc_processes[0]); 298 // 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]); 299 // good way to estimate the memory freed if multiple tabs share one process.
349 // tab content id. 300 EXPECT_EQ(3U, killed_tabs.size());
350 EXPECT_EQ(2, killed_tabs[0]); 301 EXPECT_EQ(2, killed_tabs[0]);
302 EXPECT_EQ(5, killed_tabs[1]);
303 EXPECT_EQ(1, killed_tabs[2]);
351 } 304 }
352 305
353 } // namespace memory 306 } // namespace memory
OLDNEW
« no previous file with comments | « chrome/browser/memory/tab_manager_delegate_chromeos.cc ('k') | components/arc/common/process.mojom » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698