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