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_manager.h" | 15 #include "athena/wm/public/window_manager.h" |
16 #include "athena/wm/public/window_manager_observer.h" | 16 #include "athena/wm/public/window_manager_observer.h" |
17 #include "base/logging.h" | 17 #include "base/logging.h" |
18 #include "base/memory/scoped_ptr.h" | 18 #include "base/memory/scoped_ptr.h" |
19 #include "ui/aura/window.h" | 19 #include "ui/aura/window.h" |
| 20 #include "ui/aura/window_observer.h" |
20 | 21 |
21 namespace athena { | 22 namespace athena { |
22 | 23 |
23 class ResourceManagerImpl : public ResourceManager, | 24 class ResourceManagerImpl : public ResourceManager, |
24 public WindowManagerObserver, | 25 public WindowManagerObserver, |
25 public ActivityManagerObserver, | 26 public ActivityManagerObserver, |
26 public MemoryPressureObserver { | 27 public MemoryPressureObserver, |
| 28 public aura::WindowObserver { |
27 public: | 29 public: |
28 ResourceManagerImpl(ResourceManagerDelegate* delegate); | 30 ResourceManagerImpl(ResourceManagerDelegate* delegate); |
29 virtual ~ResourceManagerImpl(); | 31 virtual ~ResourceManagerImpl(); |
30 | 32 |
31 // ResourceManager: | 33 // ResourceManager: |
32 virtual void SetMemoryPressureAndStopMonitoring( | 34 virtual void SetMemoryPressureAndStopMonitoring( |
33 MemoryPressureObserver::MemoryPressure pressure) OVERRIDE; | 35 MemoryPressureObserver::MemoryPressure pressure) OVERRIDE; |
| 36 virtual void Pause(bool pause) OVERRIDE { |
| 37 if (pause) { |
| 38 if (!pause_) |
| 39 queued_command_ = false; |
| 40 ++pause_; |
| 41 } else { |
| 42 DCHECK(pause_); |
| 43 --pause_; |
| 44 if (!pause && queued_command_) { |
| 45 UpdateActivityOrder(); |
| 46 ManageResource(); |
| 47 } |
| 48 } |
| 49 } |
34 | 50 |
35 // ActivityManagerObserver: | 51 // ActivityManagerObserver: |
36 virtual void OnActivityStarted(Activity* activity) OVERRIDE; | 52 virtual void OnActivityStarted(Activity* activity) OVERRIDE; |
37 virtual void OnActivityEnding(Activity* activity) OVERRIDE; | 53 virtual void OnActivityEnding(Activity* activity) OVERRIDE; |
38 | 54 |
39 // WindowManagerObserver: | 55 // WindowManagerObserver: |
40 virtual void OnOverviewModeEnter() OVERRIDE; | 56 virtual void OnOverviewModeEnter() OVERRIDE; |
41 virtual void OnOverviewModeExit() OVERRIDE; | 57 virtual void OnOverviewModeExit() OVERRIDE; |
42 virtual void OnActivityOrderHasChanged() OVERRIDE; | 58 virtual void OnSplitViewModeEnter() OVERRIDE; |
| 59 virtual void OnSplitViewModeExit() OVERRIDE; |
43 | 60 |
44 // MemoryPressureObserver: | 61 // MemoryPressureObserver: |
45 virtual void OnMemoryPressure( | 62 virtual void OnMemoryPressure( |
46 MemoryPressureObserver::MemoryPressure pressure) OVERRIDE; | 63 MemoryPressureObserver::MemoryPressure pressure) OVERRIDE; |
47 virtual ResourceManagerDelegate* GetDelegate() OVERRIDE; | 64 virtual ResourceManagerDelegate* GetDelegate() OVERRIDE; |
48 | 65 |
| 66 // aura::WindowObserver: |
| 67 virtual void OnWindowStackingChanged(aura::Window* window) OVERRIDE; |
| 68 |
49 private: | 69 private: |
50 // Manage the resources for our activities. | 70 // Manage the resources for our activities. |
51 void ManageResource(); | 71 void ManageResource(); |
52 | 72 |
53 // Order our activity list to the order of activities of the stream. | 73 // Order our activity list to the order of activities of the stream. |
54 // TODO(skuhne): Once the ActivityManager is responsible to create this list | 74 // TODO(skuhne): Once the ActivityManager is responsible to create this list |
55 // for us, we can remove this code here. | 75 // for us, we can remove this code here. |
56 void UpdateActivityOrder(); | 76 void UpdateActivityOrder(); |
57 | 77 |
58 // The sorted (new(front) -> old(back)) activity list. | 78 // The sorted (new(front) -> old(back)) activity list. |
59 // TODO(skuhne): Once the ActivityManager is responsible to create this list | 79 // TODO(skuhne): Once the ActivityManager is responsible to create this list |
60 // for us, we can remove this code here. | 80 // for us, we can remove this code here. |
61 std::vector<Activity*> activity_list_; | 81 std::vector<Activity*> activity_list_; |
62 | 82 |
63 // The resource manager delegate. | 83 // The resource manager delegate. |
64 scoped_ptr<ResourceManagerDelegate> delegate_; | 84 scoped_ptr<ResourceManagerDelegate> delegate_; |
65 | 85 |
66 // Keeping a reference to the current memory pressure. | 86 // Keeping a reference to the current memory pressure. |
67 MemoryPressureObserver::MemoryPressure current_memory_pressure_; | 87 MemoryPressureObserver::MemoryPressure current_memory_pressure_; |
68 | 88 |
69 // The memory pressure notifier. | 89 // The memory pressure notifier. |
70 scoped_ptr<MemoryPressureNotifier> memory_pressure_notifier_; | 90 scoped_ptr<MemoryPressureNotifier> memory_pressure_notifier_; |
71 | 91 |
| 92 // A ref counter. As long as not 0, the management is on hold. |
| 93 int pause_; |
| 94 |
| 95 // If true, a command came in while the resource manager was paused. |
| 96 bool queued_command_; |
| 97 |
| 98 // Used by ManageResource() to determine an activity state change while it |
| 99 // changes Activity properties. |
| 100 bool activity_order_changed_; |
| 101 |
| 102 // True if in overview mode - activity order changes will be ignored if true |
| 103 // and postponed till after the overview mode is ending. |
| 104 bool in_overview_mode_; |
| 105 |
| 106 // True if we are in split view mode. |
| 107 bool in_splitview_mode_; |
| 108 |
72 DISALLOW_COPY_AND_ASSIGN(ResourceManagerImpl); | 109 DISALLOW_COPY_AND_ASSIGN(ResourceManagerImpl); |
73 }; | 110 }; |
74 | 111 |
75 namespace { | 112 namespace { |
76 ResourceManagerImpl* instance = NULL; | 113 ResourceManagerImpl* instance = NULL; |
| 114 |
| 115 // We allow this many activities to be visible. All others must be at state of |
| 116 // invisible or below. |
| 117 const int kMaxVisibleActivities = 3; |
| 118 |
77 } // namespace | 119 } // namespace |
78 | 120 |
79 ResourceManagerImpl::ResourceManagerImpl(ResourceManagerDelegate* delegate) | 121 ResourceManagerImpl::ResourceManagerImpl(ResourceManagerDelegate* delegate) |
80 : delegate_(delegate), | 122 : delegate_(delegate), |
81 current_memory_pressure_(MemoryPressureObserver::MEMORY_PRESSURE_UNKNOWN), | 123 current_memory_pressure_(MemoryPressureObserver::MEMORY_PRESSURE_UNKNOWN), |
82 memory_pressure_notifier_(new MemoryPressureNotifier(this)) { | 124 memory_pressure_notifier_(new MemoryPressureNotifier(this)), |
| 125 pause_(false), |
| 126 queued_command_(false), |
| 127 activity_order_changed_(false), |
| 128 in_overview_mode_(false), |
| 129 in_splitview_mode_(false) { |
83 WindowManager::GetInstance()->AddObserver(this); | 130 WindowManager::GetInstance()->AddObserver(this); |
84 ActivityManager::Get()->AddObserver(this); | 131 ActivityManager::Get()->AddObserver(this); |
85 } | 132 } |
86 | 133 |
87 ResourceManagerImpl::~ResourceManagerImpl() { | 134 ResourceManagerImpl::~ResourceManagerImpl() { |
88 ActivityManager::Get()->RemoveObserver(this); | 135 ActivityManager::Get()->RemoveObserver(this); |
89 WindowManager::GetInstance()->RemoveObserver(this); | 136 WindowManager::GetInstance()->RemoveObserver(this); |
| 137 |
| 138 while (!activity_list_.empty()) |
| 139 OnActivityEnding(activity_list_.front()); |
90 } | 140 } |
91 | 141 |
92 void ResourceManagerImpl::SetMemoryPressureAndStopMonitoring( | 142 void ResourceManagerImpl::SetMemoryPressureAndStopMonitoring( |
93 MemoryPressureObserver::MemoryPressure pressure) { | 143 MemoryPressureObserver::MemoryPressure pressure) { |
94 memory_pressure_notifier_->StopObserving(); | 144 memory_pressure_notifier_->StopObserving(); |
95 OnMemoryPressure(pressure); | 145 OnMemoryPressure(pressure); |
96 } | 146 } |
97 | 147 |
98 void ResourceManagerImpl::OnActivityStarted(Activity* activity) { | 148 void ResourceManagerImpl::OnActivityStarted(Activity* activity) { |
99 // As long as we have to manage the list of activities ourselves, we need to | 149 // As long as we have to manage the list of activities ourselves, we need to |
100 // order it here. | 150 // order it here. |
101 activity_list_.push_back(activity); | 151 activity_list_.push_back(activity); |
102 UpdateActivityOrder(); | 152 UpdateActivityOrder(); |
103 // Update the activity states. | 153 // Update the activity states. |
104 ManageResource(); | 154 ManageResource(); |
| 155 // Remember that the activity order has changed. |
| 156 activity_order_changed_ = true; |
| 157 activity->GetWindow()->AddObserver(this); |
105 } | 158 } |
106 | 159 |
107 void ResourceManagerImpl::OnActivityEnding(Activity* activity) { | 160 void ResourceManagerImpl::OnActivityEnding(Activity* activity) { |
| 161 DCHECK(activity->GetWindow()); |
| 162 activity->GetWindow()->RemoveObserver(this); |
108 // Remove the activity from the list again. | 163 // Remove the activity from the list again. |
109 std::vector<Activity*>::iterator it = | 164 std::vector<Activity*>::iterator it = |
110 std::find(activity_list_.begin(), activity_list_.end(), activity); | 165 std::find(activity_list_.begin(), activity_list_.end(), activity); |
111 DCHECK(it != activity_list_.end()); | 166 DCHECK(it != activity_list_.end()); |
112 activity_list_.erase(it); | 167 activity_list_.erase(it); |
| 168 // Remember that the activity order has changed. |
| 169 activity_order_changed_ = true; |
113 } | 170 } |
114 | 171 |
115 void ResourceManagerImpl::OnOverviewModeEnter() { | 172 void ResourceManagerImpl::OnOverviewModeEnter() { |
116 // Nothing to do here. | 173 in_overview_mode_ = true; |
117 } | 174 } |
118 | 175 |
119 void ResourceManagerImpl::OnOverviewModeExit() { | 176 void ResourceManagerImpl::OnOverviewModeExit() { |
120 // Nothing to do here. | 177 in_overview_mode_ = false; |
| 178 // Reorder the activities. |
| 179 UpdateActivityOrder(); |
121 } | 180 } |
122 | 181 |
123 void ResourceManagerImpl::OnActivityOrderHasChanged() { | 182 void ResourceManagerImpl::OnSplitViewModeEnter() { |
| 183 // Re-apply the memory pressure to make sure enough items are visible. |
| 184 in_splitview_mode_ = true; |
| 185 ManageResource(); |
| 186 } |
| 187 |
| 188 |
| 189 void ResourceManagerImpl::OnSplitViewModeExit() { |
| 190 // We don't do immediately something yet. The next ManageResource call will |
| 191 // come soon. |
| 192 in_splitview_mode_ = false; |
| 193 } |
| 194 |
| 195 void ResourceManagerImpl::OnWindowStackingChanged(aura::Window* window) { |
| 196 // TODO(skuhne): This needs to be changed to some WindowListProvider observer |
| 197 // if we decouple window order from activity order. |
| 198 |
| 199 // No need to do anything while being in overview mode. |
| 200 if (in_overview_mode_) |
| 201 return; |
| 202 |
124 // As long as we have to manage the list of activities ourselves, we need to | 203 // As long as we have to manage the list of activities ourselves, we need to |
125 // order it here. | 204 // order it here. |
126 UpdateActivityOrder(); | 205 UpdateActivityOrder(); |
| 206 |
127 // Manage the resources of each activity. | 207 // Manage the resources of each activity. |
128 ManageResource(); | 208 ManageResource(); |
129 } | 209 } |
130 | 210 |
131 void ResourceManagerImpl::OnMemoryPressure( | 211 void ResourceManagerImpl::OnMemoryPressure( |
132 MemoryPressureObserver::MemoryPressure pressure) { | 212 MemoryPressureObserver::MemoryPressure pressure) { |
133 current_memory_pressure_ = pressure; | 213 current_memory_pressure_ = pressure; |
134 ManageResource(); | 214 ManageResource(); |
135 } | 215 } |
136 | 216 |
137 ResourceManagerDelegate* ResourceManagerImpl::GetDelegate() { | 217 ResourceManagerDelegate* ResourceManagerImpl::GetDelegate() { |
138 return delegate_.get(); | 218 return delegate_.get(); |
139 } | 219 } |
140 | 220 |
141 void ResourceManagerImpl::ManageResource() { | 221 void ResourceManagerImpl::ManageResource() { |
142 // If there is none or only one app running we cannot do anything. | 222 // If there is none or only one app running we cannot do anything. |
143 if (activity_list_.size() <= 1U) | 223 if (activity_list_.size() <= 1U) |
144 return; | 224 return; |
| 225 |
| 226 if (pause_) { |
| 227 queued_command_ = true; |
| 228 return; |
| 229 } |
| 230 |
145 // TODO(skuhne): This algorithm needs to take all kinds of predictive analysis | 231 // TODO(skuhne): This algorithm needs to take all kinds of predictive analysis |
146 // and running applications into account. For this first patch we only do a | 232 // and running applications into account. For this first patch we only do a |
147 // very simple "floating window" algorithm which is surely not good enough. | 233 // very simple "floating window" algorithm which is surely not good enough. |
148 size_t max_running_activities = 5; | 234 size_t max_running_activities = 5; |
149 switch (current_memory_pressure_) { | 235 switch (current_memory_pressure_) { |
150 case MEMORY_PRESSURE_UNKNOWN: | 236 case MEMORY_PRESSURE_UNKNOWN: |
151 // If we do not know how much memory we have we assume that it must be a | 237 // If we do not know how much memory we have we assume that it must be a |
152 // high consumption. | 238 // high consumption. |
153 // Fallthrough. | 239 // Fallthrough. |
154 case MEMORY_PRESSURE_HIGH: | 240 case MEMORY_PRESSURE_HIGH: |
155 max_running_activities = 5; | 241 max_running_activities = 5; |
156 break; | 242 break; |
157 case MEMORY_PRESSURE_CRITICAL: | 243 case MEMORY_PRESSURE_CRITICAL: |
158 max_running_activities = 0; | 244 max_running_activities = 0; |
159 break; | 245 break; |
160 case MEMORY_PRESSURE_MODERATE: | 246 case MEMORY_PRESSURE_MODERATE: |
161 max_running_activities = 7; | 247 max_running_activities = 7; |
162 break; | 248 break; |
163 case MEMORY_PRESSURE_LOW: | 249 case MEMORY_PRESSURE_LOW: |
164 // No need to do anything yet. | 250 // This doesn't really matter. We do not change anything but turning |
165 return; | 251 // activities visible. |
| 252 max_running_activities = 10000; |
| 253 break; |
166 } | 254 } |
| 255 |
| 256 // The first n activities should be trated as "visible", means they updated |
| 257 // in overview mode and will keep their layer resources for faster switch |
| 258 // times. Usually we use |kMaxVisibleActivities| items, but when the memory |
| 259 // pressure gets critical we only hold as many as are really visible. |
| 260 size_t max_activities = kMaxVisibleActivities; |
| 261 if (current_memory_pressure_ == MEMORY_PRESSURE_CRITICAL) |
| 262 max_activities = 1 + (in_splitview_mode_ ? 1 : 0); |
| 263 |
| 264 // Restart and / or bail if the order of activities changes due to our calls. |
| 265 activity_order_changed_ = false; |
| 266 |
| 267 // Change the visibility of our activities in a pre-processing step. This is |
| 268 // required since it might change the order/number of activities. |
| 269 size_t index = 0; |
| 270 while (index < activity_list_.size()) { |
| 271 Activity* activity = activity_list_[index]; |
| 272 Activity::ActivityState state = activity->GetCurrentState(); |
| 273 |
| 274 // The first |kMaxVisibleActivities| entries should be visible, all others |
| 275 // invisible or at a lower activity state. |
| 276 if (index < max_activities || |
| 277 (state == Activity::ACTIVITY_INVISIBLE || |
| 278 state == Activity::ACTIVITY_VISIBLE)) { |
| 279 Activity::ActivityState visiblity_state = |
| 280 index < max_activities ? Activity::ACTIVITY_VISIBLE : |
| 281 Activity::ACTIVITY_INVISIBLE; |
| 282 // Only change the state when it changes. Note that when the memory |
| 283 // pressure is critical, only the primary activities (1 or 2) are made |
| 284 // visible. Furthermore, in relaxed mode we only want to make visible. |
| 285 if (visiblity_state != state && |
| 286 (current_memory_pressure_ != MEMORY_PRESSURE_LOW || |
| 287 visiblity_state == Activity::ACTIVITY_VISIBLE)) |
| 288 activity->SetCurrentState(visiblity_state); |
| 289 } |
| 290 |
| 291 // See which index we should handle next. |
| 292 if (activity_order_changed_) { |
| 293 activity_order_changed_ = false; |
| 294 index = 0; |
| 295 } else { |
| 296 ++index; |
| 297 } |
| 298 } |
| 299 |
| 300 // No need to remove anything. |
| 301 if (current_memory_pressure_ == MEMORY_PRESSURE_LOW) |
| 302 return; |
| 303 |
| 304 // Check if/which activity we want to unload. |
167 Activity* oldest_media_activity = NULL; | 305 Activity* oldest_media_activity = NULL; |
168 std::vector<Activity*> unloadable_activities; | 306 std::vector<Activity*> unloadable_activities; |
169 for (std::vector<Activity*>::iterator it = activity_list_.begin(); | 307 for (std::vector<Activity*>::iterator it = activity_list_.begin(); |
170 it != activity_list_.end(); ++it) { | 308 it != activity_list_.end(); ++it) { |
171 // The activity should not be unloaded or visible. | 309 Activity::ActivityState state = (*it)->GetCurrentState(); |
172 if ((*it)->GetCurrentState() != Activity::ACTIVITY_UNLOADED && | 310 // The activity should neither be unloaded nor visible. |
173 !(*it)->IsVisible()) { | 311 if (state != Activity::ACTIVITY_UNLOADED && |
| 312 state != Activity::ACTIVITY_VISIBLE) { |
174 if ((*it)->GetMediaState() == Activity::ACTIVITY_MEDIA_STATE_NONE) { | 313 if ((*it)->GetMediaState() == Activity::ACTIVITY_MEDIA_STATE_NONE) { |
175 // Does not play media - so we can unload this immediately. | 314 // Does not play media - so we can unload this immediately. |
176 unloadable_activities.push_back(*it); | 315 unloadable_activities.push_back(*it); |
177 } else { | 316 } else { |
178 oldest_media_activity = *it; | 317 oldest_media_activity = *it; |
179 } | 318 } |
180 } | 319 } |
181 } | 320 } |
| 321 |
182 if (unloadable_activities.size() > max_running_activities) { | 322 if (unloadable_activities.size() > max_running_activities) { |
183 unloadable_activities.back()->SetCurrentState(Activity::ACTIVITY_UNLOADED); | 323 unloadable_activities.back()->SetCurrentState(Activity::ACTIVITY_UNLOADED); |
184 return; | 324 return; |
185 } else if (current_memory_pressure_ == MEMORY_PRESSURE_CRITICAL) { | 325 } else if (current_memory_pressure_ == MEMORY_PRESSURE_CRITICAL) { |
186 if (oldest_media_activity) { | 326 if (oldest_media_activity) { |
187 oldest_media_activity->SetCurrentState(Activity::ACTIVITY_UNLOADED); | 327 oldest_media_activity->SetCurrentState(Activity::ACTIVITY_UNLOADED); |
| 328 LOG(WARNING) << "Unloading item to releave critical memory pressure"; |
188 return; | 329 return; |
189 } | 330 } |
190 LOG(ERROR) << "[ResourceManager]: Single activity uses too much memory."; | 331 LOG(ERROR) << "[ResourceManager]: Single activity uses too much memory."; |
191 return; | 332 return; |
192 } | 333 } |
| 334 |
193 if (current_memory_pressure_ != MEMORY_PRESSURE_UNKNOWN) { | 335 if (current_memory_pressure_ != MEMORY_PRESSURE_UNKNOWN) { |
194 // Only show this warning when the memory pressure is actually known. This | 336 // Only show this warning when the memory pressure is actually known. This |
195 // will suppress warnings in e.g. unit tests. | 337 // will suppress warnings in e.g. unit tests. |
196 LOG(WARNING) << "[ResourceManager]: No way to release memory pressure (" << | 338 LOG(WARNING) << "[ResourceManager]: No way to release memory pressure (" << |
197 current_memory_pressure_ << | 339 current_memory_pressure_ << |
198 "), Activities (running, allowed, unloadable)=(" << | 340 "), Activities (running, allowed, unloadable)=(" << |
199 activity_list_.size() << ", " << | 341 activity_list_.size() << ", " << |
200 max_running_activities << ", " << | 342 max_running_activities << ", " << |
201 unloadable_activities.size() << ")"; | 343 unloadable_activities.size() << ")"; |
202 } | 344 } |
203 } | 345 } |
204 | 346 |
205 void ResourceManagerImpl::UpdateActivityOrder() { | 347 void ResourceManagerImpl::UpdateActivityOrder() { |
| 348 queued_command_ = true; |
206 if (activity_list_.empty()) | 349 if (activity_list_.empty()) |
207 return; | 350 return; |
208 std::vector<Activity*> new_activity_list; | 351 std::vector<Activity*> new_activity_list; |
209 const aura::Window::Windows children = | 352 const aura::Window::Windows children = |
210 activity_list_[0]->GetWindow()->parent()->children(); | 353 activity_list_[0]->GetWindow()->parent()->children(); |
211 // Find the first window in the container which is part of the application. | 354 // Find the first window in the container which is part of the application. |
212 for (aura::Window::Windows::const_iterator child_iterator = children.begin(); | 355 for (aura::Window::Windows::const_reverse_iterator child_iterator = |
213 child_iterator != children.end(); ++child_iterator) { | 356 children.rbegin(); |
| 357 child_iterator != children.rend(); ++child_iterator) { |
214 for (std::vector<Activity*>::iterator activity_iterator = | 358 for (std::vector<Activity*>::iterator activity_iterator = |
215 activity_list_.begin(); | 359 activity_list_.begin(); |
216 activity_iterator != activity_list_.end(); ++activity_iterator) { | 360 activity_iterator != activity_list_.end(); ++activity_iterator) { |
217 if (*child_iterator == (*activity_iterator)->GetWindow()) { | 361 if (*child_iterator == (*activity_iterator)->GetWindow()) { |
218 new_activity_list.push_back(*activity_iterator); | 362 new_activity_list.push_back(*activity_iterator); |
219 activity_list_.erase(activity_iterator); | 363 activity_list_.erase(activity_iterator); |
220 break; | 364 break; |
221 } | 365 } |
222 } | 366 } |
223 } | 367 } |
224 // At this point the old list should be empty and we can swap the lists. | 368 // At this point the old list should be empty and we can swap the lists. |
225 DCHECK(!activity_list_.size()); | 369 DCHECK(!activity_list_.size()); |
226 activity_list_ = new_activity_list; | 370 activity_list_ = new_activity_list; |
| 371 |
| 372 // Remember that the activity order has changed. |
| 373 activity_order_changed_ = true; |
227 } | 374 } |
228 | 375 |
229 // static | 376 // static |
230 void ResourceManager::Create() { | 377 void ResourceManager::Create() { |
231 DCHECK(!instance); | 378 DCHECK(!instance); |
232 instance = new ResourceManagerImpl( | 379 instance = new ResourceManagerImpl( |
233 ResourceManagerDelegate::CreateResourceManagerDelegate()); | 380 ResourceManagerDelegate::CreateResourceManagerDelegate()); |
234 } | 381 } |
235 | 382 |
236 // static | 383 // static |
237 ResourceManager* ResourceManager::Get() { | 384 ResourceManager* ResourceManager::Get() { |
238 return instance; | 385 return instance; |
239 } | 386 } |
240 | 387 |
241 // static | 388 // static |
242 void ResourceManager::Shutdown() { | 389 void ResourceManager::Shutdown() { |
243 DCHECK(instance); | 390 DCHECK(instance); |
244 delete instance; | 391 delete instance; |
245 instance = NULL; | 392 instance = NULL; |
246 } | 393 } |
247 | 394 |
248 ResourceManager::ResourceManager() {} | 395 ResourceManager::ResourceManager() {} |
249 | 396 |
250 ResourceManager::~ResourceManager() { | 397 ResourceManager::~ResourceManager() { |
251 DCHECK(instance); | 398 DCHECK(instance); |
252 instance = NULL; | 399 instance = NULL; |
253 } | 400 } |
254 | 401 |
255 } // namespace athena | 402 } // namespace athena |
OLD | NEW |