OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/strings/string_number_conversions.h" | 5 #include "base/strings/string_number_conversions.h" |
6 #include "base/strings/stringprintf.h" | 6 #include "base/strings/stringprintf.h" |
7 #include "base/strings/utf_string_conversions.h" | 7 #include "base/strings/utf_string_conversions.h" |
| 8 #include "chrome/browser/apps/app_browsertest_util.h" |
8 #include "chrome/browser/browser_process.h" | 9 #include "chrome/browser/browser_process.h" |
9 #include "chrome/browser/extensions/api/notifications/notifications_api.h" | 10 #include "chrome/browser/extensions/api/notifications/notifications_api.h" |
10 #include "chrome/browser/extensions/extension_apitest.h" | 11 #include "chrome/browser/extensions/extension_apitest.h" |
11 #include "chrome/browser/extensions/extension_function_test_utils.h" | 12 #include "chrome/browser/extensions/extension_function_test_utils.h" |
12 #include "chrome/browser/notifications/notification.h" | 13 #include "chrome/browser/notifications/notification.h" |
13 #include "chrome/browser/notifications/notification_ui_manager.h" | 14 #include "chrome/browser/notifications/notification_ui_manager.h" |
14 #include "chrome/browser/profiles/profile_manager.h" | 15 #include "chrome/browser/profiles/profile_manager.h" |
| 16 #include "chrome/browser/ui/extensions/app_launch_params.h" |
| 17 #include "chrome/browser/ui/extensions/application_launch.h" |
| 18 #include "chrome/test/base/interactive_test_utils.h" |
15 #include "content/public/browser/notification_service.h" | 19 #include "content/public/browser/notification_service.h" |
16 #include "content/public/test/test_utils.h" | 20 #include "content/public/test/test_utils.h" |
17 #include "extensions/browser/api/test/test_api.h" | 21 #include "extensions/browser/api/test/test_api.h" |
| 22 #include "extensions/browser/app_window/app_window.h" |
| 23 #include "extensions/browser/app_window/app_window_registry.h" |
| 24 #include "extensions/browser/app_window/native_app_window.h" |
18 #include "extensions/browser/notification_types.h" | 25 #include "extensions/browser/notification_types.h" |
19 #include "extensions/common/features/feature.h" | 26 #include "extensions/common/features/feature.h" |
20 #include "extensions/common/test_util.h" | 27 #include "extensions/common/test_util.h" |
| 28 #include "extensions/test/extension_test_message_listener.h" |
21 #include "extensions/test/result_catcher.h" | 29 #include "extensions/test/result_catcher.h" |
22 #include "ui/message_center/message_center.h" | 30 #include "ui/message_center/message_center.h" |
23 #include "ui/message_center/notification_list.h" | 31 #include "ui/message_center/notification_list.h" |
24 #include "ui/message_center/notifier_settings.h" | 32 #include "ui/message_center/notifier_settings.h" |
25 | 33 |
| 34 #if defined(OS_MACOSX) |
| 35 #include "base/mac/mac_util.h" |
| 36 #include "ui/base/test/scoped_fake_nswindow_fullscreen.h" |
| 37 #endif |
| 38 |
| 39 using extensions::AppWindow; |
| 40 using extensions::AppWindowRegistry; |
26 using extensions::Extension; | 41 using extensions::Extension; |
27 using extensions::ResultCatcher; | 42 using extensions::ResultCatcher; |
28 | 43 |
29 namespace utils = extension_function_test_utils; | 44 namespace utils = extension_function_test_utils; |
30 | 45 |
31 namespace { | 46 namespace { |
32 | 47 |
33 // A class that waits for a |chrome.test.sendMessage| call, ignores the message, | 48 // A class that waits for a |chrome.test.sendMessage| call, ignores the message, |
34 // and writes down the user gesture status of the message. | 49 // and writes down the user gesture status of the message. |
35 class UserGestureCatcher : public content::NotificationObserver { | 50 class UserGestureCatcher : public content::NotificationObserver { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 content::NotificationRegistrar registrar_; | 89 content::NotificationRegistrar registrar_; |
75 | 90 |
76 // A sequential list of user gesture notifications from the test extension(s). | 91 // A sequential list of user gesture notifications from the test extension(s). |
77 std::deque<bool> results_; | 92 std::deque<bool> results_; |
78 | 93 |
79 // True if we're in a nested message loop waiting for results from | 94 // True if we're in a nested message loop waiting for results from |
80 // the extension. | 95 // the extension. |
81 bool waiting_; | 96 bool waiting_; |
82 }; | 97 }; |
83 | 98 |
| 99 enum class WindowState { |
| 100 FULLSCREEN, |
| 101 NORMAL |
| 102 }; |
| 103 |
84 class NotificationsApiTest : public ExtensionApiTest { | 104 class NotificationsApiTest : public ExtensionApiTest { |
85 public: | 105 public: |
86 const extensions::Extension* LoadExtensionAndWait( | 106 const Extension* LoadExtensionAndWait( |
87 const std::string& test_name) { | 107 const std::string& test_name) { |
88 base::FilePath extdir = test_data_dir_.AppendASCII(test_name); | 108 base::FilePath extdir = test_data_dir_.AppendASCII(test_name); |
89 content::WindowedNotificationObserver page_created( | 109 content::WindowedNotificationObserver page_created( |
90 extensions::NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY, | 110 extensions::NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY, |
91 content::NotificationService::AllSources()); | 111 content::NotificationService::AllSources()); |
92 const extensions::Extension* extension = LoadExtension(extdir); | 112 const extensions::Extension* extension = LoadExtension(extdir); |
93 if (extension) { | 113 if (extension) { |
94 page_created.Wait(); | 114 page_created.Wait(); |
95 } | 115 } |
96 return extension; | 116 return extension; |
97 } | 117 } |
98 | 118 |
| 119 const Extension* LoadAppWithWindowState( |
| 120 const std::string& test_name, WindowState window_state) { |
| 121 const char* window_state_string = NULL; |
| 122 switch (window_state) { |
| 123 case WindowState::FULLSCREEN: |
| 124 window_state_string = "fullscreen"; |
| 125 break; |
| 126 case WindowState::NORMAL: |
| 127 window_state_string = "normal"; |
| 128 break; |
| 129 } |
| 130 const std::string& create_window_options = base::StringPrintf( |
| 131 "{\"state\":\"%s\"}", window_state_string); |
| 132 base::FilePath extdir = test_data_dir_.AppendASCII(test_name); |
| 133 const extensions::Extension* extension = LoadExtension(extdir); |
| 134 EXPECT_TRUE(extension); |
| 135 |
| 136 ExtensionTestMessageListener launched_listener("launched", true); |
| 137 LaunchPlatformApp(extension); |
| 138 EXPECT_TRUE(launched_listener.WaitUntilSatisfied()); |
| 139 launched_listener.Reply(create_window_options); |
| 140 |
| 141 return extension; |
| 142 } |
| 143 |
| 144 AppWindow* GetFirstAppWindow(const std::string& app_id) { |
| 145 AppWindowRegistry::AppWindowList app_windows = AppWindowRegistry::Get( |
| 146 browser()->profile())->GetAppWindowsForApp(app_id); |
| 147 |
| 148 AppWindowRegistry::const_iterator iter = app_windows.begin(); |
| 149 if (iter != app_windows.end()) |
| 150 return *iter; |
| 151 |
| 152 return NULL; |
| 153 } |
| 154 |
99 protected: | 155 protected: |
100 std::string GetNotificationIdFromDelegateId(const std::string& delegate_id) { | 156 std::string GetNotificationIdFromDelegateId(const std::string& delegate_id) { |
101 return g_browser_process->notification_ui_manager() | 157 return g_browser_process->notification_ui_manager() |
102 ->FindById( | 158 ->FindById( |
103 delegate_id, | 159 delegate_id, |
104 NotificationUIManager::GetProfileID( | 160 NotificationUIManager::GetProfileID( |
105 g_browser_process->profile_manager()->GetLastUsedProfile())) | 161 g_browser_process->profile_manager()->GetLastUsedProfile())) |
106 ->id(); | 162 ->id(); |
107 } | 163 } |
| 164 |
| 165 void LaunchPlatformApp(const Extension* extension) { |
| 166 OpenApplication(AppLaunchParams( |
| 167 browser()->profile(), extension, extensions::LAUNCH_CONTAINER_NONE, |
| 168 WindowOpenDisposition::NEW_WINDOW, extensions::SOURCE_TEST)); |
| 169 } |
108 }; | 170 }; |
109 | 171 |
110 } // namespace | 172 } // namespace |
111 | 173 |
112 IN_PROC_BROWSER_TEST_F(NotificationsApiTest, TestBasicUsage) { | 174 IN_PROC_BROWSER_TEST_F(NotificationsApiTest, TestBasicUsage) { |
113 ASSERT_TRUE(RunExtensionTest("notifications/api/basic_usage")) << message_; | 175 ASSERT_TRUE(RunExtensionTest("notifications/api/basic_usage")) << message_; |
114 } | 176 } |
115 | 177 |
116 IN_PROC_BROWSER_TEST_F(NotificationsApiTest, TestEvents) { | 178 IN_PROC_BROWSER_TEST_F(NotificationsApiTest, TestEvents) { |
117 ASSERT_TRUE(RunExtensionTest("notifications/api/events")) << message_; | 179 ASSERT_TRUE(RunExtensionTest("notifications/api/events")) << message_; |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 ASSERT_TRUE(extension) << message_; | 357 ASSERT_TRUE(extension) << message_; |
296 | 358 |
297 const message_center::NotificationList::Notifications& notifications = | 359 const message_center::NotificationList::Notifications& notifications = |
298 g_browser_process->message_center()->GetVisibleNotifications(); | 360 g_browser_process->message_center()->GetVisibleNotifications(); |
299 ASSERT_EQ(1u, notifications.size()); | 361 ASSERT_EQ(1u, notifications.size()); |
300 message_center::Notification* notification = *(notifications.begin()); | 362 message_center::Notification* notification = *(notifications.begin()); |
301 ASSERT_EQ(extension->url(), notification->origin_url()); | 363 ASSERT_EQ(extension->url(), notification->origin_url()); |
302 | 364 |
303 EXPECT_TRUE(notification->never_timeout()); | 365 EXPECT_TRUE(notification->never_timeout()); |
304 } | 366 } |
| 367 |
| 368 IN_PROC_BROWSER_TEST_F(NotificationsApiTest, TestShouldDisplayNormal) { |
| 369 ExtensionTestMessageListener notification_created_listener("created", false); |
| 370 const Extension* extension = LoadAppWithWindowState( |
| 371 "notifications/api/basic_app", WindowState::NORMAL); |
| 372 ASSERT_TRUE(extension) << message_; |
| 373 ASSERT_TRUE(notification_created_listener.WaitUntilSatisfied()); |
| 374 |
| 375 // We start by making sure the window is actually focused. |
| 376 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow( |
| 377 GetFirstAppWindow(extension->id())->GetNativeWindow())); |
| 378 |
| 379 const message_center::NotificationList::Notifications& notifications = |
| 380 g_browser_process->message_center()->GetVisibleNotifications(); |
| 381 ASSERT_EQ(1u, notifications.size()); |
| 382 message_center::Notification* notification = *(notifications.begin()); |
| 383 // If the app hasn't created a fullscreen window, then its notifications |
| 384 // shouldn't be displayed when a window is fullscreen. |
| 385 ASSERT_FALSE(notification->delegate()->ShouldDisplayOverFullscreen()); |
| 386 } |
| 387 |
| 388 IN_PROC_BROWSER_TEST_F(NotificationsApiTest, TestShouldDisplayFullscreen) { |
| 389 #if defined(OS_MACOSX) |
| 390 ui::test::ScopedFakeNSWindowFullscreen fake_fullscreen; |
| 391 #endif |
| 392 ExtensionTestMessageListener notification_created_listener("created", false); |
| 393 const Extension* extension = LoadAppWithWindowState( |
| 394 "notifications/api/basic_app", WindowState::FULLSCREEN); |
| 395 ASSERT_TRUE(extension) << message_; |
| 396 ASSERT_TRUE(notification_created_listener.WaitUntilSatisfied()); |
| 397 |
| 398 // We start by making sure the window is actually focused. |
| 399 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow( |
| 400 GetFirstAppWindow(extension->id())->GetNativeWindow())); |
| 401 |
| 402 ASSERT_TRUE(GetFirstAppWindow(extension->id())->IsFullscreen()) |
| 403 << "Not Fullscreen"; |
| 404 ASSERT_TRUE(GetFirstAppWindow(extension->id())->GetBaseWindow()->IsActive()) |
| 405 << "Not Active"; |
| 406 |
| 407 const message_center::NotificationList::Notifications& notifications = |
| 408 g_browser_process->message_center()->GetVisibleNotifications(); |
| 409 ASSERT_EQ(1u, notifications.size()); |
| 410 message_center::Notification* notification = *(notifications.begin()); |
| 411 // If the app has created a fullscreen window, then its notifications should |
| 412 // be displayed when a window is fullscreen. |
| 413 ASSERT_TRUE(notification->delegate()->ShouldDisplayOverFullscreen()); |
| 414 } |
| 415 |
| 416 // The Fake OSX fullscreen window doesn't like drawing a second fullscreen |
| 417 // window when another is visible. |
| 418 #if !defined(OS_MACOSX) |
| 419 IN_PROC_BROWSER_TEST_F(NotificationsApiTest, TestShouldDisplayMultiFullscreen) { |
| 420 // Start a fullscreen app, and then start another fullscreen app on top of the |
| 421 // first. Notifications from the first should not be displayed because it is |
| 422 // not the app actually displaying on the screen. |
| 423 ExtensionTestMessageListener notification_created_listener("created", false); |
| 424 const Extension* extension1 = LoadAppWithWindowState( |
| 425 "notifications/api/basic_app", WindowState::FULLSCREEN); |
| 426 ASSERT_TRUE(extension1) << message_; |
| 427 |
| 428 ExtensionTestMessageListener window_visible_listener("visible", false); |
| 429 const Extension* extension2 = LoadAppWithWindowState( |
| 430 "notifications/api/other_app", WindowState::FULLSCREEN); |
| 431 ASSERT_TRUE(extension2) << message_; |
| 432 |
| 433 ASSERT_TRUE(notification_created_listener.WaitUntilSatisfied()); |
| 434 ASSERT_TRUE(window_visible_listener.WaitUntilSatisfied()); |
| 435 |
| 436 // We start by making sure the window is actually focused. |
| 437 ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow( |
| 438 GetFirstAppWindow(extension2->id())->GetNativeWindow())); |
| 439 |
| 440 const message_center::NotificationList::Notifications& notifications = |
| 441 g_browser_process->message_center()->GetVisibleNotifications(); |
| 442 ASSERT_EQ(1u, notifications.size()); |
| 443 message_center::Notification* notification = *(notifications.begin()); |
| 444 // The first app window is superseded by the second window, so its |
| 445 // notification shouldn't be displayed. |
| 446 ASSERT_FALSE(notification->delegate()->ShouldDisplayOverFullscreen()); |
| 447 } |
| 448 #endif |
OLD | NEW |