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.cc b/manager.cc
index fe5c36b..e26dffe 100644
--- a/manager.cc
+++ b/manager.cc
@@ -239,6 +239,8 @@
it != devices_.end(); ++it) {
profile->ConfigureDevice(*it);
}
+
+ SortServices();
}
void Manager::PopProfileInternal() {
@@ -260,6 +262,7 @@
}
}
}
+ SortServices();
}
void Manager::PopProfile(const string &name, Error *error) {
@@ -299,6 +302,12 @@
bool Manager::MoveServiceToProfile(const ServiceRefPtr &to_move,
const ProfileRefPtr &destination) {
const ProfileRefPtr from = to_move->profile();
+ VLOG(2) << "Moving service "
+ << to_move->UniqueName()
+ << " to profile "
+ << destination->GetFriendlyName()
+ << " from "
+ << from->GetFriendlyName();
return destination->AdoptService(to_move) &&
from->AbandonService(to_move);
}
@@ -408,8 +417,16 @@
<< " failure: "
<< Service::ConnectFailureToString(to_update->failure());
LOG(INFO) << "IsConnected(): " << to_update->IsConnected();
- if (to_update->IsConnected())
+ if (to_update->IsConnected()) {
to_update->MakeFavorite();
+ if (to_update->profile().get() == ephemeral_profile_.get()) {
+ if (profiles_.empty()) {
+ LOG(ERROR) << "Cannot assign profile to service: no profiles exist!";
+ } else {
+ MoveServiceToProfile(to_update, profiles_.back());
+ }
+ }
+ }
SortServices();
}
@@ -484,6 +501,16 @@
services_[0]->connection()->SetIsDefault(true);
}
}
+
+ // Perform auto-connect.
+ for (it = services_.begin(); it != services_.end(); ++it) {
+ if ((*it)->auto_connect() && (*it)->IsAutoConnectable()) {
+ Error error;
+ (*it)->Connect(&error);
+ // We intentionally ignore the error returned by Connect() here since it
+ // should not prevent us from trying to connect a different service.
+ }
+ }
}
string Manager::CalculateState(Error */*error*/) {