Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(156)

Side by Side Diff: athena/resource_manager/resource_manager_impl.cc

Issue 513523002: Adding Baseframework of the ResourceManager (all hooks and observers) are being put in place with a… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "athena/resource_manager/public/resource_manager.h"
6
7 #include <algorithm>
8 #include <vector>
9
10 #include "athena/activity/public/activity.h"
11 #include "athena/activity/public/activity_manager.h"
12 #include "athena/activity/public/activity_manager_observer.h"
13 #include "athena/resource_manager/memory_pressure_notifier.h"
14 #include "athena/resource_manager/public/resource_manager_delegate.h"
15 #include "athena/wm/public/window_manager.h"
16 #include "athena/wm/public/window_manager_observer.h"
17 #include "base/logging.h"
18 #include "base/memory/scoped_ptr.h"
19 #include "ui/aura/window.h"
20
21 namespace athena {
22
23 class ResourceManagerImpl : public ResourceManager,
24 public WindowManagerObserver,
25 public ActivityManagerObserver,
26 public MemoryPressureObserver {
27 public:
28 ResourceManagerImpl(ResourceManagerDelegate* delegate);
29 virtual ~ResourceManagerImpl();
30
31 // ResourceManager:
32 virtual void SetMemoryPressureAndStopMonitoring(
33 MemoryPressureObserver::MemoryPressure pressure) OVERRIDE;
34
35 // ActivityManagerObserver:
36 virtual void OnActivityStarted(Activity* activity) OVERRIDE;
37 virtual void OnActivityEnding(Activity* activity) OVERRIDE;
38
39 // WindowManagerObserver:
40 virtual void OnOverviewModeEnter() OVERRIDE;
41 virtual void OnOverviewModeExit() OVERRIDE;
42 virtual void OnActivityOrderHasChanged() OVERRIDE;
43
44 // MemoryPressureObserver:
45 virtual void OnMemoryPressure(
46 MemoryPressureObserver::MemoryPressure pressure) OVERRIDE;
47 virtual ResourceManagerDelegate* GetDelegate() OVERRIDE;
48
49 private:
50 // Manage the resources for our activities.
51 void ManageResource();
52
53 // Order our activity list to the order of activities of the stream.
54 // TODO(skuhne): Once the ActivityManager is responsible to create this list
55 // for us, we can remove this code here.
56 void UpdateActivityOrder();
57
58 // The sorted (new(front) -> old(back)) activity list.
59 // TODO(skuhne): Once the ActivityManager is responsible to create this list
60 // for us, we can remove this code here.
61 std::vector<Activity*> activity_list_;
62
63 // The resource manager delegate.
64 scoped_ptr<ResourceManagerDelegate> delegate_;
65
66 // Keeping a reference to the current memory pressure.
67 MemoryPressureObserver::MemoryPressure current_memory_pressure_;
68
69 // The memory pressure notifier.
70 scoped_ptr<MemoryPressureNotifier> memory_pressure_notifier_;
71
72 DISALLOW_COPY_AND_ASSIGN(ResourceManagerImpl);
73 };
74
75 namespace {
76 ResourceManagerImpl* instance = NULL;
77 } // namespace
78
79 ResourceManagerImpl::ResourceManagerImpl(ResourceManagerDelegate* delegate)
80 : delegate_(delegate),
81 current_memory_pressure_(MemoryPressureObserver::MEMORY_PRESSURE_UNKNOWN),
82 memory_pressure_notifier_(new MemoryPressureNotifier(this)) {
83 WindowManager::GetInstance()->AddObserver(this);
84 ActivityManager::Get()->AddObserver(this);
85 }
86
87 ResourceManagerImpl::~ResourceManagerImpl() {
88 ActivityManager::Get()->RemoveObserver(this);
89 WindowManager::GetInstance()->RemoveObserver(this);
90 }
91
92 void ResourceManagerImpl::SetMemoryPressureAndStopMonitoring(
93 MemoryPressureObserver::MemoryPressure pressure) {
94 memory_pressure_notifier_->StopObserving();
95 OnMemoryPressure(pressure);
96 }
97
98 void ResourceManagerImpl::OnActivityStarted(Activity* activity) {
99 // As long as we have to manage the list of activities ourselves, we need to
100 // order it here.
101 activity_list_.push_back(activity);
102 UpdateActivityOrder();
103 // Update the activity states.
104 ManageResource();
105 }
106
107 void ResourceManagerImpl::OnActivityEnding(Activity* activity) {
108 // Remove the activity from the list again.
109 std::vector<Activity*>::iterator it =
110 std::find(activity_list_.begin(), activity_list_.end(), activity);
111 DCHECK(it != activity_list_.end());
112 activity_list_.erase(it);
113 }
114
115 void ResourceManagerImpl::OnOverviewModeEnter() {
116 // Nothing to do here.
117 }
118
119 void ResourceManagerImpl::OnOverviewModeExit() {
120 // Nothing to do here.
121 }
122
123 void ResourceManagerImpl::OnActivityOrderHasChanged() {
124 // As long as we have to manage the list of activities ourselves, we need to
125 // order it here.
126 UpdateActivityOrder();
127 // Manage the resources of each activity.
128 ManageResource();
129 }
130
131 void ResourceManagerImpl::OnMemoryPressure(
132 MemoryPressureObserver::MemoryPressure pressure) {
133 current_memory_pressure_ = pressure;
134 ManageResource();
135 }
136
137 ResourceManagerDelegate* ResourceManagerImpl::GetDelegate() {
138 return delegate_.get();
139 }
140
141 void ResourceManagerImpl::ManageResource() {
142 // If there is none or only one app running we cannot do anything.
143 if (activity_list_.size() <= 1U)
144 return;
145 // 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
147 // very simple "floating window" algorithm which is surely not good enough.
148 size_t max_running_activities = 5;
149 switch (current_memory_pressure_) {
150 case MEMORY_PRESSURE_UNKNOWN:
151 // If we do not know how much memory we have we assume that it must be a
152 // high consumption.
153 // Fallthrough.
154 case MEMORY_PRESSURE_HIGH:
155 max_running_activities = 5;
156 break;
157 case MEMORY_PRESSURE_CRITICAL:
158 max_running_activities = 0;
159 break;
160 case MEMORY_PRESSURE_MODERATE:
161 max_running_activities = 7;
162 break;
163 case MEMORY_PRESSURE_LOW:
164 // No need to do anything yet.
165 return;
166 }
167 Activity* oldest_media_activity = NULL;
168 std::vector<Activity*> unloadable_activities;
169 for (std::vector<Activity*>::iterator it = activity_list_.begin();
170 it != activity_list_.end(); ++it) {
171 // The activity should not be unloaded or visible.
172 if ((*it)->GetCurrentState() != Activity::ACTIVITY_UNLOADED &&
173 !(*it)->IsVisible()) {
174 if ((*it)->GetMediaState() == Activity::ACTIVITY_MEDIA_STATE_NONE) {
175 // Does not play media - so we can unload this immediately.
176 unloadable_activities.push_back(*it);
177 } else {
178 oldest_media_activity = *it;
179 }
180 }
181 }
182 if (unloadable_activities.size() > max_running_activities) {
183 unloadable_activities.back()->SetCurrentState(Activity::ACTIVITY_UNLOADED);
184 return;
185 } else if (current_memory_pressure_ == MEMORY_PRESSURE_CRITICAL) {
186 if (oldest_media_activity) {
187 oldest_media_activity->SetCurrentState(Activity::ACTIVITY_UNLOADED);
188 return;
189 }
190 LOG(ERROR) << "[ResourceManager]: Single activity uses too much memory.";
191 return;
192 }
193 LOG(WARNING) << "[ResourceManager]: No way to release memory pressure (" <<
194 current_memory_pressure_ <<
195 "), Activities (running, allowed, unloadable)=(" <<
196 activity_list_.size() << ", " <<
197 max_running_activities << ", " <<
198 unloadable_activities.size() << ")";
199 }
200
201 void ResourceManagerImpl::UpdateActivityOrder() {
202 if (activity_list_.empty())
203 return;
204 std::vector<Activity*> new_activity_list;
205 const aura::Window::Windows children =
206 activity_list_[0]->GetWindow()->parent()->children();
207 // Find the first window in the container which is part of the application.
208 for (aura::Window::Windows::const_iterator child_iterator = children.begin();
209 child_iterator != children.end(); ++child_iterator) {
210 for (std::vector<Activity*>::iterator activity_iterator =
211 activity_list_.begin();
212 activity_iterator != activity_list_.end(); ++activity_iterator) {
213 if (*child_iterator == (*activity_iterator)->GetWindow()) {
214 new_activity_list.push_back(*activity_iterator);
215 activity_list_.erase(activity_iterator);
216 break;
217 }
218 }
219 }
220 // At this point the old list should be empty and we can swap the lists.
221 DCHECK(!activity_list_.size());
222 activity_list_ = new_activity_list;
223 }
224
225 // static
226 void ResourceManager::Create() {
227 DCHECK(!instance);
228 instance = new ResourceManagerImpl(
229 ResourceManagerDelegate::CreateResourceManagerDelegate());
230 }
231
232 // static
233 ResourceManager* ResourceManager::Get() {
234 return instance;
235 }
236
237 // static
238 void ResourceManager::Shutdown() {
239 DCHECK(instance);
240 delete instance;
241 instance = NULL;
242 }
243
244 ResourceManager::ResourceManager() {}
245
246 ResourceManager::~ResourceManager() {
247 DCHECK(instance);
248 instance = NULL;
249 }
250
251 } // namespace athena
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698