Home | History | Annotate | Download | only in wifi
      1 //
      2 // Copyright (C) 2012 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #include "shill/wifi/wifi_service.h"
     18 
     19 #include <limits>
     20 #include <map>
     21 #include <set>
     22 #include <string>
     23 #include <vector>
     24 
     25 #include <base/strings/stringprintf.h>
     26 #include <base/strings/string_number_conversions.h>
     27 #include <base/strings/string_util.h>
     28 #if defined(__ANDROID__)
     29 #include <dbus/service_constants.h>
     30 #else
     31 #include <chromeos/dbus/service_constants.h>
     32 #endif  // __ANDROID__
     33 #include <gmock/gmock.h>
     34 #include <gtest/gtest.h>
     35 
     36 #include "shill/event_dispatcher.h"
     37 #include "shill/manager.h"
     38 #include "shill/metrics.h"
     39 #include "shill/mock_adaptors.h"
     40 #include "shill/mock_certificate_file.h"
     41 #include "shill/mock_control.h"
     42 #include "shill/mock_eap_credentials.h"
     43 #include "shill/mock_log.h"
     44 #include "shill/mock_manager.h"
     45 #include "shill/mock_profile.h"
     46 #include "shill/mock_service.h"
     47 #include "shill/mock_store.h"
     48 #include "shill/property_store_unittest.h"
     49 #include "shill/refptr_types.h"
     50 #include "shill/service_property_change_test.h"
     51 #include "shill/supplicant/wpa_supplicant.h"
     52 #include "shill/technology.h"
     53 #include "shill/tethering.h"
     54 #include "shill/wifi/mock_wifi.h"
     55 #include "shill/wifi/mock_wifi_provider.h"
     56 #include "shill/wifi/wifi_endpoint.h"
     57 
     58 using base::FilePath;
     59 using std::map;
     60 using std::set;
     61 using std::string;
     62 using std::vector;
     63 using ::testing::_;
     64 using ::testing::AnyNumber;
     65 using ::testing::DoAll;
     66 using ::testing::EndsWith;
     67 using ::testing::HasSubstr;
     68 using ::testing::Mock;
     69 using ::testing::NiceMock;
     70 using ::testing::Return;
     71 using ::testing::ReturnRef;
     72 using ::testing::SetArgumentPointee;
     73 using ::testing::StrEq;
     74 using ::testing::StrNe;
     75 using ::testing::StrictMock;
     76 
     77 namespace shill {
     78 
     79 class WiFiServiceTest : public PropertyStoreTest {
     80  public:
     81   WiFiServiceTest()
     82       : mock_manager_(control_interface(), dispatcher(), metrics()),
     83         wifi_(
     84             new NiceMock<MockWiFi>(control_interface(),
     85                                    dispatcher(),
     86                                    metrics(),
     87                                    manager(),
     88                                    "wifi",
     89                                    fake_mac,
     90                                    0)),
     91         simple_ssid_(1, 'a'),
     92         simple_ssid_string_("a") {}
     93   virtual ~WiFiServiceTest() {}
     94 
     95  protected:
     96   static const char fake_mac[];
     97 
     98   MockEapCredentials* SetMockEap(
     99       const WiFiServiceRefPtr& service) {
    100     MockEapCredentials* eap = new MockEapCredentials();
    101     service->eap_.reset(eap);  // Passes ownership.
    102     return eap;
    103   }
    104   bool CheckConnectable(const string& security, const char* passphrase,
    105                         bool is_1x_connectable) {
    106     Error error;
    107     WiFiServiceRefPtr service = MakeSimpleService(security);
    108     if (passphrase)
    109       service->SetPassphrase(passphrase, &error);
    110     MockEapCredentials* eap = SetMockEap(service);
    111     EXPECT_CALL(*eap, IsConnectable())
    112         .WillRepeatedly(Return(is_1x_connectable));
    113     const string kKeyManagement8021x(WPASupplicant::kKeyManagementIeee8021X);
    114     if (security == kSecurityWep && is_1x_connectable) {
    115       EXPECT_CALL(*eap, key_management())
    116           .WillRepeatedly(ReturnRef(kKeyManagement8021x));
    117     }
    118     service->OnEapCredentialsChanged(Service::kReasonCredentialsLoaded);
    119     return service->connectable();
    120   }
    121   WiFiEndpoint* MakeEndpoint(const string& ssid, const string& bssid,
    122                              uint16_t frequency, int16_t signal_dbm,
    123                              bool has_wpa_property, bool has_rsn_property) {
    124     return WiFiEndpoint::MakeEndpoint(
    125         nullptr, wifi(), ssid, bssid, WPASupplicant::kNetworkModeInfrastructure,
    126         frequency, signal_dbm, has_wpa_property, has_rsn_property);
    127   }
    128   WiFiEndpoint* MakeOpenEndpoint(const string& ssid, const string& bssid,
    129                                  uint16_t frequency, int16_t signal_dbm) {
    130     return WiFiEndpoint::MakeOpenEndpoint(
    131         nullptr, wifi(), ssid, bssid, WPASupplicant::kNetworkModeInfrastructure,
    132         frequency, signal_dbm);
    133   }
    134   WiFiEndpoint* MakeOpenEndpointWithWiFi(WiFiRefPtr wifi,
    135                                          const string& ssid,
    136                                          const string& bssid,
    137                                          uint16_t frequency,
    138                                          int16_t signal_dbm) {
    139     return WiFiEndpoint::MakeOpenEndpoint(
    140         nullptr, wifi, ssid, bssid, WPASupplicant::kNetworkModeInfrastructure,
    141         frequency, signal_dbm);
    142   }
    143   WiFiServiceRefPtr MakeSimpleService(const string& security) {
    144     return new WiFiService(control_interface(),
    145                            dispatcher(),
    146                            metrics(),
    147                            manager(),
    148                            &provider_,
    149                            simple_ssid_,
    150                            kModeManaged,
    151                            security,
    152                            false);
    153   }
    154   WiFiServiceRefPtr MakeGenericService() {
    155     return MakeSimpleService(kSecurityWep);
    156   }
    157   void SetWiFi(WiFiServiceRefPtr service, WiFiRefPtr wifi) {
    158     service->SetWiFi(wifi);  // Has side-effects.
    159   }
    160   void SetWiFiForService(WiFiServiceRefPtr service, WiFiRefPtr wifi) {
    161     service->wifi_ = wifi;
    162   }
    163   WiFiServiceRefPtr MakeServiceWithWiFi(const string& security) {
    164     WiFiServiceRefPtr service = MakeSimpleService(security);
    165     SetWiFiForService(service, wifi_);
    166     return service;
    167   }
    168   WiFiServiceRefPtr MakeServiceWithMockManager() {
    169     return new WiFiService(control_interface(),
    170                            dispatcher(),
    171                            metrics(),
    172                            &mock_manager_,
    173                            &provider_,
    174                            simple_ssid_,
    175                            kModeManaged,
    176                            kSecurityNone,
    177                            false);
    178   }
    179   scoped_refptr<MockWiFi> MakeSimpleWiFi(const string& link_name) {
    180     return new NiceMock<MockWiFi>(control_interface(),
    181                                   dispatcher(),
    182                                   metrics(),
    183                                   manager(),
    184                                   link_name,
    185                                   fake_mac,
    186                                   0);
    187   }
    188   ServiceMockAdaptor* GetAdaptor(WiFiService* service) {
    189     return static_cast<ServiceMockAdaptor*>(service->adaptor());
    190   }
    191   Error::Type TestConfigurePassphrase(const string& security,
    192                                       const char* passphrase) {
    193     WiFiServiceRefPtr service = MakeSimpleService(security);
    194     KeyValueStore args;
    195     if (passphrase) {
    196       args.SetString(kPassphraseProperty, passphrase);
    197     }
    198     Error error;
    199     service->Configure(args, &error);
    200     return error.type();
    201   }
    202   bool SetRoamThreshold(WiFiServiceRefPtr service, uint16_t threshold) {
    203     return service->SetRoamThreshold(threshold, nullptr);
    204   }
    205   uint16_t GetRoamThreshold(WiFiServiceRefPtr service) const {
    206     return service->GetRoamThreshold(nullptr);
    207   }
    208   scoped_refptr<MockWiFi> wifi() { return wifi_; }
    209   MockManager* mock_manager() { return &mock_manager_; }
    210   MockWiFiProvider* provider() { return &provider_; }
    211   string GetAnyDeviceAddress() { return WiFiService::kAnyDeviceAddress; }
    212   const vector<uint8_t>& simple_ssid() { return simple_ssid_; }
    213   const string& simple_ssid_string() { return simple_ssid_string_; }
    214 
    215  private:
    216   MockManager mock_manager_;
    217   scoped_refptr<MockWiFi> wifi_;
    218   MockWiFiProvider provider_;
    219   const vector<uint8_t> simple_ssid_;
    220   const string simple_ssid_string_;
    221 };
    222 
    223 // static
    224 const char WiFiServiceTest::fake_mac[] = "AaBBcCDDeeFF";
    225 
    226 MATCHER_P3(ContainsWiFiProperties, ssid, mode, security, "") {
    227   string hex_ssid = base::HexEncode(ssid.data(), ssid.size());
    228   return
    229       arg.ContainsString(WiFiService::kStorageType) &&
    230       arg.GetString(WiFiService::kStorageType) == kTypeWifi &&
    231       arg.ContainsString(WiFiService::kStorageSSID) &&
    232       arg.GetString(WiFiService::kStorageSSID) == hex_ssid &&
    233       arg.ContainsString(WiFiService::kStorageMode) &&
    234       arg.GetString(WiFiService::kStorageMode) == mode &&
    235       arg.ContainsString(WiFiService::kStorageSecurityClass) &&
    236       arg.GetString(WiFiService::kStorageSecurityClass) == security;
    237 }
    238 
    239 class WiFiServiceSecurityTest : public WiFiServiceTest {
    240  public:
    241   bool TestStorageSecurityIs(WiFiServiceRefPtr wifi_service,
    242                              const string& security) {
    243     string id = wifi_service->GetStorageIdentifier();
    244     size_t mac_pos = id.find(base::ToLowerASCII(GetAnyDeviceAddress()));
    245     EXPECT_NE(mac_pos, string::npos);
    246     size_t mode_pos = id.find(string(kModeManaged), mac_pos);
    247     EXPECT_NE(mode_pos, string::npos);
    248     return id.find(string(security), mode_pos) != string::npos;
    249   }
    250 
    251   // Test that a service that is created with security |from_security|
    252   // gets by default a storage identifier with |to_security| as its
    253   // security component, and that when saved, it sets the Security
    254   // property in to |to_security| as well.
    255   bool TestStorageMapping(const string& from_security,
    256                           const string& to_security) {
    257     WiFiServiceRefPtr wifi_service = MakeSimpleService(from_security);
    258     NiceMock<MockStore> mock_store;
    259     EXPECT_CALL(mock_store, SetString(_, _, _)).WillRepeatedly(Return(true));
    260     EXPECT_CALL(mock_store,
    261                 SetString(_, WiFiService::kStorageSecurity, from_security))
    262         .Times(1);
    263     EXPECT_CALL(mock_store,
    264                 SetString(_, WiFiService::kStorageSecurityClass, to_security))
    265         .Times(1);
    266     wifi_service->Save(&mock_store);
    267     return TestStorageSecurityIs(wifi_service, to_security);
    268   }
    269 
    270   // Test whether a service of type |service_security| can load from a
    271   // storage interface containing an entry for |storage_security|.
    272   // Make sure the result meets |expectation|.  If |expectation| is
    273   // true, also make sure the service storage identifier changes to
    274   // match |storage_security|.
    275   bool TestLoadMapping(const string& service_security,
    276                        const string& storage_security,
    277                        bool expectation) {
    278     WiFiServiceRefPtr wifi_service = MakeSimpleService(service_security);
    279     NiceMock<MockStore> mock_store;
    280     EXPECT_CALL(mock_store, GetGroupsWithProperties(_))
    281         .WillRepeatedly(Return(set<string>()));
    282     const string kStorageId = "storage_id";
    283     EXPECT_CALL(mock_store, ContainsGroup(kStorageId))
    284         .WillRepeatedly(Return(true));
    285     set<string> groups;
    286     groups.insert(kStorageId);
    287     EXPECT_CALL(mock_store, GetGroupsWithProperties(
    288         ContainsWiFiProperties(wifi_service->ssid(),
    289                                kModeManaged,
    290                                storage_security)))
    291         .WillRepeatedly(Return(groups));
    292     bool is_loadable = wifi_service->IsLoadableFrom(mock_store);
    293     EXPECT_EQ(expectation, is_loadable);
    294     bool is_loaded = wifi_service->Load(&mock_store);
    295     EXPECT_EQ(expectation, is_loaded);
    296     const string expected_identifier(expectation ? kStorageId : "");
    297     EXPECT_EQ(expected_identifier,
    298               wifi_service->GetLoadableStorageIdentifier(mock_store));
    299 
    300     if (expectation != is_loadable || expectation != is_loaded) {
    301       return false;
    302     } else if (!expectation) {
    303       return true;
    304     } else {
    305       return wifi_service->GetStorageIdentifier() == kStorageId;
    306     }
    307   }
    308 };
    309 
    310 class WiFiServiceUpdateFromEndpointsTest : public WiFiServiceTest {
    311  public:
    312   WiFiServiceUpdateFromEndpointsTest()
    313       : kOkEndpointStrength(WiFiService::SignalToStrength(kOkEndpointSignal)),
    314         kBadEndpointStrength(WiFiService::SignalToStrength(kBadEndpointSignal)),
    315         kGoodEndpointStrength(
    316             WiFiService::SignalToStrength(kGoodEndpointSignal)),
    317         service(MakeGenericService()),
    318         adaptor(*GetAdaptor(service.get())) {
    319     ok_endpoint = MakeOpenEndpoint(
    320         simple_ssid_string(), kOkEndpointBssId, kOkEndpointFrequency,
    321         kOkEndpointSignal);
    322     good_endpoint = MakeOpenEndpoint(
    323         simple_ssid_string(), kGoodEndpointBssId, kGoodEndpointFrequency,
    324         kGoodEndpointSignal);
    325     bad_endpoint = MakeOpenEndpoint(
    326         simple_ssid_string(), kBadEndpointBssId, kBadEndpointFrequency,
    327         kBadEndpointSignal);
    328   }
    329 
    330  protected:
    331   static const uint16_t kOkEndpointFrequency = 2422;
    332   static const uint16_t kBadEndpointFrequency = 2417;
    333   static const uint16_t kGoodEndpointFrequency = 2412;
    334   static const int16_t kOkEndpointSignal = -50;
    335   static const int16_t kBadEndpointSignal = -75;
    336   static const int16_t kGoodEndpointSignal = -25;
    337   static const char* kOkEndpointBssId;
    338   static const char* kGoodEndpointBssId;
    339   static const char* kBadEndpointBssId;
    340   // Can't be both static and const (because initialization requires a
    341   // function call). So choose to be just const.
    342   const uint8_t kOkEndpointStrength;
    343   const uint8_t kBadEndpointStrength;
    344   const uint8_t kGoodEndpointStrength;
    345   WiFiEndpointRefPtr ok_endpoint;
    346   WiFiEndpointRefPtr bad_endpoint;
    347   WiFiEndpointRefPtr good_endpoint;
    348   WiFiServiceRefPtr service;
    349   ServiceMockAdaptor& adaptor;
    350 };
    351 
    352 const char* WiFiServiceUpdateFromEndpointsTest::kOkEndpointBssId =
    353     "00:00:00:00:00:01";
    354 const char* WiFiServiceUpdateFromEndpointsTest::kGoodEndpointBssId =
    355     "00:00:00:00:00:02";
    356 const char* WiFiServiceUpdateFromEndpointsTest::kBadEndpointBssId =
    357     "00:00:00:00:00:03";
    358 
    359 class WiFiServiceFixupStorageTest : public WiFiServiceTest {
    360  protected:
    361   void AddGroup(string group_name) {
    362     groups_.insert(group_name);
    363   }
    364 
    365   void AddServiceEntry(bool has_type, bool has_mode, bool has_security,
    366                        bool has_security_class) {
    367     int index = groups_.size();
    368     string id = base::StringPrintf("%s_%d_%d_%s_%s", kTypeWifi,
    369                                    index, index, kModeManaged,
    370                                    kSecurityWpa);
    371     AddGroup(id);
    372     EXPECT_CALL(store_, GetString(id, WiFiService::kStorageType, _))
    373         .WillOnce(Return(has_type));
    374     if (!has_type) {
    375       EXPECT_CALL(store_, SetString(id, WiFiService::kStorageType,
    376                                     kTypeWifi));
    377     }
    378     EXPECT_CALL(store_, GetString(id, WiFiService::kStorageMode, _))
    379         .WillOnce(Return(has_mode));
    380     if (!has_mode) {
    381       EXPECT_CALL(store_, SetString(id, WiFiService::kStorageMode,
    382                                     kModeManaged));
    383     }
    384     EXPECT_CALL(store_, GetString(id, WiFiService::kStorageSecurity, _))
    385         .WillOnce(Return(has_security));
    386     if (!has_security) {
    387       EXPECT_CALL(store_, SetString(id, WiFiService::kStorageSecurity,
    388                                     kSecurityWpa));
    389     }
    390     EXPECT_CALL(store_, GetString(id, WiFiService::kStorageSecurityClass, _))
    391         .WillOnce(Return(has_security_class));
    392     if (!has_security_class) {
    393       EXPECT_CALL(store_, SetString(id, WiFiService::kStorageSecurityClass,
    394                                     kSecurityPsk));
    395     }
    396   }
    397 
    398   bool FixupServiceEntries() {
    399     EXPECT_CALL(store_, GetGroups()).WillOnce(Return(groups_));
    400     return WiFiService::FixupServiceEntries(&store_);
    401   }
    402 
    403  private:
    404   StrictMock<MockStore> store_;
    405   set<string> groups_;
    406 };
    407 
    408 TEST_F(WiFiServiceTest, Constructor) {
    409   string histogram = metrics()->GetFullMetricName(
    410       Metrics::kMetricTimeToJoinMillisecondsSuffix, Technology::kWifi);
    411   EXPECT_CALL(*metrics(), AddServiceStateTransitionTimer(_, _, _, _))
    412       .Times(AnyNumber());
    413   EXPECT_CALL(*metrics(), AddServiceStateTransitionTimer(
    414       _, histogram, Service::kStateAssociating, Service::kStateConfiguring));
    415   MakeSimpleService(kSecurityNone);
    416 }
    417 
    418 TEST_F(WiFiServiceTest, StorageId) {
    419   WiFiServiceRefPtr wifi_service = MakeSimpleService(kSecurityNone);
    420   string id = wifi_service->GetStorageIdentifier();
    421   for (uint i = 0; i < id.length(); ++i) {
    422     EXPECT_TRUE(id[i] == '_' ||
    423                 isxdigit(id[i]) ||
    424                 (isalpha(id[i]) && islower(id[i])));
    425   }
    426   size_t mac_pos = id.find(base::ToLowerASCII(GetAnyDeviceAddress()));
    427   EXPECT_NE(mac_pos, string::npos);
    428   EXPECT_NE(id.find(string(kModeManaged), mac_pos), string::npos);
    429 }
    430 
    431 // Make sure the passphrase is registered as a write only property
    432 // by reading and comparing all string properties returned on the store.
    433 TEST_F(WiFiServiceTest, PassphraseWriteOnly) {
    434   WiFiServiceRefPtr wifi_service = MakeSimpleService(kSecurityWpa);
    435   ReadablePropertyConstIterator<string> it =
    436       (wifi_service->store()).GetStringPropertiesIter();
    437   for ( ; !it.AtEnd(); it.Advance())
    438     EXPECT_NE(it.Key(), kPassphraseProperty);
    439 }
    440 
    441 // Make sure setting the passphrase via D-Bus Service.SetProperty validates
    442 // the passphrase.
    443 TEST_F(WiFiServiceTest, PassphraseSetPropertyValidation) {
    444   // We only spot check two password cases here to make sure the
    445   // SetProperty code path does validation.  We're not going to exhaustively
    446   // test for all types of passwords.
    447   WiFiServiceRefPtr wifi_service = MakeSimpleService(kSecurityWep);
    448   Error error;
    449   EXPECT_TRUE(wifi_service->mutable_store()->SetStringProperty(
    450                   kPassphraseProperty, "0:abcde", &error));
    451   EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
    452                    kPassphraseProperty, "invalid", &error));
    453   EXPECT_EQ(Error::kInvalidPassphrase, error.type());
    454 }
    455 
    456 TEST_F(WiFiServiceTest, PassphraseSetPropertyOpenNetwork) {
    457   WiFiServiceRefPtr wifi_service = MakeSimpleService(kSecurityNone);
    458   Error error;
    459   EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
    460                    kPassphraseProperty, "invalid", &error));
    461   EXPECT_EQ(Error::kNotSupported, error.type());
    462 }
    463 
    464 TEST_F(WiFiServiceTest, NonUTF8SSID) {
    465   vector<uint8_t> ssid;
    466 
    467   ssid.push_back(0xff);  // not a valid UTF-8 byte-sequence
    468   WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
    469                                                    dispatcher(),
    470                                                    metrics(),
    471                                                    manager(),
    472                                                    provider(),
    473                                                    ssid,
    474                                                    kModeManaged,
    475                                                    kSecurityNone,
    476                                                    false);
    477   brillo::VariantDictionary properties;
    478   // if service doesn't propertly sanitize SSID, this will generate SIGABRT.
    479   EXPECT_TRUE(wifi_service->store().GetProperties(&properties, nullptr));
    480 }
    481 
    482 MATCHER(PSKSecurityArgs, "") {
    483   return arg.ContainsString(WPASupplicant::kPropertySecurityProtocol) &&
    484       arg.GetString(WPASupplicant::kPropertySecurityProtocol) ==
    485           string("WPA RSN") &&
    486       arg.ContainsString(WPASupplicant::kPropertyPreSharedKey);
    487 }
    488 
    489 MATCHER_P(FrequencyArg, has_arg, "") {
    490   return has_arg ==
    491       arg.ContainsInt(WPASupplicant::kNetworkPropertyFrequency);
    492 }
    493 
    494 TEST_F(WiFiServiceTest, ConnectReportBSSes) {
    495   WiFiEndpointRefPtr endpoint1 =
    496       MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
    497   WiFiEndpointRefPtr endpoint2 =
    498       MakeOpenEndpoint("a", "00:00:00:00:00:02", 0, 0);
    499   WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityNone);
    500   wifi_service->AddEndpoint(endpoint1);
    501   wifi_service->AddEndpoint(endpoint2);
    502   EXPECT_CALL(*metrics(), NotifyWifiAvailableBSSes(2));
    503   EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
    504   wifi_service->Connect(nullptr, "in test");
    505 }
    506 
    507 TEST_F(WiFiServiceTest, ConnectWithPreferredDevice) {
    508   // Setup service, device, and endpoints.
    509   WiFiServiceRefPtr wifi_service = MakeServiceWithMockManager();
    510   const string kDeviceName1 = "test_device1";
    511   const string kDeviceName2 = "test_device2";
    512   scoped_refptr<MockWiFi> wifi1 = MakeSimpleWiFi(kDeviceName1);
    513   scoped_refptr<MockWiFi> wifi2 = MakeSimpleWiFi(kDeviceName2);
    514   WiFiEndpointRefPtr endpoint1 =
    515       MakeOpenEndpointWithWiFi(wifi1, "a", "00:00:00:00:00:01", 0, 0);
    516   WiFiEndpointRefPtr endpoint2 =
    517       MakeOpenEndpointWithWiFi(wifi2, "a", "00:00:00:00:00:01", 0, 0);
    518 
    519   wifi_service->SetPreferredDevice(kDeviceName1, nullptr);
    520   wifi_service->AddEndpoint(endpoint1);
    521   wifi_service->AddEndpoint(endpoint2);
    522   EXPECT_EQ(wifi1, wifi_service->wifi_);
    523 
    524   EXPECT_CALL(*wifi1, ConnectTo(wifi_service.get()));
    525   EXPECT_CALL(*wifi2, ConnectTo(_)).Times(0);
    526   wifi_service->Connect(nullptr, "in test");
    527 }
    528 
    529 TEST_F(WiFiServiceTest, ConnectTaskWPA) {
    530   WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityWpa);
    531   EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
    532   Error error;
    533   wifi_service->SetPassphrase("0:mumblemumblem", &error);
    534   wifi_service->Connect(nullptr, "in test");
    535   EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
    536               PSKSecurityArgs());
    537 }
    538 
    539 TEST_F(WiFiServiceTest, ConnectTaskRSN) {
    540   WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityRsn);
    541   EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
    542   Error error;
    543   wifi_service->SetPassphrase("0:mumblemumblem", &error);
    544   wifi_service->Connect(nullptr, "in test");
    545   EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
    546               PSKSecurityArgs());
    547 }
    548 
    549 TEST_F(WiFiServiceTest, ConnectConditions) {
    550   Error error;
    551   WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityNone);
    552   scoped_refptr<MockProfile> mock_profile(
    553       new NiceMock<MockProfile>(control_interface(), metrics(), manager()));
    554   wifi_service->set_profile(mock_profile);
    555   // With nothing else going on, the service should attempt to connect.
    556   EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
    557   wifi_service->Connect(&error, "in test");
    558   Mock::VerifyAndClearExpectations(wifi().get());
    559 
    560   // But if we're already "connecting" or "connected" then we shouldn't attempt
    561   // again.
    562   EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get())).Times(0);
    563   wifi_service->SetState(Service::kStateAssociating);
    564   wifi_service->Connect(&error, "in test");
    565   wifi_service->SetState(Service::kStateConfiguring);
    566   wifi_service->Connect(&error, "in test");
    567   wifi_service->SetState(Service::kStateConnected);
    568   wifi_service->Connect(&error, "in test");
    569   wifi_service->SetState(Service::kStatePortal);
    570   wifi_service->Connect(&error, "in test");
    571   wifi_service->SetState(Service::kStateOnline);
    572   wifi_service->Connect(&error, "in test");
    573   Mock::VerifyAndClearExpectations(wifi().get());
    574 }
    575 
    576 TEST_F(WiFiServiceTest, ConnectTaskPSK) {
    577   WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityPsk);
    578   EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
    579   Error error;
    580   wifi_service->SetPassphrase("0:mumblemumblem", &error);
    581   wifi_service->Connect(nullptr, "in test");
    582   EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
    583               PSKSecurityArgs());
    584 }
    585 
    586 TEST_F(WiFiServiceTest, ConnectTask8021x) {
    587   WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurity8021x);
    588   service->mutable_eap()->set_identity("identity");
    589   service->mutable_eap()->set_password("mumble");
    590   service->OnEapCredentialsChanged(Service::kReasonCredentialsLoaded);
    591   EXPECT_CALL(*wifi(), ConnectTo(service.get()));
    592   service->Connect(nullptr, "in test");
    593   KeyValueStore params = service->GetSupplicantConfigurationParameters();
    594   EXPECT_TRUE(
    595       params.ContainsString(WPASupplicant::kNetworkPropertyEapIdentity));
    596   EXPECT_TRUE(params.ContainsString(WPASupplicant::kNetworkPropertyCaPath));
    597 }
    598 
    599 TEST_F(WiFiServiceTest, ConnectTask8021xWithMockEap) {
    600   WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurity8021x);
    601   MockEapCredentials* eap = SetMockEap(service);
    602   EXPECT_CALL(*eap, IsConnectable()).WillOnce(Return(true));
    603   EXPECT_CALL(*wifi(), ConnectTo(service.get()));
    604   service->OnEapCredentialsChanged(Service::kReasonCredentialsLoaded);
    605   service->Connect(nullptr, "in test");
    606 
    607   EXPECT_CALL(*eap, PopulateSupplicantProperties(_, _));
    608   // The mocked function does not actually set EAP parameters so we cannot
    609   // expect them to be set.
    610   service->GetSupplicantConfigurationParameters();
    611 }
    612 
    613 TEST_F(WiFiServiceTest, ConnectTaskAdHocFrequency) {
    614   vector<uint8_t> ssid(1, 'a');
    615   WiFiEndpointRefPtr endpoint_nofreq =
    616       MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
    617   WiFiEndpointRefPtr endpoint_freq =
    618       MakeOpenEndpoint("a", "00:00:00:00:00:02", 2412, 0);
    619 
    620   WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityNone);
    621   wifi_service->AddEndpoint(endpoint_freq);
    622   EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
    623   wifi_service->Connect(nullptr, "in test");
    624 
    625   EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
    626               FrequencyArg(false));
    627 
    628   wifi_service = new WiFiService(control_interface(),
    629                                  dispatcher(),
    630                                  metrics(),
    631                                  manager(),
    632                                  provider(),
    633                                  ssid,
    634                                  kModeAdhoc,
    635                                  kSecurityNone,
    636                                  false);
    637   EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
    638   SetWiFiForService(wifi_service, wifi());
    639   wifi_service->Connect(nullptr, "in test");
    640 
    641   EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
    642               FrequencyArg(false));
    643 
    644   wifi_service = new WiFiService(control_interface(),
    645                                  dispatcher(),
    646                                  metrics(),
    647                                  manager(),
    648                                  provider(),
    649                                  ssid,
    650                                  kModeAdhoc,
    651                                  kSecurityNone,
    652                                  false);
    653   wifi_service->AddEndpoint(endpoint_nofreq);
    654   SetWiFiForService(wifi_service, wifi());
    655   EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
    656   wifi_service->Connect(nullptr, "in test");
    657 
    658   EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
    659               FrequencyArg(false));
    660 
    661   wifi_service = new WiFiService(control_interface(),
    662                                  dispatcher(),
    663                                  metrics(),
    664                                  manager(),
    665                                  provider(),
    666                                  ssid,
    667                                  kModeAdhoc,
    668                                  kSecurityNone,
    669                                  false);
    670   wifi_service->AddEndpoint(endpoint_freq);
    671   SetWiFiForService(wifi_service, wifi());
    672   EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
    673   wifi_service->Connect(nullptr, "in test");
    674   EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
    675               FrequencyArg(true));
    676 }
    677 
    678 TEST_F(WiFiServiceTest, ConnectTaskWPA80211w) {
    679   WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityPsk);
    680   WiFiEndpointRefPtr endpoint =
    681       MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
    682   endpoint->ieee80211w_required_ = true;
    683   wifi_service->AddEndpoint(endpoint);
    684   Error error;
    685   wifi_service->SetPassphrase("0:mumblemumblem", &error);
    686   EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
    687   wifi_service->Connect(nullptr, "in test");
    688 
    689   KeyValueStore params =
    690       wifi_service->GetSupplicantConfigurationParameters();
    691   EXPECT_TRUE(params.ContainsString(WPASupplicant::kPropertySecurityProtocol));
    692   EXPECT_TRUE(params.ContainsString(WPASupplicant::kPropertyPreSharedKey));
    693   EXPECT_TRUE(params.ContainsUint(WPASupplicant::kNetworkPropertyIeee80211w));
    694 }
    695 
    696 MATCHER_P(WEPSecurityArgsKeyIndex, index, "") {
    697   uint32_t index_u32 = index;
    698   return arg.ContainsString(WPASupplicant::kPropertyAuthAlg) &&
    699       arg.ContainsUint8s(
    700                   WPASupplicant::kPropertyWEPKey + base::IntToString(index)) &&
    701       arg.ContainsUint(WPASupplicant::kPropertyWEPTxKeyIndex) &&
    702       (arg.GetUint(WPASupplicant::kPropertyWEPTxKeyIndex) == index_u32);
    703 }
    704 
    705 TEST_F(WiFiServiceTest, ConnectTaskWEP) {
    706   WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityWep);
    707   Error error;
    708   wifi_service->SetPassphrase("0:abcdefghijklm", &error);
    709   EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
    710   wifi_service->Connect(nullptr, "in test");
    711   EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
    712               WEPSecurityArgsKeyIndex(0));
    713 
    714   wifi_service->SetPassphrase("abcdefghijklm", &error);
    715   EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
    716   wifi_service->Connect(nullptr, "in test");
    717   EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
    718               WEPSecurityArgsKeyIndex(0));
    719 
    720   wifi_service->SetPassphrase("1:abcdefghijklm", &error);
    721   EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
    722   wifi_service->Connect(nullptr, "in test");
    723   EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
    724               WEPSecurityArgsKeyIndex(1));
    725 
    726   wifi_service->SetPassphrase("2:abcdefghijklm", &error);
    727   EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
    728   wifi_service->Connect(nullptr, "in test");
    729   EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
    730               WEPSecurityArgsKeyIndex(2));
    731 
    732   wifi_service->SetPassphrase("3:abcdefghijklm", &error);
    733   EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
    734   wifi_service->Connect(nullptr, "in test");
    735   EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
    736               WEPSecurityArgsKeyIndex(3));
    737 }
    738 
    739 // Dynamic WEP + 802.1x.
    740 TEST_F(WiFiServiceTest, ConnectTaskDynamicWEP) {
    741   WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityWep);
    742 
    743   wifi_service->mutable_eap()->SetKeyManagement("IEEE8021X", nullptr);
    744   wifi_service->mutable_eap()->set_identity("something");
    745   wifi_service->mutable_eap()->set_password("mumble");
    746   wifi_service->OnEapCredentialsChanged(Service::kReasonCredentialsLoaded);
    747   EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
    748   wifi_service->Connect(nullptr, "in test");
    749   KeyValueStore params =
    750       wifi_service->GetSupplicantConfigurationParameters();
    751   EXPECT_TRUE(
    752       params.ContainsString(WPASupplicant::kNetworkPropertyEapIdentity));
    753   EXPECT_TRUE(params.ContainsString(WPASupplicant::kNetworkPropertyCaPath));
    754   EXPECT_FALSE(
    755       params.ContainsString(WPASupplicant::kPropertySecurityProtocol));
    756 }
    757 
    758 TEST_F(WiFiServiceTest, SetPassphraseResetHasEverConnected) {
    759   WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityRsn);
    760   const string kPassphrase = "abcdefgh";
    761 
    762   Error error;
    763   // A changed passphrase should reset has_ever_connected_ field.
    764   wifi_service->has_ever_connected_ = true;
    765   EXPECT_TRUE(wifi_service->has_ever_connected());
    766   wifi_service->SetPassphrase(kPassphrase, &error);
    767   EXPECT_FALSE(wifi_service->has_ever_connected());
    768 }
    769 
    770 TEST_F(WiFiServiceTest, SetPassphraseRemovesCachedCredentials) {
    771   WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityRsn);
    772 
    773   const string kPassphrase = "abcdefgh";
    774 
    775   {
    776     Error error;
    777     // A changed passphrase should trigger cache removal.
    778     EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
    779     wifi_service->SetPassphrase(kPassphrase, &error);
    780     Mock::VerifyAndClearExpectations(wifi().get());
    781     EXPECT_TRUE(error.IsSuccess());
    782   }
    783 
    784   {
    785     Error error;
    786     // An unchanged passphrase should not trigger cache removal.
    787     EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
    788     wifi_service->SetPassphrase(kPassphrase, &error);
    789     Mock::VerifyAndClearExpectations(wifi().get());
    790     EXPECT_TRUE(error.IsSuccess());
    791   }
    792 
    793   {
    794     Error error;
    795     // A modified passphrase should trigger cache removal.
    796     EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
    797     wifi_service->SetPassphrase(kPassphrase + "X", &error);
    798     Mock::VerifyAndClearExpectations(wifi().get());
    799     EXPECT_TRUE(error.IsSuccess());
    800   }
    801 
    802   {
    803     Error error;
    804     // A cleared passphrase should also trigger cache removal.
    805     EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
    806     wifi_service->ClearPassphrase(&error);
    807     Mock::VerifyAndClearExpectations(wifi().get());
    808     EXPECT_TRUE(error.IsSuccess());
    809   }
    810 
    811   {
    812     Error error;
    813     // An invalid passphrase should not trigger cache removal.
    814     EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
    815     wifi_service->SetPassphrase("", &error);
    816     Mock::VerifyAndClearExpectations(wifi().get());
    817     EXPECT_FALSE(error.IsSuccess());
    818   }
    819 
    820   {
    821     // A change to EAP parameters in a PSK (non 802.1x) service will not
    822     // trigger cache removal.
    823     wifi_service->has_ever_connected_ = true;
    824     EXPECT_TRUE(wifi_service->has_ever_connected());
    825     EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get())).Times(0);
    826     wifi_service->OnEapCredentialsChanged(Service::kReasonPropertyUpdate);
    827     EXPECT_TRUE(wifi_service->has_ever_connected());
    828     Mock::VerifyAndClearExpectations(wifi().get());
    829   }
    830 
    831   WiFiServiceRefPtr eap_wifi_service = MakeServiceWithWiFi(kSecurity8021x);
    832 
    833   {
    834     // Any change to EAP parameters (including a null one) will trigger cache
    835     // removal in an 802.1x service.  This is a lot less granular than the
    836     // passphrase checks above.
    837     // Changes in EAP parameters should also clear has_ever_connected_.
    838     eap_wifi_service->has_ever_connected_ = true;
    839     EXPECT_TRUE(eap_wifi_service->has_ever_connected());
    840     EXPECT_CALL(*wifi(), ClearCachedCredentials(eap_wifi_service.get()));
    841     eap_wifi_service->OnEapCredentialsChanged(Service::kReasonPropertyUpdate);
    842     EXPECT_FALSE(eap_wifi_service->has_ever_connected());
    843     Mock::VerifyAndClearExpectations(wifi().get());
    844   }
    845 }
    846 
    847 // This test is somewhat redundant, since:
    848 //
    849 // a) we test that generic property setters return false on a null
    850 //    change (e.g. in PropertyAccessorTest.SignedIntCorrectness)
    851 // b) we test that custom EAP property setters return false on a null
    852 //    change in EapCredentialsTest.CustomSetterNoopChange
    853 // c) we test that the various custom accessors pass through the
    854 //    return value of custom setters
    855 //    (e.g. PropertyAccessorTest.CustomAccessorCorrectness)
    856 // d) we test that PropertyStore skips the change callback when a
    857 //    property setter return false (PropertyStoreTypedTest.SetProperty)
    858 //
    859 // Nonetheless, I think it's worth testing the WiFi+EAP case directly.
    860 TEST_F(WiFiServiceTest, EapAuthPropertyChangeClearsCachedCredentials) {
    861   WiFiServiceRefPtr wifi_service =
    862       MakeServiceWithWiFi(kSecurity8021x);
    863   PropertyStore& property_store(*wifi_service->mutable_store());
    864 
    865   // Property with custom accessor.
    866   const string kPassword = "abcdefgh";
    867   {
    868     Error error;
    869     // A changed passphrase should trigger cache removal.
    870     EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
    871     EXPECT_TRUE(property_store.SetStringProperty(
    872         kEapPasswordProperty, kPassword, &error));
    873     Mock::VerifyAndClearExpectations(wifi().get());
    874     EXPECT_TRUE(error.IsSuccess());
    875   }
    876   {
    877     Error error;
    878     // An unchanged passphrase should not trigger cache removal.
    879     EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
    880     EXPECT_FALSE(property_store.SetStringProperty(
    881         kEapPasswordProperty, kPassword, &error));
    882     Mock::VerifyAndClearExpectations(wifi().get());
    883     EXPECT_TRUE(error.IsSuccess());
    884   }
    885   {
    886     Error error;
    887     // A modified passphrase should trigger cache removal.
    888     EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
    889     EXPECT_TRUE(property_store.SetStringProperty(
    890         kEapPasswordProperty, kPassword + "X", &error));
    891     Mock::VerifyAndClearExpectations(wifi().get());
    892     EXPECT_TRUE(error.IsSuccess());
    893   }
    894 
    895   // Property with generic accessor.
    896   const string kCertId = "abcdefgh";
    897   {
    898     Error error;
    899     // A changed cert id should trigger cache removal.
    900     EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
    901     EXPECT_TRUE(property_store.SetStringProperty(
    902         kEapCertIdProperty, kCertId, &error));
    903     Mock::VerifyAndClearExpectations(wifi().get());
    904     EXPECT_TRUE(error.IsSuccess());
    905   }
    906   {
    907     Error error;
    908     // An unchanged cert id should not trigger cache removal.
    909     EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
    910     EXPECT_FALSE(property_store.SetStringProperty(
    911         kEapCertIdProperty, kCertId, &error));
    912     Mock::VerifyAndClearExpectations(wifi().get());
    913     EXPECT_TRUE(error.IsSuccess());
    914   }
    915   {
    916     Error error;
    917     // A modified cert id should trigger cache removal.
    918     EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
    919     EXPECT_TRUE(property_store.SetStringProperty(
    920         kEapCertIdProperty, kCertId + "X", &error));
    921     Mock::VerifyAndClearExpectations(wifi().get());
    922     EXPECT_TRUE(error.IsSuccess());
    923   }
    924 }
    925 
    926 TEST_F(WiFiServiceTest, LoadHidden) {
    927   WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone);
    928   ASSERT_FALSE(service->hidden_ssid_);
    929   NiceMock<MockStore> mock_store;
    930   const string storage_id = service->GetStorageIdentifier();
    931   set<string> groups;
    932   groups.insert(storage_id);
    933   EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
    934       .WillRepeatedly(Return(true));
    935   EXPECT_CALL(mock_store, GetGroupsWithProperties(
    936       ContainsWiFiProperties(
    937           simple_ssid(), kModeManaged, kSecurityNone)))
    938       .WillRepeatedly(Return(groups));
    939   EXPECT_CALL(mock_store, GetBool(_, _, _))
    940       .WillRepeatedly(Return(false));
    941   EXPECT_CALL(mock_store,
    942               GetBool(StrEq(storage_id), WiFiService::kStorageHiddenSSID, _))
    943       .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true)));
    944   EXPECT_TRUE(service->Load(&mock_store));
    945   EXPECT_TRUE(service->hidden_ssid_);
    946 }
    947 
    948 TEST_F(WiFiServiceTest, SetPassphraseForNonPassphraseService) {
    949   WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone);
    950   NiceMock<MockStore> mock_store;
    951   const string storage_id = service->GetStorageIdentifier();
    952   set<string> groups;
    953   groups.insert(storage_id);
    954   EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
    955       .WillRepeatedly(Return(true));
    956   EXPECT_CALL(mock_store, GetGroupsWithProperties(
    957       ContainsWiFiProperties(
    958           simple_ssid(), kModeManaged, kSecurityNone)))
    959       .WillRepeatedly(Return(groups));
    960 
    961   EXPECT_TRUE(service->Load(&mock_store));
    962   Error error;
    963   EXPECT_FALSE(service->SetPassphrase("password", &error));
    964   EXPECT_TRUE(error.type() == Error::kNotSupported);
    965 }
    966 
    967 TEST_F(WiFiServiceTest, LoadMultipleMatchingGroups) {
    968   WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurityNone);
    969   set<string> groups;
    970   groups.insert("id0");
    971   groups.insert("id1");
    972   // Make sure we retain the first matched group in the same way that
    973   // WiFiService::Load() will.
    974   string first_group = *groups.begin();
    975 
    976   NiceMock<MockStore> mock_store;
    977   EXPECT_CALL(mock_store, GetGroupsWithProperties(
    978       ContainsWiFiProperties(
    979           simple_ssid(), kModeManaged, kSecurityNone)))
    980       .WillRepeatedly(Return(groups));
    981   EXPECT_CALL(mock_store, ContainsGroup(first_group))
    982       .WillRepeatedly(Return(true));
    983   EXPECT_CALL(mock_store, ContainsGroup(StrNe(first_group))).Times(0);
    984   EXPECT_CALL(mock_store, GetBool(first_group, _, _))
    985       .WillRepeatedly(Return(false));
    986   EXPECT_CALL(mock_store, GetBool(StrNe(first_group), _, _)).Times(0);
    987   ScopedMockLog log;
    988   EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
    989   EXPECT_CALL(log, Log(logging::LOG_WARNING, _,
    990                        EndsWith("choosing the first.")));
    991   EXPECT_TRUE(service->Load(&mock_store));
    992 }
    993 
    994 TEST_F(WiFiServiceSecurityTest, WPAMapping) {
    995   EXPECT_TRUE(TestStorageMapping(kSecurityRsn, kSecurityPsk));
    996   EXPECT_TRUE(TestStorageMapping(kSecurityWpa, kSecurityPsk));
    997   EXPECT_TRUE(TestStorageMapping(kSecurityPsk, kSecurityPsk));
    998   EXPECT_TRUE(TestStorageMapping(kSecurityWep, kSecurityWep));
    999   EXPECT_TRUE(TestStorageMapping(kSecurityNone, kSecurityNone));
   1000   EXPECT_TRUE(TestStorageMapping(kSecurity8021x, kSecurity8021x));
   1001 }
   1002 
   1003 TEST_F(WiFiServiceSecurityTest, LoadMapping) {
   1004   EXPECT_TRUE(TestLoadMapping(kSecurityRsn, kSecurityPsk, true));
   1005   EXPECT_TRUE(TestLoadMapping(kSecurityRsn, kSecurityRsn, false));
   1006   EXPECT_TRUE(TestLoadMapping(kSecurityRsn, kSecurityWpa, false));
   1007   EXPECT_TRUE(TestLoadMapping(kSecurityWpa, kSecurityPsk, true));
   1008   EXPECT_TRUE(TestLoadMapping(kSecurityWpa, kSecurityWpa, false));
   1009   EXPECT_TRUE(TestLoadMapping(kSecurityWpa, kSecurityRsn, false));
   1010   EXPECT_TRUE(TestLoadMapping(kSecurityWep, kSecurityWep, true));
   1011   EXPECT_TRUE(TestLoadMapping(kSecurityWep, kSecurityPsk, false));
   1012 }
   1013 
   1014 TEST_F(WiFiServiceTest, LoadAndUnloadPassphrase) {
   1015   WiFiServiceRefPtr service = MakeSimpleService(kSecurityPsk);
   1016   NiceMock<MockStore> mock_store;
   1017   const string kStorageId = service->GetStorageIdentifier();
   1018   EXPECT_CALL(mock_store, ContainsGroup(StrEq(kStorageId)))
   1019       .WillRepeatedly(Return(true));
   1020   set<string> groups;
   1021   groups.insert(kStorageId);
   1022   EXPECT_CALL(mock_store, GetGroupsWithProperties(
   1023       ContainsWiFiProperties(
   1024           simple_ssid(), kModeManaged, kSecurityPsk)))
   1025       .WillRepeatedly(Return(groups));
   1026   EXPECT_CALL(mock_store, GetBool(_, _, _))
   1027       .WillRepeatedly(Return(false));
   1028   const string kPassphrase = "passphrase";
   1029   EXPECT_CALL(mock_store,
   1030               GetCryptedString(StrEq(kStorageId),
   1031                                WiFiService::kStoragePassphrase, _))
   1032       .WillRepeatedly(DoAll(SetArgumentPointee<2>(kPassphrase), Return(true)));
   1033   EXPECT_CALL(mock_store,
   1034               GetCryptedString(StrEq(kStorageId),
   1035                                StrNe(WiFiService::kStoragePassphrase), _))
   1036       .WillRepeatedly(Return(false));
   1037   EXPECT_TRUE(service->need_passphrase_);
   1038   EXPECT_TRUE(service->Load(&mock_store));
   1039   EXPECT_EQ(kPassphrase, service->passphrase_);
   1040   EXPECT_TRUE(service->connectable());
   1041   EXPECT_FALSE(service->need_passphrase_);
   1042   service->Unload();
   1043   EXPECT_EQ(string(""), service->passphrase_);
   1044   EXPECT_FALSE(service->connectable());
   1045   EXPECT_TRUE(service->need_passphrase_);
   1046 }
   1047 
   1048 TEST_F(WiFiServiceTest, LoadPassphraseClearCredentials) {
   1049   const string kOldPassphrase = "oldpassphrase";
   1050   const string kPassphrase = "passphrase";
   1051 
   1052   const bool kHasEverConnected = true;
   1053   WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurityPsk);
   1054   NiceMock<MockStore> mock_store;
   1055   const string kStorageId = service->GetStorageIdentifier();
   1056   EXPECT_CALL(mock_store, ContainsGroup(StrEq(kStorageId)))
   1057       .WillRepeatedly(Return(true));
   1058   set<string> groups;
   1059   groups.insert(kStorageId);
   1060   EXPECT_CALL(mock_store, GetGroupsWithProperties(
   1061       ContainsWiFiProperties(
   1062           simple_ssid(), kModeManaged, kSecurityPsk)))
   1063       .WillRepeatedly(Return(groups));
   1064   EXPECT_CALL(mock_store, GetBool(_, _, _))
   1065       .WillRepeatedly(Return(false));
   1066   EXPECT_CALL(mock_store,
   1067               GetCryptedString(StrEq(kStorageId),
   1068                                WiFiService::kStoragePassphrase, _))
   1069       .WillRepeatedly(DoAll(SetArgumentPointee<2>(kPassphrase), Return(true)));
   1070   EXPECT_CALL(mock_store,
   1071               GetCryptedString(StrEq(kStorageId),
   1072                                StrNe(WiFiService::kStoragePassphrase), _))
   1073       .WillRepeatedly(Return(false));
   1074   EXPECT_CALL(mock_store,
   1075               GetBool(kStorageId, Service::kStorageHasEverConnected, _))
   1076       .WillRepeatedly(DoAll(SetArgumentPointee<2>(kHasEverConnected),
   1077                             Return(true)));
   1078   // Set old passphrase for service
   1079   EXPECT_TRUE(service->need_passphrase_);
   1080   service->passphrase_ = kOldPassphrase;
   1081   service->has_ever_connected_ = true;
   1082 
   1083   scoped_refptr<MockProfile> mock_profile(
   1084       new NiceMock<MockProfile>(control_interface(), metrics(), manager()));
   1085   service->set_profile(mock_profile);
   1086   // Detect if the service is going to attempt to update the stored profile.
   1087   EXPECT_CALL(*mock_profile, GetConstStorage()).Times(0);
   1088 
   1089   // The kOldPassphrase is different than the newly loaded passhprase,
   1090   // so the credentials should be cleared.
   1091   EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(1);
   1092   EXPECT_CALL(*mock_profile, UpdateService(_)).Times(0);
   1093   EXPECT_TRUE(service->Load(&mock_store));
   1094   EXPECT_EQ(kPassphrase, service->passphrase_);
   1095   EXPECT_TRUE(service->has_ever_connected_);
   1096 
   1097   Mock::VerifyAndClearExpectations(wifi().get());
   1098   Mock::VerifyAndClearExpectations(mock_profile.get());
   1099 
   1100 
   1101   // Repeat Service::Load with same old and new passphrase. Since the old
   1102   // and new passphrase match, verify the cache is not cleared during
   1103   // profile load.
   1104   service->set_profile(mock_profile);
   1105   EXPECT_CALL(*mock_profile, GetConstStorage()).Times(0);
   1106   EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
   1107   EXPECT_TRUE(service->Load(&mock_store));
   1108   EXPECT_EQ(kPassphrase, service->passphrase_);
   1109   EXPECT_TRUE(service->has_ever_connected_);
   1110 }
   1111 
   1112 TEST_F(WiFiServiceTest, ConfigureMakesConnectable) {
   1113   string guid("legit_guid");
   1114   KeyValueStore args;
   1115   args.SetString(kEapIdentityProperty, "legit_identity");
   1116   args.SetString(kEapPasswordProperty, "legit_password");
   1117   args.SetString(kEapMethodProperty, "PEAP");
   1118   args.SetString(kGuidProperty, guid);
   1119   Error error;
   1120 
   1121   WiFiServiceRefPtr service = MakeSimpleService(kSecurity8021x);
   1122   // Hack the GUID in so that we don't have to mess about with WiFi to regsiter
   1123   // our service.  This way, Manager will handle the lookup itself.
   1124   service->SetGuid(guid, nullptr);
   1125   manager()->RegisterService(service);
   1126   EXPECT_FALSE(service->connectable());
   1127   EXPECT_EQ(service.get(), manager()->GetService(args, &error).get());
   1128   EXPECT_TRUE(error.IsSuccess());
   1129   EXPECT_TRUE(service->connectable());
   1130 }
   1131 
   1132 TEST_F(WiFiServiceTest, ConfigurePassphrase) {
   1133   EXPECT_EQ(Error::kNotSupported,
   1134             TestConfigurePassphrase(kSecurityNone, ""));
   1135   EXPECT_EQ(Error::kNotSupported,
   1136             TestConfigurePassphrase(kSecurityNone, "foo"));
   1137   EXPECT_EQ(Error::kSuccess,
   1138             TestConfigurePassphrase(kSecurityWep, nullptr));
   1139   EXPECT_EQ(Error::kInvalidPassphrase,
   1140             TestConfigurePassphrase(kSecurityWep, ""));
   1141   EXPECT_EQ(Error::kInvalidPassphrase,
   1142             TestConfigurePassphrase(kSecurityWep, "abcd"));
   1143   EXPECT_EQ(Error::kSuccess,
   1144             TestConfigurePassphrase(kSecurityWep, "abcde"));
   1145   EXPECT_EQ(Error::kSuccess,
   1146             TestConfigurePassphrase(kSecurityWep, "abcdefghijklm"));
   1147   EXPECT_EQ(Error::kSuccess,
   1148             TestConfigurePassphrase(kSecurityWep, "0:abcdefghijklm"));
   1149   EXPECT_EQ(Error::kSuccess,
   1150             TestConfigurePassphrase(kSecurityWep, "0102030405"));
   1151   EXPECT_EQ(Error::kInvalidPassphrase,
   1152             TestConfigurePassphrase(kSecurityWep, "0x0102030405"));
   1153   EXPECT_EQ(Error::kInvalidPassphrase,
   1154             TestConfigurePassphrase(kSecurityWep, "O102030405"));
   1155   EXPECT_EQ(Error::kInvalidPassphrase,
   1156             TestConfigurePassphrase(kSecurityWep, "1:O102030405"));
   1157   EXPECT_EQ(Error::kInvalidPassphrase,
   1158             TestConfigurePassphrase(kSecurityWep, "1:0xO102030405"));
   1159   EXPECT_EQ(Error::kInvalidPassphrase,
   1160             TestConfigurePassphrase(kSecurityWep, "0xO102030405"));
   1161   EXPECT_EQ(Error::kSuccess,
   1162             TestConfigurePassphrase(kSecurityWep,
   1163                                     "0102030405060708090a0b0c0d"));
   1164   EXPECT_EQ(Error::kSuccess,
   1165             TestConfigurePassphrase(kSecurityWep,
   1166                                     "0102030405060708090A0B0C0D"));
   1167   EXPECT_EQ(Error::kSuccess,
   1168             TestConfigurePassphrase(kSecurityWep,
   1169                                     "0:0102030405060708090a0b0c0d"));
   1170   EXPECT_EQ(Error::kSuccess,
   1171             TestConfigurePassphrase(kSecurityWep,
   1172                                     "0:0x0102030405060708090a0b0c0d"));
   1173   EXPECT_EQ(Error::kSuccess,
   1174             TestConfigurePassphrase(kSecurityWpa, nullptr));
   1175   EXPECT_EQ(Error::kSuccess,
   1176             TestConfigurePassphrase(kSecurityWpa, "secure password"));
   1177   EXPECT_EQ(Error::kInvalidPassphrase,
   1178             TestConfigurePassphrase(kSecurityWpa, ""));
   1179   EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
   1180       kSecurityWpa,
   1181       string(IEEE_80211::kWPAAsciiMinLen, 'Z').c_str()));
   1182   EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
   1183       kSecurityWpa,
   1184       string(IEEE_80211::kWPAAsciiMaxLen, 'Z').c_str()));
   1185   // subtle: invalid length for hex key, but valid as ascii passphrase
   1186   EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
   1187       kSecurityWpa,
   1188       string(IEEE_80211::kWPAHexLen-1, '1').c_str()));
   1189   EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
   1190       kSecurityWpa,
   1191       string(IEEE_80211::kWPAHexLen, '1').c_str()));
   1192   EXPECT_EQ(Error::kInvalidPassphrase, TestConfigurePassphrase(
   1193       kSecurityWpa,
   1194       string(IEEE_80211::kWPAAsciiMinLen-1, 'Z').c_str()));
   1195   EXPECT_EQ(Error::kInvalidPassphrase, TestConfigurePassphrase(
   1196       kSecurityWpa,
   1197       string(IEEE_80211::kWPAAsciiMaxLen+1, 'Z').c_str()));
   1198   EXPECT_EQ(Error::kInvalidPassphrase, TestConfigurePassphrase(
   1199       kSecurityWpa,
   1200       string(IEEE_80211::kWPAHexLen+1, '1').c_str()));
   1201 }
   1202 
   1203 TEST_F(WiFiServiceTest, ConfigureRedundantProperties) {
   1204   WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone);
   1205   KeyValueStore args;
   1206   args.SetString(kTypeProperty, kTypeWifi);
   1207   args.SetString(kSSIDProperty, simple_ssid_string());
   1208   args.SetString(kSecurityProperty, kSecurityNone);
   1209   args.SetString(kWifiHexSsid, "This is ignored even if it is invalid hex.");
   1210   const string kGUID = "aguid";
   1211   args.SetString(kGuidProperty, kGUID);
   1212 
   1213   EXPECT_EQ("", service->guid());
   1214   Error error;
   1215   service->Configure(args, &error);
   1216   EXPECT_TRUE(error.IsSuccess());
   1217   EXPECT_EQ(kGUID, service->guid());
   1218 }
   1219 
   1220 TEST_F(WiFiServiceTest, DisconnectWithWiFi) {
   1221   WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurityWep);
   1222   EXPECT_CALL(*wifi(), DisconnectFromIfActive(service.get())).Times(1);
   1223   Error error;
   1224   service->Disconnect(&error, "in test");
   1225 }
   1226 
   1227 TEST_F(WiFiServiceTest, DisconnectWithoutWiFi) {
   1228   WiFiServiceRefPtr service = MakeSimpleService(kSecurityWep);
   1229   EXPECT_CALL(*wifi(), DisconnectFrom(_)).Times(0);
   1230   Error error;
   1231   service->Disconnect(&error, "in test");
   1232   EXPECT_EQ(Error::kOperationFailed, error.type());
   1233 }
   1234 
   1235 TEST_F(WiFiServiceTest, DisconnectWithoutWiFiWhileAssociating) {
   1236   WiFiServiceRefPtr service = MakeSimpleService(kSecurityWep);
   1237   EXPECT_CALL(*wifi(), DisconnectFrom(_)).Times(0);
   1238   service->SetState(Service::kStateAssociating);
   1239   ScopedMockLog log;
   1240   EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
   1241   EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
   1242                        HasSubstr("WiFi endpoints do not (yet) exist.")));
   1243   Error error;
   1244   service->Disconnect(&error, "in test");
   1245   EXPECT_EQ(Error::kOperationFailed, error.type());
   1246 }
   1247 
   1248 TEST_F(WiFiServiceTest, UnloadAndClearCacheWEP) {
   1249   WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurityWep);
   1250   EXPECT_CALL(*wifi(), ClearCachedCredentials(service.get())).Times(1);
   1251   EXPECT_CALL(*wifi(), DisconnectFromIfActive(service.get())).Times(1);
   1252   service->Unload();
   1253 }
   1254 
   1255 TEST_F(WiFiServiceTest, UnloadAndClearCache8021x) {
   1256   WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurity8021x);
   1257   EXPECT_CALL(*wifi(), ClearCachedCredentials(service.get())).Times(1);
   1258   EXPECT_CALL(*wifi(), DisconnectFromIfActive(service.get())).Times(1);
   1259   service->Unload();
   1260 }
   1261 
   1262 TEST_F(WiFiServiceTest, ParseStorageIdentifierNone) {
   1263   WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone);
   1264   const string storage_id = service->GetStorageIdentifier();
   1265   string address;
   1266   string mode;
   1267   string security;
   1268   EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
   1269                                               &security));
   1270   EXPECT_EQ(base::ToLowerASCII(GetAnyDeviceAddress()), address);
   1271   EXPECT_EQ(kModeManaged, mode);
   1272   EXPECT_EQ(kSecurityNone, security);
   1273 }
   1274 
   1275 TEST_F(WiFiServiceTest, ParseStorageIdentifier8021x) {
   1276   // Do a separate test for 802.1x, since kSecurity8021x contains a "_",
   1277   // which needs to be dealt with specially in the parser.
   1278   WiFiServiceRefPtr service = MakeSimpleService(kSecurity8021x);
   1279   const string storage_id = service->GetStorageIdentifier();
   1280   string address;
   1281   string mode;
   1282   string security;
   1283   EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
   1284                                               &security));
   1285   EXPECT_EQ(base::ToLowerASCII(GetAnyDeviceAddress()), address);
   1286   EXPECT_EQ(kModeManaged, mode);
   1287   EXPECT_EQ(kSecurity8021x, security);
   1288 }
   1289 
   1290 TEST_F(WiFiServiceFixupStorageTest, FixedEntries) {
   1291   const string kNonWiFiId = "vpn_foo";
   1292   const string kUnparsableWiFiId = "wifi_foo";
   1293 
   1294   AddGroup(kNonWiFiId);
   1295   AddGroup(kUnparsableWiFiId);
   1296   AddServiceEntry(true, true, true, true);
   1297   AddServiceEntry(false, false, false, false);
   1298   AddServiceEntry(true, true, true, true);
   1299   AddServiceEntry(false, false, false, false);
   1300   EXPECT_TRUE(FixupServiceEntries());
   1301 }
   1302 
   1303 TEST_F(WiFiServiceFixupStorageTest, NoFixedEntries) {
   1304   const string kNonWiFiId = "vpn_foo";
   1305   const string kUnparsableWiFiId = "wifi_foo";
   1306 
   1307   AddGroup(kNonWiFiId);
   1308   AddGroup(kUnparsableWiFiId);
   1309   AddServiceEntry(true, true, true, true);
   1310   EXPECT_FALSE(FixupServiceEntries());
   1311 }
   1312 
   1313 TEST_F(WiFiServiceFixupStorageTest, MissingTypeProperty) {
   1314   AddServiceEntry(false, true, true, true);
   1315   EXPECT_TRUE(FixupServiceEntries());
   1316 }
   1317 
   1318 TEST_F(WiFiServiceFixupStorageTest, MissingModeProperty) {
   1319   AddServiceEntry(true, false, true, true);
   1320   EXPECT_TRUE(FixupServiceEntries());
   1321 }
   1322 
   1323 TEST_F(WiFiServiceFixupStorageTest, MissingSecurityProperty) {
   1324   AddServiceEntry(true, true, false, true);
   1325   EXPECT_TRUE(FixupServiceEntries());
   1326 }
   1327 
   1328 TEST_F(WiFiServiceFixupStorageTest, MissingSecurityClassProperty) {
   1329   AddServiceEntry(true, true, true, false);
   1330   EXPECT_TRUE(FixupServiceEntries());
   1331 }
   1332 
   1333 TEST_F(WiFiServiceTest, Connectable) {
   1334   // Open network should be connectable.
   1335   EXPECT_TRUE(CheckConnectable(kSecurityNone, nullptr, false));
   1336 
   1337   // Open network should remain connectable if we try to set a password on it.
   1338   EXPECT_TRUE(CheckConnectable(kSecurityNone, "abcde", false));
   1339 
   1340   // WEP network with passphrase set should be connectable.
   1341   EXPECT_TRUE(CheckConnectable(kSecurityWep, "abcde", false));
   1342 
   1343   // WEP network without passphrase set should NOT be connectable.
   1344   EXPECT_FALSE(CheckConnectable(kSecurityWep, nullptr, false));
   1345 
   1346   // A bad passphrase should not make a WEP network connectable.
   1347   EXPECT_FALSE(CheckConnectable(kSecurityWep, "a", false));
   1348 
   1349   // Similar to WEP, for WPA.
   1350   EXPECT_TRUE(CheckConnectable(kSecurityWpa, "abcdefgh", false));
   1351   EXPECT_FALSE(CheckConnectable(kSecurityWpa, nullptr, false));
   1352   EXPECT_FALSE(CheckConnectable(kSecurityWpa, "a", false));
   1353 
   1354   // 802.1x without connectable EAP credentials should NOT be connectable.
   1355   EXPECT_FALSE(CheckConnectable(kSecurity8021x, nullptr, false));
   1356 
   1357   // 802.1x with connectable EAP credentials should be connectable.
   1358   EXPECT_TRUE(CheckConnectable(kSecurity8021x, nullptr, true));
   1359 
   1360   // Dynamic WEP + 802.1X should be connectable under the same conditions.
   1361   EXPECT_TRUE(CheckConnectable(kSecurityWep, nullptr, true));
   1362 }
   1363 
   1364 TEST_F(WiFiServiceTest, IsAutoConnectable) {
   1365   const char* reason;
   1366   WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone);
   1367   EXPECT_CALL(*wifi(), IsIdle())
   1368       .WillRepeatedly(Return(true));
   1369   EXPECT_FALSE(service->HasEndpoints());
   1370   EXPECT_FALSE(service->IsAutoConnectable(&reason));
   1371   EXPECT_STREQ(WiFiService::kAutoConnNoEndpoint, reason);
   1372 
   1373   reason = "";
   1374   WiFiEndpointRefPtr endpoint =
   1375       MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
   1376   service->AddEndpoint(endpoint);
   1377   EXPECT_CALL(*wifi(), IsIdle())
   1378       .WillRepeatedly(Return(true));
   1379   EXPECT_TRUE(service->HasEndpoints());
   1380   EXPECT_TRUE(service->IsAutoConnectable(&reason));
   1381   EXPECT_STREQ("", reason);
   1382 
   1383   // WiFi only supports connecting to one Service at a time. So, to
   1384   // avoid disrupting connectivity, we only allow auto-connection to
   1385   // a WiFiService when the corresponding WiFi is idle.
   1386   EXPECT_CALL(*wifi(), IsIdle())
   1387       .WillRepeatedly(Return(false));
   1388   EXPECT_TRUE(service->HasEndpoints());
   1389   EXPECT_FALSE(service->IsAutoConnectable(&reason));
   1390   EXPECT_STREQ(WiFiService::kAutoConnBusy, reason);
   1391 }
   1392 
   1393 TEST_F(WiFiServiceTest, AutoConnect) {
   1394   const char* reason;
   1395   WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone);
   1396   EXPECT_FALSE(service->IsAutoConnectable(&reason));
   1397   EXPECT_CALL(*wifi(), ConnectTo(_)).Times(0);
   1398   service->AutoConnect();
   1399   dispatcher()->DispatchPendingEvents();
   1400 
   1401   WiFiEndpointRefPtr endpoint =
   1402       MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
   1403   service->AddEndpoint(endpoint);
   1404   EXPECT_CALL(*wifi(), IsIdle())
   1405       .WillRepeatedly(Return(true));
   1406   EXPECT_TRUE(service->IsAutoConnectable(&reason));
   1407   EXPECT_CALL(*wifi(), ConnectTo(_));
   1408   service->AutoConnect();
   1409   dispatcher()->DispatchPendingEvents();
   1410 
   1411   Error error;
   1412   service->UserInitiatedDisconnect(&error);
   1413   dispatcher()->DispatchPendingEvents();
   1414   EXPECT_FALSE(service->IsAutoConnectable(&reason));
   1415 }
   1416 
   1417 TEST_F(WiFiServiceTest, ClearWriteOnlyDerivedProperty) {
   1418   WiFiServiceRefPtr wifi_service = MakeSimpleService(kSecurityWep);
   1419 
   1420   EXPECT_EQ("", wifi_service->passphrase_);
   1421 
   1422   Error error;
   1423   const string kPassphrase = "0:abcde";
   1424   EXPECT_TRUE(
   1425       wifi_service->mutable_store()->SetAnyProperty(kPassphraseProperty,
   1426                                                     brillo::Any(kPassphrase),
   1427                                                     &error));
   1428   EXPECT_EQ(kPassphrase, wifi_service->passphrase_);
   1429 
   1430   EXPECT_TRUE(wifi_service->mutable_store()->ClearProperty(kPassphraseProperty,
   1431                                                            &error));
   1432   EXPECT_EQ("", wifi_service->passphrase_);
   1433 }
   1434 
   1435 TEST_F(WiFiServiceTest, SignalToStrength) {
   1436   // Verify that our mapping is sane, in the sense that it preserves ordering.
   1437   // We break the test into two domains, because we assume that positive
   1438   // values aren't actually in dBm.
   1439   for (int16_t i = std::numeric_limits<int16_t>::min(); i < 0; ++i) {
   1440     int16_t current_mapped = WiFiService::SignalToStrength(i);
   1441     int16_t next_mapped =  WiFiService::SignalToStrength(i+1);
   1442     EXPECT_LE(current_mapped, next_mapped)
   1443         << "(original values " << i << " " << i+1 << ")";
   1444     EXPECT_GE(current_mapped, Service::kStrengthMin);
   1445     EXPECT_LE(current_mapped, Service::kStrengthMax);
   1446   }
   1447   for (int16_t i = 1; i < std::numeric_limits<int16_t>::max(); ++i) {
   1448     int16_t current_mapped = WiFiService::SignalToStrength(i);
   1449     int16_t next_mapped =  WiFiService::SignalToStrength(i+1);
   1450     EXPECT_LE(current_mapped, next_mapped)
   1451         << "(original values " << i << " " << i+1 << ")";
   1452     EXPECT_GE(current_mapped, Service::kStrengthMin);
   1453     EXPECT_LE(current_mapped, Service::kStrengthMax);
   1454   }
   1455 }
   1456 
   1457 TEST_F(WiFiServiceUpdateFromEndpointsTest, Strengths) {
   1458   // If the chosen signal values don't map to distinct strength
   1459   // values, then we can't expect our other tests to pass. So verify
   1460   // their distinctness.
   1461   EXPECT_TRUE(kOkEndpointStrength != kBadEndpointStrength);
   1462   EXPECT_TRUE(kOkEndpointStrength != kGoodEndpointStrength);
   1463   EXPECT_TRUE(kGoodEndpointStrength != kBadEndpointStrength);
   1464 }
   1465 
   1466 TEST_F(WiFiServiceUpdateFromEndpointsTest, Floating) {
   1467   // Initial endpoint updates values.
   1468   EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, kOkEndpointFrequency));
   1469   EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, kOkEndpointBssId));
   1470   EXPECT_CALL(adaptor,
   1471               EmitUint8Changed(kSignalStrengthProperty, kOkEndpointStrength));
   1472   EXPECT_CALL(adaptor,
   1473               EmitUint16Changed(kWifiPhyMode, Metrics::kWiFiNetworkPhyMode11b));
   1474   service->AddEndpoint(ok_endpoint);
   1475   EXPECT_EQ(1, service->GetEndpointCount());
   1476   Mock::VerifyAndClearExpectations(&adaptor);
   1477 
   1478   // Endpoint with stronger signal updates values.
   1479   EXPECT_CALL(adaptor,
   1480               EmitUint16Changed(kWifiFrequency, kGoodEndpointFrequency));
   1481   EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, kGoodEndpointBssId));
   1482   EXPECT_CALL(adaptor,
   1483               EmitUint8Changed(kSignalStrengthProperty, kGoodEndpointStrength));
   1484   // However, both endpoints are 11b.
   1485   EXPECT_CALL(adaptor, EmitUint16Changed(kWifiPhyMode, _)).Times(0);
   1486   service->AddEndpoint(good_endpoint);
   1487   EXPECT_EQ(2, service->GetEndpointCount());
   1488   Mock::VerifyAndClearExpectations(&adaptor);
   1489 
   1490   // Endpoint with lower signal does not change values.
   1491   EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)).Times(0);
   1492   EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)).Times(0);
   1493   EXPECT_CALL(adaptor,
   1494               EmitUint8Changed(kSignalStrengthProperty, _)).Times(0);
   1495   EXPECT_CALL(adaptor, EmitUint16Changed(kWifiPhyMode, _)).Times(0);
   1496   service->AddEndpoint(bad_endpoint);
   1497   EXPECT_EQ(3, service->GetEndpointCount());
   1498   Mock::VerifyAndClearExpectations(&adaptor);
   1499 
   1500   // Removing non-optimal endpoint does not change values.
   1501   EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)).Times(0);
   1502   EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)).Times(0);
   1503   EXPECT_CALL(adaptor,
   1504               EmitUint8Changed(kSignalStrengthProperty, _)).Times(0);
   1505   EXPECT_CALL(adaptor, EmitUint16Changed(kWifiPhyMode, _)).Times(0);
   1506   service->RemoveEndpoint(bad_endpoint);
   1507   EXPECT_EQ(2, service->GetEndpointCount());
   1508   Mock::VerifyAndClearExpectations(&adaptor);
   1509 
   1510   // Removing optimal endpoint updates values.
   1511   EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, kOkEndpointFrequency));
   1512   EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, kOkEndpointBssId));
   1513   EXPECT_CALL(adaptor,
   1514               EmitUint8Changed(kSignalStrengthProperty, kOkEndpointStrength));
   1515   // However, both endpoints are 11b.
   1516   EXPECT_CALL(adaptor, EmitUint16Changed(kWifiPhyMode, _)).Times(0);
   1517   service->RemoveEndpoint(good_endpoint);
   1518   EXPECT_EQ(1, service->GetEndpointCount());
   1519   Mock::VerifyAndClearExpectations(&adaptor);
   1520 
   1521   // Removing last endpoint updates values (and doesn't crash).
   1522   EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _));
   1523   EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _));
   1524   EXPECT_CALL(adaptor, EmitUint8Changed(kSignalStrengthProperty, _));
   1525   EXPECT_CALL(adaptor, EmitUint16Changed(
   1526       kWifiPhyMode, Metrics::kWiFiNetworkPhyModeUndef));
   1527   service->RemoveEndpoint(ok_endpoint);
   1528   EXPECT_EQ(0, service->GetEndpointCount());
   1529   Mock::VerifyAndClearExpectations(&adaptor);
   1530 }
   1531 
   1532 TEST_F(WiFiServiceUpdateFromEndpointsTest, Connected) {
   1533   EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
   1534   EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
   1535   EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
   1536   EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
   1537   service->AddEndpoint(bad_endpoint);
   1538   service->AddEndpoint(ok_endpoint);
   1539   EXPECT_EQ(2, service->GetEndpointCount());
   1540   Mock::VerifyAndClearExpectations(&adaptor);
   1541 
   1542   // Setting current endpoint forces adoption of its values, even if it
   1543   // doesn't have the highest signal.
   1544   EXPECT_CALL(adaptor,
   1545               EmitUint16Changed(kWifiFrequency, kBadEndpointFrequency));
   1546   EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, kBadEndpointBssId));
   1547   EXPECT_CALL(adaptor,
   1548               EmitUint8Changed(kSignalStrengthProperty, kBadEndpointStrength));
   1549   service->NotifyCurrentEndpoint(bad_endpoint);
   1550   Mock::VerifyAndClearExpectations(&adaptor);
   1551 
   1552   // Adding a better endpoint doesn't matter, when current endpoint is set.
   1553   EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)).Times(0);
   1554   EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)).Times(0);
   1555   EXPECT_CALL(adaptor,
   1556               EmitUint8Changed(kSignalStrengthProperty, _)).Times(0);
   1557   service->AddEndpoint(good_endpoint);
   1558   EXPECT_EQ(3, service->GetEndpointCount());
   1559   Mock::VerifyAndClearExpectations(&adaptor);
   1560 
   1561   // Removing a better endpoint doesn't matter, when current endpoint is set.
   1562   EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)).Times(0);
   1563   EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)).Times(0);
   1564   EXPECT_CALL(adaptor,
   1565               EmitUint8Changed(kSignalStrengthProperty, _)).Times(0);
   1566   service->RemoveEndpoint(good_endpoint);
   1567   Mock::VerifyAndClearExpectations(&adaptor);
   1568 
   1569   // Removing the current endpoint is safe and sane.
   1570   EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, kOkEndpointFrequency));
   1571   EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, kOkEndpointBssId));
   1572   EXPECT_CALL(adaptor,
   1573               EmitUint8Changed(kSignalStrengthProperty, kOkEndpointStrength));
   1574   service->RemoveEndpoint(bad_endpoint);
   1575   Mock::VerifyAndClearExpectations(&adaptor);
   1576 
   1577   // Clearing the current endpoint (without removing it) is also safe and sane.
   1578   service->NotifyCurrentEndpoint(ok_endpoint);
   1579   EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)).Times(0);
   1580   EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)).Times(0);
   1581   EXPECT_CALL(adaptor,
   1582               EmitUint8Changed(kSignalStrengthProperty, _)).Times(0);
   1583   service->NotifyCurrentEndpoint(nullptr);
   1584   Mock::VerifyAndClearExpectations(&adaptor);
   1585 }
   1586 
   1587 TEST_F(WiFiServiceUpdateFromEndpointsTest, EndpointModified) {
   1588   EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
   1589   EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
   1590   EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
   1591   EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
   1592   service->AddEndpoint(ok_endpoint);
   1593   service->AddEndpoint(good_endpoint);
   1594   EXPECT_EQ(2, service->GetEndpointCount());
   1595   Mock::VerifyAndClearExpectations(&adaptor);
   1596 
   1597   // Updating sub-optimal Endpoint doesn't update Service.
   1598   EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)).Times(0);
   1599   EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)).Times(0);
   1600   EXPECT_CALL(adaptor,
   1601               EmitUint8Changed(kSignalStrengthProperty, _)).Times(0);
   1602   ok_endpoint->signal_strength_ = (kOkEndpointSignal + kGoodEndpointSignal) / 2;
   1603   service->NotifyEndpointUpdated(ok_endpoint);
   1604   Mock::VerifyAndClearExpectations(&adaptor);
   1605 
   1606   // Updating optimal Endpoint updates appropriate Service property.
   1607   EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)).Times(0);
   1608   EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)).Times(0);
   1609   EXPECT_CALL(adaptor, EmitUint8Changed(kSignalStrengthProperty, _));
   1610   good_endpoint->signal_strength_ = kGoodEndpointSignal + 1;
   1611   service->NotifyEndpointUpdated(good_endpoint);
   1612   Mock::VerifyAndClearExpectations(&adaptor);
   1613 
   1614   // Change in optimal Endpoint updates Service properties.
   1615   EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, kOkEndpointFrequency));
   1616   EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, kOkEndpointBssId));
   1617   EXPECT_CALL(adaptor, EmitUint8Changed(kSignalStrengthProperty, _));
   1618   ok_endpoint->signal_strength_ = kGoodEndpointSignal + 2;
   1619   service->NotifyEndpointUpdated(ok_endpoint);
   1620   Mock::VerifyAndClearExpectations(&adaptor);
   1621 }
   1622 
   1623 TEST_F(WiFiServiceUpdateFromEndpointsTest, Ieee80211w) {
   1624   EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
   1625   EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
   1626   EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
   1627   EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
   1628   service->AddEndpoint(ok_endpoint);
   1629   EXPECT_FALSE(service->ieee80211w_required());
   1630   good_endpoint->ieee80211w_required_ = true;
   1631   service->AddEndpoint(good_endpoint);
   1632   EXPECT_TRUE(service->ieee80211w_required());
   1633   service->RemoveEndpoint(good_endpoint);
   1634   EXPECT_TRUE(service->ieee80211w_required());
   1635 }
   1636 
   1637 TEST_F(WiFiServiceUpdateFromEndpointsTest, PhysicalMode) {
   1638   EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
   1639   EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
   1640   EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
   1641   EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
   1642 
   1643   // No endpoints -> undef.
   1644   EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, service->physical_mode());
   1645 
   1646   // Endpoint has unknown physical mode -> undef.
   1647   ok_endpoint->physical_mode_ = Metrics::kWiFiNetworkPhyModeUndef;
   1648   service->AddEndpoint(ok_endpoint);
   1649   EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, service->physical_mode());
   1650 
   1651   // New endpoint with 802.11a -> 802.11a.
   1652   good_endpoint->physical_mode_ = Metrics::kWiFiNetworkPhyMode11a;
   1653   service->AddEndpoint(good_endpoint);
   1654   EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11a, service->physical_mode());
   1655 
   1656   // Remove 802.11a endpoint -> undef.
   1657   service->RemoveEndpoint(good_endpoint);
   1658   EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, service->physical_mode());
   1659 
   1660   // Change endpoint -> take endpoint's new value.
   1661   ok_endpoint->physical_mode_ = Metrics::kWiFiNetworkPhyMode11n;
   1662   service->NotifyEndpointUpdated(ok_endpoint);
   1663   EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11n, service->physical_mode());
   1664 
   1665   // No endpoints -> undef.
   1666   service->RemoveEndpoint(ok_endpoint);
   1667   EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, service->physical_mode());
   1668 }
   1669 
   1670 TEST_F(WiFiServiceUpdateFromEndpointsTest, WarningOnDisconnect) {
   1671   service->AddEndpoint(ok_endpoint);
   1672   service->SetState(Service::kStateAssociating);
   1673   ScopedMockLog log;
   1674   EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
   1675   EXPECT_CALL(log, Log(logging::LOG_WARNING, _,
   1676                        EndsWith("disconnect due to no remaining endpoints.")));
   1677   service->RemoveEndpoint(ok_endpoint);
   1678 }
   1679 
   1680 TEST_F(WiFiServiceUpdateFromEndpointsTest, AddEndpointWithPreferredDevice) {
   1681   // Setup service, device, and endpoints.
   1682   WiFiServiceRefPtr wifi_service = MakeServiceWithMockManager();
   1683   const string kDeviceName1 = "test_device1";
   1684   const string kDeviceName2 = "test_device2";
   1685   scoped_refptr<MockWiFi> wifi1 = MakeSimpleWiFi(kDeviceName1);
   1686   scoped_refptr<MockWiFi> wifi2 = MakeSimpleWiFi(kDeviceName2);
   1687   // Best signal for endpoint associated with the preferred device.
   1688   const int16_t kPreferredDeviceBestSignal = -40;
   1689   WiFiEndpointRefPtr endpoint0 =
   1690       MakeOpenEndpointWithWiFi(wifi2, "a", "00:00:00:00:00:01", 0,
   1691                                kPreferredDeviceBestSignal + 10);
   1692   WiFiEndpointRefPtr endpoint1 =
   1693       MakeOpenEndpointWithWiFi(wifi1, "a", "00:00:00:00:00:01", 0,
   1694                                kPreferredDeviceBestSignal - 10);
   1695   WiFiEndpointRefPtr endpoint2 =
   1696       MakeOpenEndpointWithWiFi(wifi1, "a", "00:00:00:00:00:01", 0,
   1697                                kPreferredDeviceBestSignal);
   1698   WiFiEndpointRefPtr endpoint3 =
   1699       MakeOpenEndpointWithWiFi(wifi2, "a", "00:00:00:00:00:01", 0,
   1700                                kPreferredDeviceBestSignal + 10);
   1701 
   1702   wifi_service->SetPreferredDevice(kDeviceName1, nullptr);
   1703 
   1704   wifi_service->AddEndpoint(endpoint0);
   1705   wifi_service->AddEndpoint(endpoint1);
   1706   wifi_service->AddEndpoint(endpoint2);
   1707   wifi_service->AddEndpoint(endpoint3);
   1708   EXPECT_EQ(wifi1, wifi_service->wifi_);
   1709   // Service should display the signal strength of the best signal endpoint
   1710   // that's associated with the preferred device.
   1711   EXPECT_EQ(WiFiService::SignalToStrength(kPreferredDeviceBestSignal),
   1712             wifi_service->strength());
   1713 }
   1714 
   1715 MATCHER_P(IsSetwiseEqual, expected_set, "") {
   1716   set<uint16_t> arg_set(arg.begin(), arg.end());
   1717   return arg_set == expected_set;
   1718 }
   1719 
   1720 TEST_F(WiFiServiceUpdateFromEndpointsTest, FrequencyList) {
   1721   EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
   1722   EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
   1723   EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
   1724   EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
   1725 
   1726   // No endpoints -> empty list.
   1727   EXPECT_EQ(vector<uint16_t>(), service->frequency_list());
   1728 
   1729   // Add endpoint -> endpoint's frequency in list.
   1730   EXPECT_CALL(adaptor, EmitUint16sChanged(
   1731       kWifiFrequencyListProperty, vector<uint16_t>{kGoodEndpointFrequency}));
   1732   service->AddEndpoint(good_endpoint);
   1733   Mock::VerifyAndClearExpectations(&adaptor);
   1734 
   1735   // Add another endpoint -> both frequencies in list.
   1736   // Order doesn't matter.
   1737   set<uint16_t> expected_frequencies{kGoodEndpointFrequency,
   1738         kOkEndpointFrequency};
   1739   EXPECT_CALL(adaptor, EmitUint16sChanged(
   1740       kWifiFrequencyListProperty, IsSetwiseEqual(expected_frequencies)));
   1741   service->AddEndpoint(ok_endpoint);
   1742   Mock::VerifyAndClearExpectations(&adaptor);
   1743 
   1744   // Remove endpoint -> other endpoint's frequency remains.
   1745   EXPECT_CALL(adaptor, EmitUint16sChanged(
   1746       kWifiFrequencyListProperty, vector<uint16_t>{kOkEndpointFrequency}));
   1747   service->RemoveEndpoint(good_endpoint);
   1748   Mock::VerifyAndClearExpectations(&adaptor);
   1749 
   1750   // Endpoint with same frequency -> frequency remains.
   1751   // Notification may or may not occur -- don't care.
   1752   // Frequency may or may not be repeated in list -- don't care.
   1753   WiFiEndpointRefPtr same_freq_as_ok_endpoint = MakeOpenEndpoint(
   1754       simple_ssid_string(), "aa:bb:cc:dd:ee:ff", ok_endpoint->frequency(), 0);
   1755   service->AddEndpoint(same_freq_as_ok_endpoint);
   1756   EXPECT_THAT(service->frequency_list(),
   1757               IsSetwiseEqual(set<uint16_t>{kOkEndpointFrequency}));
   1758   Mock::VerifyAndClearExpectations(&adaptor);
   1759 
   1760   // Remove endpoint with same frequency -> frequency remains.
   1761   // Notification may or may not occur -- don't care.
   1762   service->RemoveEndpoint(ok_endpoint);
   1763   EXPECT_EQ(vector<uint16_t>{same_freq_as_ok_endpoint->frequency()},
   1764             service->frequency_list());
   1765   Mock::VerifyAndClearExpectations(&adaptor);
   1766 
   1767   // Remove last endpoint. Frequency list goes empty.
   1768   EXPECT_CALL(adaptor, EmitUint16sChanged(
   1769       kWifiFrequencyListProperty, vector<uint16_t>{}));
   1770   service->RemoveEndpoint(same_freq_as_ok_endpoint);
   1771   Mock::VerifyAndClearExpectations(&adaptor);
   1772 }
   1773 
   1774 TEST_F(WiFiServiceTest, SecurityFromCurrentEndpoint) {
   1775   WiFiServiceRefPtr service(MakeSimpleService(kSecurityPsk));
   1776   EXPECT_EQ(kSecurityPsk, service->GetSecurity(nullptr));
   1777   WiFiEndpoint* endpoint = MakeOpenEndpoint(
   1778         simple_ssid_string(), "00:00:00:00:00:00", 0, 0);
   1779   service->AddEndpoint(endpoint);
   1780   EXPECT_EQ(kSecurityPsk, service->GetSecurity(nullptr));
   1781   service->NotifyCurrentEndpoint(endpoint);
   1782   EXPECT_EQ(kSecurityNone, service->GetSecurity(nullptr));
   1783   service->NotifyCurrentEndpoint(nullptr);
   1784   EXPECT_EQ(kSecurityPsk, service->GetSecurity(nullptr));
   1785 }
   1786 
   1787 TEST_F(WiFiServiceTest, UpdateSecurity) {
   1788   // Cleartext and pre-shared-key crypto.
   1789   {
   1790     WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone);
   1791     EXPECT_EQ(Service::kCryptoNone, service->crypto_algorithm());
   1792     EXPECT_FALSE(service->key_rotation());
   1793     EXPECT_FALSE(service->endpoint_auth());
   1794   }
   1795   {
   1796     WiFiServiceRefPtr service = MakeSimpleService(kSecurityWep);
   1797     EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
   1798     EXPECT_FALSE(service->key_rotation());
   1799     EXPECT_FALSE(service->endpoint_auth());
   1800   }
   1801   {
   1802     WiFiServiceRefPtr service = MakeSimpleService(kSecurityPsk);
   1803     EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
   1804     EXPECT_TRUE(service->key_rotation());
   1805     EXPECT_FALSE(service->endpoint_auth());
   1806   }
   1807   {
   1808     WiFiServiceRefPtr service = MakeSimpleService(kSecurityWpa);
   1809     EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
   1810     EXPECT_TRUE(service->key_rotation());
   1811     EXPECT_FALSE(service->endpoint_auth());
   1812   }
   1813   {
   1814     WiFiServiceRefPtr service = MakeSimpleService(kSecurityRsn);
   1815     EXPECT_EQ(Service::kCryptoAes, service->crypto_algorithm());
   1816     EXPECT_TRUE(service->key_rotation());
   1817     EXPECT_FALSE(service->endpoint_auth());
   1818   }
   1819 
   1820   // Crypto with 802.1X key management.
   1821   {
   1822     // WEP
   1823     WiFiServiceRefPtr service = MakeSimpleService(kSecurityWep);
   1824     service->SetEAPKeyManagement("IEEE8021X");
   1825     EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
   1826     EXPECT_TRUE(service->key_rotation());
   1827     EXPECT_TRUE(service->endpoint_auth());
   1828   }
   1829   {
   1830     // WPA
   1831     WiFiServiceRefPtr service = MakeSimpleService(kSecurity8021x);
   1832     WiFiEndpointRefPtr endpoint =
   1833         MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false);
   1834     service->AddEndpoint(endpoint);
   1835     EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
   1836     EXPECT_TRUE(service->key_rotation());
   1837     EXPECT_TRUE(service->endpoint_auth());
   1838   }
   1839   {
   1840     // RSN
   1841     WiFiServiceRefPtr service = MakeSimpleService(kSecurity8021x);
   1842     WiFiEndpointRefPtr endpoint =
   1843         MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, true);
   1844     service->AddEndpoint(endpoint);
   1845     EXPECT_EQ(Service::kCryptoAes, service->crypto_algorithm());
   1846     EXPECT_TRUE(service->key_rotation());
   1847     EXPECT_TRUE(service->endpoint_auth());
   1848   }
   1849   {
   1850     // AP supports both WPA and RSN.
   1851     WiFiServiceRefPtr service = MakeSimpleService(kSecurity8021x);
   1852     WiFiEndpointRefPtr endpoint =
   1853         MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, true);
   1854     service->AddEndpoint(endpoint);
   1855     EXPECT_EQ(Service::kCryptoAes, service->crypto_algorithm());
   1856     EXPECT_TRUE(service->key_rotation());
   1857     EXPECT_TRUE(service->endpoint_auth());
   1858   }
   1859 }
   1860 
   1861 TEST_F(WiFiServiceTest, ComputeCipher8021x) {
   1862   // No endpoints.
   1863   {
   1864     const set<WiFiEndpointConstRefPtr> endpoints;
   1865     EXPECT_EQ(Service::kCryptoNone,
   1866               WiFiService::ComputeCipher8021x(endpoints));
   1867   }
   1868 
   1869   // Single endpoint, various configs.
   1870   {
   1871     set<WiFiEndpointConstRefPtr> endpoints;
   1872     endpoints.insert(
   1873         MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, false));
   1874     EXPECT_EQ(Service::kCryptoNone,
   1875               WiFiService::ComputeCipher8021x(endpoints));
   1876   }
   1877   {
   1878     set<WiFiEndpointConstRefPtr> endpoints;
   1879     endpoints.insert(
   1880         MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false));
   1881     EXPECT_EQ(Service::kCryptoRc4,
   1882               WiFiService::ComputeCipher8021x(endpoints));
   1883   }
   1884   {
   1885     set<WiFiEndpointConstRefPtr> endpoints;
   1886     endpoints.insert(
   1887         MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, true));
   1888     EXPECT_EQ(Service::kCryptoAes,
   1889               WiFiService::ComputeCipher8021x(endpoints));
   1890   }
   1891   {
   1892     set<WiFiEndpointConstRefPtr> endpoints;
   1893     endpoints.insert(
   1894         MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, true));
   1895     EXPECT_EQ(Service::kCryptoAes,
   1896               WiFiService::ComputeCipher8021x(endpoints));
   1897   }
   1898 
   1899   // Multiple endpoints.
   1900   {
   1901     set<WiFiEndpointConstRefPtr> endpoints;
   1902     endpoints.insert(
   1903         MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, false));
   1904     endpoints.insert(
   1905         MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, false, false));
   1906     EXPECT_EQ(Service::kCryptoNone,
   1907               WiFiService::ComputeCipher8021x(endpoints));
   1908   }
   1909   {
   1910     set<WiFiEndpointConstRefPtr> endpoints;
   1911     endpoints.insert(
   1912         MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, false));
   1913     endpoints.insert(
   1914         MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, true, false));
   1915     EXPECT_EQ(Service::kCryptoNone,
   1916               WiFiService::ComputeCipher8021x(endpoints));
   1917   }
   1918   {
   1919     set<WiFiEndpointConstRefPtr> endpoints;
   1920     endpoints.insert(
   1921         MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false));
   1922     endpoints.insert(
   1923         MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, true, false));
   1924     EXPECT_EQ(Service::kCryptoRc4,
   1925               WiFiService::ComputeCipher8021x(endpoints));
   1926   }
   1927   {
   1928     set<WiFiEndpointConstRefPtr> endpoints;
   1929     endpoints.insert(
   1930         MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false));
   1931     endpoints.insert(
   1932         MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, false, true));
   1933     EXPECT_EQ(Service::kCryptoRc4,
   1934               WiFiService::ComputeCipher8021x(endpoints));
   1935   }
   1936   {
   1937     set<WiFiEndpointConstRefPtr> endpoints;
   1938     endpoints.insert(
   1939         MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, true));
   1940     endpoints.insert(
   1941         MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, false, true));
   1942     EXPECT_EQ(Service::kCryptoAes,
   1943               WiFiService::ComputeCipher8021x(endpoints));
   1944   }
   1945   {
   1946     set<WiFiEndpointConstRefPtr> endpoints;
   1947     endpoints.insert(
   1948         MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, true));
   1949     endpoints.insert(
   1950         MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, true, true));
   1951     EXPECT_EQ(Service::kCryptoAes,
   1952               WiFiService::ComputeCipher8021x(endpoints));
   1953   }
   1954 }
   1955 
   1956 TEST_F(WiFiServiceTest, Unload) {
   1957   WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurityNone);
   1958   EXPECT_CALL(*wifi(), DestroyIPConfigLease(service->GetStorageIdentifier())).
   1959     Times(1);
   1960   service->Unload();
   1961 }
   1962 
   1963 TEST_F(WiFiServiceTest, PropertyChanges) {
   1964   WiFiServiceRefPtr service = MakeServiceWithMockManager();
   1965   ServiceMockAdaptor* adaptor = GetAdaptor(service.get());
   1966   TestCommonPropertyChanges(service, adaptor);
   1967   TestAutoConnectPropertyChange(service, adaptor);
   1968 
   1969   EXPECT_CALL(*adaptor,
   1970               EmitRpcIdentifierChanged(kDeviceProperty, _));
   1971   SetWiFi(service, wifi());
   1972   Mock::VerifyAndClearExpectations(adaptor);
   1973 
   1974   EXPECT_CALL(*adaptor,
   1975               EmitRpcIdentifierChanged(kDeviceProperty, _));
   1976   service->ResetWiFi();
   1977   Mock::VerifyAndClearExpectations(adaptor);
   1978 }
   1979 
   1980 // Custom property setters should return false, and make no changes, if
   1981 // the new value is the same as the old value.
   1982 TEST_F(WiFiServiceTest, CustomSetterNoopChange) {
   1983   WiFiServiceRefPtr service = MakeServiceWithMockManager();
   1984   TestCustomSetterNoopChange(service, mock_manager());
   1985 }
   1986 
   1987 TEST_F(WiFiServiceTest, SuspectedCredentialFailure) {
   1988   WiFiServiceRefPtr service = MakeSimpleService(kSecurityWpa);
   1989   EXPECT_FALSE(service->has_ever_connected());
   1990   EXPECT_EQ(0, service->suspected_credential_failures_);
   1991 
   1992   EXPECT_TRUE(service->AddSuspectedCredentialFailure());
   1993   EXPECT_EQ(0, service->suspected_credential_failures_);
   1994 
   1995   service->has_ever_connected_ = true;
   1996   for (int i = 0; i < WiFiService::kSuspectedCredentialFailureThreshold - 1;
   1997        ++i) {
   1998     EXPECT_FALSE(service->AddSuspectedCredentialFailure());
   1999     EXPECT_EQ(i + 1, service->suspected_credential_failures_);
   2000   }
   2001 
   2002   EXPECT_TRUE(service->AddSuspectedCredentialFailure());
   2003   // Make sure the failure state does not reset just because we ask again.
   2004   EXPECT_TRUE(service->AddSuspectedCredentialFailure());
   2005   // Make sure the failure state resets because of a credential change.
   2006   // A credential change changes the has_ever_connected to false and
   2007   // immediately returns true when attempting to add the failure.
   2008   Error error;
   2009   service->SetPassphrase("Panchromatic Resonance", &error);
   2010   EXPECT_TRUE(error.IsSuccess());
   2011   EXPECT_TRUE(service->AddSuspectedCredentialFailure());
   2012   EXPECT_EQ(0, service->suspected_credential_failures_);
   2013 
   2014   // Make sure that we still return true after resetting the failure
   2015   // count.
   2016   service->suspected_credential_failures_ = 3;
   2017   EXPECT_EQ(3, service->suspected_credential_failures_);
   2018   service->ResetSuspectedCredentialFailures();
   2019   EXPECT_EQ(0, service->suspected_credential_failures_);
   2020   EXPECT_TRUE(service->AddSuspectedCredentialFailure());
   2021 }
   2022 
   2023 TEST_F(WiFiServiceTest, GetTethering) {
   2024   WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone);
   2025   EXPECT_EQ(kTetheringNotDetectedState, service->GetTethering(nullptr));
   2026 
   2027   // Since the device isn't connected, we shouldn't even query the WiFi device.
   2028   EXPECT_CALL(*wifi(), IsConnectedViaTether()).Times(0);
   2029   SetWiFiForService(service, wifi());
   2030   EXPECT_EQ(kTetheringNotDetectedState, service->GetTethering(nullptr));
   2031   Mock::VerifyAndClearExpectations(wifi().get());
   2032 
   2033   scoped_refptr<MockProfile> mock_profile(
   2034       new NiceMock<MockProfile>(control_interface(), metrics(), manager()));
   2035   service->set_profile(mock_profile);
   2036   service->SetState(Service::kStateConnected);
   2037 
   2038   // A connected service should return "confirmed" iff the underlying device
   2039   // reports it is tethered.
   2040   EXPECT_CALL(*wifi(), IsConnectedViaTether())
   2041       .WillOnce(Return(true))
   2042       .WillOnce(Return(false));
   2043   EXPECT_EQ(kTetheringConfirmedState, service->GetTethering(nullptr));
   2044   EXPECT_EQ(kTetheringNotDetectedState, service->GetTethering(nullptr));
   2045   Mock::VerifyAndClearExpectations(wifi().get());
   2046 
   2047   // Add two endpoints that have a BSSID associated with some Android devices
   2048   // in tethering mode.
   2049   WiFiEndpointRefPtr endpoint_android1 =
   2050       MakeOpenEndpoint("a", "02:1a:11:00:00:01", 2412, 0);
   2051   service->AddEndpoint(endpoint_android1);
   2052   WiFiEndpointRefPtr endpoint_android2 =
   2053       MakeOpenEndpoint("a", "02:1a:11:00:00:02", 2412, 0);
   2054   service->AddEndpoint(endpoint_android2);
   2055 
   2056   // Since there are two endpoints, we should not detect tethering mode.
   2057   EXPECT_CALL(*wifi(), IsConnectedViaTether()).WillOnce(Return(false));
   2058   EXPECT_EQ(kTetheringNotDetectedState, service->GetTethering(nullptr));
   2059 
   2060   // If the device reports that it is tethered, this should override any
   2061   // findings gained from examining the endpoints.
   2062   EXPECT_CALL(*wifi(), IsConnectedViaTether()).WillOnce(Return(true));
   2063   EXPECT_EQ(kTetheringConfirmedState, service->GetTethering(nullptr));
   2064 
   2065   // Continue in the un-tethered device case for a few more tests below.
   2066   Mock::VerifyAndClearExpectations(wifi().get());
   2067   EXPECT_CALL(*wifi(), IsConnectedViaTether())
   2068       .WillRepeatedly(Return(false));
   2069 
   2070   // Removing an endpoint so we only have one should put us in the "Suspected"
   2071   // state.
   2072   service->RemoveEndpoint(endpoint_android1);
   2073   EXPECT_EQ(kTetheringSuspectedState, service->GetTethering(nullptr));
   2074 
   2075   // Add a different endpoint which has a locally administered MAC address
   2076   // but not one used by Android.
   2077   service->RemoveEndpoint(endpoint_android2);
   2078   WiFiEndpointRefPtr endpoint_ios =
   2079       MakeOpenEndpoint("a", "02:00:00:00:00:01", 2412, 0);
   2080   service->AddEndpoint(endpoint_ios);
   2081   EXPECT_EQ(kTetheringNotDetectedState, service->GetTethering(nullptr));
   2082 
   2083   // If this endpoint reports the right vendor OUI, we should suspect
   2084   // it to be tethered.  However since this evaluation normally only
   2085   // happens in the endpoint constructor, we must force it to recalculate.
   2086   endpoint_ios->vendor_information_.oui_set.insert(Tethering::kIosOui);
   2087   endpoint_ios->CheckForTetheringSignature();
   2088   EXPECT_EQ(kTetheringSuspectedState, service->GetTethering(nullptr));
   2089 
   2090   // If the device reports that it is tethered, this should override any
   2091   // findings gained from examining the endpoints.
   2092   Mock::VerifyAndClearExpectations(wifi().get());
   2093   EXPECT_CALL(*wifi(), IsConnectedViaTether()).WillOnce(Return(true));
   2094   EXPECT_EQ(kTetheringConfirmedState, service->GetTethering(nullptr));
   2095 }
   2096 
   2097 TEST_F(WiFiServiceTest, IsVisible) {
   2098   WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityNone);
   2099   ServiceMockAdaptor* adaptor = GetAdaptor(wifi_service.get());
   2100 
   2101   // Adding the first endpoint emits a change: Visible = true.
   2102   EXPECT_CALL(*adaptor, EmitBoolChanged(kVisibleProperty, true));
   2103   WiFiEndpointRefPtr endpoint =
   2104       MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
   2105   wifi_service->AddEndpoint(endpoint);
   2106   EXPECT_TRUE(wifi_service->IsVisible());
   2107   Mock::VerifyAndClearExpectations(adaptor);
   2108 
   2109   // Removing the last endpoint emits a change: Visible = false.
   2110   EXPECT_CALL(*adaptor, EmitBoolChanged(kVisibleProperty, false));
   2111   wifi_service->RemoveEndpoint(endpoint);
   2112   EXPECT_FALSE(wifi_service->IsVisible());
   2113   Mock::VerifyAndClearExpectations(adaptor);
   2114 
   2115   // Entering the a connecting state emits a change: Visible = true
   2116   // although the service has no endpoints.
   2117   EXPECT_CALL(*adaptor, EmitBoolChanged(kVisibleProperty, true));
   2118   wifi_service->SetState(Service::kStateAssociating);
   2119   EXPECT_TRUE(wifi_service->IsVisible());
   2120   Mock::VerifyAndClearExpectations(adaptor);
   2121 
   2122   // Moving between connecting / connected states does not trigger an Emit.
   2123   EXPECT_CALL(*adaptor, EmitBoolChanged(kVisibleProperty, _)).Times(0);
   2124   wifi_service->SetState(Service::kStateConfiguring);
   2125   EXPECT_TRUE(wifi_service->IsVisible());
   2126   Mock::VerifyAndClearExpectations(adaptor);
   2127 
   2128   // Entering the Idle state emits a change: Visible = false.
   2129   EXPECT_CALL(*adaptor, EmitBoolChanged(kVisibleProperty, false));
   2130   wifi_service->SetState(Service::kStateIdle);
   2131   EXPECT_FALSE(wifi_service->IsVisible());
   2132   Mock::VerifyAndClearExpectations(adaptor);
   2133 }
   2134 
   2135 TEST_F(WiFiServiceTest, ConfigurePreferredDevice) {
   2136   const string kDeviceName = "test_device";
   2137 
   2138   WiFiServiceRefPtr service = MakeGenericService();
   2139   KeyValueStore args;
   2140   args.SetString(kWifiPreferredDeviceProperty, kDeviceName);
   2141 
   2142   // With no wifi device.
   2143   Error error;
   2144   service->Configure(args, &error);
   2145   EXPECT_EQ(Error::kSuccess, error.type());
   2146   EXPECT_EQ(kDeviceName, service->preferred_device_);
   2147 
   2148   // With non-preferred wifi device.
   2149   SetWiFiForService(service, wifi());
   2150   service->Configure(args, &error);
   2151   EXPECT_EQ(Error::kSuccess, error.type());
   2152   EXPECT_EQ(nullptr, service->wifi_);
   2153   EXPECT_EQ(kDeviceName, service->preferred_device_);
   2154 
   2155   // With preferred wifi device.
   2156   scoped_refptr<MockWiFi> preferred_wifi = MakeSimpleWiFi(kDeviceName);
   2157   SetWiFiForService(service, preferred_wifi);
   2158   service->Configure(args, &error);
   2159   EXPECT_EQ(Error::kSuccess, error.type());
   2160   EXPECT_EQ(preferred_wifi, service->wifi_);
   2161   EXPECT_EQ(kDeviceName, service->preferred_device_);
   2162 }
   2163 
   2164 TEST_F(WiFiServiceTest, LoadAndUnloadPreferredDevice) {
   2165   WiFiServiceRefPtr service = MakeGenericService();
   2166   NiceMock<MockStore> mock_store;
   2167   const string kStorageId = service->GetStorageIdentifier();
   2168   EXPECT_CALL(mock_store, ContainsGroup(StrEq(kStorageId)))
   2169       .WillRepeatedly(Return(true));
   2170   set<string> groups;
   2171   groups.insert(kStorageId);
   2172   EXPECT_CALL(mock_store, GetGroupsWithProperties(
   2173       ContainsWiFiProperties(
   2174           simple_ssid(), kModeManaged, kSecurityWep)))
   2175       .WillRepeatedly(Return(groups));
   2176   EXPECT_CALL(mock_store, GetBool(_, _, _))
   2177       .WillRepeatedly(Return(false));
   2178   const string kDeviceName = "test_device";
   2179   EXPECT_CALL(mock_store,
   2180               GetString(StrEq(kStorageId),
   2181                         WiFiService::kStoragePreferredDevice, _))
   2182       .WillRepeatedly(DoAll(SetArgumentPointee<2>(kDeviceName), Return(true)));
   2183   EXPECT_CALL(mock_store,
   2184               GetString(StrEq(kStorageId),
   2185                         StrNe(WiFiService::kStoragePreferredDevice), _))
   2186       .WillRepeatedly(Return(false));
   2187 
   2188   // With no wifi device.
   2189   EXPECT_TRUE(service->Load(&mock_store));
   2190   EXPECT_EQ(kDeviceName, service->preferred_device_);
   2191   service->Unload();
   2192   EXPECT_EQ("", service->preferred_device_);
   2193 
   2194   // With non-preferred wifi device.
   2195   SetWiFiForService(service, wifi());
   2196   EXPECT_TRUE(service->Load(&mock_store));
   2197   EXPECT_EQ(nullptr, service->wifi_);
   2198   EXPECT_EQ(kDeviceName, service->preferred_device_);
   2199   service->Unload();
   2200   EXPECT_EQ("", service->preferred_device_);
   2201 
   2202   // With preferred wifi device.
   2203   scoped_refptr<MockWiFi> preferred_wifi = MakeSimpleWiFi(kDeviceName);
   2204   SetWiFiForService(service, preferred_wifi);
   2205   EXPECT_TRUE(service->Load(&mock_store));
   2206   EXPECT_EQ(preferred_wifi, service->wifi_);
   2207   EXPECT_EQ(kDeviceName, service->preferred_device_);
   2208   service->Unload();
   2209   EXPECT_EQ("", service->preferred_device_);
   2210 }
   2211 
   2212 TEST_F(WiFiServiceTest, ChooseDevice) {
   2213   const string kDeviceName1 = "test_device1";
   2214   const string kDeviceName2 = "test_device2";
   2215   scoped_refptr<MockWiFi> wifi1 = MakeSimpleWiFi(kDeviceName1);
   2216   scoped_refptr<MockWiFi> wifi2 = MakeSimpleWiFi(kDeviceName2);
   2217   WiFiServiceRefPtr service = MakeServiceWithMockManager();
   2218 
   2219   // No preferred device.
   2220   EXPECT_CALL(*mock_manager(), GetEnabledDeviceByLinkName(_)).Times(0);
   2221   EXPECT_CALL(*mock_manager(),
   2222               GetEnabledDeviceWithTechnology(Technology::kWifi))
   2223       .WillOnce(Return(wifi1));
   2224   EXPECT_EQ(wifi1, service->ChooseDevice());
   2225   Mock::VerifyAndClearExpectations(mock_manager());
   2226 
   2227   // With preferred device.
   2228   service->SetPreferredDevice(kDeviceName2, nullptr);
   2229   EXPECT_CALL(*mock_manager(), GetEnabledDeviceByLinkName(kDeviceName2))
   2230       .WillOnce(Return(wifi2));
   2231   EXPECT_CALL(*mock_manager(), GetEnabledDeviceWithTechnology(_)).Times(0);
   2232   EXPECT_EQ(wifi2, service->ChooseDevice());
   2233   Mock::VerifyAndClearExpectations(mock_manager());
   2234 }
   2235 
   2236 TEST_F(WiFiServiceTest, RoamThresholdProperty) {
   2237   WiFiServiceRefPtr service = MakeGenericService();
   2238   static const uint16_t kRoamThreshold16 = 16;
   2239   static const uint16_t kRoamThreshold32 = 32;
   2240 
   2241   EXPECT_TRUE(SetRoamThreshold(service, kRoamThreshold16));
   2242   EXPECT_EQ(GetRoamThreshold(service), kRoamThreshold16);
   2243 
   2244   // Try a different number
   2245   EXPECT_TRUE(SetRoamThreshold(service, kRoamThreshold32));
   2246   EXPECT_EQ(GetRoamThreshold(service), kRoamThreshold32);
   2247 }
   2248 
   2249 TEST_F(WiFiServiceTest, SaveLoadRoamThreshold) {
   2250   WiFiServiceRefPtr service = MakeGenericService();
   2251   NiceMock<MockStore> mock_store;
   2252   const uint16_t kRoamThreshold = 10;
   2253   const string kStorageId = service->GetStorageIdentifier();
   2254   EXPECT_CALL(mock_store, ContainsGroup(StrEq(kStorageId)))
   2255       .WillRepeatedly(Return(true));
   2256   set<string> groups;
   2257   groups.insert(kStorageId);
   2258   EXPECT_CALL(mock_store, GetGroupsWithProperties(ContainsWiFiProperties(
   2259                               simple_ssid(), kModeManaged, kSecurityWep)))
   2260       .WillRepeatedly(Return(groups));
   2261   EXPECT_CALL(mock_store, GetBool(_, _, _)).Times(AnyNumber());
   2262   EXPECT_CALL(mock_store, SetBool(_, _, _)).Times(AnyNumber());
   2263 
   2264   // First, save these values.
   2265   service->roam_threshold_db_ = kRoamThreshold;
   2266   service->roam_threshold_db_set_ = true;
   2267   EXPECT_CALL(mock_store,
   2268               SetUint64(StrEq(kStorageId), WiFiService::kStorageRoamThreshold,
   2269                         kRoamThreshold));
   2270   EXPECT_CALL(mock_store, SetBool(StrEq(kStorageId),
   2271                                   WiFiService::kStorageRoamThresholdSet, true));
   2272   EXPECT_TRUE(service->Save(&mock_store));
   2273 
   2274   // Then, load these values into the WiFiService members.
   2275   service->roam_threshold_db_ = 0;
   2276   service->roam_threshold_db_set_ = false;
   2277   EXPECT_CALL(mock_store, GetUint64(StrEq(kStorageId),
   2278                                     WiFiService::kStorageRoamThreshold, _))
   2279       .WillOnce(DoAll(SetArgumentPointee<2>(kRoamThreshold), Return(true)));
   2280   EXPECT_CALL(mock_store, GetBool(StrEq(kStorageId),
   2281                                   WiFiService::kStorageRoamThresholdSet, _))
   2282       .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)));
   2283   EXPECT_TRUE(service->Load(&mock_store));
   2284   EXPECT_EQ(kRoamThreshold, service->roam_threshold_db_);
   2285   EXPECT_TRUE(service->roam_threshold_db_set_);
   2286 }
   2287 
   2288 }  // namespace shill
   2289