shill: Initiate scan on resume, if appropriate
When a power resume event occurs, start a scan if the WiFi device is idle.
BUG=chromium-os:24885
TEST=Added new unit tests to WiFiMainTest. Ran all shill unit tests.
autotest WiFiRoaming.009ConnectOnResume should pass but currently doesn't
because shill crashes on suspend-resume.
Change-Id: I2730b0f27c0d85e72c0add57a3e9a5a2c995a04f
Reviewed-on: https://gerrit.chromium.org/gerrit/16107
Reviewed-by: mukesh agrawal <quiche@chromium.org>
Commit-Ready: Gary Morain <gmorain@chromium.org>
Tested-by: Gary Morain <gmorain@chromium.org>
diff --git a/wifi_unittest.cc b/wifi_unittest.cc
index bd5e2a4..a196641 100644
--- a/wifi_unittest.cc
+++ b/wifi_unittest.cc
@@ -35,6 +35,8 @@
#include "shill/mock_dhcp_provider.h"
#include "shill/mock_manager.h"
#include "shill/mock_metrics.h"
+#include "shill/mock_power_manager.h"
+#include "shill/mock_power_manager_proxy.h"
#include "shill/mock_rtnl_handler.h"
#include "shill/mock_store.h"
#include "shill/mock_supplicant_bss_proxy.h"
@@ -45,10 +47,10 @@
#include "shill/property_store_unittest.h"
#include "shill/proxy_factory.h"
#include "shill/wifi_endpoint.h"
-#include "shill/wifi.h"
#include "shill/wifi_service.h"
#include "shill/wpa_supplicant.h"
+
using std::map;
using std::set;
using std::string;
@@ -62,6 +64,7 @@
using ::testing::Mock;
using ::testing::NiceMock;
using ::testing::Return;
+using ::testing::SaveArg;
using ::testing::SetArgumentPointee;
using ::testing::StrEq;
using ::testing::StrictMock;
@@ -176,7 +179,9 @@
kDeviceName,
kHostName,
&glib_)),
- proxy_factory_(this) {
+ proxy_factory_(this),
+ power_manager_(new MockPowerManager(&proxy_factory_)),
+ power_state_callback_(NULL) {
::testing::DefaultValue< ::DBus::Path>::Set("/default/path");
// Except for WiFiServices created via WiFi::GetService, we expect
// that any WiFiService has been registered with the Manager. So
@@ -189,6 +194,9 @@
WillByDefault(Return(dhcp_config_));
ON_CALL(*dhcp_config_.get(), RequestIP()).
WillByDefault(Return(true));
+
+ // |manager_| takes ownership of |power_manager_|.
+ manager_.set_power_manager(power_manager_);
}
virtual void SetUp() {
@@ -239,6 +247,11 @@
const DBus::Path &object_path,
const char *dbus_addr));
+ virtual PowerManagerProxyInterface *CreatePowerManagerProxy(
+ PowerManagerProxyDelegate */*delegate*/) {
+ return new MockPowerManagerProxy();
+ }
+
private:
SupplicantBSSProxyInterface *CreateSupplicantBSSProxyInternal(
WiFiEndpoint */*wifi_endpoint*/,
@@ -329,12 +342,15 @@
wifi_->StateChanged(new_state);
}
void StartWiFi() {
+ EXPECT_CALL(*power_manager_, AddStateChangeCallback(wifi_->UniqueName(), _))
+ .WillOnce(SaveArg<1>(&power_state_callback_));
wifi_->Start();
}
void StopWiFi() {
wifi_->Stop();
}
- void GetOpenService(const char *service_type,
+
+ void GetOpenService(const char *service_type,
const char *ssid,
const char *mode,
Error *result) {
@@ -415,6 +431,10 @@
return &dhcp_provider_;
}
+ PowerManager::PowerStateCallback *power_state_callback() const {
+ return power_state_callback_;
+ }
+
const WiFiConstRefPtr wifi() const {
return wifi_;
}
@@ -451,6 +471,8 @@
private:
TestProxyFactory proxy_factory_;
+ MockPowerManager *power_manager_;
+ PowerManager::PowerStateCallback *power_state_callback_;
};
const char WiFiMainTest::kDeviceName[] = "wlan0";
@@ -541,6 +563,53 @@
StartWiFi();
}
+TEST_F(WiFiMainTest, PowerChangeToResumeStartsScanWhenIdle) {
+ EXPECT_CALL(*supplicant_interface_proxy_, Scan(_));
+ StartWiFi();
+ dispatcher_.DispatchPendingEvents();
+ Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
+ ASSERT_TRUE(power_state_callback() != NULL);
+ ASSERT_TRUE(wifi()->IsIdle());
+ EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_));
+ power_state_callback()->Run(PowerManagerProxyDelegate::kOn);
+ dispatcher_.DispatchPendingEvents();
+}
+
+TEST_F(WiFiMainTest, PowerChangeToSuspendDoesNotStartScan) {
+ EXPECT_CALL(*supplicant_interface_proxy_, Scan(_));
+ StartWiFi();
+ dispatcher_.DispatchPendingEvents();
+ Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
+ ASSERT_TRUE(power_state_callback() != NULL);
+ ASSERT_TRUE(wifi()->IsIdle());
+ EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
+ power_state_callback()->Run(PowerManagerProxyDelegate::kStandby);
+ dispatcher_.DispatchPendingEvents();
+ power_state_callback()->Run(PowerManagerProxyDelegate::kMem);
+ dispatcher_.DispatchPendingEvents();
+ power_state_callback()->Run(PowerManagerProxyDelegate::kDisk);
+ dispatcher_.DispatchPendingEvents();
+}
+
+TEST_F(WiFiMainTest, PowerChangeDoesNotStartScanWhenNotIdle) {
+ EXPECT_CALL(*supplicant_interface_proxy_, Scan(_));
+ StartWiFi();
+
+ WiFiEndpointRefPtr ap = MakeEndpoint("an_ssid", "00:01:02:03:04:05");
+ WiFiServiceRefPtr service = CreateServiceForEndpoint(*ap);
+ Error error;
+ service->AddEndpoint(ap);
+ service->AutoConnect();
+ EXPECT_FALSE(wifi()->IsIdle());
+ dispatcher_.DispatchPendingEvents();
+ Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
+ ASSERT_TRUE(power_state_callback() != NULL);
+ ASSERT_FALSE(wifi()->IsIdle());
+ EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
+ power_state_callback()->Run(PowerManagerProxyDelegate::kOn);
+ dispatcher_.DispatchPendingEvents();
+}
+
TEST_F(WiFiMainTest, ScanResults) {
EXPECT_CALL(*manager(), RegisterService(_)).Times(AnyNumber());
StartWiFi();
@@ -1550,6 +1619,7 @@
EXPECT_CALL(*manager(), device_info()).Times(AnyNumber());
EXPECT_CALL(*dhcp_provider(), CreateConfig(_, _)).Times(AnyNumber());
EXPECT_CALL(*manager(), HasService(_)).Times(AnyNumber());
+ EXPECT_CALL(*manager(), IsPortalDetectionEnabled(_)).Times(AnyNumber());
WiFiEndpointRefPtr ap = MakeEndpoint("an_ssid", "00:01:02:03:04:05");
WiFiServiceRefPtr service = CreateServiceForEndpoint(*ap);