Chromium Code Reviews| 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 |