OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "base/utf_string_conversions.h" |
| 6 #include "chrome/browser/browser_process.h" |
| 7 #include "chrome/browser/notifications/balloon.h" |
| 8 #include "chrome/browser/notifications/balloon_collection_impl.h" |
| 9 #include "chrome/browser/notifications/desktop_notification_service.h" |
| 10 #include "chrome/browser/notifications/notification.h" |
| 11 #include "chrome/browser/notifications/notification_ui_manager.h" |
| 12 #include "chrome/browser/prefs/pref_service.h" |
| 13 #include "chrome/browser/ui/browser.h" |
| 14 #include "chrome/browser/ui/panels/base_panel_browser_test.h" |
| 15 #include "chrome/browser/ui/panels/panel.h" |
| 16 #include "chrome/browser/ui/panels/panel_manager.h" |
| 17 #include "chrome/browser/ui/panels/test_panel_mouse_watcher.h" |
| 18 #include "chrome/common/pref_names.h" |
| 19 #include "content/public/common/show_desktop_notification_params.h" |
| 20 #include "ui/gfx/screen.h" |
| 21 |
| 22 // Desktop notification code subscribes to various panel change notifications |
| 23 // so that it knows when to adjusts balloon positions. In order to give |
| 24 // desktop notification code a chance to process the change notifications, |
| 25 // we call MessageLoopForUI::current()->RunAllPending() after any panel change |
| 26 // has been made. |
| 27 class PanelAndDesktopNotificationTest : public BasePanelBrowserTest { |
| 28 public: |
| 29 PanelAndDesktopNotificationTest() : BasePanelBrowserTest() { |
| 30 } |
| 31 |
| 32 virtual ~PanelAndDesktopNotificationTest() { |
| 33 } |
| 34 |
| 35 virtual void SetUpOnMainThread() OVERRIDE { |
| 36 // Do not use our own testing work area since desktop notification code |
| 37 // does not have the hook up for testing work area. |
| 38 disable_display_settings_mock(); |
| 39 |
| 40 BasePanelBrowserTest::SetUpOnMainThread(); |
| 41 |
| 42 g_browser_process->local_state()->SetInteger( |
| 43 prefs::kDesktopNotificationPosition, BalloonCollection::LOWER_RIGHT); |
| 44 balloons_ = new BalloonCollectionImpl(); |
| 45 ui_manager_.reset(NotificationUIManager::Create( |
| 46 g_browser_process->local_state(), balloons_)); |
| 47 service_.reset(new DesktopNotificationService(browser()->profile(), |
| 48 ui_manager_.get())); |
| 49 } |
| 50 |
| 51 virtual void CleanUpOnMainThread() OVERRIDE { |
| 52 balloons_->RemoveAll(); |
| 53 MessageLoopForUI::current()->RunAllPending(); |
| 54 |
| 55 service_.reset(); |
| 56 ui_manager_.reset(); |
| 57 |
| 58 BasePanelBrowserTest::CleanUpOnMainThread(); |
| 59 } |
| 60 |
| 61 content::ShowDesktopNotificationHostMsgParams StandardTestNotification() { |
| 62 content::ShowDesktopNotificationHostMsgParams params; |
| 63 params.notification_id = 0; |
| 64 params.origin = GURL("http://www.google.com"); |
| 65 params.is_html = false; |
| 66 params.icon_url = GURL("/icon.png"); |
| 67 params.title = ASCIIToUTF16("Title"); |
| 68 params.body = ASCIIToUTF16("Text"); |
| 69 params.direction = WebKit::WebTextDirectionDefault; |
| 70 return params; |
| 71 } |
| 72 |
| 73 Balloon* CreateBalloon() { |
| 74 content::ShowDesktopNotificationHostMsgParams params = |
| 75 StandardTestNotification(); |
| 76 EXPECT_TRUE(service()->ShowDesktopNotification( |
| 77 params, 0, 0, DesktopNotificationService::PageNotification)); |
| 78 MessageLoopForUI::current()->RunAllPending(); |
| 79 return balloons().front(); |
| 80 } |
| 81 |
| 82 static int GetBalloonBottomPosition(Balloon* balloon) { |
| 83 #if defined(OS_MACOSX) |
| 84 // The position returned by the notification balloon is based on Mac's |
| 85 // vertically inverted orientation. We need to flip it so that it can |
| 86 // be compared against the position returned by the panel. |
| 87 gfx::Size screen_size = gfx::Screen::GetPrimaryMonitor().size(); |
| 88 return screen_size.height() - balloon->GetPosition().y(); |
| 89 #else |
| 90 return balloon->GetPosition().y() + balloon->GetViewSize().height(); |
| 91 #endif |
| 92 } |
| 93 |
| 94 static void DragPanelToMouseLocation(Panel* panel, |
| 95 const gfx::Point& new_mouse_location) { |
| 96 PanelManager* panel_manager = PanelManager::GetInstance(); |
| 97 panel_manager->StartDragging(panel, panel->GetBounds().origin()); |
| 98 panel_manager->Drag(new_mouse_location); |
| 99 panel_manager->EndDragging(false); |
| 100 } |
| 101 |
| 102 static void ResizePanelByMouseWithDelta(Panel* panel, |
| 103 panel::ResizingSides side, |
| 104 const gfx::Point& delta) { |
| 105 PanelManager* panel_manager = PanelManager::GetInstance(); |
| 106 gfx::Point mouse_location = panel->GetBounds().origin(); |
| 107 panel_manager->StartResizingByMouse(panel, mouse_location, side); |
| 108 panel_manager->ResizeByMouse(mouse_location.Add(delta)); |
| 109 panel_manager->EndResizingByMouse(false); |
| 110 } |
| 111 |
| 112 DesktopNotificationService* service() const { return service_.get(); } |
| 113 const BalloonCollection::Balloons& balloons() const { |
| 114 return balloons_->GetActiveBalloons(); |
| 115 } |
| 116 |
| 117 private: |
| 118 BalloonCollectionImpl* balloons_; // Owned by NotificationUIManager. |
| 119 scoped_ptr<NotificationUIManager> ui_manager_; |
| 120 scoped_ptr<DesktopNotificationService> service_; |
| 121 }; |
| 122 |
| 123 IN_PROC_BROWSER_TEST_F(PanelAndDesktopNotificationTest, AddAndClosePanel) { |
| 124 Balloon* balloon = CreateBalloon(); |
| 125 int original_balloon_bottom = GetBalloonBottomPosition(balloon); |
| 126 |
| 127 // Create a docked panel. Expect that the notification balloon moves up to be |
| 128 // above the panel. |
| 129 Panel* panel = CreateDockedPanel("1", gfx::Rect(0, 0, 200, 200)); |
| 130 MessageLoopForUI::current()->RunAllPending(); |
| 131 int balloon_bottom = GetBalloonBottomPosition(balloon); |
| 132 EXPECT_LT(balloon_bottom, panel->GetBounds().y()); |
| 133 EXPECT_LT(balloon_bottom, original_balloon_bottom); |
| 134 |
| 135 // Close the panel. Expect the notification balloon moves back to its original |
| 136 // position. |
| 137 panel->Close(); |
| 138 MessageLoopForUI::current()->RunAllPending(); |
| 139 EXPECT_EQ(original_balloon_bottom, GetBalloonBottomPosition(balloon)); |
| 140 } |
| 141 |
| 142 IN_PROC_BROWSER_TEST_F(PanelAndDesktopNotificationTest, |
| 143 ExpandAndCollapsePanel) { |
| 144 // Disable mouse watcher since we don't want mouse movements to affect panel |
| 145 // testing for title-only state. |
| 146 PanelManager* panel_manager = PanelManager::GetInstance(); |
| 147 PanelMouseWatcher* mouse_watcher = new TestPanelMouseWatcher(); |
| 148 panel_manager->SetMouseWatcherForTesting(mouse_watcher); |
| 149 |
| 150 Balloon* balloon = CreateBalloon(); |
| 151 |
| 152 // Create a docked panel. Expect that the notification balloon moves up to be |
| 153 // above the panel. |
| 154 Panel* panel = CreateDockedPanel("1", gfx::Rect(0, 0, 200, 200)); |
| 155 MessageLoopForUI::current()->RunAllPending(); |
| 156 int balloon_bottom_on_expanded = GetBalloonBottomPosition(balloon); |
| 157 EXPECT_LT(balloon_bottom_on_expanded, panel->GetBounds().y()); |
| 158 |
| 159 // Minimize the panel. Expect that the notification balloon moves down, but |
| 160 // still above the minimized panel. |
| 161 panel->Minimize(); |
| 162 MessageLoopForUI::current()->RunAllPending(); |
| 163 int balloon_bottom_on_minimized = GetBalloonBottomPosition(balloon); |
| 164 EXPECT_LT(balloon_bottom_on_minimized, panel->GetBounds().y()); |
| 165 EXPECT_LT(balloon_bottom_on_expanded, balloon_bottom_on_minimized); |
| 166 |
| 167 // Bring up the title-bar for the panel by drawing attention. Expect that the |
| 168 // notification balloon moves up a little bit to be still above the title-only |
| 169 // panel. |
| 170 panel->FlashFrame(true); |
| 171 MessageLoopForUI::current()->RunAllPending(); |
| 172 int balloon_bottom_on_title_only = GetBalloonBottomPosition(balloon); |
| 173 EXPECT_LT(balloon_bottom_on_title_only, panel->GetBounds().y()); |
| 174 EXPECT_LT(balloon_bottom_on_title_only, balloon_bottom_on_minimized); |
| 175 EXPECT_LT(balloon_bottom_on_expanded, balloon_bottom_on_title_only); |
| 176 |
| 177 // Expand the panel. Expect that the notification balloon moves up to go back |
| 178 // to the same position when the panel is expanded. |
| 179 panel->Restore(); |
| 180 MessageLoopForUI::current()->RunAllPending(); |
| 181 EXPECT_EQ(balloon_bottom_on_expanded, GetBalloonBottomPosition(balloon)); |
| 182 |
| 183 PanelManager::GetInstance()->CloseAll(); |
| 184 } |
| 185 |
| 186 IN_PROC_BROWSER_TEST_F(PanelAndDesktopNotificationTest, DragNarrowPanel) { |
| 187 Balloon* balloon = CreateBalloon(); |
| 188 |
| 189 // Let the panel width be smaller than the balloon width. |
| 190 int panel_width = balloon->GetViewSize().width() - 50; |
| 191 |
| 192 // Create 2 docked panels. Expect that the notification balloon moves up to be |
| 193 // above the tall panel. |
| 194 Panel* tall_panel = CreateDockedPanel("1", gfx::Rect(0, 0, panel_width, 300)); |
| 195 Panel* short_panel = CreateDockedPanel( |
| 196 "2", gfx::Rect(0, 0, panel_width, 200)); |
| 197 MessageLoopForUI::current()->RunAllPending(); |
| 198 int balloon_bottom = GetBalloonBottomPosition(balloon); |
| 199 EXPECT_LT(balloon_bottom, tall_panel->GetBounds().y()); |
| 200 |
| 201 // Swap 2 docked panels by dragging. Expect that the notificaition balloon |
| 202 // remains at the same position. |
| 203 DragPanelToMouseLocation(tall_panel, short_panel->GetBounds().origin()); |
| 204 MessageLoopForUI::current()->RunAllPending(); |
| 205 EXPECT_EQ(balloon_bottom, GetBalloonBottomPosition(balloon)); |
| 206 |
| 207 PanelManager::GetInstance()->CloseAll(); |
| 208 } |
| 209 |
| 210 IN_PROC_BROWSER_TEST_F(PanelAndDesktopNotificationTest, DragWidePanel) { |
| 211 Balloon* balloon = CreateBalloon(); |
| 212 |
| 213 // Let the panel width be greater than the balloon width. |
| 214 int panel_width = balloon->GetViewSize().width() + 50; |
| 215 |
| 216 // Create 2 docked panels. Expect that the notification balloon moves up to be |
| 217 // above the tall panel. |
| 218 Panel* tall_panel = CreateDockedPanel("1", gfx::Rect(0, 0, panel_width, 300)); |
| 219 Panel* short_panel = CreateDockedPanel( |
| 220 "2", gfx::Rect(0, 0, panel_width, 200)); |
| 221 MessageLoopForUI::current()->RunAllPending(); |
| 222 int balloon_bottom_before_drag = GetBalloonBottomPosition(balloon); |
| 223 EXPECT_LT(balloon_bottom_before_drag, tall_panel->GetBounds().y()); |
| 224 |
| 225 // Swap 2 docked panels by dragging. Expect that the notificaiton balloon |
| 226 // moves down to be just above the short panel. |
| 227 DragPanelToMouseLocation(tall_panel, short_panel->GetBounds().origin()); |
| 228 MessageLoopForUI::current()->RunAllPending(); |
| 229 int balloon_bottom_after_drag = GetBalloonBottomPosition(balloon); |
| 230 EXPECT_LT(balloon_bottom_after_drag, short_panel->GetBounds().y()); |
| 231 EXPECT_LT(balloon_bottom_before_drag, balloon_bottom_after_drag); |
| 232 |
| 233 PanelManager::GetInstance()->CloseAll(); |
| 234 } |
| 235 |
| 236 IN_PROC_BROWSER_TEST_F(PanelAndDesktopNotificationTest, DetachAndAttachPanel) { |
| 237 PanelManager* panel_manager = PanelManager::GetInstance(); |
| 238 Balloon* balloon = CreateBalloon(); |
| 239 int original_balloon_bottom = GetBalloonBottomPosition(balloon); |
| 240 |
| 241 // Create a docked panel. Expect that the notification balloon moves up to be |
| 242 // above the panel. |
| 243 Panel* panel = CreateDockedPanel("1", gfx::Rect(0, 0, 200, 200)); |
| 244 MessageLoopForUI::current()->RunAllPending(); |
| 245 int balloon_bottom_after_panel_created = GetBalloonBottomPosition(balloon); |
| 246 EXPECT_LT(balloon_bottom_after_panel_created, panel->GetBounds().y()); |
| 247 EXPECT_LT(balloon_bottom_after_panel_created, original_balloon_bottom); |
| 248 |
| 249 // Detach the panel. Expect that the notification balloon moves down to its |
| 250 // original position. |
| 251 panel_manager->MovePanelToStrip( |
| 252 panel, PanelStrip::DETACHED, PanelStrip::DEFAULT_POSITION); |
| 253 MessageLoopForUI::current()->RunAllPending(); |
| 254 EXPECT_EQ(PanelStrip::DETACHED, panel->panel_strip()->type()); |
| 255 EXPECT_EQ(original_balloon_bottom, GetBalloonBottomPosition(balloon)); |
| 256 |
| 257 // Reattach the panel. Expect that the notification balloon moves above the |
| 258 // panel. |
| 259 panel_manager->MovePanelToStrip( |
| 260 panel, PanelStrip::DOCKED, PanelStrip::DEFAULT_POSITION); |
| 261 MessageLoopForUI::current()->RunAllPending(); |
| 262 EXPECT_EQ(PanelStrip::DOCKED, panel->panel_strip()->type()); |
| 263 EXPECT_EQ(balloon_bottom_after_panel_created, |
| 264 GetBalloonBottomPosition(balloon)); |
| 265 |
| 266 panel_manager->CloseAll(); |
| 267 } |
| 268 |
| 269 IN_PROC_BROWSER_TEST_F(PanelAndDesktopNotificationTest, ResizePanel) { |
| 270 PanelManager* panel_manager = PanelManager::GetInstance(); |
| 271 Balloon* balloon = CreateBalloon(); |
| 272 |
| 273 // Create a docked panel. Expect that the notification balloon moves up to be |
| 274 // above the panel. |
| 275 Panel* panel = CreateDockedPanel("1", gfx::Rect(0, 0, 200, 200)); |
| 276 MessageLoopForUI::current()->RunAllPending(); |
| 277 int balloon_bottom = GetBalloonBottomPosition(balloon); |
| 278 gfx::Rect original_bounds = panel->GetBounds(); |
| 279 EXPECT_LT(balloon_bottom, original_bounds.y()); |
| 280 |
| 281 // Resize the panel to make it taller. Expect that the notification balloon |
| 282 // moves further up by the amount of enlarge offset. |
| 283 gfx::Point resize_delta(50, 100); |
| 284 gfx::Rect new_bounds = original_bounds; |
| 285 new_bounds.set_width(new_bounds.width() + resize_delta.x()); |
| 286 new_bounds.set_height(new_bounds.height() + resize_delta.y()); |
| 287 panel->SetBounds(new_bounds); |
| 288 MessageLoopForUI::current()->RunAllPending(); |
| 289 int balloon_bottom2 = GetBalloonBottomPosition(balloon); |
| 290 EXPECT_EQ(balloon_bottom - resize_delta.y(), balloon_bottom2); |
| 291 |
| 292 // Resize the panel to make it shorter. Expect that the notification balloon |
| 293 // moves down by the amount of shrink offset. |
| 294 resize_delta = gfx::Point(0, -60); |
| 295 new_bounds.set_width(new_bounds.width() + resize_delta.x()); |
| 296 new_bounds.set_height(new_bounds.height() + resize_delta.y()); |
| 297 panel->SetBounds(new_bounds); |
| 298 MessageLoopForUI::current()->RunAllPending(); |
| 299 int balloon_bottom3 = GetBalloonBottomPosition(balloon); |
| 300 EXPECT_EQ(balloon_bottom2 - resize_delta.y(), balloon_bottom3); |
| 301 |
| 302 panel_manager->CloseAll(); |
| 303 } |
| 304 |
| 305 IN_PROC_BROWSER_TEST_F(PanelAndDesktopNotificationTest, ResizePanelByMouse) { |
| 306 Balloon* balloon = CreateBalloon(); |
| 307 |
| 308 // Create a docked panel. Expect that the notification balloon moves up to be |
| 309 // above the panel. |
| 310 Panel* panel = CreateDockedPanel("1", gfx::Rect(0, 0, 200, 200)); |
| 311 MessageLoopForUI::current()->RunAllPending(); |
| 312 int balloon_bottom = GetBalloonBottomPosition(balloon); |
| 313 EXPECT_LT(balloon_bottom, panel->GetBounds().y()); |
| 314 |
| 315 // Resize the panel to make it taller. Expect that the notification balloon |
| 316 // moves further up by the amount of enlarge offset. |
| 317 gfx::Point drag_delta(-50, -100); |
| 318 ResizePanelByMouseWithDelta(panel, panel::RESIZE_TOP_LEFT, drag_delta); |
| 319 MessageLoopForUI::current()->RunAllPending(); |
| 320 int balloon_bottom2 = GetBalloonBottomPosition(balloon); |
| 321 EXPECT_EQ(balloon_bottom + drag_delta.y(), balloon_bottom2); |
| 322 |
| 323 // Resize the panel to make it shorter. Expect that the notification balloon |
| 324 // moves down by the amount of shrink offset. |
| 325 drag_delta = gfx::Point(0, 60); |
| 326 ResizePanelByMouseWithDelta(panel, panel::RESIZE_TOP, drag_delta); |
| 327 MessageLoopForUI::current()->RunAllPending(); |
| 328 int balloon_bottom3 = GetBalloonBottomPosition(balloon); |
| 329 EXPECT_EQ(balloon_bottom2 + drag_delta.y(), balloon_bottom3); |
| 330 |
| 331 PanelManager::GetInstance()->CloseAll(); |
| 332 } |
| 333 |
| 334 IN_PROC_BROWSER_TEST_F(PanelAndDesktopNotificationTest, InteractWithTwoPanels) { |
| 335 Balloon* balloon = CreateBalloon(); |
| 336 int original_balloon_bottom = GetBalloonBottomPosition(balloon); |
| 337 |
| 338 // Let the panel width be smaller than the balloon width. |
| 339 int panel_width = balloon->GetViewSize().width() - 50; |
| 340 |
| 341 // Create a short panel. Expect that the notification balloon moves up to be |
| 342 // above the short panel. |
| 343 Panel* short_panel = CreateDockedPanel( |
| 344 "1", gfx::Rect(0, 0, panel_width, 150)); |
| 345 MessageLoopForUI::current()->RunAllPending(); |
| 346 int balloon_bottom_after_short_panel_created = |
| 347 GetBalloonBottomPosition(balloon); |
| 348 EXPECT_LT(balloon_bottom_after_short_panel_created, |
| 349 short_panel->GetBounds().y()); |
| 350 EXPECT_LT(balloon_bottom_after_short_panel_created, original_balloon_bottom); |
| 351 |
| 352 // Create a tall panel. Expect that the notification balloon moves further up |
| 353 // to be above the tall panel. |
| 354 Panel* tall_panel = CreateDockedPanel("2", gfx::Rect(0, 0, panel_width, 200)); |
| 355 MessageLoopForUI::current()->RunAllPending(); |
| 356 int balloon_bottom_after_tall_panel_created = |
| 357 GetBalloonBottomPosition(balloon); |
| 358 EXPECT_LT(balloon_bottom_after_tall_panel_created, |
| 359 tall_panel->GetBounds().y()); |
| 360 EXPECT_LT(balloon_bottom_after_tall_panel_created, |
| 361 balloon_bottom_after_short_panel_created); |
| 362 |
| 363 // Minimize tall panel. Expect that the notification balloon moves down to the |
| 364 // same position when short panel is first created. |
| 365 tall_panel->Minimize(); |
| 366 MessageLoopForUI::current()->RunAllPending(); |
| 367 int balloon_bottom_after_tall_panel_minimized = |
| 368 GetBalloonBottomPosition(balloon); |
| 369 EXPECT_EQ(balloon_bottom_after_short_panel_created, |
| 370 balloon_bottom_after_tall_panel_minimized); |
| 371 |
| 372 // Minimize short panel. Expect that the notification balloon moves further |
| 373 // down. |
| 374 short_panel->Minimize(); |
| 375 MessageLoopForUI::current()->RunAllPending(); |
| 376 int balloon_bottom_after_both_panels_minimized = |
| 377 GetBalloonBottomPosition(balloon); |
| 378 EXPECT_LT(balloon_bottom_after_both_panels_minimized, |
| 379 short_panel->GetBounds().y()); |
| 380 EXPECT_LT(balloon_bottom_after_both_panels_minimized, |
| 381 tall_panel->GetBounds().y()); |
| 382 EXPECT_LT(balloon_bottom_after_short_panel_created, |
| 383 balloon_bottom_after_both_panels_minimized); |
| 384 EXPECT_LT(balloon_bottom_after_both_panels_minimized, |
| 385 original_balloon_bottom); |
| 386 |
| 387 // Expand short panel. Expect that the notification balloon moves further up |
| 388 // to the same position when short panel is first created. |
| 389 short_panel->Restore(); |
| 390 MessageLoopForUI::current()->RunAllPending(); |
| 391 int balloon_bottom_after_short_panel_expanded = |
| 392 GetBalloonBottomPosition(balloon); |
| 393 EXPECT_EQ(balloon_bottom_after_short_panel_created, |
| 394 balloon_bottom_after_short_panel_expanded); |
| 395 |
| 396 // Close tall panel. Expect that the notification balloon moves down to the |
| 397 // same position when short panel is first created. |
| 398 tall_panel->Close(); |
| 399 MessageLoopForUI::current()->RunAllPending(); |
| 400 EXPECT_EQ(balloon_bottom_after_short_panel_created, |
| 401 GetBalloonBottomPosition(balloon)); |
| 402 |
| 403 // Close short panel. Expect that the notification balloo moves back to its |
| 404 // original position. |
| 405 short_panel->Close(); |
| 406 MessageLoopForUI::current()->RunAllPending(); |
| 407 EXPECT_EQ(original_balloon_bottom, GetBalloonBottomPosition(balloon)); |
| 408 } |
OLD | NEW |