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