1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file.
4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/compiler_specific.h"
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/macros.h"
7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/message_loop/message_loop.h"
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/run_loop.h"
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/browser_process.h"
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/login/login_manager_test.h"
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/login/startup_utils.h"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/net/network_portal_detector_impl.h"
13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/chromeos/net/network_portal_detector_test_utils.h"
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chromeos/chromeos_switches.h"
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chromeos/dbus/shill_service_client.h"
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chromeos/network/portal_detector/network_portal_detector.h"
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chromeos/network/portal_detector/network_portal_detector_strategy.h"
195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "components/captive_portal/captive_portal_testing_utils.h"
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/test/test_utils.h"
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "dbus/object_path.h"
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/message_center/message_center.h"
24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/message_center/message_center_observer.h"
25effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
26effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochusing base::MessageLoop;
27effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochusing message_center::MessageCenter;
28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochusing message_center::MessageCenterObserver;
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace chromeos {
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace {
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochconst char* kNotificationId =
35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    NetworkPortalNotificationController::kNotificationId;
36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochconst char* kNotificationMetric =
37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    NetworkPortalNotificationController::kNotificationMetric;
38effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochconst char* kUserActionMetric =
39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    NetworkPortalNotificationController::kUserActionMetric;
40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const char kTestUser[] = "test-user@gmail.com";
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst char kWifiServicePath[] = "/service/wifi";
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst char kWifiGuid[] = "wifi";
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ErrorCallbackFunction(const std::string& error_name,
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                           const std::string& error_message) {
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CHECK(false) << "Shill Error: " << error_name << " : " << error_message;
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void SetConnected(const std::string& service_path) {
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DBusThreadManager::Get()->GetShillServiceClient()->Connect(
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(service_path),
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&base::DoNothing),
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&ErrorCallbackFunction));
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass TestObserver : public MessageCenterObserver {
59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch public:
60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  TestObserver() : run_loop_(new base::RunLoop()) {
61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    MessageCenter::Get()->AddObserver(this);
62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual ~TestObserver() {
65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    MessageCenter::Get()->RemoveObserver(this);
66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void WaitAndReset() {
69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    run_loop_->Run();
70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    run_loop_.reset(new base::RunLoop());
71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual void OnNotificationDisplayed(
74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      const std::string& notification_id,
75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      const message_center::DisplaySource source)
76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      OVERRIDE {
77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (notification_id == kNotificationId)
78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      MessageLoop::current()->PostTask(FROM_HERE, run_loop_->QuitClosure());
79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual void OnNotificationRemoved(const std::string& notification_id,
82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                     bool by_user) OVERRIDE {
83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (notification_id == kNotificationId && by_user)
84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      MessageLoop::current()->PostTask(FROM_HERE, run_loop_->QuitClosure());
85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch private:
88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<base::RunLoop> run_loop_;
89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DISALLOW_COPY_AND_ASSIGN(TestObserver);
91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch};
92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class NetworkPortalDetectorImplBrowserTest
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : public LoginManagerTest,
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      public captive_portal::CaptivePortalDetectorTestBase {
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NetworkPortalDetectorImplBrowserTest()
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      : LoginManagerTest(false), network_portal_detector_(NULL) {}
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual ~NetworkPortalDetectorImplBrowserTest() {}
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void SetUpOnMainThread() OVERRIDE {
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    LoginManagerTest::SetUpOnMainThread();
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ShillServiceClient::TestInterface* service_test =
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    service_test->ClearServices();
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    service_test->AddService(kWifiServicePath,
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                             kWifiGuid,
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                             "wifi",
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             shill::kTypeEthernet,
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             shill::kStateIdle,
11446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                             true /* add_to_visible */);
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        dbus::ObjectPath(kWifiServicePath),
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        shill::kStateProperty,
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::StringValue(shill::kStatePortal),
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::Bind(&base::DoNothing),
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::Bind(&ErrorCallbackFunction));
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    network_portal_detector_ = new NetworkPortalDetectorImpl(
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        g_browser_process->system_request_context());
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    NetworkPortalDetector::InitializeForTesting(network_portal_detector_);
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    network_portal_detector_->Enable(false /* start_detection */);
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    set_detector(network_portal_detector_->captive_portal_detector_.get());
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    PortalDetectorStrategy::set_delay_till_next_attempt_for_testing(
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::TimeDelta());
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void RestartDetection() {
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    network_portal_detector_->StopDetection();
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    network_portal_detector_->StartDetection();
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PortalDetectorStrategy* strategy() {
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return network_portal_detector_->strategy_.get();
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MessageCenter* message_center() { return MessageCenter::Get(); }
143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private:
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NetworkPortalDetectorImpl* network_portal_detector_;
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NetworkPortalDetectorImplBrowserTest);
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(NetworkPortalDetectorImplBrowserTest,
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       PRE_InSessionDetection) {
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RegisterUser(kTestUser);
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  StartupUtils::MarkOobeCompleted();
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(PortalDetectorStrategy::STRATEGY_ID_LOGIN_SCREEN, strategy()->Id());
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(NetworkPortalDetectorImplBrowserTest,
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       InSessionDetection) {
159effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  typedef NetworkPortalNotificationController Controller;
160effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
161effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  TestObserver observer;
162effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
163effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EnumHistogramChecker ui_checker(
164effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      kNotificationMetric, Controller::NOTIFICATION_METRIC_COUNT, NULL);
165effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EnumHistogramChecker action_checker(
166effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      kUserActionMetric, Controller::USER_ACTION_METRIC_COUNT, NULL);
167effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LoginUser(kTestUser);
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  content::RunAllPendingInMessageLoop();
170effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
171effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // User connects to wifi.
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SetConnected(kWifiServicePath);
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(PortalDetectorStrategy::STRATEGY_ID_SESSION, strategy()->Id());
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // No notification until portal detection is completed.
177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_FALSE(message_center()->FindVisibleNotificationById(kNotificationId));
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RestartDetection();
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CompleteURLFetch(net::OK, 200, NULL);
180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Check that wifi is marked as behind the portal and that notification
182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // is displayed.
183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_TRUE(message_center()->FindVisibleNotificationById(kNotificationId));
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_EQ(
185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL,
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      NetworkPortalDetector::Get()->GetCaptivePortalState(kWifiGuid).status);
187effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
188effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Wait until notification is displayed.
189effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  observer.WaitAndReset();
190effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
191effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ASSERT_TRUE(
192effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      ui_checker.Expect(Controller::NOTIFICATION_METRIC_DISPLAYED, 1)->Check());
193effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ASSERT_TRUE(action_checker.Check());
194effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
195effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // User explicitly closes the notification.
196effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  message_center()->RemoveNotification(kNotificationId, true);
197effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
198effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Wait until notification is closed.
199effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  observer.WaitAndReset();
200effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
201effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ASSERT_TRUE(ui_checker.Check());
202effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ASSERT_TRUE(
203effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      action_checker.Expect(Controller::USER_ACTION_METRIC_CLOSED, 1)->Check());
204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace chromeos
207