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

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

Issue 2898033002: [TabManager] Move TabManager into chrome/browser/resource_coordinator. (Closed)
Patch Set: rebase Created 3 years, 6 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "base/base_switches.h"
6 #include "base/command_line.h"
7 #include "base/memory/memory_pressure_listener.h"
8 #include "base/test/simple_test_tick_clock.h"
9 #include "build/build_config.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
12 #include "chrome/browser/media/webrtc/media_stream_capture_indicator.h"
13 #include "chrome/browser/memory/tab_manager.h"
14 #include "chrome/browser/memory/tab_manager_web_contents_data.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/browser_commands.h"
17 #include "chrome/browser/ui/find_bar/find_bar_controller.h"
18 #include "chrome/browser/ui/tabs/tab_strip_model.h"
19 #include "chrome/common/chrome_features.h"
20 #include "chrome/common/url_constants.h"
21 #include "chrome/test/base/in_process_browser_test.h"
22 #include "chrome/test/base/interactive_test_utils.h"
23 #include "content/public/browser/navigation_details.h"
24 #include "content/public/browser/navigation_entry.h"
25 #include "content/public/browser/notification_service.h"
26 #include "content/public/browser/notification_types.h"
27 #include "content/public/browser/render_process_host.h"
28 #include "content/public/common/content_switches.h"
29 #include "content/public/test/test_utils.h"
30 #include "url/gurl.h"
31
32 using content::OpenURLParams;
33
34 #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
35
36 namespace memory {
37
38 class TabManagerTest : public InProcessBrowserTest {
39 };
40
41 bool ObserveNavEntryCommitted(const GURL& expected_url,
42 const content::NotificationSource& source,
43 const content::NotificationDetails& details) {
44 return content::Details<content::LoadCommittedDetails>(details)
45 ->entry->GetURL() == expected_url;
46 }
47
48 IN_PROC_BROWSER_TEST_F(TabManagerTest, TabManagerBasics) {
49 using content::WindowedNotificationObserver;
50 TabManager* tab_manager = g_browser_process->GetTabManager();
51 EXPECT_FALSE(tab_manager->recent_tab_discard());
52
53 // Disable the protection of recent tabs.
54 tab_manager->set_minimum_protection_time_for_tests(
55 base::TimeDelta::FromMinutes(0));
56
57 // Get three tabs open.
58 WindowedNotificationObserver load1(
59 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
60 content::NotificationService::AllSources());
61 OpenURLParams open1(GURL(chrome::kChromeUIAboutURL), content::Referrer(),
62 WindowOpenDisposition::CURRENT_TAB,
63 ui::PAGE_TRANSITION_TYPED, false);
64 browser()->OpenURL(open1);
65 load1.Wait();
66
67 WindowedNotificationObserver load2(
68 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
69 content::NotificationService::AllSources());
70 OpenURLParams open2(GURL(chrome::kChromeUICreditsURL), content::Referrer(),
71 WindowOpenDisposition::NEW_FOREGROUND_TAB,
72 ui::PAGE_TRANSITION_TYPED, false);
73 browser()->OpenURL(open2);
74 load2.Wait();
75
76 WindowedNotificationObserver load3(
77 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
78 content::NotificationService::AllSources());
79 OpenURLParams open3(GURL(chrome::kChromeUITermsURL), content::Referrer(),
80 WindowOpenDisposition::NEW_FOREGROUND_TAB,
81 ui::PAGE_TRANSITION_TYPED, false);
82 browser()->OpenURL(open3);
83 load3.Wait();
84
85 auto* tsm = browser()->tab_strip_model();
86 EXPECT_EQ(3, tsm->count());
87
88 // Navigate the current (third) tab to a different URL, so we can test
89 // back/forward later.
90 WindowedNotificationObserver load4(
91 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
92 content::NotificationService::AllSources());
93 OpenURLParams open4(GURL(chrome::kChromeUIVersionURL), content::Referrer(),
94 WindowOpenDisposition::CURRENT_TAB,
95 ui::PAGE_TRANSITION_TYPED, false);
96 browser()->OpenURL(open4);
97 load4.Wait();
98
99 // Navigate the third tab again, such that we have three navigation entries.
100 WindowedNotificationObserver load5(
101 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
102 content::NotificationService::AllSources());
103 OpenURLParams open5(GURL("chrome://dns"), content::Referrer(),
104 WindowOpenDisposition::CURRENT_TAB,
105 ui::PAGE_TRANSITION_TYPED, false);
106 browser()->OpenURL(open5);
107 load5.Wait();
108
109 EXPECT_EQ(3, tsm->count());
110
111 // Discard a tab. It should kill the first tab, since it was the oldest
112 // and was not selected.
113 EXPECT_TRUE(tab_manager->DiscardTabImpl());
114 EXPECT_EQ(3, tsm->count());
115 EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(0)));
116 EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(1)));
117 EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(2)));
118 EXPECT_TRUE(tab_manager->recent_tab_discard());
119
120 // Run discard again, make sure it kills the second tab.
121 EXPECT_TRUE(tab_manager->DiscardTabImpl());
122 EXPECT_EQ(3, tsm->count());
123 EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(0)));
124 EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(1)));
125 EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(2)));
126
127 // Kill the third tab. It should not kill the last tab, since it is active
128 // tab.
129 EXPECT_FALSE(tab_manager->DiscardTabImpl());
130 EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(0)));
131 EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(1)));
132 EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(2)));
133
134 // Kill the third tab after making second tab active.
135 tsm->ActivateTabAt(1, true);
136 EXPECT_EQ(1, tsm->active_index());
137 EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(1)));
138 tab_manager->DiscardWebContentsAt(2, tsm);
139 EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(2)));
140
141 // Force creation of the FindBarController.
142 browser()->GetFindBarController();
143
144 // Select the first tab. It should reload.
145 WindowedNotificationObserver reload1(
146 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
147 base::Bind(&ObserveNavEntryCommitted,
148 GURL(chrome::kChromeUIChromeURLsURL)));
149 chrome::SelectNumberedTab(browser(), 0);
150 reload1.Wait();
151 // Make sure the FindBarController gets the right WebContents.
152 EXPECT_EQ(browser()->GetFindBarController()->web_contents(),
153 tsm->GetActiveWebContents());
154 EXPECT_EQ(0, tsm->active_index());
155 EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(0)));
156 EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(1)));
157 EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(2)));
158
159 // Select the third tab. It should reload.
160 WindowedNotificationObserver reload2(
161 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
162 base::Bind(&ObserveNavEntryCommitted, GURL("chrome://dns")));
163 chrome::SelectNumberedTab(browser(), 2);
164 reload2.Wait();
165 EXPECT_EQ(2, tsm->active_index());
166 EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(0)));
167 EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(1)));
168 EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(2)));
169
170 // Navigate the third tab back twice. We used to crash here due to
171 // crbug.com/121373.
172 EXPECT_TRUE(chrome::CanGoBack(browser()));
173 EXPECT_FALSE(chrome::CanGoForward(browser()));
174 WindowedNotificationObserver back1(
175 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
176 base::Bind(&ObserveNavEntryCommitted, GURL(chrome::kChromeUIVersionURL)));
177 chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB);
178 back1.Wait();
179 EXPECT_TRUE(chrome::CanGoBack(browser()));
180 EXPECT_TRUE(chrome::CanGoForward(browser()));
181 WindowedNotificationObserver back2(
182 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
183 base::Bind(&ObserveNavEntryCommitted, GURL(chrome::kChromeUITermsURL)));
184 chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB);
185 back2.Wait();
186 EXPECT_FALSE(chrome::CanGoBack(browser()));
187 EXPECT_TRUE(chrome::CanGoForward(browser()));
188 }
189
190 // On Linux, memory pressure listener is not implemented yet.
191 #if defined(OS_WIN) || defined(OS_MACOSX)
192
193 // Test that the MemoryPressureListener event is properly triggering a tab
194 // discard upon |MEMORY_PRESSURE_LEVEL_CRITICAL| event.
195 IN_PROC_BROWSER_TEST_F(TabManagerTest, OomPressureListener) {
196 TabManager* tab_manager = g_browser_process->GetTabManager();
197
198 // Disable the protection of recent tabs.
199 tab_manager->set_minimum_protection_time_for_tests(
200 base::TimeDelta::FromMinutes(0));
201
202 // Get three tabs open.
203 content::WindowedNotificationObserver load1(
204 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
205 content::NotificationService::AllSources());
206 OpenURLParams open1(GURL(chrome::kChromeUIAboutURL), content::Referrer(),
207 WindowOpenDisposition::CURRENT_TAB,
208 ui::PAGE_TRANSITION_TYPED, false);
209 browser()->OpenURL(open1);
210 load1.Wait();
211
212 content::WindowedNotificationObserver load2(
213 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
214 content::NotificationService::AllSources());
215 OpenURLParams open2(GURL(chrome::kChromeUICreditsURL), content::Referrer(),
216 WindowOpenDisposition::NEW_FOREGROUND_TAB,
217 ui::PAGE_TRANSITION_TYPED, false);
218 browser()->OpenURL(open2);
219 load2.Wait();
220 EXPECT_FALSE(tab_manager->recent_tab_discard());
221
222 // Nothing should happen with a moderate memory pressure event.
223 base::MemoryPressureListener::NotifyMemoryPressure(
224 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
225 EXPECT_FALSE(tab_manager->recent_tab_discard());
226
227 // A critical memory pressure event should discard a tab.
228 base::MemoryPressureListener::NotifyMemoryPressure(
229 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
230 // Coming here, an asynchronous operation will collect system stats. Once in,
231 // a tab should get discarded. As such we need to give it 10s time to discard.
232 const int kTimeoutTimeInMS = 10000;
233 const int kIntervalTimeInMS = 5;
234 int timeout = kTimeoutTimeInMS / kIntervalTimeInMS;
235 while (--timeout) {
236 base::PlatformThread::Sleep(
237 base::TimeDelta::FromMilliseconds(kIntervalTimeInMS));
238 base::RunLoop().RunUntilIdle();
239 if (tab_manager->recent_tab_discard())
240 break;
241 }
242 EXPECT_TRUE(tab_manager->recent_tab_discard());
243 }
244
245 #endif
246
247 IN_PROC_BROWSER_TEST_F(TabManagerTest, InvalidOrEmptyURL) {
248 TabManager* tab_manager = g_browser_process->GetTabManager();
249
250 // Disable the protection of recent tabs.
251 tab_manager->set_minimum_protection_time_for_tests(
252 base::TimeDelta::FromMinutes(0));
253
254 // Open two tabs. Wait for the foreground one to load but do not wait for the
255 // background one.
256 content::WindowedNotificationObserver load1(
257 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
258 content::NotificationService::AllSources());
259 OpenURLParams open1(GURL(chrome::kChromeUIAboutURL), content::Referrer(),
260 WindowOpenDisposition::CURRENT_TAB,
261 ui::PAGE_TRANSITION_TYPED, false);
262 browser()->OpenURL(open1);
263 load1.Wait();
264
265 content::WindowedNotificationObserver load2(
266 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
267 content::NotificationService::AllSources());
268 OpenURLParams open2(GURL(chrome::kChromeUICreditsURL), content::Referrer(),
269 WindowOpenDisposition::NEW_BACKGROUND_TAB,
270 ui::PAGE_TRANSITION_TYPED, false);
271 browser()->OpenURL(open2);
272
273 ASSERT_EQ(2, browser()->tab_strip_model()->count());
274
275 // This shouldn't be able to discard a tab as the background tab has not yet
276 // started loading (its URL is not committed).
277 EXPECT_FALSE(tab_manager->DiscardTabImpl());
278
279 // Wait for the background tab to load which then allows it to be discarded.
280 load2.Wait();
281 EXPECT_TRUE(tab_manager->DiscardTabImpl());
282 }
283
284 // Makes sure that PDF pages are protected.
285 IN_PROC_BROWSER_TEST_F(TabManagerTest, ProtectPDFPages) {
286 TabManager* tab_manager = g_browser_process->GetTabManager();
287
288 // Start the embedded test server so we can get served the required PDF page.
289 ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
290 embedded_test_server()->StartAcceptingConnections();
291
292 // Get two tabs open, the first one being a PDF page and the second one being
293 // the foreground tab.
294 GURL url1 = embedded_test_server()->GetURL("/pdf/test.pdf");
295 ui_test_utils::NavigateToURL(browser(), url1);
296
297 GURL url2(chrome::kChromeUIAboutURL);
298 ui_test_utils::NavigateToURLWithDisposition(
299 browser(), url2, WindowOpenDisposition::NEW_FOREGROUND_TAB,
300 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
301
302 // No discarding should be possible as the only background tab is displaying a
303 // PDF page, hence protected.
304 EXPECT_FALSE(tab_manager->DiscardTabImpl());
305 }
306
307 // Makes sure that recently opened or used tabs are protected, depending on the
308 // value of of |minimum_protection_time_|.
309 // TODO(georgesak): Move this to a unit test instead (requires change to API).
310 IN_PROC_BROWSER_TEST_F(TabManagerTest, ProtectRecentlyUsedTabs) {
311 // TODO(georgesak): Retrieve this value from tab_manager.h once it becomes a
312 // constant (as of now, it gets set through variations).
313 const int kProtectionTime = 5;
314 TabManager* tab_manager = g_browser_process->GetTabManager();
315
316 base::SimpleTestTickClock test_clock_;
317 tab_manager->set_test_tick_clock(&test_clock_);
318
319 auto* tsm = browser()->tab_strip_model();
320
321 // Set the minimum time of protection.
322 tab_manager->set_minimum_protection_time_for_tests(
323 base::TimeDelta::FromMinutes(kProtectionTime));
324
325 // Open 2 tabs, the second one being in the background.
326 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIAboutURL));
327 ui_test_utils::NavigateToURLWithDisposition(
328 browser(), GURL(chrome::kChromeUIAboutURL),
329 WindowOpenDisposition::NEW_BACKGROUND_TAB,
330 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
331 EXPECT_EQ(2, tsm->count());
332
333 // Advance the clock for less than the protection time.
334 test_clock_.Advance(base::TimeDelta::FromMinutes(kProtectionTime / 2));
335
336 // Should not be able to discard a tab.
337 ASSERT_FALSE(tab_manager->DiscardTabImpl());
338
339 // Advance the clock for more than the protection time.
340 test_clock_.Advance(base::TimeDelta::FromMinutes(kProtectionTime / 2 + 2));
341
342 // Should be able to discard the background tab now.
343 EXPECT_TRUE(tab_manager->DiscardTabImpl());
344
345 // Activate the 2nd tab.
346 tsm->ActivateTabAt(1, true);
347 EXPECT_EQ(1, tsm->active_index());
348
349 // Advance the clock for less than the protection time.
350 test_clock_.Advance(base::TimeDelta::FromMinutes(kProtectionTime / 2));
351
352 // Should not be able to discard a tab.
353 ASSERT_FALSE(tab_manager->DiscardTabImpl());
354
355 // Advance the clock for more than the protection time.
356 test_clock_.Advance(base::TimeDelta::FromMinutes(kProtectionTime / 2 + 2));
357
358 // Should be able to discard the background tab now.
359 EXPECT_TRUE(tab_manager->DiscardTabImpl());
360
361 // This is necessary otherwise the test crashes in
362 // WebContentsData::WebContentsDestroyed.
363 tsm->CloseAllTabs();
364 }
365
366 // Makes sure that tabs using media devices are protected.
367 IN_PROC_BROWSER_TEST_F(TabManagerTest, ProtectVideoTabs) {
368 TabManager* tab_manager = g_browser_process->GetTabManager();
369
370 // Disable the protection of recent tabs.
371 tab_manager->set_minimum_protection_time_for_tests(
372 base::TimeDelta::FromMinutes(0));
373
374 // Open 2 tabs, the second one being in the background.
375 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIAboutURL));
376 ui_test_utils::NavigateToURLWithDisposition(
377 browser(), GURL(chrome::kChromeUIAboutURL),
378 WindowOpenDisposition::NEW_BACKGROUND_TAB,
379 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
380
381 auto* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
382
383 // Simulate that a video stream is now being captured.
384 content::MediaStreamDevice fake_media_device(
385 content::MEDIA_DEVICE_VIDEO_CAPTURE, "fake_media_device",
386 "fake_media_device");
387 content::MediaStreamDevices video_devices(1, fake_media_device);
388 MediaCaptureDevicesDispatcher* dispatcher =
389 MediaCaptureDevicesDispatcher::GetInstance();
390 dispatcher->SetTestVideoCaptureDevices(video_devices);
391 std::unique_ptr<content::MediaStreamUI> video_stream_ui =
392 dispatcher->GetMediaStreamCaptureIndicator()->RegisterMediaStream(
393 tab, video_devices);
394 video_stream_ui->OnStarted(base::Closure());
395
396 // Should not be able to discard a tab.
397 ASSERT_FALSE(tab_manager->DiscardTabImpl());
398
399 // Remove the video stream.
400 video_stream_ui.reset();
401
402 // Should be able to discard the background tab now.
403 EXPECT_TRUE(tab_manager->DiscardTabImpl());
404 }
405
406 IN_PROC_BROWSER_TEST_F(TabManagerTest, CanSuspendBackgroundedRenderer) {
407 TabManager* tab_manager = g_browser_process->GetTabManager();
408
409 // Open 2 tabs, the second one being in the background.
410 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIAboutURL));
411 ui_test_utils::NavigateToURLWithDisposition(
412 browser(), GURL(chrome::kChromeUIAboutURL),
413 WindowOpenDisposition::NEW_BACKGROUND_TAB,
414 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
415
416 auto* tab = browser()->tab_strip_model()->GetWebContentsAt(1);
417 // Simulate that a video stream is now being captured.
418 content::MediaStreamDevice fake_media_device(
419 content::MEDIA_DEVICE_VIDEO_CAPTURE, "fake_media_device",
420 "fake_media_device");
421 content::MediaStreamDevices video_devices(1, fake_media_device);
422 MediaCaptureDevicesDispatcher* dispatcher =
423 MediaCaptureDevicesDispatcher::GetInstance();
424 dispatcher->SetTestVideoCaptureDevices(video_devices);
425 std::unique_ptr<content::MediaStreamUI> video_stream_ui =
426 dispatcher->GetMediaStreamCaptureIndicator()->RegisterMediaStream(
427 tab, video_devices);
428 video_stream_ui->OnStarted(base::Closure());
429
430 // Should not be able to suspend a tab which plays a video.
431 int render_process_id = tab->GetRenderProcessHost()->GetID();
432 ASSERT_FALSE(tab_manager->CanSuspendBackgroundedRenderer(render_process_id));
433
434 // Remove the video stream.
435 video_stream_ui.reset();
436
437 // Should be able to suspend the background tab now.
438 EXPECT_TRUE(tab_manager->CanSuspendBackgroundedRenderer(render_process_id));
439 }
440
441 IN_PROC_BROWSER_TEST_F(TabManagerTest, AutoDiscardable) {
442 using content::WindowedNotificationObserver;
443 TabManager* tab_manager = g_browser_process->GetTabManager();
444
445 // Disable the protection of recent tabs.
446 tab_manager->set_minimum_protection_time_for_tests(
447 base::TimeDelta::FromMinutes(0));
448
449 // Get two tabs open.
450 WindowedNotificationObserver load1(
451 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
452 content::NotificationService::AllSources());
453 OpenURLParams open1(GURL(chrome::kChromeUIAboutURL), content::Referrer(),
454 WindowOpenDisposition::CURRENT_TAB,
455 ui::PAGE_TRANSITION_TYPED, false);
456 browser()->OpenURL(open1);
457 load1.Wait();
458
459 WindowedNotificationObserver load2(
460 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
461 content::NotificationService::AllSources());
462 OpenURLParams open2(GURL(chrome::kChromeUICreditsURL), content::Referrer(),
463 WindowOpenDisposition::NEW_FOREGROUND_TAB,
464 ui::PAGE_TRANSITION_TYPED, false);
465 browser()->OpenURL(open2);
466 load2.Wait();
467
468 // Set the auto-discardable state of the first tab to false.
469 auto* tsm = browser()->tab_strip_model();
470 ASSERT_EQ(2, tsm->count());
471 tab_manager->SetTabAutoDiscardableState(tsm->GetWebContentsAt(0), false);
472
473 // Shouldn't discard the tab, since auto-discardable is deactivated.
474 EXPECT_FALSE(tab_manager->DiscardTabImpl());
475
476 // Reset auto-discardable state to true.
477 tab_manager->SetTabAutoDiscardableState(tsm->GetWebContentsAt(0), true);
478
479 // Now it should be able to discard the tab.
480 EXPECT_TRUE(tab_manager->DiscardTabImpl());
481 EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(0)));
482 }
483
484 IN_PROC_BROWSER_TEST_F(TabManagerTest, PurgeBackgroundRenderer) {
485 TabManager* tab_manager = g_browser_process->GetTabManager();
486
487 base::SimpleTestTickClock test_clock_;
488 tab_manager->set_test_tick_clock(&test_clock_);
489
490 // Get three tabs open.
491 content::WindowedNotificationObserver load1(
492 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
493 content::NotificationService::AllSources());
494 OpenURLParams open1(GURL(chrome::kChromeUIAboutURL), content::Referrer(),
495 WindowOpenDisposition::CURRENT_TAB,
496 ui::PAGE_TRANSITION_TYPED, false);
497 browser()->OpenURL(open1);
498 load1.Wait();
499
500 content::WindowedNotificationObserver load2(
501 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
502 content::NotificationService::AllSources());
503 OpenURLParams open2(GURL(chrome::kChromeUICreditsURL), content::Referrer(),
504 WindowOpenDisposition::NEW_FOREGROUND_TAB,
505 ui::PAGE_TRANSITION_TYPED, false);
506 browser()->OpenURL(open2);
507 load2.Wait();
508
509 content::WindowedNotificationObserver load3(
510 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
511 content::NotificationService::AllSources());
512 OpenURLParams open3(GURL(chrome::kChromeUITermsURL), content::Referrer(),
513 WindowOpenDisposition::NEW_FOREGROUND_TAB,
514 ui::PAGE_TRANSITION_TYPED, false);
515 browser()->OpenURL(open3);
516 load3.Wait();
517
518 auto* tsm = browser()->tab_strip_model();
519 TabManager::WebContentsData* tab1_contents_data =
520 tab_manager->GetWebContentsData(tsm->GetWebContentsAt(0));
521 TabManager::WebContentsData* tab2_contents_data =
522 tab_manager->GetWebContentsData(tsm->GetWebContentsAt(1));
523 TabManager::WebContentsData* tab3_contents_data =
524 tab_manager->GetWebContentsData(tsm->GetWebContentsAt(2));
525
526 // The time-to-purge initialized at ActiveTabChanged should be in the
527 // right default range.
528 EXPECT_GE(tab1_contents_data->time_to_purge(),
529 base::TimeDelta::FromMinutes(30));
530 EXPECT_LT(tab1_contents_data->time_to_purge(),
531 base::TimeDelta::FromMinutes(60));
532 EXPECT_GE(tab2_contents_data->time_to_purge(),
533 base::TimeDelta::FromMinutes(30));
534 EXPECT_LT(tab2_contents_data->time_to_purge(),
535 base::TimeDelta::FromMinutes(60));
536 EXPECT_GE(tab3_contents_data->time_to_purge(),
537 base::TimeDelta::FromMinutes(30));
538 EXPECT_LT(tab3_contents_data->time_to_purge(),
539 base::TimeDelta::FromMinutes(60));
540
541 // To make it easy to test, configure time-to-purge here.
542 base::TimeDelta time_to_purge1 = base::TimeDelta::FromMinutes(30);
543 base::TimeDelta time_to_purge2 = base::TimeDelta::FromMinutes(40);
544 tab1_contents_data->set_time_to_purge(time_to_purge1);
545 tab2_contents_data->set_time_to_purge(time_to_purge2);
546 tab3_contents_data->set_time_to_purge(time_to_purge1);
547
548 // No tabs are not purged yet.
549 ASSERT_FALSE(tab1_contents_data->is_purged());
550 ASSERT_FALSE(tab2_contents_data->is_purged());
551 ASSERT_FALSE(tab3_contents_data->is_purged());
552
553 // Advance the clock for time_to_purge1.
554 test_clock_.Advance(time_to_purge1);
555 tab_manager->PurgeBackgroundedTabsIfNeeded();
556
557 ASSERT_FALSE(tab1_contents_data->is_purged());
558 ASSERT_FALSE(tab2_contents_data->is_purged());
559 ASSERT_FALSE(tab3_contents_data->is_purged());
560
561 // Advance the clock for 1 minutes.
562 test_clock_.Advance(base::TimeDelta::FromMinutes(1));
563 tab_manager->PurgeBackgroundedTabsIfNeeded();
564
565 // Since tab1 is kept inactive and background for more than
566 // time_to_purge1, tab1 should be purged.
567 ASSERT_TRUE(tab1_contents_data->is_purged());
568 ASSERT_FALSE(tab2_contents_data->is_purged());
569 ASSERT_FALSE(tab3_contents_data->is_purged());
570
571 // Advance the clock.
572 test_clock_.Advance(time_to_purge2 - time_to_purge1);
573 tab_manager->PurgeBackgroundedTabsIfNeeded();
574
575 // Since tab2 is kept inactive and background for more than
576 // time_to_purge2, tab1 should be purged.
577 // Since tab3 is active, tab3 should not be purged.
578 ASSERT_TRUE(tab1_contents_data->is_purged());
579 ASSERT_TRUE(tab2_contents_data->is_purged());
580 ASSERT_FALSE(tab3_contents_data->is_purged());
581
582 tsm->CloseAllTabs();
583 }
584
585 } // namespace memory
586
587 #endif // OS_WIN || OS_MAXOSX || OS_LINUX
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698