OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "athena/resource_manager/public/resource_manager.h" | 5 #include "athena/resource_manager/public/resource_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "athena/activity/public/activity.h" | 10 #include "athena/activity/public/activity.h" |
11 #include "athena/activity/public/activity_manager.h" | 11 #include "athena/activity/public/activity_manager.h" |
12 #include "athena/activity/public/activity_manager_observer.h" | 12 #include "athena/activity/public/activity_manager_observer.h" |
13 #include "athena/resource_manager/memory_pressure_notifier.h" | 13 #include "athena/resource_manager/memory_pressure_notifier.h" |
14 #include "athena/resource_manager/public/resource_manager_delegate.h" | 14 #include "athena/resource_manager/public/resource_manager_delegate.h" |
15 #include "athena/wm/public/window_list_provider.h" | 15 #include "athena/wm/public/window_list_provider.h" |
16 #include "athena/wm/public/window_list_provider_observer.h" | 16 #include "athena/wm/public/window_list_provider_observer.h" |
17 #include "athena/wm/public/window_manager.h" | 17 #include "athena/wm/public/window_manager.h" |
18 #include "athena/wm/public/window_manager_observer.h" | 18 #include "athena/wm/public/window_manager_observer.h" |
19 #include "base/containers/adapters.h" | |
19 #include "base/logging.h" | 20 #include "base/logging.h" |
20 #include "base/memory/scoped_ptr.h" | 21 #include "base/memory/scoped_ptr.h" |
21 #include "base/time/time.h" | 22 #include "base/time/time.h" |
22 #include "ui/aura/window.h" | 23 #include "ui/aura/window.h" |
23 | 24 |
24 namespace athena { | 25 namespace athena { |
25 namespace { | 26 namespace { |
26 | 27 |
27 class ResourceManagerImpl : public ResourceManager, | 28 class ResourceManagerImpl : public ResourceManager, |
28 public WindowManagerObserver, | 29 public WindowManagerObserver, |
(...skipping 15 matching lines...) Expand all Loading... | |
44 } | 45 } |
45 | 46 |
46 virtual void Pause(bool pause) override { | 47 virtual void Pause(bool pause) override { |
47 if (pause) { | 48 if (pause) { |
48 if (!pause_) | 49 if (!pause_) |
49 queued_command_ = false; | 50 queued_command_ = false; |
50 ++pause_; | 51 ++pause_; |
51 } else { | 52 } else { |
52 DCHECK(pause_); | 53 DCHECK(pause_); |
53 --pause_; | 54 --pause_; |
54 if (!pause && queued_command_) { | 55 if (!pause && queued_command_) |
55 UpdateActivityOrder(); | |
56 ManageResource(); | 56 ManageResource(); |
57 } | |
58 } | 57 } |
59 } | 58 } |
60 | 59 |
61 // ActivityManagerObserver: | 60 // ActivityManagerObserver: |
62 virtual void OnActivityStarted(Activity* activity) override; | 61 virtual void OnActivityStarted(Activity* activity) override; |
63 virtual void OnActivityEnding(Activity* activity) override; | 62 virtual void OnActivityEnding(Activity* activity) override; |
63 virtual void OnActivityOrderChanged() override; | |
64 | 64 |
65 // WindowManagerObserver: | 65 // WindowManagerObserver: |
66 virtual void OnOverviewModeEnter() override; | 66 virtual void OnOverviewModeEnter() override; |
67 virtual void OnOverviewModeExit() override; | 67 virtual void OnOverviewModeExit() override; |
68 virtual void OnSplitViewModeEnter() override; | 68 virtual void OnSplitViewModeEnter() override; |
69 virtual void OnSplitViewModeExit() override; | 69 virtual void OnSplitViewModeExit() override; |
70 | 70 |
71 // MemoryPressureObserver: | 71 // MemoryPressureObserver: |
72 virtual void OnMemoryPressure(MemoryPressure pressure) override; | 72 virtual void OnMemoryPressure(MemoryPressure pressure) override; |
73 virtual ResourceManagerDelegate* GetDelegate() override; | 73 virtual ResourceManagerDelegate* GetDelegate() override; |
74 | 74 |
75 // WindowListProviderObserver: | 75 // WindowListProviderObserver: |
76 virtual void OnWindowStackingChangedInList() override; | 76 virtual void OnWindowStackingChangedInList() override; |
77 virtual void OnWindowAddedToList(aura::Window* added_window) override {} | 77 virtual void OnWindowAddedToList(aura::Window* added_window) override {} |
78 virtual void OnWindowRemovedFromList(aura::Window* removed_window, | 78 virtual void OnWindowRemovedFromList(aura::Window* removed_window, |
79 int index) override {} | 79 int index) override {} |
80 | 80 |
81 private: | 81 private: |
82 // Manage the resources for our activities. | 82 // Manage the resources for our activities. |
83 void ManageResource(); | 83 void ManageResource(); |
84 | 84 |
85 // Check that the visibility of activities is properly set. | 85 // Check that the visibility of activities is properly set. |
86 void UpdateVisibilityStates(); | 86 void UpdateVisibilityStates(); |
87 | 87 |
88 // Check if activities can be unloaded to reduce memory pressure. | 88 // Check if activities can be unloaded to reduce memory pressure. |
89 void TryToUnloadAnActivity(); | 89 void TryToUnloadAnActivity(); |
90 | 90 |
91 // Order our activity list to the order of activities of the stream. | |
92 // TODO(skuhne): Once the ActivityManager is responsible to create this list | |
93 // for us, we can remove this code here. | |
94 void UpdateActivityOrder(); | |
95 | |
96 // Resources were released and a quiet period is needed before we release | 91 // Resources were released and a quiet period is needed before we release |
97 // more since it takes a while to trickle through the system. | 92 // more since it takes a while to trickle through the system. |
98 void OnResourcesReleased(); | 93 void OnResourcesReleased(); |
99 | 94 |
100 // The memory pressure has increased, previously applied measures did not show | 95 // The memory pressure has increased, previously applied measures did not show |
101 // effect and immediate action is required. | 96 // effect and immediate action is required. |
102 void OnMemoryPressureIncreased(); | 97 void OnMemoryPressureIncreased(); |
103 | 98 |
104 // Returns true when the previous memory release was long enough ago to try | 99 // Returns true when the previous memory release was long enough ago to try |
105 // unloading another activity. | 100 // unloading another activity. |
106 bool AllowedToUnloadActivity(); | 101 bool AllowedToUnloadActivity(); |
107 | 102 |
108 // The sorted (new(front) -> old(back)) activity list. | |
109 // TODO(skuhne): Once the ActivityManager is responsible to create this list | |
110 // for us, we can remove this code here. | |
111 std::vector<Activity*> activity_list_; | |
112 | |
113 // The resource manager delegate. | 103 // The resource manager delegate. |
114 scoped_ptr<ResourceManagerDelegate> delegate_; | 104 scoped_ptr<ResourceManagerDelegate> delegate_; |
115 | 105 |
116 // Keeping a reference to the current memory pressure. | 106 // Keeping a reference to the current memory pressure. |
117 MemoryPressure current_memory_pressure_; | 107 MemoryPressure current_memory_pressure_; |
118 | 108 |
119 // The memory pressure notifier. | 109 // The memory pressure notifier. |
120 scoped_ptr<MemoryPressureNotifier> memory_pressure_notifier_; | 110 scoped_ptr<MemoryPressureNotifier> memory_pressure_notifier_; |
121 | 111 |
122 // A ref counter. As long as not 0, the management is on hold. | 112 // A ref counter. As long as not 0, the management is on hold. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
170 delegate_->MemoryPressureIntervalInMS())) { | 160 delegate_->MemoryPressureIntervalInMS())) { |
171 WindowManager::Get()->AddObserver(this); | 161 WindowManager::Get()->AddObserver(this); |
172 WindowManager::Get()->GetWindowListProvider()->AddObserver(this); | 162 WindowManager::Get()->GetWindowListProvider()->AddObserver(this); |
173 ActivityManager::Get()->AddObserver(this); | 163 ActivityManager::Get()->AddObserver(this); |
174 } | 164 } |
175 | 165 |
176 ResourceManagerImpl::~ResourceManagerImpl() { | 166 ResourceManagerImpl::~ResourceManagerImpl() { |
177 ActivityManager::Get()->RemoveObserver(this); | 167 ActivityManager::Get()->RemoveObserver(this); |
178 WindowManager::Get()->GetWindowListProvider()->RemoveObserver(this); | 168 WindowManager::Get()->GetWindowListProvider()->RemoveObserver(this); |
179 WindowManager::Get()->RemoveObserver(this); | 169 WindowManager::Get()->RemoveObserver(this); |
180 | |
181 while (!activity_list_.empty()) | |
182 OnActivityEnding(activity_list_.front()); | |
183 } | 170 } |
184 | 171 |
185 void ResourceManagerImpl::SetMemoryPressureAndStopMonitoring( | 172 void ResourceManagerImpl::SetMemoryPressureAndStopMonitoring( |
186 MemoryPressure pressure) { | 173 MemoryPressure pressure) { |
187 memory_pressure_notifier_->StopObserving(); | 174 memory_pressure_notifier_->StopObserving(); |
188 OnMemoryPressure(pressure); | 175 OnMemoryPressure(pressure); |
189 } | 176 } |
190 | 177 |
191 void ResourceManagerImpl::OnActivityStarted(Activity* activity) { | 178 void ResourceManagerImpl::OnActivityStarted(Activity* activity) { |
192 // As long as we have to manage the list of activities ourselves, we need to | |
193 // order it here. | |
194 activity_list_.push_back(activity); | |
195 UpdateActivityOrder(); | |
196 // Update the activity states. | 179 // Update the activity states. |
197 ManageResource(); | 180 ManageResource(); |
198 // Remember that the activity order has changed. | |
199 activity_order_changed_ = true; | 181 activity_order_changed_ = true; |
200 } | 182 } |
201 | 183 |
202 void ResourceManagerImpl::OnActivityEnding(Activity* activity) { | 184 void ResourceManagerImpl::OnActivityEnding(Activity* activity) { |
203 DCHECK(activity->GetWindow()); | |
204 // Remove the activity from the list again. | |
205 std::vector<Activity*>::iterator it = | |
206 std::find(activity_list_.begin(), activity_list_.end(), activity); | |
207 DCHECK(it != activity_list_.end()); | |
208 activity_list_.erase(it); | |
209 // Remember that the activity order has changed. | |
210 activity_order_changed_ = true; | 185 activity_order_changed_ = true; |
211 } | 186 } |
212 | 187 |
188 void ResourceManagerImpl::OnActivityOrderChanged() { | |
189 activity_order_changed_ = true; | |
190 } | |
191 | |
213 void ResourceManagerImpl::OnOverviewModeEnter() { | 192 void ResourceManagerImpl::OnOverviewModeEnter() { |
214 in_overview_mode_ = true; | 193 in_overview_mode_ = true; |
215 } | 194 } |
216 | 195 |
217 void ResourceManagerImpl::OnOverviewModeExit() { | 196 void ResourceManagerImpl::OnOverviewModeExit() { |
218 in_overview_mode_ = false; | 197 in_overview_mode_ = false; |
219 // Reorder the activities and manage the resources again since an order change | |
220 // might have caused a visibility change. | |
221 UpdateActivityOrder(); | |
222 ManageResource(); | 198 ManageResource(); |
223 } | 199 } |
224 | 200 |
225 void ResourceManagerImpl::OnSplitViewModeEnter() { | 201 void ResourceManagerImpl::OnSplitViewModeEnter() { |
226 // Re-apply the memory pressure to make sure enough items are visible. | 202 // Re-apply the memory pressure to make sure enough items are visible. |
227 in_split_view_mode_ = true; | 203 in_split_view_mode_ = true; |
228 ManageResource(); | 204 ManageResource(); |
229 } | 205 } |
230 | 206 |
231 | 207 |
232 void ResourceManagerImpl::OnSplitViewModeExit() { | 208 void ResourceManagerImpl::OnSplitViewModeExit() { |
233 // We don't do immediately something yet. The next ManageResource call will | 209 // We don't do immediately something yet. The next ManageResource call will |
234 // come soon. | 210 // come soon. |
235 in_split_view_mode_ = false; | 211 in_split_view_mode_ = false; |
236 } | 212 } |
237 | 213 |
238 void ResourceManagerImpl::OnWindowStackingChangedInList() { | 214 void ResourceManagerImpl::OnWindowStackingChangedInList() { |
239 activity_order_changed_ = true; | |
240 if (pause_) { | 215 if (pause_) { |
241 queued_command_ = true; | 216 queued_command_ = true; |
242 return; | 217 return; |
243 } | 218 } |
244 | 219 |
245 // No need to do anything while being in overview mode. | 220 // No need to do anything while being in overview mode. |
246 if (in_overview_mode_) | 221 if (in_overview_mode_) |
247 return; | 222 return; |
248 | 223 |
249 // As long as we have to manage the list of activities ourselves, we need to | |
250 // order it here. | |
251 UpdateActivityOrder(); | |
252 | |
253 // Manage the resources of each activity. | 224 // Manage the resources of each activity. |
254 ManageResource(); | 225 ManageResource(); |
255 } | 226 } |
256 | 227 |
257 void ResourceManagerImpl::OnMemoryPressure(MemoryPressure pressure) { | 228 void ResourceManagerImpl::OnMemoryPressure(MemoryPressure pressure) { |
258 if (pressure > current_memory_pressure_) | 229 if (pressure > current_memory_pressure_) |
259 OnMemoryPressureIncreased(); | 230 OnMemoryPressureIncreased(); |
260 current_memory_pressure_ = pressure; | 231 current_memory_pressure_ = pressure; |
261 ManageResource(); | 232 ManageResource(); |
262 } | 233 } |
263 | 234 |
264 ResourceManagerDelegate* ResourceManagerImpl::GetDelegate() { | 235 ResourceManagerDelegate* ResourceManagerImpl::GetDelegate() { |
265 return delegate_.get(); | 236 return delegate_.get(); |
266 } | 237 } |
267 | 238 |
268 void ResourceManagerImpl::ManageResource() { | 239 void ResourceManagerImpl::ManageResource() { |
269 // If there is none or only one app running we cannot do anything. | 240 // If there is none or only one app running we cannot do anything. |
270 if (activity_list_.size() <= 1U) | 241 if (ActivityManager::Get()->GetActivities().size() <= 1U) |
271 return; | 242 return; |
272 | 243 |
273 if (pause_) { | 244 if (pause_) { |
274 queued_command_ = true; | 245 queued_command_ = true; |
275 return; | 246 return; |
276 } | 247 } |
277 | 248 |
278 // Check that the visibility of items is properly set. Note that this might | 249 // Check that the visibility of items is properly set. Note that this might |
279 // already trigger a release of resources. If this happens, | 250 // already trigger a release of resources. If this happens, |
280 // AllowedToUnloadActivity() will return false. | 251 // AllowedToUnloadActivity() will return false. |
281 UpdateVisibilityStates(); | 252 UpdateVisibilityStates(); |
282 | 253 |
283 // Since resource deallocation takes time, we avoid to release more resources | 254 // Since resource deallocation takes time, we avoid to release more resources |
284 // in short succession. Note that we come here periodically and if one call | 255 // in short succession. Note that we come here periodically and if one call |
285 // is not triggering an unload, the next one will. | 256 // is not triggering an unload, the next one will. |
286 if (AllowedToUnloadActivity()) | 257 if (AllowedToUnloadActivity()) |
287 TryToUnloadAnActivity(); | 258 TryToUnloadAnActivity(); |
288 } | 259 } |
289 | 260 |
290 void ResourceManagerImpl::UpdateVisibilityStates() { | 261 void ResourceManagerImpl::UpdateVisibilityStates() { |
291 // The first n activities should be treated as "visible", means they updated | 262 // The first n activities should be treated as "visible", means they updated |
292 // in overview mode and will keep their layer resources for faster switch | 263 // in overview mode and will keep their layer resources for faster switch |
293 // times. Usually we use |kMaxVisibleActivities| items, but when the memory | 264 // times. Usually we use |kMaxVisibleActivities| items, but when the memory |
294 // pressure gets critical we only hold as many as are really visible. | 265 // pressure gets critical we only hold as many as are really visible. |
295 size_t max_activities = kMaxVisibleActivities; | 266 size_t max_activities = kMaxVisibleActivities; |
296 if (current_memory_pressure_ == MEMORY_PRESSURE_CRITICAL) | 267 if (current_memory_pressure_ == MEMORY_PRESSURE_CRITICAL) |
297 max_activities = in_split_view_mode_ ? 2 : 1; | 268 max_activities = in_split_view_mode_ ? 2 : 1; |
298 | 269 |
299 // Restart and / or bail if the order of activities changes due to our calls. | 270 do { |
300 activity_order_changed_ = false; | 271 activity_order_changed_ = false; |
301 | 272 |
302 // Change the visibility of our activities in a pre-processing step. This is | 273 // Change the visibility of our activities in a pre-processing step. This is |
303 // required since it might change the order/number of activities. | 274 // required since it might change the order/number of activities. |
304 size_t index = 0; | 275 size_t count = 0; |
305 while (index < activity_list_.size()) { | 276 for (Activity* activity : ActivityManager::Get()->GetActivities()) { |
306 Activity* activity = activity_list_[index]; | 277 Activity::ActivityState state = activity->GetCurrentState(); |
307 Activity::ActivityState state = activity->GetCurrentState(); | |
308 | 278 |
309 // The first |kMaxVisibleActivities| entries should be visible, all others | 279 // The first |kMaxVisibleActivities| entries should be visible, all others |
310 // invisible or at a lower activity state. | 280 // invisible or at a lower activity state. |
311 if (index < max_activities || | 281 if (count < max_activities || |
312 (state == Activity::ACTIVITY_INVISIBLE || | 282 (state == Activity::ACTIVITY_INVISIBLE || |
313 state == Activity::ACTIVITY_VISIBLE)) { | 283 state == Activity::ACTIVITY_VISIBLE)) { |
314 Activity::ActivityState visiblity_state = | 284 Activity::ActivityState visiblity_state = |
315 index < max_activities ? Activity::ACTIVITY_VISIBLE : | 285 count < max_activities ? Activity::ACTIVITY_VISIBLE : |
316 Activity::ACTIVITY_INVISIBLE; | 286 Activity::ACTIVITY_INVISIBLE; |
317 // Only change the state when it changes. Note that when the memory | 287 // Only change the state when it changes. Note that when the memory |
318 // pressure is critical, only the primary activities (1 or 2) are made | 288 // pressure is critical, only the primary activities (1 or 2) are made |
319 // visible. Furthermore, in relaxed mode we only want to turn visible, | 289 // visible. Furthermore, in relaxed mode we only want to turn visible, |
320 // never invisible. | 290 // never invisible. |
321 if (visiblity_state != state && | 291 if (visiblity_state != state && |
322 (current_memory_pressure_ != MEMORY_PRESSURE_LOW || | 292 (current_memory_pressure_ != MEMORY_PRESSURE_LOW || |
323 visiblity_state == Activity::ACTIVITY_VISIBLE)) { | 293 visiblity_state == Activity::ACTIVITY_VISIBLE)) { |
324 activity->SetCurrentState(visiblity_state); | 294 activity->SetCurrentState(visiblity_state); |
325 // If we turned an activity invisible, we are already releasing memory | 295 // If we turned an activity invisible, we are already releasing memory |
326 // and can hold off releasing more for now. | 296 // and can hold off releasing more for now. |
327 if (visiblity_state == Activity::ACTIVITY_INVISIBLE) | 297 if (visiblity_state == Activity::ACTIVITY_INVISIBLE) |
328 OnResourcesReleased(); | 298 OnResourcesReleased(); |
299 } | |
329 } | 300 } |
301 | |
302 // See which count we should handle next. | |
303 if (activity_order_changed_) | |
304 break; | |
305 ++count; | |
330 } | 306 } |
331 | 307 // If we stopped iterating over the list of activities because of the change |
332 // See which index we should handle next. | 308 // in ordering, then restart processing the activities from the beginning. |
333 if (activity_order_changed_) { | 309 } while (activity_order_changed_); |
334 activity_order_changed_ = false; | |
335 index = 0; | |
336 } else { | |
337 ++index; | |
338 } | |
339 } | |
340 } | 310 } |
341 | 311 |
342 void ResourceManagerImpl::TryToUnloadAnActivity() { | 312 void ResourceManagerImpl::TryToUnloadAnActivity() { |
343 // TODO(skuhne): This algorithm needs to take all kinds of predictive analysis | 313 // TODO(skuhne): This algorithm needs to take all kinds of predictive analysis |
344 // and running applications into account. For this first patch we only do a | 314 // and running applications into account. For this first patch we only do a |
345 // very simple "floating window" algorithm which is surely not good enough. | 315 // very simple "floating window" algorithm which is surely not good enough. |
346 size_t max_running_activities = 5; | 316 size_t max_running_activities = 5; |
347 switch (current_memory_pressure_) { | 317 switch (current_memory_pressure_) { |
348 case MEMORY_PRESSURE_UNKNOWN: | 318 case MEMORY_PRESSURE_UNKNOWN: |
349 // If we do not know how much memory we have we assume that it must be a | 319 // If we do not know how much memory we have we assume that it must be a |
350 // high consumption. | 320 // high consumption. |
351 // Fallthrough. | 321 // Fallthrough. |
352 case MEMORY_PRESSURE_HIGH: | 322 case MEMORY_PRESSURE_HIGH: |
353 max_running_activities = 5; | 323 max_running_activities = 5; |
354 break; | 324 break; |
355 case MEMORY_PRESSURE_CRITICAL: | 325 case MEMORY_PRESSURE_CRITICAL: |
356 max_running_activities = 0; | 326 max_running_activities = 0; |
357 break; | 327 break; |
358 case MEMORY_PRESSURE_MODERATE: | 328 case MEMORY_PRESSURE_MODERATE: |
359 max_running_activities = 7; | 329 max_running_activities = 7; |
360 break; | 330 break; |
361 case MEMORY_PRESSURE_LOW: | 331 case MEMORY_PRESSURE_LOW: |
362 NOTREACHED(); | 332 NOTREACHED(); |
363 return; | 333 return; |
364 } | 334 } |
365 | 335 |
366 // Check if / which activity we want to unload. | 336 // Check if / which activity we want to unload. |
367 Activity* oldest_media_activity = nullptr; | 337 Activity* oldest_media_activity = nullptr; |
368 std::vector<Activity*> unloadable_activities; | 338 Activity* oldest_unloadable_activity = nullptr; |
369 for (std::vector<Activity*>::iterator it = activity_list_.begin(); | 339 size_t unloadable_activity_count = 0; |
370 it != activity_list_.end(); ++it) { | 340 const ActivityList& activity_list = ActivityManager::Get()->GetActivities(); |
371 Activity::ActivityState state = (*it)->GetCurrentState(); | 341 for (Activity* activity : activity_list) { |
342 Activity::ActivityState state = activity->GetCurrentState(); | |
372 // The activity should neither be unloaded nor visible. | 343 // The activity should neither be unloaded nor visible. |
373 if (state != Activity::ACTIVITY_UNLOADED && | 344 if (state != Activity::ACTIVITY_UNLOADED && |
374 state != Activity::ACTIVITY_VISIBLE) { | 345 state != Activity::ACTIVITY_VISIBLE) { |
375 if ((*it)->GetMediaState() == Activity::ACTIVITY_MEDIA_STATE_NONE) { | 346 if (activity->GetMediaState() == Activity::ACTIVITY_MEDIA_STATE_NONE) { |
376 // Does not play media - so we can unload this immediately. | 347 // Does not play media - so we can unload this immediately. |
377 unloadable_activities.push_back(*it); | 348 ++unloadable_activity_count; |
Mr4D (OOO till 08-26)
2014/11/03 23:48:00
For the time being this is ok.
However - note that
sadrul
2014/11/04 03:43:46
Acknowledged.
| |
349 oldest_unloadable_activity = activity; | |
378 } else { | 350 } else { |
379 oldest_media_activity = *it; | 351 oldest_media_activity = activity; |
380 } | 352 } |
381 } | 353 } |
382 } | 354 } |
383 | 355 |
384 if (unloadable_activities.size() > max_running_activities) { | 356 if (unloadable_activity_count > max_running_activities) { |
357 CHECK(oldest_unloadable_activity); | |
385 OnResourcesReleased(); | 358 OnResourcesReleased(); |
386 unloadable_activities.back()->SetCurrentState(Activity::ACTIVITY_UNLOADED); | 359 oldest_unloadable_activity->SetCurrentState(Activity::ACTIVITY_UNLOADED); |
387 return; | 360 return; |
388 } else if (current_memory_pressure_ == MEMORY_PRESSURE_CRITICAL) { | 361 } else if (current_memory_pressure_ == MEMORY_PRESSURE_CRITICAL) { |
389 if (oldest_media_activity) { | 362 if (oldest_media_activity) { |
390 OnResourcesReleased(); | 363 OnResourcesReleased(); |
391 oldest_media_activity->SetCurrentState(Activity::ACTIVITY_UNLOADED); | 364 oldest_media_activity->SetCurrentState(Activity::ACTIVITY_UNLOADED); |
392 LOG(WARNING) << "Unloading item to releave critical memory pressure"; | 365 LOG(WARNING) << "Unloading item to releave critical memory pressure"; |
393 return; | 366 return; |
394 } | 367 } |
395 LOG(ERROR) << "[ResourceManager]: Single activity uses too much memory."; | 368 LOG(ERROR) << "[ResourceManager]: Single activity uses too much memory."; |
396 return; | 369 return; |
397 } | 370 } |
398 | 371 |
399 if (current_memory_pressure_ != MEMORY_PRESSURE_UNKNOWN) { | 372 if (current_memory_pressure_ != MEMORY_PRESSURE_UNKNOWN) { |
400 // Only show this warning when the memory pressure is actually known. This | 373 // Only show this warning when the memory pressure is actually known. This |
401 // will suppress warnings in e.g. unit tests. | 374 // will suppress warnings in e.g. unit tests. |
402 LOG(WARNING) << "[ResourceManager]: No way to release memory pressure (" << | 375 LOG(WARNING) << "[ResourceManager]: No way to release memory pressure (" << |
403 current_memory_pressure_ << | 376 current_memory_pressure_ << |
404 "), Activities (running, allowed, unloadable)=(" << | 377 "), Activities (running, allowed, unloadable)=(" << |
405 activity_list_.size() << ", " << | 378 activity_list.size() << ", " << |
406 max_running_activities << ", " << | 379 max_running_activities << ", " << |
407 unloadable_activities.size() << ")"; | 380 unloadable_activity_count << ")"; |
408 } | 381 } |
409 } | 382 } |
410 | 383 |
411 void ResourceManagerImpl::UpdateActivityOrder() { | |
412 queued_command_ = true; | |
413 if (activity_list_.empty()) | |
414 return; | |
415 std::vector<Activity*> new_activity_list; | |
416 const aura::Window::Windows children = | |
417 WindowManager::Get()->GetWindowListProvider()->GetWindowList(); | |
418 // Find the first window in the container which is part of the application. | |
419 for (aura::Window::Windows::const_reverse_iterator child_iterator = | |
420 children.rbegin(); | |
421 child_iterator != children.rend(); ++child_iterator) { | |
422 for (std::vector<Activity*>::iterator activity_iterator = | |
423 activity_list_.begin(); | |
424 activity_iterator != activity_list_.end(); ++activity_iterator) { | |
425 if (*child_iterator == (*activity_iterator)->GetWindow()) { | |
426 new_activity_list.push_back(*activity_iterator); | |
427 activity_list_.erase(activity_iterator); | |
428 break; | |
429 } | |
430 } | |
431 } | |
432 // At this point the old list should be empty and we can swap the lists. | |
433 DCHECK(!activity_list_.size()); | |
434 activity_list_ = new_activity_list; | |
435 | |
436 // Remember that the activity order has changed. | |
437 activity_order_changed_ = true; | |
438 } | |
439 | |
440 void ResourceManagerImpl::OnResourcesReleased() { | 384 void ResourceManagerImpl::OnResourcesReleased() { |
441 // Do not release too many activities in short succession since it takes time | 385 // Do not release too many activities in short succession since it takes time |
442 // to release resources. As such wait the memory pressure interval before the | 386 // to release resources. As such wait the memory pressure interval before the |
443 // next call. | 387 // next call. |
444 next_resource_management_time_ = base::Time::Now() + | 388 next_resource_management_time_ = base::Time::Now() + |
445 wait_time_for_resource_deallocation_; | 389 wait_time_for_resource_deallocation_; |
446 } | 390 } |
447 | 391 |
448 void ResourceManagerImpl::OnMemoryPressureIncreased() { | 392 void ResourceManagerImpl::OnMemoryPressureIncreased() { |
449 // By setting the timer to Now, the next call will immediately be performed. | 393 // By setting the timer to Now, the next call will immediately be performed. |
(...skipping 27 matching lines...) Expand all Loading... | |
477 } | 421 } |
478 | 422 |
479 ResourceManager::ResourceManager() {} | 423 ResourceManager::ResourceManager() {} |
480 | 424 |
481 ResourceManager::~ResourceManager() { | 425 ResourceManager::~ResourceManager() { |
482 DCHECK(instance); | 426 DCHECK(instance); |
483 instance = nullptr; | 427 instance = nullptr; |
484 } | 428 } |
485 | 429 |
486 } // namespace athena | 430 } // namespace athena |
OLD | NEW |