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 |