shill: Enable auto-connect for WiFi services

This performs a few of the last tidbits to get auto-connect
working for WiFi networks.  The tweaks include:

  * Adding calls to SortServices() in Push/PopProfile
  * On successful connection, move service to the profile on
    the top of the stack if this service was previously in the
    ephemeral profile.
  * Add a method to Services to return whether they are eligible
    for auto-connect.  Implement this for the WiFi services by
    using a new method to test if the WiFi device is busy.

BUG=chromium-os:24261,chromium-os:17255
TEST=Unit Tests (for regression)
Manual: Connect to WPA-PSK network successfully; restart shill and
observe an auto-connect after scan.

Change-Id: Ia4e1fd94795a4ce64d66ec6db940ee16ff694431
Reviewed-on: https://gerrit.chromium.org/gerrit/12963
Reviewed-by: mukesh agrawal <quiche@chromium.org>
Commit-Ready: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
diff --git a/manager_unittest.cc b/manager_unittest.cc
index ab9372b..d9e7c1c 100644
--- a/manager_unittest.cc
+++ b/manager_unittest.cc
@@ -49,6 +49,7 @@
 using ::testing::NiceMock;
 using ::testing::Return;
 using ::testing::StrEq;
+using ::testing::StrictMock;
 using ::testing::Test;
 
 class ManagerTest : public PropertyStoreTest {
@@ -949,4 +950,29 @@
   EXPECT_TRUE(mock_service->auto_connect());
 }
 
+TEST_F(ManagerTest, SaveSuccessfulService) {
+  scoped_refptr<MockProfile> profile(
+      new StrictMock<MockProfile>(control_interface(), manager(), ""));
+  AdoptProfile(manager(), profile);
+  scoped_refptr<MockService> service(
+      new NiceMock<MockService>(control_interface(),
+                                dispatcher(),
+                                manager()));
+
+  // Re-cast this back to a ServiceRefPtr, so EXPECT arguments work correctly.
+  ServiceRefPtr expect_service(service.get());
+
+  EXPECT_CALL(*profile.get(), ConfigureService(expect_service))
+      .WillOnce(Return(false));
+  manager()->RegisterService(service);
+
+  EXPECT_CALL(*service.get(), state())
+      .WillRepeatedly(Return(Service::kStateConnected));
+  EXPECT_CALL(*service.get(), IsConnected())
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(*profile.get(), AdoptService(expect_service))
+      .WillOnce(Return(true));
+  manager()->UpdateService(service);
+}
+
 }  // namespace shill