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

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

Powered by Google App Engine
This is Rietveld 408576698