linux: Cache families from FontRenderParams queries.
[chromium-blink-merge.git] / athena / content / app_activity_unittest.cc
blobf265c0ce613a99b537c863485853abe163387caa
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.
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_registry.h"
10 #include "athena/extensions/public/extensions_delegate.h"
11 #include "athena/resource_manager/public/resource_manager.h"
12 #include "athena/test/base/athena_test_base.h"
13 #include "extensions/common/extension_set.h"
14 #include "ui/aura/window.h"
15 #include "ui/views/view.h"
16 #include "ui/views/widget/widget.h"
18 namespace content {
19 class BrowserContext;
22 namespace athena {
23 namespace test {
25 namespace {
27 // An identifier for the running apps.
28 const char kDummyApp1[] = "aaaaaaa";
29 const char kDummyApp2[] = "bbbbbbb";
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(app_id),
36 view_(new views::View()),
37 current_state_(ACTIVITY_VISIBLE) {
38 app_activity_registry_ =
39 AppRegistry::Get()->GetAppActivityRegistry(app_id, NULL);
40 app_activity_registry_->RegisterAppActivity(this);
42 virtual ~TestAppActivity() {
43 app_activity_registry_->UnregisterAppActivity(this);
46 AppActivityRegistry* app_activity_registry() {
47 return app_activity_registry_;
50 // Activity:
51 virtual ActivityViewModel* GetActivityViewModel() override {
52 return this;
54 virtual void SetCurrentState(Activity::ActivityState state) override {
55 current_state_ = state;
56 if (state == ACTIVITY_UNLOADED)
57 app_activity_registry_->Unload();
59 virtual ActivityState GetCurrentState() override {
60 return current_state_;
62 virtual bool IsVisible() override {
63 return true;
65 virtual ActivityMediaState GetMediaState() override {
66 return Activity::ACTIVITY_MEDIA_STATE_NONE;
68 virtual aura::Window* GetWindow() override {
69 return view_->GetWidget()->GetNativeWindow();
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 views::Widget* CreateWidget() override { return NULL; }
79 virtual gfx::ImageSkia GetOverviewModeImage() override {
80 return gfx::ImageSkia();
83 private:
84 // If known the registry which holds all activities for the associated app.
85 AppActivityRegistry* app_activity_registry_;
87 // The title of the activity.
88 base::string16 title_;
90 // Our view.
91 views::View* view_;
93 // The current state for this activity.
94 ActivityState current_state_;
96 DISALLOW_COPY_AND_ASSIGN(TestAppActivity);
99 // An AppContentDelegateClass which we can query for call stats.
100 class TestExtensionsDelegate : public ExtensionsDelegate {
101 public:
102 TestExtensionsDelegate() : unload_called_(0), restart_called_(0) {}
103 virtual ~TestExtensionsDelegate() {}
105 int unload_called() const { return unload_called_; }
106 int restart_called() const { return restart_called_; }
108 // ExtensionsDelegate:
109 virtual content::BrowserContext* GetBrowserContext() const override {
110 return NULL;
112 virtual const extensions::ExtensionSet& GetInstalledExtensions() override {
113 return extension_set_;
115 // Unload an application. Returns true when unloaded.
116 virtual bool UnloadApp(const std::string& app_id) override {
117 unload_called_++;
118 // Since we did not close anything we let the framework clean up.
119 return false;
121 // Restarts an application. Returns true when the restart was initiated.
122 virtual bool LaunchApp(const std::string& app_id) override {
123 restart_called_++;
124 return true;
127 private:
128 int unload_called_;
129 int restart_called_;
131 extensions::ExtensionSet extension_set_;
133 DISALLOW_COPY_AND_ASSIGN(TestExtensionsDelegate);
136 } // namespace
138 // Our testing base.
139 class AppActivityTest : public AthenaTestBase {
140 public:
141 AppActivityTest() : test_extensions_delegate_(NULL) {}
142 virtual ~AppActivityTest() {}
144 // AthenaTestBase:
145 virtual void SetUp() override {
146 AthenaTestBase::SetUp();
147 // Create and install our TestAppContentDelegate with instrumentation.
148 ExtensionsDelegate::Shutdown();
149 // The instance will be deleted by ExtensionsDelegate::Shutdown().
150 test_extensions_delegate_ = new TestExtensionsDelegate();
153 // A function to create an Activity.
154 TestAppActivity* CreateAppActivity(const std::string& app_id) {
155 TestAppActivity* activity = new TestAppActivity(app_id);
156 ActivityManager::Get()->AddActivity(activity);
157 return activity;
160 void DeleteActivity(Activity* activity) {
161 Activity::Delete(activity);
162 RunAllPendingInMessageLoop();
165 // Get the position of the activity in the navigation history.
166 int GetActivityPosition(Activity* activity) {
167 aura::Window* window = activity->GetActivityViewModel()->GetContentsView()
168 ->GetWidget()->GetNativeWindow();
169 aura::Window::Windows windows = activity->GetWindow()->parent()->children();
170 for (size_t i = 0; i < windows.size(); i++) {
171 if (windows[i] == window)
172 return i;
174 return -1;
177 // To avoid interference of the ResourceManager in these AppActivity
178 // framework tests, we disable the ResourceManager for some tests.
179 // Every use/interference of this function gets explained.
180 void DisableResourceManager() {
181 ResourceManager::Get()->Pause(true);
184 protected:
185 TestExtensionsDelegate* test_extensions_delegate() {
186 return test_extensions_delegate_;
189 private:
190 TestExtensionsDelegate* test_extensions_delegate_;
192 DISALLOW_COPY_AND_ASSIGN(AppActivityTest);
195 // Only creates one activity and destroys it.
196 TEST_F(AppActivityTest, OneAppActivity) {
197 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
199 TestAppActivity* app_activity = CreateAppActivity(kDummyApp1);
200 EXPECT_EQ(1, AppRegistry::Get()->NumberOfApplications());
201 EXPECT_EQ(1, app_activity->app_activity_registry()->NumberOfActivities());
202 EXPECT_EQ(AppRegistry::Get()->GetAppActivityRegistry(kDummyApp1, NULL),
203 app_activity->app_activity_registry());
204 DeleteActivity(app_activity);
206 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
207 EXPECT_EQ(0, test_extensions_delegate()->unload_called());
208 EXPECT_EQ(0, test_extensions_delegate()->restart_called());
211 // Test running of two applications.
212 TEST_F(AppActivityTest, TwoAppsWithOneActivityEach) {
213 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
215 TestAppActivity* app_activity1 = CreateAppActivity(kDummyApp1);
216 EXPECT_EQ(1, AppRegistry::Get()->NumberOfApplications());
217 EXPECT_EQ(1, app_activity1->app_activity_registry()->NumberOfActivities());
218 TestAppActivity* app_activity2 = CreateAppActivity(kDummyApp2);
219 EXPECT_EQ(2, AppRegistry::Get()->NumberOfApplications());
220 EXPECT_EQ(1, app_activity2->app_activity_registry()->NumberOfActivities());
221 EXPECT_EQ(1, app_activity1->app_activity_registry()->NumberOfActivities());
222 DeleteActivity(app_activity1);
223 DeleteActivity(app_activity2);
225 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
226 EXPECT_EQ(0, test_extensions_delegate()->unload_called());
227 EXPECT_EQ(0, test_extensions_delegate()->restart_called());
230 // Create and destroy two activities for the same application.
231 TEST_F(AppActivityTest, TwoAppActivities) {
232 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
234 TestAppActivity* app_activity1 = CreateAppActivity(kDummyApp1);
235 TestAppActivity* app_activity2 = CreateAppActivity(kDummyApp1);
236 EXPECT_EQ(1, AppRegistry::Get()->NumberOfApplications());
237 EXPECT_EQ(2, app_activity1->app_activity_registry()->NumberOfActivities());
238 EXPECT_EQ(app_activity1->app_activity_registry(),
239 app_activity2->app_activity_registry());
240 DeleteActivity(app_activity1);
241 EXPECT_EQ(1, AppRegistry::Get()->NumberOfApplications());
242 EXPECT_EQ(1, app_activity2->app_activity_registry()->NumberOfActivities());
243 DeleteActivity(app_activity2);
245 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
247 TestAppActivity* app_activity1 = CreateAppActivity(kDummyApp1);
248 TestAppActivity* app_activity2 = CreateAppActivity(kDummyApp1);
249 EXPECT_EQ(1, AppRegistry::Get()->NumberOfApplications());
250 EXPECT_EQ(2, app_activity1->app_activity_registry()->NumberOfActivities());
251 EXPECT_EQ(app_activity1->app_activity_registry(),
252 app_activity2->app_activity_registry());
253 DeleteActivity(app_activity2);
254 EXPECT_EQ(1, AppRegistry::Get()->NumberOfApplications());
255 EXPECT_EQ(1, app_activity1->app_activity_registry()->NumberOfActivities());
256 DeleteActivity(app_activity1);
258 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
259 EXPECT_EQ(0, test_extensions_delegate()->unload_called());
260 EXPECT_EQ(0, test_extensions_delegate()->restart_called());
263 // Test unload and the creation of the proxy, then "closing the activity".
264 TEST_F(AppActivityTest, TestUnloadFollowedByClose) {
265 // We do not want the ResourceManager to interfere with this test. In this
266 // case it would (dependent on its current internal implementation)
267 // automatically re-load the unloaded activity if it is in an "active"
268 // position.
269 DisableResourceManager();
270 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
272 TestAppActivity* app_activity = CreateAppActivity(kDummyApp1);
273 EXPECT_EQ(1, AppRegistry::Get()->NumberOfApplications());
274 AppActivityRegistry* app_activity_registry =
275 app_activity->app_activity_registry();
276 EXPECT_EQ(1, app_activity_registry->NumberOfActivities());
277 EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app_activity->GetCurrentState());
279 // Calling Unload now should not do anything since at least one activity in
280 // the registry is still visible.
281 app_activity_registry->Unload();
282 RunAllPendingInMessageLoop();
283 EXPECT_EQ(0, test_extensions_delegate()->unload_called());
285 // After setting our activity to unloaded however the application should get
286 // unloaded as requested.
287 app_activity->SetCurrentState(Activity::ACTIVITY_UNLOADED);
288 RunAllPendingInMessageLoop();
289 EXPECT_EQ(1, test_extensions_delegate()->unload_called());
291 // Check that our created application is gone, and instead a proxy got
292 // created.
293 ASSERT_EQ(1, AppRegistry::Get()->NumberOfApplications());
294 ASSERT_EQ(app_activity_registry,
295 AppRegistry::Get()->GetAppActivityRegistry(kDummyApp1, NULL));
296 EXPECT_EQ(0, app_activity_registry->NumberOfActivities());
297 Activity* activity_proxy = app_activity_registry->unloaded_activity_proxy();
298 ASSERT_TRUE(activity_proxy);
299 EXPECT_NE(app_activity, activity_proxy);
300 EXPECT_EQ(Activity::ACTIVITY_UNLOADED, activity_proxy->GetCurrentState());
301 EXPECT_EQ(0, test_extensions_delegate()->restart_called());
303 // Close the proxy object and make sure that nothing bad happens.
304 DeleteActivity(activity_proxy);
306 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
307 EXPECT_EQ(1, test_extensions_delegate()->unload_called());
308 EXPECT_EQ(0, test_extensions_delegate()->restart_called());
311 // Test that when unloading an app while multiple apps / activities are present,
312 // the proxy gets created in the correct location.
313 TEST_F(AppActivityTest, TestUnloadProxyLocation) {
314 // Disable the resource manager since some build bots run this test for an
315 // extended amount of time which allows the MemoryPressureNotifier to fire.
316 DisableResourceManager();
317 // Set up some activities for some applications.
318 TestAppActivity* app_activity1a = CreateAppActivity(kDummyApp1);
319 TestAppActivity* app_activity2a = CreateAppActivity(kDummyApp2);
320 TestAppActivity* app_activity2b = CreateAppActivity(kDummyApp2);
321 TestAppActivity* app_activity1b = CreateAppActivity(kDummyApp1);
322 EXPECT_EQ(3, GetActivityPosition(app_activity1b));
323 EXPECT_EQ(2, GetActivityPosition(app_activity2b));
324 EXPECT_EQ(1, GetActivityPosition(app_activity2a));
325 EXPECT_EQ(0, GetActivityPosition(app_activity1a));
327 // Unload an app and make sure that the proxy is in the newest activity slot.
328 AppActivityRegistry* app_activity_registry =
329 app_activity2a->app_activity_registry();
330 app_activity2a->SetCurrentState(Activity::ACTIVITY_UNLOADED);
331 app_activity2b->SetCurrentState(Activity::ACTIVITY_UNLOADED);
332 RunAllPendingInMessageLoop();
333 EXPECT_EQ(0, app_activity_registry->NumberOfActivities());
334 Activity* activity_proxy = app_activity_registry->unloaded_activity_proxy();
335 RunAllPendingInMessageLoop();
337 EXPECT_EQ(2, GetActivityPosition(app_activity1b));
338 EXPECT_EQ(1, GetActivityPosition(activity_proxy));
339 EXPECT_EQ(0, GetActivityPosition(app_activity1a));
340 EXPECT_EQ(0, test_extensions_delegate()->restart_called());
342 DeleteActivity(activity_proxy);
343 DeleteActivity(app_activity1b);
344 DeleteActivity(app_activity1a);
347 // Test that an unload with multiple activities of the same app will only unload
348 // when all activities were marked for unloading.
349 TEST_F(AppActivityTest, TestMultipleActivityUnloadLock) {
350 // Disable the resource manager since some build bots run this test for an
351 // extended amount of time which allows the MemoryPressureNotifier to fire.
352 DisableResourceManager();
354 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
356 TestAppActivity* app_activity1 = CreateAppActivity(kDummyApp1);
357 TestAppActivity* app_activity2 = CreateAppActivity(kDummyApp1);
358 TestAppActivity* app_activity3 = CreateAppActivity(kDummyApp1);
360 // Check that we have 3 activities of the same application.
361 EXPECT_EQ(1, AppRegistry::Get()->NumberOfApplications());
362 AppActivityRegistry* app_activity_registry =
363 app_activity1->app_activity_registry();
364 EXPECT_EQ(app_activity_registry, app_activity2->app_activity_registry());
365 EXPECT_EQ(app_activity_registry, app_activity3->app_activity_registry());
366 EXPECT_EQ(3, app_activity_registry->NumberOfActivities());
367 EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app_activity1->GetCurrentState());
368 EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app_activity2->GetCurrentState());
369 EXPECT_EQ(Activity::ACTIVITY_VISIBLE, app_activity3->GetCurrentState());
371 // After setting all activities to UNLOADED the application should unload.
372 app_activity1->SetCurrentState(Activity::ACTIVITY_UNLOADED);
373 RunAllPendingInMessageLoop();
374 EXPECT_EQ(0, test_extensions_delegate()->unload_called());
375 app_activity2->SetCurrentState(Activity::ACTIVITY_UNLOADED);
376 RunAllPendingInMessageLoop();
377 EXPECT_EQ(0, test_extensions_delegate()->unload_called());
378 app_activity3->SetCurrentState(Activity::ACTIVITY_UNLOADED);
379 RunAllPendingInMessageLoop();
380 EXPECT_EQ(1, test_extensions_delegate()->unload_called());
382 // Now there should only be the proxy activity left.
383 ASSERT_EQ(1, AppRegistry::Get()->NumberOfApplications());
384 ASSERT_EQ(app_activity_registry,
385 AppRegistry::Get()->GetAppActivityRegistry(kDummyApp1, NULL));
386 EXPECT_EQ(0, app_activity_registry->NumberOfActivities());
387 Activity* activity_proxy = app_activity_registry->unloaded_activity_proxy();
388 ASSERT_TRUE(activity_proxy);
389 EXPECT_NE(app_activity1, activity_proxy);
390 EXPECT_NE(app_activity2, activity_proxy);
391 EXPECT_NE(app_activity3, activity_proxy);
392 EXPECT_EQ(Activity::ACTIVITY_UNLOADED, activity_proxy->GetCurrentState());
394 // Close the proxy object and make sure that nothing bad happens.
395 DeleteActivity(activity_proxy);
397 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
398 EXPECT_EQ(1, test_extensions_delegate()->unload_called());
399 EXPECT_EQ(0, test_extensions_delegate()->restart_called());
402 // Test that activating the proxy will reload the application.
403 TEST_F(AppActivityTest, TestUnloadWithReload) {
404 // We do not want the ResourceManager to interfere with this test. In this
405 // case it would (dependent on its current internal implementation)
406 // automatically re-load the unloaded activity if it is in an "active"
407 // position.
408 DisableResourceManager();
409 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
411 TestAppActivity* app_activity = CreateAppActivity(kDummyApp1);
412 AppActivityRegistry* app_activity_registry =
413 app_activity->app_activity_registry();
415 // Unload the activity.
416 app_activity->SetCurrentState(Activity::ACTIVITY_UNLOADED);
417 RunAllPendingInMessageLoop();
418 EXPECT_EQ(1, test_extensions_delegate()->unload_called());
420 // Try to activate the activity again. This will force the application to
421 // reload.
422 Activity* activity_proxy = app_activity_registry->unloaded_activity_proxy();
423 activity_proxy->SetCurrentState(Activity::ACTIVITY_VISIBLE);
424 EXPECT_EQ(1, test_extensions_delegate()->restart_called());
426 // However - the restart in this test framework does not really restart and
427 // all objects should be still there..
428 EXPECT_EQ(1, AppRegistry::Get()->NumberOfApplications());
429 EXPECT_TRUE(app_activity_registry->unloaded_activity_proxy());
430 Activity::Delete(app_activity_registry->unloaded_activity_proxy());
431 EXPECT_EQ(0, AppRegistry::Get()->NumberOfApplications());
434 } // namespace test
435 } // namespace athena