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

Side by Side Diff: athena/content/app_activity_unittest.cc

Issue 477523002: Athena: Adding basic resource management framework (un-/re-loading) of V2 applications (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merged with trunk Created 6 years, 4 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/activity/public/activity_factory.h"
6 #include "athena/activity/public/activity_manager.h"
7 #include "athena/content/app_activity.h"
8 #include "athena/content/app_activity_registry.h"
9 #include "athena/content/public/app_content_delegate.h"
10 #include "athena/content/public/app_registry.h"
11 #include "athena/test/athena_test_base.h"
12 #include "extensions/shell/browser/shell_app_window.h"
13 #include "ui/aura/window.h"
14 #include "ui/views/view.h"
15 #include "ui/views/widget/widget.h"
16
17
18 namespace content {
19 class BrowserContext;
20 }
21
22 namespace athena {
23 namespace test {
24
25 namespace {
26
27 // An identifier for the running apps.
28 const char kDummyApp1[] = "aaaaaaa";
29 const char kDummyApp2[] = "bbbbbbb";
30
31 // A dummy test app activity which works without content / ShellAppWindow.
32 class TestAppActivity : public AppActivity {
33 public:
34 explicit TestAppActivity(const std::string& app_id) :
35 AppActivity(NULL),
36 app_id_(app_id),
37 view_(new views::View()),
38 current_state_(ACTIVITY_VISIBLE) {
39 app_activity_registry_ =
40 AppRegistry::Get()->GetAppActivityRegistry(app_id, NULL);
41 app_activity_registry_->RegisterAppActivity(this);
42 }
43 virtual ~TestAppActivity() {
44 app_activity_registry_->UnregisterAppActivity(this);
45 }
46
47 AppActivityRegistry* app_activity_registry() {
48 return app_activity_registry_;
49 }
50
51 // Activity:
52 virtual ActivityViewModel* GetActivityViewModel() OVERRIDE {
53 return this;
54 }
55 virtual void SetCurrentState(Activity::ActivityState state) OVERRIDE {
56 current_state_ = state;
57 }
58 virtual ActivityState GetCurrentState() OVERRIDE {
59 return current_state_;
60 }
61
oshima 2014/08/18 23:14:02 nuke new line
Mr4D (OOO till 08-26) 2014/08/19 14:21:10 Done.
62 virtual bool IsVisible() OVERRIDE {
63 return true;
64 }
65 virtual ActivityMediaState GetMediaState() OVERRIDE {
66 return Activity::ACTIVITY_MEDIA_STATE_NONE;
67 }
68 virtual aura::Window* GetWindow() OVERRIDE {
69 return view_->GetWidget()->GetNativeWindow();
70 }
71
72 // ActivityViewModel:
73 virtual void Init() OVERRIDE {}
74 virtual SkColor GetRepresentativeColor() const OVERRIDE { return 0; }
75 virtual base::string16 GetTitle() const OVERRIDE { return title_; }
76 virtual bool UsesFrame() const OVERRIDE { return true; }
77 virtual views::View* GetContentsView() OVERRIDE { return view_; }
78 virtual void CreateOverviewModeImage() OVERRIDE {}
79
80 private:
81 // If known the registry which holds all activities for the associated app.
82 AppActivityRegistry* app_activity_registry_;
83
84 // The application ID.
85 const std::string& app_id_;
86
87 // The title of the activity.
88 base::string16 title_;
89
90 // Our view.
91 views::View* view_;
92
93 // The current state for this activity.
94 ActivityState current_state_;
95
96 DISALLOW_COPY_AND_ASSIGN(TestAppActivity);
97 };
98
99 // An AppContentDelegateClass which we can query for call stats.
100 class TestAppContentDelegate : public AppContentDelegate {
101 public:
102 TestAppContentDelegate() : unload_called_(0),
103 restart_called_(0) {}
104 virtual ~TestAppContentDelegate() {}
105
106 int unload_called() { return unload_called_; }
107 int restart_called() { return restart_called_; }
108 void SetExtensionID(const std::string& extension_id) {
109 extension_id_to_return_ = extension_id;
110 }
111
112 // Unload an application. Returns true when unloaded.
113 virtual bool UnloadApplication(
114 const std::string& app_id,
115 content::BrowserContext* browser_context) OVERRIDE {
116 unload_called_++;
117 // Since we did not close anything we let the framework clean up.
118 return false;
119 }
120 // Restarts an application. Returns true when the restart was initiated.
121 virtual bool RestartApplication(
122 const std::string& app_id,
123 content::BrowserContext* browser_context) OVERRIDE {
124 restart_called_++;
125 return true;
126 }
127 // Returns the application ID (or an empty string) for a given web content.
128 virtual std::string GetExtensionID(
129 content::WebContents* web_contents) OVERRIDE {
130 return extension_id_to_return_;
131 }
132
133 private:
134 int unload_called_;
135 int restart_called_;
136 std::string extension_id_to_return_;
137
138 DISALLOW_COPY_AND_ASSIGN(TestAppContentDelegate);
139 };
140
141 } // namespace
142
143 // Our testing base.
144 class AppActivityTest : public AthenaTestBase {
145 public:
146 AppActivityTest() : test_app_content_delegate_(NULL) {}
147 virtual ~AppActivityTest() {}
148
149 // AthenaTestBase:
150 virtual void SetUp() OVERRIDE {
151 AthenaTestBase::SetUp();
152 // Create and install our TestAppContentDelegate with instrumentation.
153 test_app_content_delegate_ = new TestAppContentDelegate();
154 AppRegistry::Get()->SetDelegate(test_app_content_delegate_);
155 }
156
157 // A function to create an Activity.
158 TestAppActivity* CreateAppActivity(const std::string& app_id) {
159 TestAppActivity* activity = new TestAppActivity(app_id);
160 ActivityManager::Get()->AddActivity(activity);
161 return activity;
162 }
163
164 void CloseActivity(Activity* activity) {
165 delete activity;
166 RunAllPendingInMessageLoop();
167 }
168
169 // Get the position of the activity in the navigation history.
170 int GetActivityPosition(Activity* activity) {
171 aura::Window* window = activity->GetActivityViewModel()->GetContentsView()
172 ->GetWidget()->GetNativeWindow();
173 aura::Window::Windows windows = activity->GetWindow()->parent()->children();
174 for (size_t i = 0; i < windows.size(); i++) {
175 if (windows[i] == window)
176 return i;
177 }
178 return -1;
179 }
180
181 protected:
182 TestAppContentDelegate* test_app_content_delegate() {
183 return test_app_content_delegate_;
184 }
185
186 private:
187 TestAppContentDelegate* test_app_content_delegate_;
188
189 DISALLOW_COPY_AND_ASSIGN(AppActivityTest);
190 };
191
192 // Only creates one activity and destroys it.
193 TEST_F(AppActivityTest, OneAppActivity) {
194 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
195 {
196 TestAppActivity* app_activity = CreateAppActivity(kDummyApp1);
197 EXPECT_EQ(1, AppRegistry::Get()->NumberOfApplications());
198 EXPECT_EQ(1, app_activity->app_activity_registry()->NumberOfActivities());
199 EXPECT_EQ(AppRegistry::Get()->GetAppActivityRegistry(kDummyApp1, NULL),
200 app_activity->app_activity_registry());
201 CloseActivity(app_activity);
202 }
203 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
204 EXPECT_EQ(0, test_app_content_delegate()->unload_called());
205 EXPECT_EQ(0, test_app_content_delegate()->restart_called());
206 }
207
208 // Test running of two applications.
209 TEST_F(AppActivityTest, TwoAppsWithOneActivityEach) {
210 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
211 {
212 TestAppActivity* app_activity1 = CreateAppActivity(kDummyApp1);
213 EXPECT_EQ(1, AppRegistry::Get()->NumberOfApplications());
214 EXPECT_EQ(1, app_activity1->app_activity_registry()->NumberOfActivities());
215 TestAppActivity* app_activity2 = CreateAppActivity(kDummyApp2);
216 EXPECT_EQ(2, AppRegistry::Get()->NumberOfApplications());
217 EXPECT_EQ(1, app_activity2->app_activity_registry()->NumberOfActivities());
218 EXPECT_EQ(1, app_activity1->app_activity_registry()->NumberOfActivities());
219 CloseActivity(app_activity1);
220 CloseActivity(app_activity2);
221 }
222 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
223 EXPECT_EQ(0, test_app_content_delegate()->unload_called());
224 EXPECT_EQ(0, test_app_content_delegate()->restart_called());
225 }
226
227 // Create and destroy two activities for the same application.
228 TEST_F(AppActivityTest, TwoAppActivities) {
229 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
230 {
231 TestAppActivity* app_activity1 = CreateAppActivity(kDummyApp1);
232 TestAppActivity* app_activity2 = CreateAppActivity(kDummyApp1);
233 EXPECT_EQ(1, AppRegistry::Get()->NumberOfApplications());
234 EXPECT_EQ(2, app_activity1->app_activity_registry()->NumberOfActivities());
235 EXPECT_EQ(app_activity1->app_activity_registry(),
236 app_activity2->app_activity_registry());
237 CloseActivity(app_activity1);
238 EXPECT_EQ(1, AppRegistry::Get()->NumberOfApplications());
239 EXPECT_EQ(1, app_activity2->app_activity_registry()->NumberOfActivities());
240 CloseActivity(app_activity2);
241 }
242 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
243 {
244 TestAppActivity* app_activity1 = CreateAppActivity(kDummyApp1);
245 TestAppActivity* app_activity2 = CreateAppActivity(kDummyApp1);
246 EXPECT_EQ(1, AppRegistry::Get()->NumberOfApplications());
247 EXPECT_EQ(2, app_activity1->app_activity_registry()->NumberOfActivities());
248 EXPECT_EQ(app_activity1->app_activity_registry(),
249 app_activity2->app_activity_registry());
250 CloseActivity(app_activity2);
251 EXPECT_EQ(1, AppRegistry::Get()->NumberOfApplications());
252 EXPECT_EQ(1, app_activity1->app_activity_registry()->NumberOfActivities());
253 CloseActivity(app_activity1);
254 }
255 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
256 EXPECT_EQ(0, test_app_content_delegate()->unload_called());
257 EXPECT_EQ(0, test_app_content_delegate()->restart_called());
258 }
259
260 // Test unload and the creation of the proxy, then "closing the activity".
261 TEST_F(AppActivityTest, TestUnloadFollowedByClose) {
262 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
263
264 TestAppActivity* app_activity = CreateAppActivity(kDummyApp1);
265 EXPECT_EQ(1, AppRegistry::Get()->NumberOfApplications());
266 AppActivityRegistry* app_activity_registry =
267 app_activity->app_activity_registry();
268 EXPECT_EQ(1, app_activity_registry->NumberOfActivities());
269 EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app_activity->GetCurrentState());
270
271 // Calling Unload now should not do anything since at least one activity in
272 // the registry is still visible.
273 app_activity_registry->Unload();
274 EXPECT_EQ(0, test_app_content_delegate()->unload_called());
275
276 // After setting our activity to unloaded however the application should get
277 // unloaded as requested.
278 app_activity->SetCurrentState(Activity::ACTIVITY_UNLOADED);
279 app_activity_registry->Unload();
280 EXPECT_EQ(1, test_app_content_delegate()->unload_called());
281
282 // Check that our created application is gone, and instead a proxy got
283 // created.
284 ASSERT_EQ(1, AppRegistry::Get()->NumberOfApplications());
285 ASSERT_EQ(app_activity_registry,
286 AppRegistry::Get()->GetAppActivityRegistry(kDummyApp1, NULL));
287 EXPECT_EQ(0, app_activity_registry->NumberOfActivities());
288 Activity* activity_proxy =
289 app_activity_registry->unloaded_activity_proxy_for_test();
290 ASSERT_TRUE(activity_proxy);
291 EXPECT_NE(app_activity, activity_proxy);
292 EXPECT_EQ(Activity::ACTIVITY_UNLOADED, activity_proxy->GetCurrentState());
293
294 // Close the proxy object and make sure that nothing bad happens.
295 CloseActivity(activity_proxy);
296
297 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
298 EXPECT_EQ(1, test_app_content_delegate()->unload_called());
299 EXPECT_EQ(0, test_app_content_delegate()->restart_called());
300 }
301
302 // Test that when unloading an app while multiple apps / activities are present,
303 // the proxy gets created in the correct location.
304 TEST_F(AppActivityTest, TestUnloadProxyLocation) {
305 // Set up some activities for some applications.
306 TestAppActivity* app_activity1a = CreateAppActivity(kDummyApp1);
307 TestAppActivity* app_activity2a = CreateAppActivity(kDummyApp2);
308 TestAppActivity* app_activity2b = CreateAppActivity(kDummyApp2);
309 TestAppActivity* app_activity1b = CreateAppActivity(kDummyApp1);
310 EXPECT_EQ(3, GetActivityPosition(app_activity1b));
311 EXPECT_EQ(2, GetActivityPosition(app_activity2b));
312 EXPECT_EQ(1, GetActivityPosition(app_activity2a));
313 EXPECT_EQ(0, GetActivityPosition(app_activity1a));
314
315 // Unload an app and make sure that the proxy is in the newest activity slot.
316 AppActivityRegistry* app_activity_registry =
317 app_activity2a->app_activity_registry();
318 app_activity2a->SetCurrentState(Activity::ACTIVITY_UNLOADED);
319 app_activity2b->SetCurrentState(Activity::ACTIVITY_UNLOADED);
320 app_activity2a->app_activity_registry()->Unload();
321 EXPECT_EQ(0, app_activity_registry->NumberOfActivities());
322 Activity* activity_proxy =
323 app_activity_registry->unloaded_activity_proxy_for_test();
324 RunAllPendingInMessageLoop();
325
326 EXPECT_EQ(2, GetActivityPosition(app_activity1b));
327 EXPECT_EQ(1, GetActivityPosition(activity_proxy));
328 EXPECT_EQ(0, GetActivityPosition(app_activity1a));
329
330 CloseActivity(activity_proxy);
331 CloseActivity(app_activity1b);
332 CloseActivity(app_activity1a);
333 }
334
335 // Test that an unload with multiple activities of the same app will only unload
336 // when all activities were marked for unloading.
337 TEST_F(AppActivityTest, TestMultipleActivityUnloadLock) {
338 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
339
340 TestAppActivity* app_activity1 = CreateAppActivity(kDummyApp1);
341 TestAppActivity* app_activity2 = CreateAppActivity(kDummyApp1);
342 TestAppActivity* app_activity3 = CreateAppActivity(kDummyApp1);
343
344 // Check that we have 3 activities of the same application.
345 EXPECT_EQ(1, AppRegistry::Get()->NumberOfApplications());
346 AppActivityRegistry* app_activity_registry =
347 app_activity1->app_activity_registry();
348 EXPECT_EQ(app_activity_registry, app_activity2->app_activity_registry());
349 EXPECT_EQ(app_activity_registry, app_activity3->app_activity_registry());
350 EXPECT_EQ(3, app_activity_registry->NumberOfActivities());
351 EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app_activity1->GetCurrentState());
352 EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app_activity2->GetCurrentState());
353 EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app_activity3->GetCurrentState());
354
355 // After setting all activities to UNLOADED the application should unload.
356 app_activity1->SetCurrentState(Activity::ACTIVITY_UNLOADED);
357 app_activity1->app_activity_registry()->Unload();
358 EXPECT_EQ(0, test_app_content_delegate()->unload_called());
359 app_activity2->SetCurrentState(Activity::ACTIVITY_UNLOADED);
360 app_activity2->app_activity_registry()->Unload();
361 EXPECT_EQ(0, test_app_content_delegate()->unload_called());
362 app_activity3->SetCurrentState(Activity::ACTIVITY_UNLOADED);
363 app_activity3->app_activity_registry()->Unload();
364 EXPECT_EQ(1, test_app_content_delegate()->unload_called());
365
366 // Now there should only be the proxy activity left.
367 ASSERT_EQ(1, AppRegistry::Get()->NumberOfApplications());
368 ASSERT_EQ(app_activity_registry,
369 AppRegistry::Get()->GetAppActivityRegistry(kDummyApp1, NULL));
370 EXPECT_EQ(0, app_activity_registry->NumberOfActivities());
371 Activity* activity_proxy =
372 app_activity_registry->unloaded_activity_proxy_for_test();
373 ASSERT_TRUE(activity_proxy);
374 EXPECT_NE(app_activity1, activity_proxy);
375 EXPECT_NE(app_activity2, activity_proxy);
376 EXPECT_NE(app_activity3, activity_proxy);
377 EXPECT_EQ(Activity::ACTIVITY_UNLOADED, activity_proxy->GetCurrentState());
378
379 // Close the proxy object and make sure that nothing bad happens.
380 CloseActivity(activity_proxy);
381
382 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
383 EXPECT_EQ(1, test_app_content_delegate()->unload_called());
384 EXPECT_EQ(0, test_app_content_delegate()->restart_called());
385 }
386
387 // Test that activating the proxy will reload the application.
388 TEST_F(AppActivityTest, TestUnloadWithReload) {
389 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
390
391 TestAppActivity* app_activity = CreateAppActivity(kDummyApp1);
392 AppActivityRegistry* app_activity_registry =
393 app_activity->app_activity_registry();
394
395 // Unload the activity.
396 app_activity->SetCurrentState(Activity::ACTIVITY_UNLOADED);
397 app_activity_registry->Unload();
398 EXPECT_EQ(1, test_app_content_delegate()->unload_called());
399
400 // Try to activate the activity again. This will force the application to
401 // reload.
402 Activity* activity_proxy =
403 app_activity_registry->unloaded_activity_proxy_for_test();
404 activity_proxy->SetCurrentState(Activity::ACTIVITY_VISIBLE);
405 EXPECT_EQ(1, test_app_content_delegate()->restart_called());
406
407 // However - the restart in this test framework does not really restart and
408 // all objects should be gone now.
409 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
410 }
411
412 } // namespace test
413 } // namespace athena
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698