• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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/memory/ref_counted.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/message_loop.h"
8 #include "base/string16.h"
9 #include "base/string_util.h"
10 #include "base/stringprintf.h"
11 #include "base/utf_string_conversions.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/chromeos/notifications/balloon_collection_impl.h"
14 #include "chrome/browser/chromeos/notifications/balloon_view.h"
15 #include "chrome/browser/chromeos/notifications/notification_panel.h"
16 #include "chrome/browser/chromeos/notifications/system_notification_factory.h"
17 #include "chrome/browser/notifications/notification_test_util.h"
18 #include "chrome/browser/notifications/notification_ui_manager.h"
19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/test/in_process_browser_test.h"
21 #include "chrome/test/ui_test_utils.h"
22 #include "content/common/notification_service.h"
23 #include "ui/base/x/x11_util.h"
24 
25 namespace {
26 
27 // The name of ChromeOS's window manager.
28 const char* kChromeOsWindowManagerName = "chromeos-wm";
29 
30 }  // namespace
31 
32 namespace chromeos {
33 
34 class NotificationTest : public InProcessBrowserTest,
35                          public NotificationObserver {
36  public:
NotificationTest()37   NotificationTest()
38       : under_chromeos_(false),
39         state_(PanelController::INITIAL),
40         expected_(PanelController::INITIAL) {
41   }
42 
HandleWebUIMessage(const ListValue * value)43   void HandleWebUIMessage(const ListValue* value) {
44     MessageLoop::current()->Quit();
45   }
46 
47  protected:
SetUp()48   virtual void SetUp() {
49     // Detect if we're running under ChromeOS WindowManager. See
50     // the description for "under_chromeos_" below for why we need this.
51     std::string wm_name;
52     bool wm_name_valid = ui::GetWindowManagerName(&wm_name);
53     // NOTE: On Chrome OS the wm and Chrome are started in parallel. This
54     // means it's possible for us not to be able to get the name of the window
55     // manager. We assume that when this happens we're on Chrome OS.
56     under_chromeos_ = (!wm_name_valid ||
57                        wm_name == kChromeOsWindowManagerName);
58     InProcessBrowserTest::SetUp();
59   }
60 
GetBalloonCollectionImpl()61   BalloonCollectionImpl* GetBalloonCollectionImpl() {
62     return static_cast<BalloonCollectionImpl*>(
63         g_browser_process->notification_ui_manager()->balloon_collection());
64   }
65 
GetNotificationPanel()66   NotificationPanel* GetNotificationPanel() {
67     return static_cast<NotificationPanel*>(
68         GetBalloonCollectionImpl()->notification_ui());
69   }
70 
NewMockNotification(const std::string & id)71   Notification NewMockNotification(const std::string& id) {
72     return NewMockNotification(new MockNotificationDelegate(id));
73   }
74 
NewMockNotification(NotificationDelegate * delegate)75   Notification NewMockNotification(NotificationDelegate* delegate) {
76     std::string text = delegate->id();
77     return SystemNotificationFactory::Create(
78         GURL(), ASCIIToUTF16(text.c_str()), ASCIIToUTF16(text.c_str()),
79         delegate);
80   }
81 
MarkStale(const char * id)82   void MarkStale(const char* id) {
83     GetNotificationPanel()->GetTester()->MarkStale(NewMockNotification(id));
84   }
85 
86   // Waits untilt the panel's state becomes the specified state.
87   // Does nothing if it's not running with ChromeOS Window Manager.
WaitForPanelState(NotificationPanelTester * tester,PanelController::State state)88   void WaitForPanelState(NotificationPanelTester* tester,
89                          PanelController::State state) {
90     if (under_chromeos_ && state != state_) {
91       expected_ = state;
92       ui_test_utils::RunAllPendingInMessageLoop();
93     }
94   }
95 
96   // Busy loop to wait until the view becomes visible in the panel.
WaitForVisible(BalloonViewImpl * view)97   void WaitForVisible(BalloonViewImpl* view) {
98     WaitForResize(view);
99     NotificationPanelTester* tester = GetNotificationPanel()->GetTester();
100     while (!tester->IsVisible(view)) {
101       ui_test_utils::RunAllPendingInMessageLoop();
102     }
103   }
104 
105   // Busy loop to wait until the webkit give some size to the notification.
WaitForResize(BalloonViewImpl * view)106   void WaitForResize(BalloonViewImpl* view) {
107     while (view->bounds().IsEmpty()) {
108       ui_test_utils::RunAllPendingInMessageLoop();
109     }
110   }
111 
112   // NotificationObserver overrides.
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)113   virtual void Observe(NotificationType type,
114                        const NotificationSource& source,
115                        const NotificationDetails& details) {
116     ASSERT_TRUE(NotificationType::PANEL_STATE_CHANGED == type);
117     PanelController::State* state =
118         reinterpret_cast<PanelController::State*>(details.map_key());
119     state_ = *state;
120     if (under_chromeos_ && expected_ == state_) {
121       expected_ = PanelController::INITIAL;
122       MessageLoop::current()->Quit();
123     }
124   }
125 
126  private:
127   // ChromeOS build of chrome communicates with ChromeOS's
128   // WindowManager, and behaves differently if it runs under a
129   // chromeos window manager.  ChromeOS WindowManager sends
130   // EXPANDED/MINIMIED state change message when the panels's state
131   // changed (regardless of who changed it), and to avoid
132   // mis-recognizing such events as user-initiated actions, we need to
133   // wait and eat them before moving to a next step.
134   bool under_chromeos_;
135   PanelController::State state_;
136   PanelController::State expected_;
137 };
138 
IN_PROC_BROWSER_TEST_F(NotificationTest,TestBasic)139 IN_PROC_BROWSER_TEST_F(NotificationTest, TestBasic) {
140   BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
141   NotificationPanel* panel = GetNotificationPanel();
142   NotificationPanelTester* tester = panel->GetTester();
143 
144   // Using system notification as regular notification.
145   collection->Add(NewMockNotification("1"), browser()->profile());
146 
147   EXPECT_EQ(1, tester->GetNewNotificationCount());
148   EXPECT_EQ(1, tester->GetNotificationCount());
149   EXPECT_EQ(0, tester->GetStickyNotificationCount());
150   EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
151 
152   collection->Add(NewMockNotification("2"), browser()->profile());
153 
154   EXPECT_EQ(2, tester->GetNewNotificationCount());
155   EXPECT_EQ(2, tester->GetNotificationCount());
156   EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
157 
158   collection->RemoveById("1");
159   ui_test_utils::RunAllPendingInMessageLoop();
160 
161   EXPECT_EQ(1, tester->GetNewNotificationCount());
162   EXPECT_EQ(1, tester->GetNotificationCount());
163   EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
164 
165   collection->RemoveById("2");
166   ui_test_utils::RunAllPendingInMessageLoop();
167   EXPECT_EQ(0, tester->GetNewNotificationCount());
168   EXPECT_EQ(0, tester->GetNotificationCount());
169   EXPECT_EQ(NotificationPanel::CLOSED, tester->state());
170 
171   // CLOSE is asynchronous. Run the all pending tasks to finish closing
172   // task.
173   ui_test_utils::RunAllPendingInMessageLoop();
174 }
175 
176 // [CLOSED] -add->[STICKY_AND_NEW] -mouse-> [KEEP_SIZE] -remove/add->
177 // [KEEP_SIZE] -remove-> [CLOSED] -add-> [STICKY_AND_NEW] -remove-> [CLOSED]
IN_PROC_BROWSER_TEST_F(NotificationTest,TestKeepSizeState)178 IN_PROC_BROWSER_TEST_F(NotificationTest, TestKeepSizeState) {
179   BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
180   NotificationPanel* panel = GetNotificationPanel();
181   NotificationPanelTester* tester = panel->GetTester();
182 
183   EXPECT_EQ(NotificationPanel::CLOSED, tester->state());
184 
185   // Using system notification as regular notification.
186   collection->Add(NewMockNotification("1"), browser()->profile());
187   collection->Add(NewMockNotification("2"), browser()->profile());
188 
189   EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
190 
191   panel->OnMouseMotion(gfx::Point(10, 10));
192   EXPECT_EQ(NotificationPanel::KEEP_SIZE, tester->state());
193 
194   collection->RemoveById("1");
195   ui_test_utils::RunAllPendingInMessageLoop();
196   EXPECT_EQ(1, tester->GetNewNotificationCount());
197   EXPECT_EQ(1, tester->GetNotificationCount());
198   EXPECT_EQ(NotificationPanel::KEEP_SIZE, tester->state());
199 
200   collection->Add(NewMockNotification("1"), browser()->profile());
201   ui_test_utils::RunAllPendingInMessageLoop();
202   EXPECT_EQ(2, tester->GetNewNotificationCount());
203   EXPECT_EQ(2, tester->GetNotificationCount());
204   EXPECT_EQ(NotificationPanel::KEEP_SIZE, tester->state());
205 
206   collection->RemoveById("1");
207   ui_test_utils::RunAllPendingInMessageLoop();
208   EXPECT_EQ(1, tester->GetNewNotificationCount());
209   EXPECT_EQ(1, tester->GetNotificationCount());
210   EXPECT_EQ(NotificationPanel::KEEP_SIZE, tester->state());
211 
212   collection->RemoveById("2");
213   ui_test_utils::RunAllPendingInMessageLoop();
214   EXPECT_EQ(0, tester->GetNotificationCount());
215   EXPECT_EQ(NotificationPanel::CLOSED, tester->state());
216 
217   collection->Add(NewMockNotification("3"), browser()->profile());
218   EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
219   collection->RemoveById("3");
220 
221   ui_test_utils::RunAllPendingInMessageLoop();
222   EXPECT_EQ(0, tester->GetNotificationCount());
223   EXPECT_EQ(NotificationPanel::CLOSED, tester->state());
224 }
225 
IN_PROC_BROWSER_TEST_F(NotificationTest,TestSystemNotification)226 IN_PROC_BROWSER_TEST_F(NotificationTest, TestSystemNotification) {
227   BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
228   NotificationPanel* panel = GetNotificationPanel();
229   scoped_refptr<MockNotificationDelegate> delegate(
230       new MockNotificationDelegate("power"));
231   NotificationPanelTester* tester = panel->GetTester();
232 
233   Notification notify = NewMockNotification(delegate.get());
234   collection->AddSystemNotification(notify, browser()->profile(), true, false);
235 
236   EXPECT_EQ(1, tester->GetNewNotificationCount());
237   EXPECT_EQ(1, tester->GetStickyNotificationCount());
238 
239   Notification update = SystemNotificationFactory::Create(
240       GURL(), ASCIIToUTF16("Title"), ASCIIToUTF16("updated"), delegate.get());
241   collection->UpdateNotification(update);
242 
243   EXPECT_EQ(1, tester->GetStickyNotificationCount());
244 
245   Notification update_and_show = SystemNotificationFactory::Create(
246       GURL(), ASCIIToUTF16("Title"), ASCIIToUTF16("updated and shown"),
247       delegate.get());
248   collection->UpdateAndShowNotification(update_and_show);
249 
250   EXPECT_EQ(1, tester->GetStickyNotificationCount());
251 
252   // Dismiss the notification.
253   collection->RemoveById(delegate->id());
254   ui_test_utils::RunAllPendingInMessageLoop();
255 
256   EXPECT_EQ(0, tester->GetStickyNotificationCount());
257   EXPECT_EQ(0, tester->GetNewNotificationCount());
258   // TODO(oshima): check content, etc..
259 }
260 
261 // [CLOSED] -add,add->[STICKY_AND_NEW] -stale-> [MINIMIZED] -remove->
262 // [MINIMIZED] -remove-> [CLOSED]
IN_PROC_BROWSER_TEST_F(NotificationTest,TestStateTransition1)263 IN_PROC_BROWSER_TEST_F(NotificationTest, TestStateTransition1) {
264   BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
265   NotificationPanel* panel = GetNotificationPanel();
266   NotificationPanelTester* tester = panel->GetTester();
267 
268   tester->SetStaleTimeout(0);
269   EXPECT_EQ(NotificationPanel::CLOSED, tester->state());
270 
271   collection->Add(NewMockNotification("1"), browser()->profile());
272   EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
273 
274   collection->Add(NewMockNotification("2"), browser()->profile());
275   EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
276 
277   ui_test_utils::RunAllPendingInMessageLoop();
278   EXPECT_EQ(NotificationPanel::MINIMIZED, tester->state());
279 
280   collection->RemoveById("2");
281   ui_test_utils::RunAllPendingInMessageLoop();
282   EXPECT_EQ(NotificationPanel::MINIMIZED, tester->state());
283 
284   collection->RemoveById("1");
285   ui_test_utils::RunAllPendingInMessageLoop();
286   EXPECT_EQ(0, tester->GetNotificationCount());
287   EXPECT_EQ(NotificationPanel::CLOSED, tester->state());
288 
289   ui_test_utils::RunAllPendingInMessageLoop();
290 }
291 
292 // [CLOSED] -add->[STICKY_AND_NEW] -stale-> [MINIMIZED] -add->
293 // [STICKY_AND_NEW] -stale-> [MINIMIZED] -add sys-> [STICKY_NEW]
294 // -stale-> [STICKY_NEW] -remove-> [STICKY_NEW] -remove sys->
295 // [MINIMIZED] -remove-> [CLOSED]
296 //
297 // This test depends on the fact that the panel state change occurs
298 // quicker than stale timeout, thus the stale timeout cannot be set to
299 // 0. This test explicitly controls the stale state instead.
IN_PROC_BROWSER_TEST_F(NotificationTest,TestStateTransition2)300 IN_PROC_BROWSER_TEST_F(NotificationTest, TestStateTransition2) {
301   // Register observer here as the registration does not work in SetUp().
302   NotificationRegistrar registrar;
303   registrar.Add(this,
304                 NotificationType::PANEL_STATE_CHANGED,
305                 NotificationService::AllSources());
306 
307   BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
308   NotificationPanel* panel = GetNotificationPanel();
309   NotificationPanelTester* tester = panel->GetTester();
310 
311   // See description above.
312   tester->SetStaleTimeout(100000);
313 
314   EXPECT_EQ(NotificationPanel::CLOSED, tester->state());
315 
316   collection->Add(NewMockNotification("1"), browser()->profile());
317   EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
318   ui_test_utils::RunAllPendingInMessageLoop();
319 
320   // Make the notification stale and make sure panel is minimized state.
321   MarkStale("1");
322   ui_test_utils::RunAllPendingInMessageLoop();
323   EXPECT_EQ(NotificationPanel::MINIMIZED, tester->state());
324   WaitForPanelState(tester, PanelController::MINIMIZED);
325 
326   // Adding new notification expands the panel.
327   collection->Add(NewMockNotification("2"), browser()->profile());
328   EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
329   WaitForPanelState(tester, PanelController::EXPANDED);
330 
331   // The panel must be minimzied when the new notification becomes stale.
332   MarkStale("2");
333   ui_test_utils::RunAllPendingInMessageLoop();
334   EXPECT_EQ(NotificationPanel::MINIMIZED, tester->state());
335   WaitForPanelState(tester, PanelController::MINIMIZED);
336 
337   // The panel must be expanded again when a new system notification is added.
338   collection->AddSystemNotification(
339       NewMockNotification("3"), browser()->profile(), true, false);
340   EXPECT_EQ(3, tester->GetNotificationCount());
341   EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
342   WaitForPanelState(tester, PanelController::EXPANDED);
343 
344   // Running all events nor removing non sticky should not change the state.
345   ui_test_utils::RunAllPendingInMessageLoop();
346   EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
347 
348   collection->RemoveById("1");
349   ui_test_utils::RunAllPendingInMessageLoop();
350   EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
351 
352   // Removing the system notification should minimize the panel.
353   collection->RemoveById("3");
354   ui_test_utils::RunAllPendingInMessageLoop();
355   EXPECT_EQ(1, tester->GetNotificationCount());
356   EXPECT_EQ(NotificationPanel::MINIMIZED, tester->state());
357   WaitForPanelState(tester, PanelController::MINIMIZED);
358 
359   // Removing the last notification. Should close the panel.
360   collection->RemoveById("2");
361   ui_test_utils::RunAllPendingInMessageLoop();
362   EXPECT_EQ(0, tester->GetNotificationCount());
363   EXPECT_EQ(NotificationPanel::CLOSED, tester->state());
364 
365   ui_test_utils::RunAllPendingInMessageLoop();
366 }
367 
IN_PROC_BROWSER_TEST_F(NotificationTest,TestCleanupOnExit)368 IN_PROC_BROWSER_TEST_F(NotificationTest, TestCleanupOnExit) {
369   NotificationRegistrar registrar;
370   registrar.Add(this,
371                 NotificationType::PANEL_STATE_CHANGED,
372                 NotificationService::AllSources());
373 
374   BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
375   NotificationPanel* panel = GetNotificationPanel();
376   NotificationPanelTester* tester = panel->GetTester();
377 
378   // Don't become stale.
379   tester->SetStaleTimeout(100000);
380 
381   collection->Add(NewMockNotification("1"), browser()->profile());
382   EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
383   WaitForPanelState(tester, PanelController::EXPANDED);
384   // end without closing.
385 }
386 
IN_PROC_BROWSER_TEST_F(NotificationTest,TestCloseOpen)387 IN_PROC_BROWSER_TEST_F(NotificationTest, TestCloseOpen) {
388   BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
389   NotificationPanel* panel = GetNotificationPanel();
390   NotificationPanelTester* tester = panel->GetTester();
391   Profile* profile = browser()->profile();
392 
393   collection->Add(NewMockNotification("1"), profile);
394   collection->Add(NewMockNotification("2"), profile);
395   ui_test_utils::RunAllPendingInMessageLoop();
396   WaitForPanelState(tester, PanelController::EXPANDED);
397   PanelController* controller = tester->GetPanelController();
398   // close now
399   panel->ClosePanel();
400   controller->Close();
401   ui_test_utils::RunAllPendingInMessageLoop();
402   EXPECT_EQ(NotificationPanel::CLOSED, tester->state());
403   // open again
404   collection->Add(NewMockNotification("3"), profile);
405   WaitForPanelState(tester, PanelController::EXPANDED);
406   EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
407 
408   // close again
409   controller = tester->GetPanelController();
410   panel->ClosePanel();
411   controller->Close();
412   ui_test_utils::RunAllPendingInMessageLoop();
413   EXPECT_EQ(NotificationPanel::CLOSED, tester->state());
414 }
415 
IN_PROC_BROWSER_TEST_F(NotificationTest,TestScrollBalloonToVisible)416 IN_PROC_BROWSER_TEST_F(NotificationTest, TestScrollBalloonToVisible) {
417   BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
418   NotificationPanel* panel = GetNotificationPanel();
419   NotificationPanelTester* tester = panel->GetTester();
420   Profile* profile = browser()->profile();
421 
422   // Create notifications enough to overflow the panel size.
423   const int create_count = 15;
424 
425   // new notification is always visible
426   for (int i = 0; i < create_count; i++) {
427     {
428       SCOPED_TRACE(base::StringPrintf("new normal %d", i));
429       std::string id = base::StringPrintf("n%d", i);
430       collection->Add(NewMockNotification(id), profile);
431       EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
432       BalloonViewImpl* view =
433           tester->GetBalloonView(collection, NewMockNotification(id));
434       WaitForVisible(view);
435     }
436     {
437       SCOPED_TRACE(base::StringPrintf("new system %d", i));
438       std::string id = base::StringPrintf("s%d", i);
439       collection->AddSystemNotification(
440           NewMockNotification(id), browser()->profile(), true, false);
441       BalloonViewImpl* view =
442           tester->GetBalloonView(collection, NewMockNotification(id));
443       WaitForVisible(view);
444     }
445   }
446 
447   // Update should not change the visibility
448   for (int i = 0; i < create_count; i++) {
449     {
450       SCOPED_TRACE(base::StringPrintf("update n%d", i));
451       Notification notify = NewMockNotification(base::StringPrintf("n%d", i));
452       // The last shown notification is sticky, which makes all non sticky
453       // invisible.
454       EXPECT_TRUE(collection->UpdateNotification(notify));
455       ui_test_utils::RunAllPendingInMessageLoop();
456       BalloonViewImpl* view = tester->GetBalloonView(collection, notify);
457       EXPECT_FALSE(tester->IsVisible(view));
458     }
459     {
460       SCOPED_TRACE(base::StringPrintf("update s%d", i));
461       Notification notify = NewMockNotification(base::StringPrintf("s%d", i));
462       BalloonViewImpl* view = tester->GetBalloonView(collection, notify);
463       bool currently_visible = tester->IsVisible(view);
464       EXPECT_TRUE(collection->UpdateNotification(notify));
465       ui_test_utils::RunAllPendingInMessageLoop();
466       EXPECT_EQ(view, tester->GetBalloonView(collection, notify));
467       EXPECT_EQ(currently_visible, tester->IsVisible(view));
468     }
469   }
470   // UpdateAndShowNotification makes notification visible
471   for (int i = 0; i < create_count; i++) {
472     {
473       SCOPED_TRACE(base::StringPrintf("update and show n%d", i));
474       Notification notify = NewMockNotification(base::StringPrintf("n%d", i));
475       EXPECT_TRUE(collection->UpdateAndShowNotification(notify));
476       ui_test_utils::RunAllPendingInMessageLoop();
477       BalloonViewImpl* view = tester->GetBalloonView(collection, notify);
478       EXPECT_TRUE(tester->IsVisible(view));
479     }
480     {
481       SCOPED_TRACE(base::StringPrintf("update and show s%d", i));
482       Notification notify = NewMockNotification(base::StringPrintf("s%d", i));
483       EXPECT_TRUE(collection->UpdateAndShowNotification(notify));
484       ui_test_utils::RunAllPendingInMessageLoop();
485       BalloonViewImpl* view = tester->GetBalloonView(collection, notify);
486       EXPECT_TRUE(tester->IsVisible(view));
487     }
488   }
489 }
490 
IN_PROC_BROWSER_TEST_F(NotificationTest,TestActivateDeactivate)491 IN_PROC_BROWSER_TEST_F(NotificationTest, TestActivateDeactivate) {
492   BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
493   NotificationPanel* panel = GetNotificationPanel();
494   NotificationPanelTester* tester = panel->GetTester();
495   Profile* profile = browser()->profile();
496 
497   collection->Add(NewMockNotification("1"), profile);
498   collection->AddSystemNotification(
499       NewMockNotification("2"), profile, true, false);
500   ui_test_utils::RunAllPendingInMessageLoop();
501   EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
502   BalloonViewImpl* view1 =
503       tester->GetBalloonView(collection, NewMockNotification("1"));
504   BalloonViewImpl* view2 =
505       tester->GetBalloonView(collection, NewMockNotification("2"));
506   // Wait until all renderers get size.
507   WaitForResize(view1);
508   WaitForResize(view2);
509   EXPECT_LT(view2->size().height(), 50) << "view size is bigger than expected";
510 
511   panel->OnMouseMotion(gfx::Point(10, 50));
512   EXPECT_TRUE(tester->IsActive(view1));
513   EXPECT_FALSE(tester->IsActive(view2));
514 
515   panel->OnMouseMotion(gfx::Point(10, 10));
516   EXPECT_FALSE(tester->IsActive(view1));
517   EXPECT_TRUE(tester->IsActive(view2));
518 
519   panel->OnMouseMotion(gfx::Point(500, 500));
520   EXPECT_FALSE(tester->IsActive(view1));
521   EXPECT_FALSE(tester->IsActive(view2));
522 }
523 
IN_PROC_BROWSER_TEST_F(NotificationTest,TestCloseDismissAllNonSticky)524 IN_PROC_BROWSER_TEST_F(NotificationTest, TestCloseDismissAllNonSticky) {
525   BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
526   NotificationPanel* panel = GetNotificationPanel();
527   NotificationPanelTester* tester = panel->GetTester();
528   Profile* profile = browser()->profile();
529 
530   collection->Add(NewMockNotification("1"), profile);
531   collection->AddSystemNotification(
532       NewMockNotification("2"), profile, true, false);
533   collection->Add(NewMockNotification("3"), profile);
534 
535   ui_test_utils::RunAllPendingInMessageLoop();
536   EXPECT_EQ(NotificationPanel::STICKY_AND_NEW, tester->state());
537   EXPECT_EQ(3, tester->GetNotificationCount());
538   EXPECT_EQ(1, tester->GetStickyNotificationCount());
539 
540   // Hide
541   panel->Hide();
542   ui_test_utils::RunAllPendingInMessageLoop();
543   EXPECT_EQ(1, tester->GetNotificationCount());
544   EXPECT_EQ(1, tester->GetStickyNotificationCount());
545 }
546 
IN_PROC_BROWSER_TEST_F(NotificationTest,TestAddWebUIMessageCallback)547 IN_PROC_BROWSER_TEST_F(NotificationTest, TestAddWebUIMessageCallback) {
548   BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
549   Profile* profile = browser()->profile();
550 
551   collection->AddSystemNotification(
552       NewMockNotification("1"), profile, false, false);
553 
554   EXPECT_TRUE(collection->AddWebUIMessageCallback(
555       NewMockNotification("1"),
556       "test",
557       NewCallback(
558           static_cast<NotificationTest*>(this),
559           &NotificationTest::HandleWebUIMessage)));
560 
561   // Adding callback for the same message twice should fail.
562   EXPECT_FALSE(collection->AddWebUIMessageCallback(
563       NewMockNotification("1"),
564       "test",
565       NewCallback(
566           static_cast<NotificationTest*>(this),
567           &NotificationTest::HandleWebUIMessage)));
568 
569   // Adding callback to nonexistent notification should fail.
570   EXPECT_FALSE(collection->AddWebUIMessageCallback(
571       NewMockNotification("2"),
572       "test1",
573       NewCallback(
574           static_cast<NotificationTest*>(this),
575           &NotificationTest::HandleWebUIMessage)));
576 }
577 
IN_PROC_BROWSER_TEST_F(NotificationTest,TestWebUIMessageCallback)578 IN_PROC_BROWSER_TEST_F(NotificationTest, TestWebUIMessageCallback) {
579   BalloonCollectionImpl* collection = GetBalloonCollectionImpl();
580   Profile* profile = browser()->profile();
581   // A notification that sends 'test' WebUI message back to chrome.
582   const GURL content_url(
583       "data:text/html;charset=utf-8,"
584       "<html><script>function send() { chrome.send('test', ['']); }</script>"
585       "<body onload='send()'></body></html>");
586   collection->AddSystemNotification(
587       Notification(GURL(), content_url, string16(), string16(),
588                    new MockNotificationDelegate("1")),
589       profile,
590       false,
591       false);
592   EXPECT_TRUE(collection->AddWebUIMessageCallback(
593       NewMockNotification("1"),
594       "test",
595       NewCallback(
596           static_cast<NotificationTest*>(this),
597           &NotificationTest::HandleWebUIMessage)));
598   MessageLoop::current()->Run();
599 }
600 
601 }  // namespace chromeos
602