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

Side by Side Diff: athena/resource_manager/resource_manager.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: Self nits 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.
Jun Mukai 2014/08/27 01:21:19 In athena, usually this file is named as resoure_m
Mr4D (OOO till 08-26) 2014/08/27 16:12:14 Done.
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 SetMemoryPressureForTest(
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.
Jun Mukai 2014/08/27 01:21:18 Also, it's better to be unified with WindowListPro
Mr4D (OOO till 08-26) 2014/08/27 16:12:13 I know. I have a CL queued (480293003) which adds
Jun Mukai 2014/08/27 16:57:47 Turns out I was still confused by the difference b
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::SetMemoryPressureForTest(
Jun Mukai 2014/08/27 01:21:19 It might be great to cancel memory_pressure_notifi
Mr4D (OOO till 08-26) 2014/08/27 16:12:13 The TestResourceManagerDelegate will never report
Jun Mukai 2014/08/27 16:57:48 Acknowledged.
93 MemoryPressureObserver::MemoryPressure pressure) {
94 OnMemoryPressure(pressure);
95 }
96
97 void ResourceManagerImpl::OnActivityStarted(Activity* activity) {
98 // As long as we have to manage the list of activities ourselves, we need to
99 // order it here.
100 activity_list_.push_back(activity);
101 UpdateActivityOrder();
102 // Update the activity states.
103 ManageResource();
104 }
105
106 void ResourceManagerImpl::OnActivityEnding(Activity* activity) {
107 // Remove the activity from the list again.
108 std::vector<Activity*>::iterator it =
109 std::find(activity_list_.begin(), activity_list_.end(), activity);
110 DCHECK(it != activity_list_.end());
111 activity_list_.erase(it);
112 }
113
114 void ResourceManagerImpl::OnOverviewModeEnter() {
115 // Nothing to do here.
116 }
117
118 void ResourceManagerImpl::OnOverviewModeExit() {
119 // Nothing to do here.
120 }
121
122 void ResourceManagerImpl::OnActivityOrderHasChanged() {
123 // As long as we have to manage the list of activities ourselves, we need to
124 // order it here.
125 UpdateActivityOrder();
126 // Manage the resources of each activity.
127 ManageResource();
128 }
129
130 void ResourceManagerImpl::OnMemoryPressure(
131 MemoryPressureObserver::MemoryPressure pressure) {
132 current_memory_pressure_ = pressure;
133 ManageResource();
134 }
135
136 ResourceManagerDelegate* ResourceManagerImpl::GetDelegate() {
137 return delegate_.get();
138 }
139
140 void ResourceManagerImpl::ManageResource() {
141 // If there is none or only one app running we cannot do anything.
142 if (activity_list_.size() <= 1U)
143 return;
144 // TODO(skuhne): This algorithm needs to take all kinds of predictive analysis
145 // and running applications into account. For this first patch we only do a
146 // very simple "floating window" algorithm which is surely not good enough.
147 size_t max_running_activities = 5;
148 switch (current_memory_pressure_) {
149 case MEMORY_PRESSURE_UNKNOWN:
150 max_running_activities = 5;
151 break;
152 case MEMORY_PRESSURE_CRITICAL:
153 max_running_activities = 0;
154 break;
155 case MEMORY_PRESSURE_HIGH:
156 max_running_activities = 5;
157 break;
158 case MEMORY_PRESSURE_MODERATE:
159 max_running_activities = 7;
160 break;
161 case MEMORY_PRESSURE_LOW:
162 // No need to do anything yet.
Jun Mukai 2014/08/27 01:21:19 Not sure the difference between HIGH/UNKNOWN (sett
Mr4D (OOO till 08-26) 2014/08/27 16:12:13 I added another comment for unknown. You can find
163 return;
164 }
165 Activity* oldest_media_activity = NULL;
166 std::vector<Activity*> unloadable_activities;
167 for (std::vector<Activity*>::iterator it = activity_list_.begin();
168 it != activity_list_.end(); ++it) {
169 // The activity should not be unloaded or visible.
170 if ((*it)->GetCurrentState() != Activity::ACTIVITY_UNLOADED &&
171 !(*it)->IsVisible()) {
172 if ((*it)->GetMediaState() == Activity::ACTIVITY_MEDIA_STATE_NONE) {
173 // Does not play media - so we can unload this immediately.
174 unloadable_activities.push_back(*it);
175 } else {
176 oldest_media_activity = *it;
177 }
178 }
179 }
180 if (unloadable_activities.size() > max_running_activities) {
181 unloadable_activities.back()->SetCurrentState(Activity::ACTIVITY_UNLOADED);
Jun Mukai 2014/08/27 01:21:18 Is it enough to set the state on only the oldest u
Mr4D (OOO till 08-26) 2014/08/27 16:12:13 The crux here is that any resource change takes ti
Jun Mukai 2014/08/27 16:57:47 Ah, I see.
182 return;
183 } else if (current_memory_pressure_ == MEMORY_PRESSURE_CRITICAL) {
Jun Mukai 2014/08/27 01:21:18 Think that there are multiple media activities and
Mr4D (OOO till 08-26) 2014/08/27 16:12:13 That was the intent. If there is no memory left an
Jun Mukai 2014/08/27 16:57:47 Acknowledged.
184 if (oldest_media_activity) {
185 oldest_media_activity->SetCurrentState(Activity::ACTIVITY_UNLOADED);
186 return;
187 }
188 LOG(ERROR) << "[ResourceManager]: Single activity uses too much memory.";
189 return;
190 }
191 LOG(WARNING) << "[ResourceManager]: No way to release memory pressure (" <<
192 current_memory_pressure_ <<
193 "), Activities (running, allowed, unloadable)=(" <<
194 activity_list_.size() << ", " <<
195 max_running_activities << ", " <<
196 unloadable_activities.size() << ")";
197 }
198
199 void ResourceManagerImpl::UpdateActivityOrder() {
200 if (!activity_list_.size())
Jun Mukai 2014/08/27 01:21:18 activity_list_.empty() is clearer to me
Mr4D (OOO till 08-26) 2014/08/27 16:12:13 Done.
201 return;
202 std::vector<Activity*> new_activity_list;
203 const aura::Window::Windows children =
204 activity_list_[0]->GetWindow()->parent()->children();;
Jun Mukai 2014/08/27 01:21:18 double semicolon at end
Mr4D (OOO till 08-26) 2014/08/27 16:12:14 Done.
205 // Find the first window in the container which is part of the application.
206 for (aura::Window::Windows::const_iterator child_iterator = children.begin();
207 child_iterator != children.end(); ++child_iterator) {
208 for (std::vector<Activity*>::iterator activity_iterator =
209 activity_list_.begin();
210 activity_iterator != activity_list_.end(); ++activity_iterator) {
211 if (*child_iterator == (*activity_iterator)->GetWindow()) {
212 new_activity_list.push_back(*activity_iterator);
213 activity_list_.erase(activity_iterator);
214 break;
215 }
216 }
217 }
218 // At this point the old list should be empty and we can swap the lists.
219 DCHECK(!activity_list_.size());
220 activity_list_ = new_activity_list;
221 }
222
223 // static
224 void ResourceManager::Create() {
225 DCHECK(!instance);
226 instance = new ResourceManagerImpl(
227 ResourceManagerDelegate::CreateResourceManagerDelegate());
228 }
229
230 // static
231 ResourceManager* ResourceManager::Get() {
232 return instance;
233 }
234
235 // static
236 void ResourceManager::Shutdown() {
237 DCHECK(instance);
238 delete instance;
239 instance = NULL;
240 }
241
242 ResourceManager::ResourceManager() {}
243
244 ResourceManager::~ResourceManager() {
245 DCHECK(instance);
246 instance = NULL;
247 }
248
249 } // namespace athena
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698