| 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/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 MockChildMemoryCoordinator* CreateChildMemoryCoordinator( | 109 MockChildMemoryCoordinator* CreateChildMemoryCoordinator( |
| 110 int process_id) { | 110 int process_id) { |
| 111 mojom::ChildMemoryCoordinatorPtr cmc_ptr; | 111 mojom::ChildMemoryCoordinatorPtr cmc_ptr; |
| 112 children_.push_back(std::unique_ptr<Child>(new Child(&cmc_ptr))); | 112 children_.push_back(std::unique_ptr<Child>(new Child(&cmc_ptr))); |
| 113 AddChildForTesting(process_id, std::move(cmc_ptr)); | 113 AddChildForTesting(process_id, std::move(cmc_ptr)); |
| 114 return &children_.back()->cmc; | 114 return &children_.back()->cmc; |
| 115 } | 115 } |
| 116 | 116 |
| 117 // Wrapper of MemoryCoordinator::SetMemoryState that also calls RunUntilIdle. | 117 // Wrapper of MemoryCoordinator::SetMemoryState that also calls RunUntilIdle. |
| 118 bool SetChildMemoryState( | 118 bool SetChildMemoryState( |
| 119 int render_process_id, mojom::MemoryState memory_state) { | 119 int render_process_id, MemoryState memory_state) { |
| 120 bool result = MemoryCoordinatorImpl::SetChildMemoryState( | 120 bool result = MemoryCoordinatorImpl::SetChildMemoryState( |
| 121 render_process_id, memory_state); | 121 render_process_id, memory_state); |
| 122 RunUntilIdle(); | 122 RunUntilIdle(); |
| 123 return result; | 123 return result; |
| 124 } | 124 } |
| 125 | 125 |
| 126 std::vector<std::unique_ptr<Child>> children_; | 126 std::vector<std::unique_ptr<Child>> children_; |
| 127 }; | 127 }; |
| 128 | 128 |
| 129 } // namespace | 129 } // namespace |
| 130 | 130 |
| 131 class MemoryCoordinatorImplTest : public testing::Test { | 131 class MemoryCoordinatorImplTest : public testing::Test { |
| 132 public: | 132 public: |
| 133 using MemoryState = base::MemoryState; |
| 134 |
| 133 void SetUp() override { | 135 void SetUp() override { |
| 134 scoped_feature_list_.InitAndEnableFeature(features::kMemoryCoordinator); | 136 scoped_feature_list_.InitAndEnableFeature(features::kMemoryCoordinator); |
| 135 | 137 |
| 136 task_runner_ = new base::TestMockTimeTaskRunner(); | 138 task_runner_ = new base::TestMockTimeTaskRunner(); |
| 137 coordinator_.reset(new TestMemoryCoordinatorImpl(task_runner_)); | 139 coordinator_.reset(new TestMemoryCoordinatorImpl(task_runner_)); |
| 138 | 140 |
| 139 base::MemoryCoordinatorProxy::GetInstance()-> | 141 base::MemoryCoordinatorProxy::GetInstance()-> |
| 140 SetGetCurrentMemoryStateCallback(base::Bind( | 142 SetGetCurrentMemoryStateCallback(base::Bind( |
| 141 &MemoryCoordinatorImpl::GetCurrentMemoryState, | 143 &MemoryCoordinatorImpl::GetCurrentMemoryState, |
| 142 base::Unretained(coordinator_.get()))); | 144 base::Unretained(coordinator_.get()))); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 161 coordinator_->CreateChildMemoryCoordinator(1); | 163 coordinator_->CreateChildMemoryCoordinator(1); |
| 162 ASSERT_EQ(1u, coordinator_->children().size()); | 164 ASSERT_EQ(1u, coordinator_->children().size()); |
| 163 coordinator_->OnConnectionError(1); | 165 coordinator_->OnConnectionError(1); |
| 164 EXPECT_EQ(0u, coordinator_->children().size()); | 166 EXPECT_EQ(0u, coordinator_->children().size()); |
| 165 } | 167 } |
| 166 | 168 |
| 167 TEST_F(MemoryCoordinatorImplTest, SetMemoryStateFailsInvalidState) { | 169 TEST_F(MemoryCoordinatorImplTest, SetMemoryStateFailsInvalidState) { |
| 168 auto cmc1 = coordinator_->CreateChildMemoryCoordinator(1); | 170 auto cmc1 = coordinator_->CreateChildMemoryCoordinator(1); |
| 169 | 171 |
| 170 EXPECT_FALSE( | 172 EXPECT_FALSE( |
| 171 coordinator_->SetChildMemoryState(1, mojom::MemoryState::UNKNOWN)); | 173 coordinator_->SetChildMemoryState(1, MemoryState::UNKNOWN)); |
| 172 EXPECT_EQ(0, cmc1->on_state_change_calls()); | 174 EXPECT_EQ(0, cmc1->on_state_change_calls()); |
| 173 } | 175 } |
| 174 | 176 |
| 175 TEST_F(MemoryCoordinatorImplTest, SetMemoryStateFailsInvalidRenderer) { | 177 TEST_F(MemoryCoordinatorImplTest, SetMemoryStateFailsInvalidRenderer) { |
| 176 auto cmc1 = coordinator_->CreateChildMemoryCoordinator(1); | 178 auto cmc1 = coordinator_->CreateChildMemoryCoordinator(1); |
| 177 | 179 |
| 178 EXPECT_FALSE( | 180 EXPECT_FALSE( |
| 179 coordinator_->SetChildMemoryState(2, mojom::MemoryState::THROTTLED)); | 181 coordinator_->SetChildMemoryState(2, MemoryState::THROTTLED)); |
| 180 EXPECT_EQ(0, cmc1->on_state_change_calls()); | 182 EXPECT_EQ(0, cmc1->on_state_change_calls()); |
| 181 } | 183 } |
| 182 | 184 |
| 183 TEST_F(MemoryCoordinatorImplTest, SetMemoryStateNotDeliveredNop) { | 185 TEST_F(MemoryCoordinatorImplTest, SetMemoryStateNotDeliveredNop) { |
| 184 auto cmc1 = coordinator_->CreateChildMemoryCoordinator(1); | 186 auto cmc1 = coordinator_->CreateChildMemoryCoordinator(1); |
| 185 | 187 |
| 186 EXPECT_FALSE( | 188 EXPECT_FALSE( |
| 187 coordinator_->SetChildMemoryState(2, mojom::MemoryState::NORMAL)); | 189 coordinator_->SetChildMemoryState(2, MemoryState::NORMAL)); |
| 188 EXPECT_EQ(0, cmc1->on_state_change_calls()); | 190 EXPECT_EQ(0, cmc1->on_state_change_calls()); |
| 189 } | 191 } |
| 190 | 192 |
| 191 TEST_F(MemoryCoordinatorImplTest, SetMemoryStateDelivered) { | 193 TEST_F(MemoryCoordinatorImplTest, SetMemoryStateDelivered) { |
| 192 auto cmc1 = coordinator_->CreateChildMemoryCoordinator(1); | 194 auto cmc1 = coordinator_->CreateChildMemoryCoordinator(1); |
| 193 auto cmc2 = coordinator_->CreateChildMemoryCoordinator(2); | 195 auto cmc2 = coordinator_->CreateChildMemoryCoordinator(2); |
| 194 | 196 |
| 195 EXPECT_TRUE( | 197 EXPECT_TRUE( |
| 196 coordinator_->SetChildMemoryState(1, mojom::MemoryState::THROTTLED)); | 198 coordinator_->SetChildMemoryState(1, MemoryState::THROTTLED)); |
| 197 EXPECT_EQ(1, cmc1->on_state_change_calls()); | 199 EXPECT_EQ(1, cmc1->on_state_change_calls()); |
| 198 EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc1->state()); | 200 EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc1->state()); |
| 199 | 201 |
| 200 EXPECT_TRUE( | 202 EXPECT_TRUE( |
| 201 coordinator_->SetChildMemoryState(2, mojom::MemoryState::SUSPENDED)); | 203 coordinator_->SetChildMemoryState(2, MemoryState::SUSPENDED)); |
| 202 EXPECT_EQ(1, cmc2->on_state_change_calls()); | 204 EXPECT_EQ(1, cmc2->on_state_change_calls()); |
| 203 // Child processes are considered as visible (foreground) by default, | 205 // Child processes are considered as visible (foreground) by default, |
| 204 // and visible ones won't be suspended but throttled. | 206 // and visible ones won't be suspended but throttled. |
| 205 EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc2->state()); | 207 EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc2->state()); |
| 206 } | 208 } |
| 207 | 209 |
| 208 TEST_F(MemoryCoordinatorImplTest, SetChildMemoryState) { | 210 TEST_F(MemoryCoordinatorImplTest, SetChildMemoryState) { |
| 209 auto cmc = coordinator_->CreateChildMemoryCoordinator(1); | 211 auto cmc = coordinator_->CreateChildMemoryCoordinator(1); |
| 210 auto iter = coordinator_->children().find(1); | 212 auto iter = coordinator_->children().find(1); |
| 211 ASSERT_TRUE(iter != coordinator_->children().end()); | 213 ASSERT_TRUE(iter != coordinator_->children().end()); |
| 212 | 214 |
| 213 // Foreground | 215 // Foreground |
| 214 iter->second.is_visible = true; | 216 iter->second.is_visible = true; |
| 215 EXPECT_TRUE(coordinator_->SetChildMemoryState(1, mojom::MemoryState::NORMAL)); | 217 EXPECT_TRUE(coordinator_->SetChildMemoryState(1, MemoryState::NORMAL)); |
| 216 EXPECT_EQ(mojom::MemoryState::NORMAL, cmc->state()); | 218 EXPECT_EQ(mojom::MemoryState::NORMAL, cmc->state()); |
| 217 EXPECT_TRUE( | 219 EXPECT_TRUE( |
| 218 coordinator_->SetChildMemoryState(1, mojom::MemoryState::THROTTLED)); | 220 coordinator_->SetChildMemoryState(1, MemoryState::THROTTLED)); |
| 219 EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc->state()); | 221 EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc->state()); |
| 220 EXPECT_TRUE( | 222 EXPECT_TRUE( |
| 221 coordinator_->SetChildMemoryState(1, mojom::MemoryState::SUSPENDED)); | 223 coordinator_->SetChildMemoryState(1, MemoryState::SUSPENDED)); |
| 222 EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc->state()); | 224 EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc->state()); |
| 223 | 225 |
| 224 // Background | 226 // Background |
| 225 iter->second.is_visible = false; | 227 iter->second.is_visible = false; |
| 226 EXPECT_TRUE(coordinator_->SetChildMemoryState(1, mojom::MemoryState::NORMAL)); | 228 EXPECT_TRUE(coordinator_->SetChildMemoryState(1, MemoryState::NORMAL)); |
| 227 #if defined(OS_ANDROID) | 229 #if defined(OS_ANDROID) |
| 228 EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc->state()); | 230 EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc->state()); |
| 229 #else | 231 #else |
| 230 EXPECT_EQ(mojom::MemoryState::NORMAL, cmc->state()); | 232 EXPECT_EQ(mojom::MemoryState::NORMAL, cmc->state()); |
| 231 #endif | 233 #endif |
| 232 EXPECT_TRUE( | 234 EXPECT_TRUE( |
| 233 coordinator_->SetChildMemoryState(1, mojom::MemoryState::THROTTLED)); | 235 coordinator_->SetChildMemoryState(1, MemoryState::THROTTLED)); |
| 234 EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc->state()); | 236 EXPECT_EQ(mojom::MemoryState::THROTTLED, cmc->state()); |
| 235 EXPECT_TRUE( | 237 EXPECT_TRUE( |
| 236 coordinator_->SetChildMemoryState(1, mojom::MemoryState::SUSPENDED)); | 238 coordinator_->SetChildMemoryState(1, MemoryState::SUSPENDED)); |
| 237 EXPECT_EQ(mojom::MemoryState::SUSPENDED, cmc->state()); | 239 EXPECT_EQ(mojom::MemoryState::SUSPENDED, cmc->state()); |
| 238 } | 240 } |
| 239 | 241 |
| 240 TEST_F(MemoryCoordinatorImplTest, CalculateNextState) { | 242 TEST_F(MemoryCoordinatorImplTest, CalculateNextState) { |
| 241 auto* state_updater = coordinator_->state_updater_.get(); | 243 auto* state_updater = coordinator_->state_updater_.get(); |
| 242 state_updater->expected_renderer_size_ = 10; | 244 state_updater->expected_renderer_size_ = 10; |
| 243 state_updater->new_renderers_until_throttled_ = 4; | 245 state_updater->new_renderers_until_throttled_ = 4; |
| 244 state_updater->new_renderers_until_suspended_ = 2; | 246 state_updater->new_renderers_until_suspended_ = 2; |
| 245 state_updater->new_renderers_back_to_normal_ = 5; | 247 state_updater->new_renderers_back_to_normal_ = 5; |
| 246 state_updater->new_renderers_back_to_throttled_ = 3; | 248 state_updater->new_renderers_back_to_throttled_ = 3; |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 // Also make sure that the state is updated based on free avaiable memory. | 417 // Also make sure that the state is updated based on free avaiable memory. |
| 416 // Since the global state has changed in the previous task, we have to wait | 418 // Since the global state has changed in the previous task, we have to wait |
| 417 // for |minimum_transition|. | 419 // for |minimum_transition|. |
| 418 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(40); | 420 GetMockMemoryMonitor()->SetFreeMemoryUntilCriticalMB(40); |
| 419 task_runner_->FastForwardBy(minimum_transition); | 421 task_runner_->FastForwardBy(minimum_transition); |
| 420 task_runner_->RunUntilIdle(); | 422 task_runner_->RunUntilIdle(); |
| 421 EXPECT_EQ(base::MemoryState::THROTTLED, coordinator_->GetGlobalMemoryState()); | 423 EXPECT_EQ(base::MemoryState::THROTTLED, coordinator_->GetGlobalMemoryState()); |
| 422 } | 424 } |
| 423 | 425 |
| 424 } // namespace content | 426 } // namespace content |
| OLD | NEW |