| 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_proxy.h" | 8 #include "base/memory/memory_coordinator_proxy.h" |
| 9 #include "base/memory/memory_pressure_monitor.h" |
| 10 #include "base/message_loop/message_loop.h" |
| 8 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
| 9 #include "base/test/scoped_feature_list.h" | 12 #include "base/test/scoped_feature_list.h" |
| 10 #include "base/test/test_mock_time_task_runner.h" | 13 #include "base/test/test_mock_time_task_runner.h" |
| 11 #include "content/browser/memory/memory_monitor.h" | 14 #include "content/browser/memory/memory_monitor.h" |
| 12 #include "content/browser/memory/memory_state_updater.h" | 15 #include "content/browser/memory/memory_state_updater.h" |
| 13 #include "content/public/common/content_features.h" | 16 #include "content/public/common/content_features.h" |
| 17 #include "mojo/public/cpp/bindings/binding.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
| 15 | 19 |
| 16 namespace content { | 20 namespace content { |
| 17 | 21 |
| 18 namespace { | 22 namespace { |
| 19 | 23 |
| 24 void RunUntilIdle() { |
| 25 base::RunLoop loop; |
| 26 loop.RunUntilIdle(); |
| 27 } |
| 28 |
| 29 // A mock ChildMemoryCoordinator, for testing interaction between MC and CMC. |
| 30 class MockChildMemoryCoordinator : public mojom::ChildMemoryCoordinator { |
| 31 public: |
| 32 MockChildMemoryCoordinator() |
| 33 : state_(mojom::MemoryState::NORMAL), |
| 34 on_state_change_calls_(0) {} |
| 35 |
| 36 ~MockChildMemoryCoordinator() override {} |
| 37 |
| 38 void OnStateChange(mojom::MemoryState state) override { |
| 39 state_ = state; |
| 40 ++on_state_change_calls_; |
| 41 } |
| 42 |
| 43 mojom::MemoryState state() const { return state_; } |
| 44 int on_state_change_calls() const { return on_state_change_calls_; } |
| 45 |
| 46 private: |
| 47 mojom::MemoryState state_; |
| 48 int on_state_change_calls_; |
| 49 }; |
| 50 |
| 51 // A mock MemoryCoordinatorClient, for testing interaction between MC and |
| 52 // clients. |
| 20 class MockMemoryCoordinatorClient : public base::MemoryCoordinatorClient { | 53 class MockMemoryCoordinatorClient : public base::MemoryCoordinatorClient { |
| 21 public: | 54 public: |
| 22 void OnMemoryStateChange(base::MemoryState state) override { | 55 void OnMemoryStateChange(base::MemoryState state) override { |
| 23 is_called_ = true; | 56 is_called_ = true; |
| 24 state_ = state; | 57 state_ = state; |
| 25 } | 58 } |
| 26 | 59 |
| 27 bool is_called() { return is_called_; } | 60 bool is_called() { return is_called_; } |
| 28 base::MemoryState state() { return state_; } | 61 base::MemoryState state() { return state_; } |
| 29 | 62 |
| 30 private: | 63 private: |
| 31 bool is_called_ = false; | 64 bool is_called_ = false; |
| 32 base::MemoryState state_ = base::MemoryState::NORMAL; | 65 base::MemoryState state_ = base::MemoryState::NORMAL; |
| 33 }; | 66 }; |
| 34 | 67 |
| 35 } // namespace | |
| 36 | |
| 37 class MockMemoryMonitor : public MemoryMonitor { | 68 class MockMemoryMonitor : public MemoryMonitor { |
| 38 public: | 69 public: |
| 39 MockMemoryMonitor() {} | 70 MockMemoryMonitor() {} |
| 40 ~MockMemoryMonitor() override {} | 71 ~MockMemoryMonitor() override {} |
| 41 | 72 |
| 42 void SetFreeMemoryUntilCriticalMB(int free_memory) { | 73 void SetFreeMemoryUntilCriticalMB(int free_memory) { |
| 43 free_memory_ = free_memory; | 74 free_memory_ = free_memory; |
| 44 } | 75 } |
| 45 | 76 |
| 46 // MemoryMonitor implementation | 77 // MemoryMonitor implementation |
| 47 int GetFreeMemoryUntilCriticalMB() override { return free_memory_; } | 78 int GetFreeMemoryUntilCriticalMB() override { return free_memory_; } |
| 48 | 79 |
| 49 private: | 80 private: |
| 50 int free_memory_ = 0; | 81 int free_memory_ = 0; |
| 51 | 82 |
| 52 DISALLOW_COPY_AND_ASSIGN(MockMemoryMonitor); | 83 DISALLOW_COPY_AND_ASSIGN(MockMemoryMonitor); |
| 53 }; | 84 }; |
| 54 | 85 |
| 86 // A MemoryCoordinatorImpl that can be directly constructed. |
| 87 class TestMemoryCoordinatorImpl : public MemoryCoordinatorImpl { |
| 88 public: |
| 89 // Mojo machinery for wrapping a mock ChildMemoryCoordinator. |
| 90 struct Child { |
| 91 Child(mojom::ChildMemoryCoordinatorPtr* cmc_ptr) : cmc_binding(&cmc) { |
| 92 cmc_binding.Bind(mojo::GetProxy(cmc_ptr)); |
| 93 RunUntilIdle(); |
| 94 } |
| 95 |
| 96 MockChildMemoryCoordinator cmc; |
| 97 mojo::Binding<mojom::ChildMemoryCoordinator> cmc_binding; |
| 98 }; |
| 99 |
| 100 TestMemoryCoordinatorImpl( |
| 101 scoped_refptr<base::TestMockTimeTaskRunner> task_runner) |
| 102 : MemoryCoordinatorImpl(task_runner, |
| 103 base::MakeUnique<MockMemoryMonitor>()) {} |
| 104 ~TestMemoryCoordinatorImpl() override {} |
| 105 |
| 106 using MemoryCoordinatorImpl::OnConnectionError; |
| 107 using MemoryCoordinatorImpl::children; |
| 108 |
| 109 MockChildMemoryCoordinator* CreateChildMemoryCoordinator( |
| 110 int process_id) { |
| 111 mojom::ChildMemoryCoordinatorPtr cmc_ptr; |
| 112 children_.push_back(std::unique_ptr<Child>(new Child(&cmc_ptr))); |
| 113 AddChildForTesting(process_id, std::move(cmc_ptr)); |
| 114 return &children_.back()->cmc; |
| 115 } |
| 116 |
| 117 // Wrapper of MemoryCoordinator::SetMemoryState that also calls RunUntilIdle. |
| 118 bool SetChildMemoryState( |
| 119 int render_process_id, mojom::MemoryState memory_state) { |
| 120 bool result = MemoryCoordinatorImpl::SetChildMemoryState( |
| 121 render_process_id, memory_state); |
| 122 RunUntilIdle(); |
| 123 return result; |
| 124 } |
| 125 |
| 126 std::vector<std::unique_ptr<Child>> children_; |
| 127 }; |
| 128 |
| 129 } // namespace |
| 130 |
| 55 class MemoryCoordinatorImplTest : public testing::Test { | 131 class MemoryCoordinatorImplTest : public testing::Test { |
| 56 public: | 132 public: |
| 57 void SetUp() override { | 133 void SetUp() override { |
| 58 scoped_feature_list_.InitAndEnableFeature(features::kMemoryCoordinator); | 134 scoped_feature_list_.InitAndEnableFeature(features::kMemoryCoordinator); |
| 59 | 135 |
| 60 task_runner_ = new base::TestMockTimeTaskRunner(); | 136 task_runner_ = new base::TestMockTimeTaskRunner(); |
| 61 coordinator_.reset(new MemoryCoordinatorImpl( | 137 coordinator_.reset(new TestMemoryCoordinatorImpl(task_runner_)); |
| 62 task_runner_, base::WrapUnique(new MockMemoryMonitor))); | |
| 63 | 138 |
| 64 base::MemoryCoordinatorProxy::GetInstance()-> | 139 base::MemoryCoordinatorProxy::GetInstance()-> |
| 65 SetGetCurrentMemoryStateCallback(base::Bind( | 140 SetGetCurrentMemoryStateCallback(base::Bind( |
| 66 &MemoryCoordinator::GetCurrentMemoryState, | 141 &MemoryCoordinatorImpl::GetCurrentMemoryState, |
| 67 base::Unretained(coordinator_.get()))); | 142 base::Unretained(coordinator_.get()))); |
| 68 base::MemoryCoordinatorProxy::GetInstance()-> | 143 base::MemoryCoordinatorProxy::GetInstance()-> |
| 69 SetSetCurrentMemoryStateForTestingCallback(base::Bind( | 144 SetSetCurrentMemoryStateForTestingCallback(base::Bind( |
| 70 &MemoryCoordinator::SetCurrentMemoryStateForTesting, | 145 &MemoryCoordinatorImpl::SetCurrentMemoryStateForTesting, |
| 71 base::Unretained(coordinator_.get()))); | 146 base::Unretained(coordinator_.get()))); |
| 72 } | 147 } |
| 73 | 148 |
| 74 MockMemoryMonitor* GetMockMemoryMonitor() { | 149 MockMemoryMonitor* GetMockMemoryMonitor() { |
| 75 return static_cast<MockMemoryMonitor*>(coordinator_->memory_monitor()); | 150 return static_cast<MockMemoryMonitor*>(coordinator_->memory_monitor()); |
| 76 } | 151 } |
| 77 | 152 |
| 78 protected: | 153 protected: |
| 79 std::unique_ptr<MemoryCoordinatorImpl> coordinator_; | 154 std::unique_ptr<TestMemoryCoordinatorImpl> coordinator_; |
| 80 scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; | 155 scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; |
| 81 base::MessageLoop message_loop_; | 156 base::MessageLoop message_loop_; |
| 82 base::test::ScopedFeatureList scoped_feature_list_; | 157 base::test::ScopedFeatureList scoped_feature_list_; |
| 83 }; | 158 }; |
| 84 | 159 |
| 160 TEST_F(MemoryCoordinatorImplTest, ChildRemovedOnConnectionError) { |
| 161 coordinator_->CreateChildMemoryCoordinator(1); |
| 162 ASSERT_EQ(1u, coordinator_->children().size()); |
| 163 coordinator_->OnConnectionError(1); |
| 164 EXPECT_EQ(0u, coordinator_->children().size()); |
| 165 } |
| 166 |
| 167 TEST_F(MemoryCoordinatorImplTest, SetMemoryStateFailsInvalidState) { |
| 168 auto cmc1 = coordinator_->CreateChildMemoryCoordinator(1); |
| 169 |
| 170 EXPECT_FALSE( |
| 171 coordinator_->SetChildMemoryState(1, mojom::MemoryState::UNKNOWN)); |
| 172 EXPECT_EQ(0, cmc1->on_state_change_calls()); |
| 173 } |
| 174 |
| 175 TEST_F(MemoryCoordinatorImplTest, SetMemoryStateFailsInvalidRenderer) { |
| 176 auto cmc1 = coordinator_->CreateChildMemoryCoordinator(1); |
| 177 |
| 178 EXPECT_FALSE( |
| 179 coordinator_->SetChildMemoryState(2, mojom::MemoryState::THROTTLED)); |
| 180 EXPECT_EQ(0, cmc1->on_state_change_calls()); |
| 181 } |
| 182 |
| 183 TEST_F(MemoryCoordinatorImplTest, SetMemoryStateNotDeliveredNop) { |
| 184 auto cmc1 = coordinator_->CreateChildMemoryCoordinator(1); |
| 185 |
| 186 EXPECT_FALSE( |
| 187 coordinator_->SetChildMemoryState(2, mojom::MemoryState::NORMAL)); |
| 188 EXPECT_EQ(0, cmc1->on_state_change_calls()); |
| 189 } |
| 190 |
| 191 TEST_F(MemoryCoordinatorImplTest, SetMemoryStateDelivered) { |
| 192 auto cmc1 = coordinator_->CreateChildMemoryCoordinator(1); |
| 193 auto cmc2 = coordinator_->CreateChildMemoryCoordinator(2); |
| 194 |
| 195 EXPECT_TRUE( |
| 196 coordinator_->SetChildMemoryState(1, mojom::MemoryState::THROTTLED)); |
| 197 EXPECT_EQ(1, cmc1->on_state_change_calls()); |
| 198 EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc1->state()); |
| 199 |
| 200 EXPECT_TRUE( |
| 201 coordinator_->SetChildMemoryState(2, mojom::MemoryState::SUSPENDED)); |
| 202 EXPECT_EQ(1, cmc2->on_state_change_calls()); |
| 203 // Child processes are considered as visible (foreground) by default, |
| 204 // and visible ones won't be suspended but throttled. |
| 205 EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc2->state()); |
| 206 } |
| 207 |
| 208 TEST_F(MemoryCoordinatorImplTest, SetChildMemoryState) { |
| 209 auto cmc = coordinator_->CreateChildMemoryCoordinator(1); |
| 210 auto iter = coordinator_->children().find(1); |
| 211 ASSERT_TRUE(iter != coordinator_->children().end()); |
| 212 |
| 213 // Foreground |
| 214 iter->second.is_visible = true; |
| 215 EXPECT_TRUE(coordinator_->SetChildMemoryState(1, mojom::MemoryState::NORMAL)); |
| 216 EXPECT_EQ(mojom::MemoryState::NORMAL, cmc->state()); |
| 217 EXPECT_TRUE( |
| 218 coordinator_->SetChildMemoryState(1, mojom::MemoryState::THROTTLED)); |
| 219 EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc->state()); |
| 220 EXPECT_TRUE( |
| 221 coordinator_->SetChildMemoryState(1, mojom::MemoryState::SUSPENDED)); |
| 222 EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc->state()); |
| 223 |
| 224 // Background |
| 225 iter->second.is_visible = false; |
| 226 EXPECT_TRUE(coordinator_->SetChildMemoryState(1, mojom::MemoryState::NORMAL)); |
| 227 #if defined(OS_ANDROID) |
| 228 EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc->state()); |
| 229 #else |
| 230 EXPECT_EQ(mojom::MemoryState::NORMAL, cmc->state()); |
| 231 #endif |
| 232 EXPECT_TRUE( |
| 233 coordinator_->SetChildMemoryState(1, mojom::MemoryState::THROTTLED)); |
| 234 EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc->state()); |
| 235 EXPECT_TRUE( |
| 236 coordinator_->SetChildMemoryState(1, mojom::MemoryState::SUSPENDED)); |
| 237 EXPECT_EQ(mojom::MemoryState::SUSPENDED, cmc->state()); |
| 238 } |
| 239 |
| 85 TEST_F(MemoryCoordinatorImplTest, CalculateNextState) { | 240 TEST_F(MemoryCoordinatorImplTest, CalculateNextState) { |
| 86 auto* state_updater = coordinator_->state_updater_.get(); | 241 auto* state_updater = coordinator_->state_updater_.get(); |
| 87 state_updater->expected_renderer_size_ = 10; | 242 state_updater->expected_renderer_size_ = 10; |
| 88 state_updater->new_renderers_until_throttled_ = 4; | 243 state_updater->new_renderers_until_throttled_ = 4; |
| 89 state_updater->new_renderers_until_suspended_ = 2; | 244 state_updater->new_renderers_until_suspended_ = 2; |
| 90 state_updater->new_renderers_back_to_normal_ = 5; | 245 state_updater->new_renderers_back_to_normal_ = 5; |
| 91 state_updater->new_renderers_back_to_throttled_ = 3; | 246 state_updater->new_renderers_back_to_throttled_ = 3; |
| 92 DCHECK(state_updater->ValidateParameters()); | 247 DCHECK(state_updater->ValidateParameters()); |
| 93 | 248 |
| 94 // The default state is NORMAL. | 249 // The default state is NORMAL. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 state_updater->new_renderers_back_to_throttled_ = 3; | 308 state_updater->new_renderers_back_to_throttled_ = 3; |
| 154 DCHECK(state_updater->ValidateParameters()); | 309 DCHECK(state_updater->ValidateParameters()); |
| 155 | 310 |
| 156 { | 311 { |
| 157 // Transition happens (NORMAL -> THROTTLED). | 312 // Transition happens (NORMAL -> THROTTLED). |
| 158 MockMemoryCoordinatorClient client; | 313 MockMemoryCoordinatorClient client; |
| 159 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(&client); | 314 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(&client); |
| 160 coordinator_->current_state_ = base::MemoryState::NORMAL; | 315 coordinator_->current_state_ = base::MemoryState::NORMAL; |
| 161 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(40); | 316 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(40); |
| 162 state_updater->UpdateState(); | 317 state_updater->UpdateState(); |
| 163 base::RunLoop loop; | 318 RunUntilIdle(); |
| 164 loop.RunUntilIdle(); | |
| 165 EXPECT_TRUE(client.is_called()); | 319 EXPECT_TRUE(client.is_called()); |
| 166 EXPECT_EQ(base::MemoryState::THROTTLED, client.state()); | 320 EXPECT_EQ(base::MemoryState::THROTTLED, client.state()); |
| 167 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(&client); | 321 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(&client); |
| 168 } | 322 } |
| 169 | 323 |
| 170 { | 324 { |
| 171 // No transtion (NORMAL -> NORMAL). OnStateChange shouldn't be called. | 325 // No transtion (NORMAL -> NORMAL). OnStateChange shouldn't be called. |
| 172 MockMemoryCoordinatorClient client; | 326 MockMemoryCoordinatorClient client; |
| 173 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(&client); | 327 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(&client); |
| 174 coordinator_->current_state_ = base::MemoryState::NORMAL; | 328 coordinator_->current_state_ = base::MemoryState::NORMAL; |
| 175 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(50); | 329 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(50); |
| 176 state_updater->UpdateState(); | 330 state_updater->UpdateState(); |
| 177 base::RunLoop loop; | 331 RunUntilIdle(); |
| 178 loop.RunUntilIdle(); | |
| 179 EXPECT_FALSE(client.is_called()); | 332 EXPECT_FALSE(client.is_called()); |
| 180 EXPECT_EQ(base::MemoryState::NORMAL, client.state()); | 333 EXPECT_EQ(base::MemoryState::NORMAL, client.state()); |
| 181 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(&client); | 334 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(&client); |
| 182 } | 335 } |
| 183 } | 336 } |
| 184 | 337 |
| 185 TEST_F(MemoryCoordinatorImplTest, SetMemoryStateForTesting) { | 338 TEST_F(MemoryCoordinatorImplTest, SetMemoryStateForTesting) { |
| 186 auto* state_updater = coordinator_->state_updater_.get(); | 339 auto* state_updater = coordinator_->state_updater_.get(); |
| 187 state_updater->expected_renderer_size_ = 10; | 340 state_updater->expected_renderer_size_ = 10; |
| 188 state_updater->new_renderers_until_throttled_ = 4; | 341 state_updater->new_renderers_until_throttled_ = 4; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 208 EXPECT_EQ(base::MemoryState::THROTTLED, | 361 EXPECT_EQ(base::MemoryState::THROTTLED, |
| 209 base::MemoryCoordinatorProxy::GetInstance()-> | 362 base::MemoryCoordinatorProxy::GetInstance()-> |
| 210 GetCurrentMemoryState()); | 363 GetCurrentMemoryState()); |
| 211 | 364 |
| 212 base::MemoryCoordinatorProxy::GetInstance()->SetCurrentMemoryStateForTesting( | 365 base::MemoryCoordinatorProxy::GetInstance()->SetCurrentMemoryStateForTesting( |
| 213 base::MemoryState::THROTTLED); | 366 base::MemoryState::THROTTLED); |
| 214 EXPECT_EQ(base::MemoryState::THROTTLED, | 367 EXPECT_EQ(base::MemoryState::THROTTLED, |
| 215 coordinator_->GetCurrentMemoryState()); | 368 coordinator_->GetCurrentMemoryState()); |
| 216 EXPECT_EQ(base::MemoryState::THROTTLED, | 369 EXPECT_EQ(base::MemoryState::THROTTLED, |
| 217 base::MemoryCoordinatorProxy::GetInstance()-> | 370 base::MemoryCoordinatorProxy::GetInstance()-> |
| 218 GetCurrentMemoryState()); | 371 GetCurrentMemoryState()); |
| 219 base::RunLoop loop; | 372 RunUntilIdle(); |
| 220 loop.RunUntilIdle(); | |
| 221 EXPECT_TRUE(client.is_called()); | 373 EXPECT_TRUE(client.is_called()); |
| 222 EXPECT_EQ(base::MemoryState::THROTTLED, client.state()); | 374 EXPECT_EQ(base::MemoryState::THROTTLED, client.state()); |
| 223 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(&client); | 375 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(&client); |
| 224 } | 376 } |
| 225 | 377 |
| 226 TEST_F(MemoryCoordinatorImplTest, ForceSetGlobalState) { | 378 TEST_F(MemoryCoordinatorImplTest, ForceSetGlobalState) { |
| 227 auto* state_updater = coordinator_->state_updater_.get(); | 379 auto* state_updater = coordinator_->state_updater_.get(); |
| 228 state_updater->expected_renderer_size_ = 10; | 380 state_updater->expected_renderer_size_ = 10; |
| 229 state_updater->new_renderers_until_throttled_ = 4; | 381 state_updater->new_renderers_until_throttled_ = 4; |
| 230 state_updater->new_renderers_until_suspended_ = 2; | 382 state_updater->new_renderers_until_suspended_ = 2; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 // Also make sure that the state is updated based on free avaiable memory. | 415 // Also make sure that the state is updated based on free avaiable memory. |
| 264 // Since the global state has changed in the previous task, we have to wait | 416 // Since the global state has changed in the previous task, we have to wait |
| 265 // for |minimum_transition|. | 417 // for |minimum_transition|. |
| 266 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(40); | 418 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(40); |
| 267 task_runner_->FastForwardBy(minimum_transition); | 419 task_runner_->FastForwardBy(minimum_transition); |
| 268 task_runner_->RunUntilIdle(); | 420 task_runner_->RunUntilIdle(); |
| 269 EXPECT_EQ(base::MemoryState::THROTTLED, coordinator_->GetGlobalMemoryState()); | 421 EXPECT_EQ(base::MemoryState::THROTTLED, coordinator_->GetGlobalMemoryState()); |
| 270 } | 422 } |
| 271 | 423 |
| 272 } // namespace content | 424 } // namespace content |
| OLD | NEW |