| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "content/browser/memory/memory_coordinator_impl.h" | 5 #include "content/browser/memory/memory_coordinator_impl.h" |
| 6 | 6 |
| 7 #include "base/memory/memory_coordinator_client_registry.h" | 7 #include "base/memory/memory_coordinator_client_registry.h" |
| 8 #include "base/memory/memory_coordinator_proxy.h" | 8 #include "base/memory/memory_coordinator_proxy.h" |
| 9 #include "base/memory/memory_pressure_monitor.h" | 9 #include "base/memory/memory_pressure_monitor.h" |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 RunUntilIdle(); | 294 RunUntilIdle(); |
| 295 EXPECT_EQ(mojom::MemoryState::NORMAL, child->state()); | 295 EXPECT_EQ(mojom::MemoryState::NORMAL, child->state()); |
| 296 coordinator_->policy_->OnChildVisibilityChanged(1, false); | 296 coordinator_->policy_->OnChildVisibilityChanged(1, false); |
| 297 RunUntilIdle(); | 297 RunUntilIdle(); |
| 298 #if defined(OS_ANDROID) | 298 #if defined(OS_ANDROID) |
| 299 EXPECT_EQ(mojom::MemoryState::THROTTLED, child->state()); | 299 EXPECT_EQ(mojom::MemoryState::THROTTLED, child->state()); |
| 300 #else | 300 #else |
| 301 EXPECT_EQ(mojom::MemoryState::NORMAL, child->state()); | 301 EXPECT_EQ(mojom::MemoryState::NORMAL, child->state()); |
| 302 #endif | 302 #endif |
| 303 | 303 |
| 304 coordinator_->memory_condition_ = MemoryCondition::WARNING; | |
| 305 coordinator_->policy_->OnChildVisibilityChanged(1, true); | |
| 306 RunUntilIdle(); | |
| 307 EXPECT_EQ(mojom::MemoryState::NORMAL, child->state()); | |
| 308 coordinator_->policy_->OnChildVisibilityChanged(1, false); | |
| 309 RunUntilIdle(); | |
| 310 EXPECT_EQ(mojom::MemoryState::THROTTLED, child->state()); | |
| 311 | |
| 312 coordinator_->memory_condition_ = MemoryCondition::CRITICAL; | 304 coordinator_->memory_condition_ = MemoryCondition::CRITICAL; |
| 313 coordinator_->policy_->OnChildVisibilityChanged(1, true); | 305 coordinator_->policy_->OnChildVisibilityChanged(1, true); |
| 314 RunUntilIdle(); | 306 RunUntilIdle(); |
| 315 EXPECT_EQ(mojom::MemoryState::THROTTLED, child->state()); | 307 EXPECT_EQ(mojom::MemoryState::THROTTLED, child->state()); |
| 316 coordinator_->policy_->OnChildVisibilityChanged(1, false); | 308 coordinator_->policy_->OnChildVisibilityChanged(1, false); |
| 317 RunUntilIdle(); | 309 RunUntilIdle(); |
| 318 EXPECT_EQ(mojom::MemoryState::THROTTLED, child->state()); | 310 EXPECT_EQ(mojom::MemoryState::THROTTLED, child->state()); |
| 319 } | 311 } |
| 320 | 312 |
| 321 TEST_F(MemoryCoordinatorImplTest, CalculateNextCondition) { | 313 TEST_F(MemoryCoordinatorImplTest, CalculateNextCondition) { |
| 322 auto* condition_observer = coordinator_->condition_observer_.get(); | 314 auto* condition_observer = coordinator_->condition_observer_.get(); |
| 323 condition_observer->expected_renderer_size_ = 10; | |
| 324 condition_observer->new_renderers_until_warning_ = 4; | |
| 325 condition_observer->new_renderers_until_critical_ = 2; | |
| 326 condition_observer->new_renderers_back_to_normal_ = 5; | |
| 327 condition_observer->new_renderers_back_to_warning_ = 3; | |
| 328 DCHECK(condition_observer->ValidateParameters()); | |
| 329 | 315 |
| 330 // The default condition is NORMAL. | 316 // The default condition is NORMAL. |
| 331 EXPECT_EQ(MemoryCondition::NORMAL, coordinator_->GetMemoryCondition()); | 317 EXPECT_EQ(MemoryCondition::NORMAL, coordinator_->GetMemoryCondition()); |
| 332 | 318 |
| 333 // Transitions from NORMAL | 319 // Transitions from NORMAL |
| 334 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(50); | 320 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(1000); |
| 335 EXPECT_EQ(MemoryCondition::NORMAL, | 321 EXPECT_EQ(MemoryCondition::NORMAL, |
| 336 condition_observer->CalculateNextCondition()); | 322 condition_observer->CalculateNextCondition()); |
| 337 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(40); | 323 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(0); |
| 338 EXPECT_EQ(MemoryCondition::WARNING, | |
| 339 condition_observer->CalculateNextCondition()); | |
| 340 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(20); | |
| 341 EXPECT_EQ(MemoryCondition::CRITICAL, | |
| 342 condition_observer->CalculateNextCondition()); | |
| 343 | |
| 344 // Transitions from WARNING | |
| 345 coordinator_->memory_condition_ = MemoryCondition::WARNING; | |
| 346 EXPECT_EQ(MemoryCondition::WARNING, coordinator_->GetMemoryCondition()); | |
| 347 | |
| 348 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(40); | |
| 349 EXPECT_EQ(MemoryCondition::WARNING, | |
| 350 condition_observer->CalculateNextCondition()); | |
| 351 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(50); | |
| 352 EXPECT_EQ(MemoryCondition::NORMAL, | |
| 353 condition_observer->CalculateNextCondition()); | |
| 354 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(20); | |
| 355 EXPECT_EQ(MemoryCondition::CRITICAL, | 324 EXPECT_EQ(MemoryCondition::CRITICAL, |
| 356 condition_observer->CalculateNextCondition()); | 325 condition_observer->CalculateNextCondition()); |
| 357 | 326 |
| 358 // Transitions from CRITICAL | 327 // Transitions from CRITICAL |
| 359 coordinator_->memory_condition_ = MemoryCondition::CRITICAL; | 328 coordinator_->memory_condition_ = MemoryCondition::CRITICAL; |
| 360 EXPECT_EQ(MemoryCondition::CRITICAL, coordinator_->GetMemoryCondition()); | 329 EXPECT_EQ(MemoryCondition::CRITICAL, coordinator_->GetMemoryCondition()); |
| 361 | 330 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(1000); |
| 362 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(20); | |
| 363 EXPECT_EQ(MemoryCondition::CRITICAL, | |
| 364 condition_observer->CalculateNextCondition()); | |
| 365 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(30); | |
| 366 EXPECT_EQ(MemoryCondition::WARNING, | |
| 367 condition_observer->CalculateNextCondition()); | |
| 368 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(50); | |
| 369 EXPECT_EQ(MemoryCondition::NORMAL, | 331 EXPECT_EQ(MemoryCondition::NORMAL, |
| 370 condition_observer->CalculateNextCondition()); | 332 condition_observer->CalculateNextCondition()); |
| 371 } | 333 } |
| 372 | 334 |
| 373 TEST_F(MemoryCoordinatorImplTest, UpdateCondition) { | 335 TEST_F(MemoryCoordinatorImplTest, UpdateCondition) { |
| 374 auto* condition_observer = coordinator_->condition_observer_.get(); | 336 auto* condition_observer = coordinator_->condition_observer_.get(); |
| 375 condition_observer->expected_renderer_size_ = 10; | |
| 376 condition_observer->new_renderers_until_warning_ = 4; | |
| 377 condition_observer->new_renderers_until_critical_ = 2; | |
| 378 condition_observer->new_renderers_back_to_normal_ = 5; | |
| 379 condition_observer->new_renderers_back_to_warning_ = 3; | |
| 380 DCHECK(condition_observer->ValidateParameters()); | |
| 381 | 337 |
| 382 auto* foreground_child = coordinator_->CreateChildMemoryCoordinator(1); | 338 auto* foreground_child = coordinator_->CreateChildMemoryCoordinator(1); |
| 383 auto* background_child = coordinator_->CreateChildMemoryCoordinator(2); | 339 auto* background_child = coordinator_->CreateChildMemoryCoordinator(2); |
| 384 auto iter = coordinator_->children().find(2); | 340 auto iter = coordinator_->children().find(2); |
| 385 iter->second.is_visible = false; | 341 iter->second.is_visible = false; |
| 386 | 342 |
| 387 { | 343 { |
| 388 // Transition happens (NORMAL -> WARNING). | 344 // Transition happens (NORMAL -> CRITICAL). |
| 389 // Foreground processes should remain NORMAL state but background processes | 345 // All processes should be in THROTTLED memory state. |
| 390 // should become THROTTLED state. | |
| 391 MockMemoryCoordinatorClient client; | 346 MockMemoryCoordinatorClient client; |
| 392 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(&client); | 347 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(&client); |
| 393 coordinator_->memory_condition_ = MemoryCondition::NORMAL; | 348 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(0); |
| 394 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(40); | |
| 395 condition_observer->UpdateCondition(); | 349 condition_observer->UpdateCondition(); |
| 396 task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(40)); | 350 task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(40)); |
| 397 RunUntilIdle(); | 351 RunUntilIdle(); |
| 398 EXPECT_FALSE(client.did_state_changed()); | |
| 399 EXPECT_EQ(base::MemoryState::NORMAL, client.state()); | |
| 400 EXPECT_EQ(mojom::MemoryState::NORMAL, foreground_child->state()); | |
| 401 EXPECT_EQ(mojom::MemoryState::THROTTLED, background_child->state()); | |
| 402 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(&client); | |
| 403 } | |
| 404 | |
| 405 { | |
| 406 // Transition happens (WARNING -> CRITICAL). | |
| 407 // All processes should be in THROTTLED memory state. | |
| 408 MockMemoryCoordinatorClient client; | |
| 409 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(&client); | |
| 410 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(20); | |
| 411 condition_observer->UpdateCondition(); | |
| 412 task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(40)); | |
| 413 RunUntilIdle(); | |
| 414 EXPECT_TRUE(client.did_state_changed()); | 352 EXPECT_TRUE(client.did_state_changed()); |
| 415 EXPECT_EQ(base::MemoryState::THROTTLED, client.state()); | 353 EXPECT_EQ(base::MemoryState::THROTTLED, client.state()); |
| 416 EXPECT_EQ(mojom::MemoryState::THROTTLED, foreground_child->state()); | 354 EXPECT_EQ(mojom::MemoryState::THROTTLED, foreground_child->state()); |
| 417 EXPECT_EQ(mojom::MemoryState::THROTTLED, background_child->state()); | 355 EXPECT_EQ(mojom::MemoryState::THROTTLED, background_child->state()); |
| 418 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(&client); | 356 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(&client); |
| 419 } | 357 } |
| 420 | 358 |
| 421 { | 359 { |
| 422 // No transtion (NORMAL -> NORMAL). OnStateChange shouldn't be called. | 360 // No transtion (NORMAL -> NORMAL). OnStateChange shouldn't be called. |
| 423 MockMemoryCoordinatorClient client; | 361 MockMemoryCoordinatorClient client; |
| 424 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(&client); | 362 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(&client); |
| 425 coordinator_->memory_condition_ = MemoryCondition::NORMAL; | 363 coordinator_->memory_condition_ = MemoryCondition::NORMAL; |
| 426 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(50); | 364 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(1000); |
| 427 condition_observer->UpdateCondition(); | 365 condition_observer->UpdateCondition(); |
| 428 RunUntilIdle(); | 366 RunUntilIdle(); |
| 429 EXPECT_FALSE(client.did_state_changed()); | 367 EXPECT_FALSE(client.did_state_changed()); |
| 430 EXPECT_EQ(base::MemoryState::NORMAL, client.state()); | 368 EXPECT_EQ(base::MemoryState::NORMAL, client.state()); |
| 431 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(&client); | 369 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(&client); |
| 432 } | 370 } |
| 433 | 371 |
| 434 { | 372 { |
| 435 // Transition happends but browser state change is delayed | 373 // Transition happends but browser state change is delayed |
| 436 // (CRITICAL -> NORMAL). | 374 // (CRITICAL -> NORMAL). |
| 437 base::TimeDelta transition_interval = | 375 base::TimeDelta transition_interval = |
| 438 coordinator_->minimum_state_transition_period_ + | 376 coordinator_->minimum_state_transition_period_ + |
| 439 base::TimeDelta::FromSeconds(1); | 377 base::TimeDelta::FromSeconds(1); |
| 440 coordinator_->memory_condition_ = MemoryCondition::NORMAL; | 378 coordinator_->memory_condition_ = MemoryCondition::NORMAL; |
| 441 coordinator_->last_state_change_ = task_runner_->NowTicks(); | 379 coordinator_->last_state_change_ = task_runner_->NowTicks(); |
| 442 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(20); | 380 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(0); |
| 443 condition_observer->UpdateCondition(); | 381 condition_observer->UpdateCondition(); |
| 444 EXPECT_EQ(base::MemoryState::THROTTLED, | 382 EXPECT_EQ(base::MemoryState::THROTTLED, |
| 445 coordinator_->GetCurrentMemoryState()); | 383 coordinator_->GetCurrentMemoryState()); |
| 446 | 384 |
| 447 // Back to NORMAL condition before |minimum_state_transition_period_| is | 385 // Back to NORMAL condition before |minimum_state_transition_period_| is |
| 448 // passed. At this point the browser's state shouldn't be changed. | 386 // passed. At this point the browser's state shouldn't be changed. |
| 449 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(50); | 387 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(1000); |
| 450 condition_observer->UpdateCondition(); | 388 condition_observer->UpdateCondition(); |
| 451 task_runner_->FastForwardBy(transition_interval / 2); | 389 task_runner_->FastForwardBy(transition_interval / 2); |
| 452 EXPECT_EQ(MemoryCondition::NORMAL, coordinator_->GetMemoryCondition()); | 390 EXPECT_EQ(MemoryCondition::NORMAL, coordinator_->GetMemoryCondition()); |
| 453 EXPECT_EQ(base::MemoryState::THROTTLED, | 391 EXPECT_EQ(base::MemoryState::THROTTLED, |
| 454 coordinator_->GetCurrentMemoryState()); | 392 coordinator_->GetCurrentMemoryState()); |
| 455 | 393 |
| 456 // |minimum_state_transition_period_| is passed. State should be changed. | 394 // |minimum_state_transition_period_| is passed. State should be changed. |
| 457 task_runner_->FastForwardBy(transition_interval / 2); | 395 task_runner_->FastForwardBy(transition_interval / 2); |
| 458 EXPECT_EQ(base::MemoryState::NORMAL, coordinator_->GetCurrentMemoryState()); | 396 EXPECT_EQ(base::MemoryState::NORMAL, coordinator_->GetCurrentMemoryState()); |
| 459 } | 397 } |
| 460 } | 398 } |
| 461 | 399 |
| 400 // TODO(bashi): Move ForceSetMemoryCondition? |
| 462 TEST_F(MemoryCoordinatorImplTest, ForceSetMemoryCondition) { | 401 TEST_F(MemoryCoordinatorImplTest, ForceSetMemoryCondition) { |
| 463 auto* condition_observer = coordinator_->condition_observer_.get(); | 402 auto* condition_observer = coordinator_->condition_observer_.get(); |
| 464 condition_observer->expected_renderer_size_ = 10; | 403 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(1000); |
| 465 condition_observer->new_renderers_until_warning_ = 4; | |
| 466 condition_observer->new_renderers_until_critical_ = 2; | |
| 467 condition_observer->new_renderers_back_to_normal_ = 5; | |
| 468 condition_observer->new_renderers_back_to_warning_ = 3; | |
| 469 DCHECK(condition_observer->ValidateParameters()); | |
| 470 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(50); | |
| 471 | 404 |
| 472 base::TimeDelta interval = base::TimeDelta::FromSeconds(5); | 405 base::TimeDelta interval = base::TimeDelta::FromSeconds(5); |
| 473 condition_observer->monitoring_interval_ = interval; | 406 condition_observer->monitoring_interval_ = interval; |
| 474 | 407 |
| 475 // Starts updating memory condition. The initial condition should be NORMAL | 408 // Starts updating memory condition. The initial condition should be NORMAL |
| 476 // with above configuration. | 409 // with above configuration. |
| 477 coordinator_->Start(); | 410 coordinator_->Start(); |
| 478 task_runner_->RunUntilIdle(); | 411 task_runner_->RunUntilIdle(); |
| 479 EXPECT_EQ(MemoryCondition::NORMAL, coordinator_->GetMemoryCondition()); | 412 EXPECT_EQ(MemoryCondition::NORMAL, coordinator_->GetMemoryCondition()); |
| 480 | 413 |
| 481 base::TimeDelta force_set_duration = interval * 3; | 414 base::TimeDelta force_set_duration = interval * 3; |
| 482 coordinator_->ForceSetMemoryCondition(MemoryCondition::WARNING, | 415 coordinator_->ForceSetMemoryCondition(MemoryCondition::CRITICAL, |
| 483 force_set_duration); | 416 force_set_duration); |
| 484 EXPECT_EQ(MemoryCondition::WARNING, coordinator_->GetMemoryCondition()); | 417 EXPECT_EQ(MemoryCondition::CRITICAL, coordinator_->GetMemoryCondition()); |
| 485 | 418 |
| 486 // The condition should remain SUSPENDED even after some monitoring period are | 419 // The condition should remain CRITICAL even after some monitoring period are |
| 487 // passed. | 420 // passed. |
| 488 task_runner_->FastForwardBy(interval * 2); | 421 task_runner_->FastForwardBy(interval * 2); |
| 489 task_runner_->RunUntilIdle(); | 422 task_runner_->RunUntilIdle(); |
| 490 EXPECT_EQ(MemoryCondition::WARNING, coordinator_->GetMemoryCondition()); | 423 EXPECT_EQ(MemoryCondition::CRITICAL, coordinator_->GetMemoryCondition()); |
| 491 | 424 |
| 492 // The condition should be updated after |force_set_duration| is passed. | 425 // The condition should be updated after |force_set_duration| is passed. |
| 493 task_runner_->FastForwardBy(force_set_duration); | 426 task_runner_->FastForwardBy(force_set_duration); |
| 494 task_runner_->RunUntilIdle(); | 427 task_runner_->RunUntilIdle(); |
| 495 EXPECT_EQ(MemoryCondition::NORMAL, coordinator_->GetMemoryCondition()); | 428 EXPECT_EQ(MemoryCondition::NORMAL, coordinator_->GetMemoryCondition()); |
| 496 | 429 |
| 497 // Also make sure that the condition is updated based on free avaiable memory. | 430 // Also make sure that the condition is updated based on free avaiable memory. |
| 498 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(40); | 431 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(0); |
| 499 task_runner_->FastForwardBy(interval * 2); | 432 task_runner_->FastForwardBy(interval * 2); |
| 500 task_runner_->RunUntilIdle(); | 433 task_runner_->RunUntilIdle(); |
| 501 EXPECT_EQ(MemoryCondition::WARNING, coordinator_->GetMemoryCondition()); | 434 EXPECT_EQ(MemoryCondition::CRITICAL, coordinator_->GetMemoryCondition()); |
| 502 } | 435 } |
| 503 | 436 |
| 504 TEST_F(MemoryCoordinatorImplTest, DiscardTab) { | 437 TEST_F(MemoryCoordinatorImplTest, DiscardTab) { |
| 505 coordinator_->DiscardTab(); | 438 coordinator_->DiscardTab(); |
| 506 EXPECT_EQ(1, coordinator_->GetDelegate()->discard_tab_count()); | 439 EXPECT_EQ(1, coordinator_->GetDelegate()->discard_tab_count()); |
| 507 } | 440 } |
| 508 | 441 |
| 509 TEST_F(MemoryCoordinatorImplTest, DiscardTabUnderCritical) { | 442 TEST_F(MemoryCoordinatorImplTest, DiscardTabUnderCritical) { |
| 510 auto* condition_observer = coordinator_->condition_observer_.get(); | 443 auto* condition_observer = coordinator_->condition_observer_.get(); |
| 511 condition_observer->expected_renderer_size_ = 10; | 444 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(1000); |
| 512 condition_observer->new_renderers_until_warning_ = 4; | |
| 513 condition_observer->new_renderers_until_critical_ = 2; | |
| 514 condition_observer->new_renderers_back_to_normal_ = 5; | |
| 515 condition_observer->new_renderers_back_to_warning_ = 3; | |
| 516 DCHECK(condition_observer->ValidateParameters()); | |
| 517 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(50); | |
| 518 | 445 |
| 519 base::TimeDelta interval = base::TimeDelta::FromSeconds(5); | 446 base::TimeDelta interval = base::TimeDelta::FromSeconds(5); |
| 520 condition_observer->monitoring_interval_ = interval; | 447 condition_observer->monitoring_interval_ = interval; |
| 521 | 448 |
| 522 auto* delegate = coordinator_->GetDelegate(); | 449 auto* delegate = coordinator_->GetDelegate(); |
| 523 | 450 |
| 524 coordinator_->Start(); | 451 coordinator_->Start(); |
| 525 task_runner_->RunUntilIdle(); | 452 task_runner_->RunUntilIdle(); |
| 526 EXPECT_EQ(MemoryCondition::NORMAL, coordinator_->GetMemoryCondition()); | 453 EXPECT_EQ(MemoryCondition::NORMAL, coordinator_->GetMemoryCondition()); |
| 527 EXPECT_EQ(0, delegate->discard_tab_count()); | 454 EXPECT_EQ(0, delegate->discard_tab_count()); |
| 528 | 455 |
| 529 // Enter WARNING condition. No tab discarding should happen. | |
| 530 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(40); | |
| 531 task_runner_->FastForwardBy(interval + base::TimeDelta::FromSeconds(1)); | |
| 532 EXPECT_EQ(0, delegate->discard_tab_count()); | |
| 533 task_runner_->FastForwardBy(interval); | |
| 534 EXPECT_EQ(0, delegate->discard_tab_count()); | |
| 535 | |
| 536 // Enter CRITICAL condition. Tab discarding should start. | 456 // Enter CRITICAL condition. Tab discarding should start. |
| 537 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(20); | 457 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(0); |
| 538 task_runner_->FastForwardBy(interval); | 458 task_runner_->FastForwardBy(interval); |
| 539 EXPECT_EQ(1, delegate->discard_tab_count()); | 459 EXPECT_EQ(1, delegate->discard_tab_count()); |
| 540 task_runner_->FastForwardBy(interval); | 460 task_runner_->FastForwardBy(interval); |
| 541 EXPECT_EQ(2, delegate->discard_tab_count()); | 461 EXPECT_EQ(2, delegate->discard_tab_count()); |
| 542 | 462 |
| 543 // Back to NORMAL. Tab discarding should stop. | 463 // Back to NORMAL. Tab discarding should stop. |
| 544 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(50); | 464 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(1000); |
| 545 task_runner_->FastForwardBy(interval); | 465 task_runner_->FastForwardBy(interval); |
| 546 EXPECT_EQ(2, delegate->discard_tab_count()); | 466 EXPECT_EQ(2, delegate->discard_tab_count()); |
| 547 task_runner_->FastForwardBy(interval); | 467 task_runner_->FastForwardBy(interval); |
| 548 EXPECT_EQ(2, delegate->discard_tab_count()); | 468 EXPECT_EQ(2, delegate->discard_tab_count()); |
| 549 } | 469 } |
| 550 | 470 |
| 551 // TODO(bashi): Move policy specific tests into a separate file. | 471 // TODO(bashi): Move policy specific tests into a separate file. |
| 552 TEST_F(MemoryCoordinatorImplTest, OnWarningCondition) { | |
| 553 MockMemoryCoordinatorClient client; | |
| 554 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(&client); | |
| 555 auto* child1 = coordinator_->CreateChildMemoryCoordinator(1); | |
| 556 auto* child2 = coordinator_->CreateChildMemoryCoordinator(2); | |
| 557 base::TimeDelta interval = base::TimeDelta::FromSeconds(31); | |
| 558 | |
| 559 // child1: Foreground, child2: Background | |
| 560 coordinator_->policy_->OnChildVisibilityChanged(1, true); | |
| 561 coordinator_->policy_->OnChildVisibilityChanged(2, false); | |
| 562 | |
| 563 // Note: we never ask foreground processes (including the browser process) to | |
| 564 // purge memory on WARNING condition. | |
| 565 | |
| 566 // Don't ask the background child to purge until the child remains | |
| 567 // backgrounded for a certain period of time. | |
| 568 coordinator_->policy_->OnWarningCondition(); | |
| 569 RunUntilIdle(); | |
| 570 EXPECT_EQ(0, client.purge_memory_calls()); | |
| 571 EXPECT_EQ(0, child1->purge_memory_calls()); | |
| 572 EXPECT_EQ(0, child2->purge_memory_calls()); | |
| 573 | |
| 574 // After a certain period of time is passed, request the child to purge | |
| 575 // memory. | |
| 576 task_runner_->FastForwardBy(interval); | |
| 577 coordinator_->policy_->OnWarningCondition(); | |
| 578 task_runner_->RunUntilIdle(); | |
| 579 RunUntilIdle(); | |
| 580 EXPECT_EQ(0, client.purge_memory_calls()); | |
| 581 EXPECT_EQ(0, child1->purge_memory_calls()); | |
| 582 EXPECT_EQ(1, child2->purge_memory_calls()); | |
| 583 | |
| 584 // Don't purge memory more than once when the child stays backgrounded. | |
| 585 task_runner_->FastForwardBy(interval); | |
| 586 coordinator_->policy_->OnWarningCondition(); | |
| 587 RunUntilIdle(); | |
| 588 EXPECT_EQ(0, client.purge_memory_calls()); | |
| 589 EXPECT_EQ(0, child1->purge_memory_calls()); | |
| 590 EXPECT_EQ(1, child2->purge_memory_calls()); | |
| 591 | |
| 592 // The background child goes to foreground, goes to background, then a | |
| 593 // certain period of time is passed. Another purging request should be sent. | |
| 594 coordinator_->policy_->OnChildVisibilityChanged(2, true); | |
| 595 coordinator_->policy_->OnChildVisibilityChanged(2, false); | |
| 596 task_runner_->FastForwardBy(interval); | |
| 597 coordinator_->policy_->OnWarningCondition(); | |
| 598 RunUntilIdle(); | |
| 599 EXPECT_EQ(0, client.purge_memory_calls()); | |
| 600 EXPECT_EQ(0, child1->purge_memory_calls()); | |
| 601 EXPECT_EQ(2, child2->purge_memory_calls()); | |
| 602 | |
| 603 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(&client); | |
| 604 } | |
| 605 | |
| 606 // TODO(bashi): Move policy specific tests into a separate file. | |
| 607 TEST_F(MemoryCoordinatorImplTest, OnCriticalCondition) { | 472 TEST_F(MemoryCoordinatorImplTest, OnCriticalCondition) { |
| 608 MockMemoryCoordinatorClient client; | 473 MockMemoryCoordinatorClient client; |
| 609 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(&client); | 474 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(&client); |
| 610 auto* child1 = coordinator_->CreateChildMemoryCoordinator(1); | 475 auto* child1 = coordinator_->CreateChildMemoryCoordinator(1); |
| 611 auto* child2 = coordinator_->CreateChildMemoryCoordinator(2); | 476 auto* child2 = coordinator_->CreateChildMemoryCoordinator(2); |
| 612 auto* delegate = coordinator_->GetDelegate(); | 477 auto* delegate = coordinator_->GetDelegate(); |
| 613 base::TimeDelta interval = base::TimeDelta::FromSeconds(31); | 478 base::TimeDelta interval = base::TimeDelta::FromSeconds(31); |
| 614 | 479 |
| 615 // child1: Foreground, child2: Background | 480 // child1: Foreground, child2: Background |
| 616 coordinator_->policy_->OnChildVisibilityChanged(1, true); | 481 coordinator_->policy_->OnChildVisibilityChanged(1, true); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 682 | 547 |
| 683 EXPECT_TRUE( | 548 EXPECT_TRUE( |
| 684 coordinator_->SetChildMemoryState(1, MemoryState::THROTTLED)); | 549 coordinator_->SetChildMemoryState(1, MemoryState::THROTTLED)); |
| 685 EXPECT_EQ(base::MemoryState::THROTTLED, | 550 EXPECT_EQ(base::MemoryState::THROTTLED, |
| 686 coordinator_->GetStateForProcess(process1.Handle())); | 551 coordinator_->GetStateForProcess(process1.Handle())); |
| 687 EXPECT_EQ(base::MemoryState::NORMAL, | 552 EXPECT_EQ(base::MemoryState::NORMAL, |
| 688 coordinator_->GetStateForProcess(process2.Handle())); | 553 coordinator_->GetStateForProcess(process2.Handle())); |
| 689 } | 554 } |
| 690 | 555 |
| 691 } // namespace content | 556 } // namespace content |
| OLD | NEW |