Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / athena / resource_manager / resource_manager_unittest.cc
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/activity/public/activity.h"
6 #include "athena/activity/public/activity_manager.h"
7 #include "athena/activity/public/activity_view_model.h"
8 #include "athena/resource_manager/memory_pressure_notifier.h"
9 #include "athena/resource_manager/public/resource_manager.h"
10 #include "athena/test/base/athena_test_base.h"
11 #include "athena/test/base/sample_activity.h"
12 #include "athena/wm/public/window_manager.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "ui/gfx/image/image_skia.h"
15 #include "ui/views/view.h"
16 #include "ui/views/widget/widget.h"
17
18 namespace athena {
19 namespace test {
20
21 namespace {
22
23 // A dummy test app activity which works without content / ShellAppWindow.
24 class TestActivity : public SampleActivity {
25  public:
26   explicit TestActivity(const std::string& title)
27       : SampleActivity(0, 0, base::UTF8ToUTF16(title)),
28         media_state_(ACTIVITY_MEDIA_STATE_NONE),
29         is_visible_(false) {}
30   ~TestActivity() override {}
31
32   void set_media_state(ActivityMediaState media_state) {
33     media_state_ = media_state;
34   }
35   void set_visible(bool visible) { is_visible_ = visible; }
36
37   // Activity overrides:
38   virtual bool IsVisible() override { return is_visible_; }
39   virtual ActivityMediaState GetMediaState() override { return media_state_; }
40
41  private:
42   // The current media state.
43   ActivityMediaState media_state_;
44
45   // Returns if it is visible or not.
46   bool is_visible_;
47
48   DISALLOW_COPY_AND_ASSIGN(TestActivity);
49 };
50
51 }  // namespace
52
53 // Our testing base.
54 class ResourceManagerTest : public AthenaTestBase {
55  public:
56   ResourceManagerTest() {}
57   ~ResourceManagerTest() override {}
58
59   virtual void SetUp() override {
60     AthenaTestBase::SetUp();
61     // Override the delay to be instantaneous.
62     ResourceManager::Get()->SetWaitTimeBetweenResourceManageCalls(0);
63   }
64   virtual void TearDown() override {
65     while (!activity_list_.empty())
66       DeleteActivity(activity_list_[0]);
67     AthenaTestBase::TearDown();
68   }
69
70   TestActivity* CreateActivity(const std::string& title) {
71     TestActivity* activity = new TestActivity(title);
72     ActivityManager::Get()->AddActivity(activity);
73     activity->SetCurrentState(Activity::ACTIVITY_INVISIBLE);
74     activity_list_.push_back(activity);
75     return activity;
76   }
77
78   void DeleteActivity(Activity* activity) {
79     Activity::Delete(activity);
80     RunAllPendingInMessageLoop();
81     std::vector<TestActivity*>::iterator it = std::find(activity_list_.begin(),
82                                                         activity_list_.end(),
83                                                         activity);
84     DCHECK(it != activity_list_.end());
85     activity_list_.erase(it);
86   }
87
88  private:
89   std::vector<TestActivity*> activity_list_;
90
91   DISALLOW_COPY_AND_ASSIGN(ResourceManagerTest);
92 };
93
94 // Only creates and destroys it to see that the system gets properly shut down.
95 TEST_F(ResourceManagerTest, SimpleTest) {
96 }
97
98 // Test that we release an activity when the memory pressure goes critical.
99 TEST_F(ResourceManagerTest, OnCriticalWillUnloadOneActivity) {
100   // Create a few dummy activities in the reverse order as we need them.
101   TestActivity* app_unloadable2 = CreateActivity("unloadable2");
102   TestActivity* app_unloadable1 = CreateActivity("unloadable1");
103   TestActivity* app_visible = CreateActivity("visible");
104   app_visible->set_visible(true);
105   app_unloadable1->set_visible(false);
106   app_unloadable2->set_visible(false);
107
108   // Set the initial visibility states.
109   app_visible->SetCurrentState(Activity::ACTIVITY_VISIBLE);
110   app_unloadable1->SetCurrentState(Activity::ACTIVITY_INVISIBLE);
111   app_unloadable2->SetCurrentState(Activity::ACTIVITY_INVISIBLE);
112
113   // Call the resource manager and say we are in a critical memory condition.
114   ResourceManager::Get()->SetMemoryPressureAndStopMonitoring(
115       ResourceManager::MEMORY_PRESSURE_CRITICAL);
116   DCHECK_NE(Activity::ACTIVITY_UNLOADED, app_visible->GetCurrentState());
117   DCHECK_NE(Activity::ACTIVITY_UNLOADED, app_unloadable1->GetCurrentState());
118   DCHECK_EQ(Activity::ACTIVITY_UNLOADED, app_unloadable2->GetCurrentState());
119
120   // Calling it a second time will release the second app.
121   ResourceManager::Get()->SetMemoryPressureAndStopMonitoring(
122       ResourceManager::MEMORY_PRESSURE_CRITICAL);
123   DCHECK_NE(Activity::ACTIVITY_UNLOADED, app_visible->GetCurrentState());
124   DCHECK_EQ(Activity::ACTIVITY_UNLOADED, app_unloadable1->GetCurrentState());
125   DCHECK_EQ(Activity::ACTIVITY_UNLOADED, app_unloadable2->GetCurrentState());
126
127   // Calling it once more will change nothing.
128   ResourceManager::Get()->SetMemoryPressureAndStopMonitoring(
129       ResourceManager::MEMORY_PRESSURE_CRITICAL);
130   DCHECK_NE(Activity::ACTIVITY_UNLOADED, app_visible->GetCurrentState());
131   DCHECK_EQ(Activity::ACTIVITY_UNLOADED, app_unloadable1->GetCurrentState());
132   DCHECK_EQ(Activity::ACTIVITY_UNLOADED, app_unloadable2->GetCurrentState());
133 }
134
135 // Test that media playing activities only get unloaded if there is no other
136 // way.
137 TEST_F(ResourceManagerTest, OnCriticalMediaHandling) {
138   // Create a few dummy activities in the reverse order as we need them.
139   TestActivity* app_media_locked2 = CreateActivity("medialocked2");
140   TestActivity* app_unloadable = CreateActivity("unloadable2");
141   TestActivity* app_media_locked1 = CreateActivity("medialocked1");
142   TestActivity* app_visible = CreateActivity("visible");
143   app_visible->set_visible(true);
144   app_unloadable->set_visible(false);
145   app_media_locked1->set_visible(false);
146   app_media_locked2->set_visible(false);
147
148   app_media_locked1->set_media_state(
149       Activity::ACTIVITY_MEDIA_STATE_AUDIO_PLAYING);
150   app_media_locked2->set_media_state(Activity::ACTIVITY_MEDIA_STATE_RECORDING);
151
152   // Set the initial visibility states.
153   app_visible->SetCurrentState(Activity::ACTIVITY_VISIBLE);
154   app_media_locked1->SetCurrentState(Activity::ACTIVITY_INVISIBLE);
155   app_unloadable->SetCurrentState(Activity::ACTIVITY_INVISIBLE);
156   app_media_locked2->SetCurrentState(Activity::ACTIVITY_INVISIBLE);
157
158   DCHECK_NE(Activity::ACTIVITY_UNLOADED, app_visible->GetCurrentState());
159   DCHECK_NE(Activity::ACTIVITY_UNLOADED, app_media_locked1->GetCurrentState());
160   DCHECK_NE(Activity::ACTIVITY_UNLOADED, app_unloadable->GetCurrentState());
161   DCHECK_NE(Activity::ACTIVITY_UNLOADED, app_media_locked2->GetCurrentState());
162
163   // Calling it with a critical situation first, it will release the non media
164   // locked app.
165   ResourceManager::Get()->SetMemoryPressureAndStopMonitoring(
166       ResourceManager::MEMORY_PRESSURE_CRITICAL);
167   DCHECK_NE(Activity::ACTIVITY_UNLOADED, app_visible->GetCurrentState());
168   DCHECK_NE(Activity::ACTIVITY_UNLOADED, app_media_locked1->GetCurrentState());
169   DCHECK_EQ(Activity::ACTIVITY_UNLOADED, app_unloadable->GetCurrentState());
170   DCHECK_NE(Activity::ACTIVITY_UNLOADED, app_media_locked2->GetCurrentState());
171
172   // Calling it the second time, the oldest media playing activity will get
173   // unloaded.
174   ResourceManager::Get()->SetMemoryPressureAndStopMonitoring(
175       ResourceManager::MEMORY_PRESSURE_CRITICAL);
176   DCHECK_NE(Activity::ACTIVITY_UNLOADED, app_visible->GetCurrentState());
177   DCHECK_NE(Activity::ACTIVITY_UNLOADED, app_media_locked1->GetCurrentState());
178   DCHECK_EQ(Activity::ACTIVITY_UNLOADED, app_unloadable->GetCurrentState());
179   DCHECK_EQ(Activity::ACTIVITY_UNLOADED, app_media_locked2->GetCurrentState());
180
181   // Calling it the third time, the oldest media playing activity will get
182   // unloaded.
183   ResourceManager::Get()->SetMemoryPressureAndStopMonitoring(
184       ResourceManager::MEMORY_PRESSURE_CRITICAL);
185   DCHECK_NE(Activity::ACTIVITY_UNLOADED, app_visible->GetCurrentState());
186   DCHECK_EQ(Activity::ACTIVITY_UNLOADED, app_media_locked1->GetCurrentState());
187   DCHECK_EQ(Activity::ACTIVITY_UNLOADED, app_unloadable->GetCurrentState());
188   DCHECK_EQ(Activity::ACTIVITY_UNLOADED, app_media_locked2->GetCurrentState());
189 }
190
191 // Test the visibility of items.
192 TEST_F(ResourceManagerTest, VisibilityChanges) {
193   // Create a few dummy activities in the reverse order as we need them.
194   TestActivity* app4 = CreateActivity("app4");
195   TestActivity* app3 = CreateActivity("app3");
196   TestActivity* app2 = CreateActivity("app2");
197   TestActivity* app1 = CreateActivity("app1");
198   app1->SetCurrentState(Activity::ACTIVITY_VISIBLE);
199   app2->SetCurrentState(Activity::ACTIVITY_VISIBLE);
200   app3->SetCurrentState(Activity::ACTIVITY_VISIBLE);
201   app4->SetCurrentState(Activity::ACTIVITY_VISIBLE);
202
203   // Applying low resource pressure should keep everything as is.
204   ResourceManager::Get()->SetMemoryPressureAndStopMonitoring(
205       ResourceManager::MEMORY_PRESSURE_LOW);
206   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app1->GetCurrentState());
207   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app2->GetCurrentState());
208   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app3->GetCurrentState());
209   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app4->GetCurrentState());
210
211   // Applying moderate resource pressure we should see 3 visible activities.
212   // This is testing an internal algorithm constant, but for the time being
213   // this should suffice.
214   ResourceManager::Get()->SetMemoryPressureAndStopMonitoring(
215       ResourceManager::MEMORY_PRESSURE_MODERATE);
216   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app1->GetCurrentState());
217   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app2->GetCurrentState());
218   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app3->GetCurrentState());
219   EXPECT_EQ(Activity::ACTIVITY_INVISIBLE, app4->GetCurrentState());
220
221   // Applying higher pressure should get rid of everything unneeded.
222   ResourceManager::Get()->SetMemoryPressureAndStopMonitoring(
223       ResourceManager::MEMORY_PRESSURE_CRITICAL);
224   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app1->GetCurrentState());
225   EXPECT_EQ(Activity::ACTIVITY_INVISIBLE, app2->GetCurrentState());
226   EXPECT_EQ(Activity::ACTIVITY_INVISIBLE, app3->GetCurrentState());
227   // Note: This might very well be unloaded with this memory pressure.
228   EXPECT_NE(Activity::ACTIVITY_VISIBLE, app4->GetCurrentState());
229
230   // Once the split view mode gets turned on, more windows should become
231   // visible.
232   WindowManager::Get()->ToggleSplitViewForTest();
233   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app1->GetCurrentState());
234   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app2->GetCurrentState());
235   EXPECT_NE(Activity::ACTIVITY_VISIBLE, app3->GetCurrentState());
236   EXPECT_NE(Activity::ACTIVITY_VISIBLE, app4->GetCurrentState());
237
238   // Going back to a relaxed memory pressure should reload the old activities.
239   ResourceManager::Get()->SetMemoryPressureAndStopMonitoring(
240       ResourceManager::MEMORY_PRESSURE_LOW);
241   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app1->GetCurrentState());
242   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app2->GetCurrentState());
243   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app3->GetCurrentState());
244   EXPECT_NE(Activity::ACTIVITY_INVISIBLE, app4->GetCurrentState());
245 }
246
247 // Make sure that an activity which got just reduced from visible to invisible,
248 // does not get thrown out of memory in the same step.
249 TEST_F(ResourceManagerTest, NoUnloadFromVisible) {
250   // The timeout override in milliseconds.
251   const int kTimeoutOverrideInMs = 20;
252   // Tell the resource manager to wait for 20ms between calls.
253   ResourceManager::Get()->SetWaitTimeBetweenResourceManageCalls(
254       kTimeoutOverrideInMs);
255
256   // Create a few dummy activities in the reverse order as we need them.
257   TestActivity* app2 = CreateActivity("app2");
258   TestActivity* app1 = CreateActivity("app1");
259   app1->SetCurrentState(Activity::ACTIVITY_VISIBLE);
260   app2->SetCurrentState(Activity::ACTIVITY_VISIBLE);
261
262   // Applying low resource pressure should turn one item invisible.
263   ResourceManager::Get()->SetMemoryPressureAndStopMonitoring(
264       ResourceManager::MEMORY_PRESSURE_CRITICAL);
265   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app1->GetCurrentState());
266   EXPECT_EQ(Activity::ACTIVITY_INVISIBLE, app2->GetCurrentState());
267
268   // Trying to apply the memory pressure again does not do anything.
269   ResourceManager::Get()->SetMemoryPressureAndStopMonitoring(
270       ResourceManager::MEMORY_PRESSURE_CRITICAL);
271   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app1->GetCurrentState());
272   EXPECT_EQ(Activity::ACTIVITY_INVISIBLE, app2->GetCurrentState());
273
274   // Waiting and applying the pressure again should unload it.
275   usleep(kTimeoutOverrideInMs * 1000);
276   ResourceManager::Get()->SetMemoryPressureAndStopMonitoring(
277       ResourceManager::MEMORY_PRESSURE_CRITICAL);
278   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app1->GetCurrentState());
279   EXPECT_EQ(Activity::ACTIVITY_UNLOADED, app2->GetCurrentState());
280 }
281
282 // Make sure that ActivityVisibility changes will be updated instantaneously
283 // when the ResourceManager is called for operation.
284 TEST_F(ResourceManagerTest, VisibilityChangeIsInstantaneous) {
285   // Create a few dummy activities in the reverse order as we need them.
286   TestActivity* app3 = CreateActivity("app3");
287   TestActivity* app2 = CreateActivity("app2");
288   TestActivity* app1 = CreateActivity("app1");
289   app1->SetCurrentState(Activity::ACTIVITY_VISIBLE);
290   app2->SetCurrentState(Activity::ACTIVITY_VISIBLE);
291   app3->SetCurrentState(Activity::ACTIVITY_VISIBLE);
292
293   // Tell the resource manager to wait for a long time between calls.
294   ResourceManager::Get()->SetWaitTimeBetweenResourceManageCalls(1000);
295
296   // Applying higher pressure should get rid of everything unneeded.
297   ResourceManager::Get()->SetMemoryPressureAndStopMonitoring(
298       ResourceManager::MEMORY_PRESSURE_CRITICAL);
299   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app1->GetCurrentState());
300   EXPECT_EQ(Activity::ACTIVITY_INVISIBLE, app2->GetCurrentState());
301   EXPECT_EQ(Activity::ACTIVITY_INVISIBLE, app3->GetCurrentState());
302
303   // Setting now one window visible again and call a second time should
304   // immediately change the state again.
305   app2->SetCurrentState(Activity::ACTIVITY_VISIBLE);
306   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app1->GetCurrentState());
307   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app2->GetCurrentState());
308   EXPECT_EQ(Activity::ACTIVITY_INVISIBLE, app3->GetCurrentState());
309   ResourceManager::Get()->SetMemoryPressureAndStopMonitoring(
310       ResourceManager::MEMORY_PRESSURE_CRITICAL);
311
312   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app1->GetCurrentState());
313   EXPECT_EQ(Activity::ACTIVITY_INVISIBLE, app2->GetCurrentState());
314   EXPECT_EQ(Activity::ACTIVITY_INVISIBLE, app3->GetCurrentState());
315 }
316
317 // Make sure that a timeout has to be reached before another resource managing
318 // operations can be performed.
319 TEST_F(ResourceManagerTest, ResourceChangeDelayed) {
320   // Create a few dummy activities in the reverse order as we need them.
321   TestActivity* app4 = CreateActivity("app4");
322   TestActivity* app3 = CreateActivity("app3");
323   TestActivity* app2 = CreateActivity("app2");
324   TestActivity* app1 = CreateActivity("app1");
325   app1->SetCurrentState(Activity::ACTIVITY_VISIBLE);
326   app2->SetCurrentState(Activity::ACTIVITY_INVISIBLE);
327   app3->SetCurrentState(Activity::ACTIVITY_INVISIBLE);
328   app4->SetCurrentState(Activity::ACTIVITY_INVISIBLE);
329
330   // The timeout override in milliseconds.
331   const int kTimeoutOverrideInMs = 20;
332   // Tell the resource manager to wait for 20ms between calls.
333   ResourceManager::Get()->SetWaitTimeBetweenResourceManageCalls(
334       kTimeoutOverrideInMs);
335   // Applying higher pressure should get unload the oldest activity.
336   ResourceManager::Get()->SetMemoryPressureAndStopMonitoring(
337       ResourceManager::MEMORY_PRESSURE_CRITICAL);
338   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app1->GetCurrentState());
339   EXPECT_EQ(Activity::ACTIVITY_INVISIBLE, app2->GetCurrentState());
340   EXPECT_EQ(Activity::ACTIVITY_INVISIBLE, app3->GetCurrentState());
341   EXPECT_EQ(Activity::ACTIVITY_UNLOADED, app4->GetCurrentState());
342   // Trying to apply the resource pressure again within the timeout time should
343   // not trigger any operation.
344   ResourceManager::Get()->SetMemoryPressureAndStopMonitoring(
345       ResourceManager::MEMORY_PRESSURE_CRITICAL);
346   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app1->GetCurrentState());
347   EXPECT_EQ(Activity::ACTIVITY_INVISIBLE, app2->GetCurrentState());
348   EXPECT_EQ(Activity::ACTIVITY_INVISIBLE, app3->GetCurrentState());
349   EXPECT_EQ(Activity::ACTIVITY_UNLOADED, app4->GetCurrentState());
350
351   // Passing the timeout however should allow for another call.
352   usleep(kTimeoutOverrideInMs * 1000);
353   ResourceManager::Get()->SetMemoryPressureAndStopMonitoring(
354       ResourceManager::MEMORY_PRESSURE_CRITICAL);
355   EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app1->GetCurrentState());
356   EXPECT_EQ(Activity::ACTIVITY_INVISIBLE, app2->GetCurrentState());
357   EXPECT_EQ(Activity::ACTIVITY_UNLOADED, app3->GetCurrentState());
358   EXPECT_EQ(Activity::ACTIVITY_UNLOADED, app4->GetCurrentState());
359 }
360
361 }  // namespace test
362 }  // namespace athena