shill_property_util.cc revision 010d83a9304c5a91596085d917d248abff47903a
158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// found in the LICENSE file.
458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chromeos/network/shill_property_util.h"
658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/i18n/icu_encoding_detection.h"
858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/i18n/icu_string_conversions.h"
958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/json/json_writer.h"
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/strings/string_util.h"
1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/strings/stringprintf.h"
1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/strings/utf_string_conversion_utils.h"
1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/values.h"
1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chromeos/network/network_event_log.h"
1658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chromeos/network/network_ui_data.h"
1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chromeos/network/onc/onc_utils.h"
1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace chromeos {
2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace shill_property_util {
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace {
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Replace non UTF8 characters in |str| with a replacement character.
2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)std::string ValidateUTF8(const std::string& str) {
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::string result;
2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (int32 index = 0; index < static_cast<int32>(str.size()); ++index) {
3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    uint32 code_point_out;
3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool is_unicode_char = base::ReadUnicodeCharacter(
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        str.c_str(), str.size(), &index, &code_point_out);
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const uint32 kFirstNonControlChar = 0x20;
3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (is_unicode_char && (code_point_out >= kFirstNonControlChar)) {
3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::WriteUnicodeCharacter(code_point_out, &result);
3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    } else {
3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      const uint32 kReplacementChar = 0xFFFD;
3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // Puts kReplacementChar if character is a control character [0,0x20)
3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // or is not readable UTF8.
4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::WriteUnicodeCharacter(kReplacementChar, &result);
4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return result;
4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// If existent and non-empty, copies the string at |key| from |source| to
4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// |dest|. Returns true if the string was copied.
4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool CopyStringFromDictionary(const base::DictionaryValue& source,
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              const std::string& key,
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              base::DictionaryValue* dest) {
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::string string_value;
5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!source.GetStringWithoutPathExpansion(key, &string_value) ||
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      string_value.empty())
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  dest->SetStringWithoutPathExpansion(key, string_value);
5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return true;
5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace
6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void SetSSID(const std::string ssid, base::DictionaryValue* properties) {
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string hex_ssid = base::HexEncode(ssid.c_str(), ssid.size());
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  properties->SetStringWithoutPathExpansion(shill::kWifiHexSsid, hex_ssid);
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)std::string GetSSIDFromProperties(const base::DictionaryValue& properties,
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                  bool* unknown_encoding) {
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (unknown_encoding)
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    *unknown_encoding = false;
704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string hex_ssid;
7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  properties.GetStringWithoutPathExpansion(shill::kWifiHexSsid, &hex_ssid);
7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (hex_ssid.empty()) {
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NET_LOG_ERROR("GetSSIDFromProperties", "No HexSSID set.");
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return std::string();
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::string ssid;
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::vector<uint8> raw_ssid_bytes;
8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (base::HexStringToBytes(hex_ssid, &raw_ssid_bytes)) {
8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ssid = std::string(raw_ssid_bytes.begin(), raw_ssid_bytes.end());
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NET_LOG_DEBUG(
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        "GetSSIDFromProperties",
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        base::StringPrintf("%s, SSID: %s", hex_ssid.c_str(), ssid.c_str()));
8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  } else {
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NET_LOG_ERROR("GetSSIDFromProperties",
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                  base::StringPrintf("Error processing: %s", hex_ssid.c_str()));
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return std::string();
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (base::IsStringUTF8(ssid))
9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return ssid;
9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Detect encoding and convert to UTF-8.
9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::string encoding;
9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!base::DetectEncoding(ssid, &encoding)) {
9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // TODO(stevenjb): This is currently experimental. If we find a case where
9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // base::DetectEncoding() fails, we need to figure out whether we can use
9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // country_code with ConvertToUtf8(). crbug.com/233267.
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    properties.GetStringWithoutPathExpansion(shill::kCountryProperty,
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                             &encoding);
10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string utf8_ssid;
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!encoding.empty() &&
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::ConvertToUtf8AndNormalize(ssid, encoding, &utf8_ssid)) {
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (utf8_ssid != ssid) {
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      NET_LOG_DEBUG(
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          "GetSSIDFromProperties",
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          base::StringPrintf(
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Encoding=%s: %s", encoding.c_str(), utf8_ssid.c_str()));
11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return utf8_ssid;
11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (unknown_encoding)
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    *unknown_encoding = true;
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NET_LOG_DEBUG(
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      "GetSSIDFromProperties",
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::StringPrintf("Unrecognized Encoding=%s", encoding.c_str()));
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return ssid;
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
123effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochstd::string GetNetworkIdFromProperties(
124effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const base::DictionaryValue& properties) {
125effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (properties.empty())
126effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return "EmptyProperties";
127effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::string result;
128effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (properties.GetStringWithoutPathExpansion(shill::kGuidProperty, &result))
129effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return result;
130effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (properties.GetStringWithoutPathExpansion(shill::kSSIDProperty, &result))
131effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return result;
132effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (properties.GetStringWithoutPathExpansion(shill::kNameProperty, &result))
133effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return result;
134effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::string type = "UnknownType";
135effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  properties.GetStringWithoutPathExpansion(shill::kTypeProperty, &type);
136effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return "Unidentified " + type;
137effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
138effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)std::string GetNameFromProperties(const std::string& service_path,
1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                  const base::DictionaryValue& properties) {
1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string name;
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  properties.GetStringWithoutPathExpansion(shill::kNameProperty, &name);
1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string validated_name = ValidateUTF8(name);
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (validated_name != name) {
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NET_LOG_DEBUG("GetNameFromProperties",
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                  base::StringPrintf("Validated name %s: UTF8: %s",
1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                     service_path.c_str(),
1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                     validated_name.c_str()));
1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string type;
1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  properties.GetStringWithoutPathExpansion(shill::kTypeProperty, &type);
154effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (type.empty()) {
155effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    NET_LOG_ERROR("GetNameFromProperties: No type", service_path);
156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return validated_name;
157effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!NetworkTypePattern::WiFi().MatchesType(type))
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return validated_name;
1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool unknown_ssid_encoding = false;
1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string ssid = GetSSIDFromProperties(properties, &unknown_ssid_encoding);
1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (ssid.empty())
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NET_LOG_ERROR("GetNameFromProperties", "No SSID set: " + service_path);
1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Use |validated_name| if |ssid| is empty.
1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // And if the encoding of the SSID is unknown, use |ssid|, which contains raw
1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // bytes in that case, only if |validated_name| is empty.
1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (ssid.empty() || (unknown_ssid_encoding && !validated_name.empty()))
1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return validated_name;
1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (ssid != validated_name) {
1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NET_LOG_DEBUG("GetNameFromProperties",
1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                  base::StringPrintf("%s: SSID: %s, Name: %s",
1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                     service_path.c_str(),
1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                     ssid.c_str(),
1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                     validated_name.c_str()));
1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return ssid;
18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)scoped_ptr<NetworkUIData> GetUIDataFromValue(const base::Value& ui_data_value) {
18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::string ui_data_str;
18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!ui_data_value.GetAsString(&ui_data_str))
18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return scoped_ptr<NetworkUIData>();
18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (ui_data_str.empty())
18758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return make_scoped_ptr(new NetworkUIData());
18858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> ui_data_dict(
18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      chromeos::onc::ReadDictionaryFromJson(ui_data_str));
19058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!ui_data_dict)
19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return scoped_ptr<NetworkUIData>();
19258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return make_scoped_ptr(new NetworkUIData(*ui_data_dict));
19358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
19458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
19558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)scoped_ptr<NetworkUIData> GetUIDataFromProperties(
19658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const base::DictionaryValue& shill_dictionary) {
19758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const base::Value* ui_data_value = NULL;
19868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  shill_dictionary.GetWithoutPathExpansion(shill::kUIDataProperty,
19958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                           &ui_data_value);
20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!ui_data_value) {
20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    VLOG(2) << "Dictionary has no UIData entry.";
20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return scoped_ptr<NetworkUIData>();
20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<NetworkUIData> ui_data = GetUIDataFromValue(*ui_data_value);
20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!ui_data)
20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    LOG(ERROR) << "UIData is not a valid JSON dictionary.";
20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return ui_data.Pass();
20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void SetUIData(const NetworkUIData& ui_data,
21158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)               base::DictionaryValue* shill_dictionary) {
21258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::DictionaryValue ui_data_dict;
21358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ui_data.FillDictionary(&ui_data_dict);
21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::string ui_data_blob;
21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::JSONWriter::Write(&ui_data_dict, &ui_data_blob);
21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  shill_dictionary->SetStringWithoutPathExpansion(shill::kUIDataProperty,
21758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                  ui_data_blob);
21858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
21958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool CopyIdentifyingProperties(const base::DictionaryValue& service_properties,
22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                               base::DictionaryValue* dest) {
22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool success = true;
22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // GUID is optional.
22568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  CopyStringFromDictionary(service_properties, shill::kGuidProperty, dest);
22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::string type;
22868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  service_properties.GetStringWithoutPathExpansion(shill::kTypeProperty, &type);
22958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  success &= !type.empty();
23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  dest->SetStringWithoutPathExpansion(shill::kTypeProperty, type);
23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (type == shill::kTypeWifi) {
23258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    success &= CopyStringFromDictionary(
23368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        service_properties, shill::kSecurityProperty, dest);
2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    success &=
2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        CopyStringFromDictionary(service_properties, shill::kWifiHexSsid, dest);
23658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    success &= CopyStringFromDictionary(
23768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        service_properties, shill::kModeProperty, dest);
23868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  } else if (type == shill::kTypeVPN) {
23958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    success &= CopyStringFromDictionary(
24068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        service_properties, shill::kNameProperty, dest);
24158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // VPN Provider values are read from the "Provider" dictionary, but written
24258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // with the keys "Provider.Type" and "Provider.Host".
24358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const base::DictionaryValue* provider_properties = NULL;
24458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!service_properties.GetDictionaryWithoutPathExpansion(
245effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch            shill::kProviderProperty, &provider_properties)) {
246effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      NET_LOG_ERROR("Missing VPN provider dict",
247effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                    GetNetworkIdFromProperties(service_properties));
24858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return false;
24958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    std::string vpn_provider_type;
25168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    provider_properties->GetStringWithoutPathExpansion(shill::kTypeProperty,
25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                       &vpn_provider_type);
25358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    success &= !vpn_provider_type.empty();
25468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    dest->SetStringWithoutPathExpansion(shill::kProviderTypeProperty,
25558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                        vpn_provider_type);
25658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
25758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    std::string vpn_provider_host;
25868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    provider_properties->GetStringWithoutPathExpansion(shill::kHostProperty,
25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                       &vpn_provider_host);
26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    success &= !vpn_provider_host.empty();
26168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    dest->SetStringWithoutPathExpansion(shill::kProviderHostProperty,
26258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                        vpn_provider_host);
26368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  } else if (type == shill::kTypeEthernet || type == shill::kTypeEthernetEap) {
26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Ethernet and EthernetEAP don't have any additional identifying
26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // properties.
26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  } else {
26758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    NOTREACHED() << "Unsupported network type " << type;
26858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    success = false;
26958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
270effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!success) {
271effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    NET_LOG_ERROR("Missing required properties",
272effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                  GetNetworkIdFromProperties(service_properties));
273effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
27458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return success;
27558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
27658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool DoIdentifyingPropertiesMatch(const base::DictionaryValue& properties_a,
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                  const base::DictionaryValue& properties_b) {
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::DictionaryValue identifying_a;
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!CopyIdentifyingProperties(properties_a, &identifying_a))
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::DictionaryValue identifying_b;
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!CopyIdentifyingProperties(properties_b, &identifying_b))
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return identifying_a.Equals(&identifying_b);
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
289effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool IsPassphraseKey(const std::string& key) {
290effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return key == shill::kEapPrivateKeyPasswordProperty ||
291effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      key == shill::kEapPasswordProperty ||
292effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      key == shill::kL2tpIpsecPasswordProperty ||
293effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      key == shill::kOpenVPNPasswordProperty ||
294effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      key == shill::kOpenVPNAuthUserPassProperty ||
295effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      key == shill::kOpenVPNTLSAuthContentsProperty ||
296effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      key == shill::kPassphraseProperty ||
297effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      key == shill::kOpenVPNOTPProperty ||
298effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      key == shill::kEapPrivateKeyProperty ||
299effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      key == shill::kEapPinProperty ||
300effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      key == shill::kApnPasswordProperty;
301effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
302effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
30358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace shill_property_util
30458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
30558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace {
30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kPatternDefault[] = "PatternDefault";
30858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kPatternEthernet[] = "PatternEthernet";
30958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kPatternWireless[] = "PatternWireless";
31058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kPatternMobile[] = "PatternMobile";
31158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kPatternNonVirtual[] = "PatternNonVirtual";
31258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
31358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)enum NetworkTypeBitFlag {
31458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  kNetworkTypeNone = 0,
31558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  kNetworkTypeEthernet = 1 << 0,
31658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  kNetworkTypeWifi = 1 << 1,
31758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  kNetworkTypeWimax = 1 << 2,
31858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  kNetworkTypeCellular = 1 << 3,
31958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  kNetworkTypeVPN = 1 << 4,
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  kNetworkTypeEthernetEap = 1 << 5,
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  kNetworkTypeBluetooth = 1 << 6
32258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
32358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
32458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)struct ShillToBitFlagEntry {
32558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const char* shill_network_type;
32658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  NetworkTypeBitFlag bit_flag;
32758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} shill_type_to_flag[] = {
32868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  { shill::kTypeEthernet, kNetworkTypeEthernet },
32958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  { shill::kTypeEthernetEap, kNetworkTypeEthernetEap },
33068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  { shill::kTypeWifi, kNetworkTypeWifi },
33168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  { shill::kTypeWimax, kNetworkTypeWimax },
33268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  { shill::kTypeCellular, kNetworkTypeCellular },
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  { shill::kTypeVPN, kNetworkTypeVPN },
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  { shill::kTypeBluetooth, kNetworkTypeBluetooth }
33558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
33658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
33758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)NetworkTypeBitFlag ShillNetworkTypeToFlag(const std::string& shill_type) {
33858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (size_t i = 0; i < arraysize(shill_type_to_flag); ++i) {
33958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (shill_type_to_flag[i].shill_network_type == shill_type)
34058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return shill_type_to_flag[i].bit_flag;
34158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
34258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  NET_LOG_ERROR("ShillNetworkTypeToFlag", "Unknown type: " + shill_type);
34358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return kNetworkTypeNone;
34458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
34558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
34658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace
34758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
34858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// static
34958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)NetworkTypePattern NetworkTypePattern::Default() {
35058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return NetworkTypePattern(~0);
35158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
35258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
35358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// static
35458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)NetworkTypePattern NetworkTypePattern::Wireless() {
35558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return NetworkTypePattern(kNetworkTypeWifi | kNetworkTypeWimax |
35658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                            kNetworkTypeCellular);
35758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
35858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
35958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// static
36058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)NetworkTypePattern NetworkTypePattern::Mobile() {
36158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return NetworkTypePattern(kNetworkTypeCellular | kNetworkTypeWimax);
36258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
36358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
36458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// static
36558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)NetworkTypePattern NetworkTypePattern::NonVirtual() {
36658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return NetworkTypePattern(~kNetworkTypeVPN);
36758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
36858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
36958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// static
37058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)NetworkTypePattern NetworkTypePattern::Ethernet() {
37158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return NetworkTypePattern(kNetworkTypeEthernet);
37258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
37358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
37458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// static
37558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)NetworkTypePattern NetworkTypePattern::WiFi() {
37658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return NetworkTypePattern(kNetworkTypeWifi);
37758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
37858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
37958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// static
38058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)NetworkTypePattern NetworkTypePattern::Cellular() {
38158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return NetworkTypePattern(kNetworkTypeCellular);
38258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
38358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
38458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// static
38558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)NetworkTypePattern NetworkTypePattern::VPN() {
38658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return NetworkTypePattern(kNetworkTypeVPN);
38758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
38858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
38958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// static
39058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)NetworkTypePattern NetworkTypePattern::Wimax() {
39158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return NetworkTypePattern(kNetworkTypeWimax);
39258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
39358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
39458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// static
39558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)NetworkTypePattern NetworkTypePattern::Primitive(
39658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& shill_network_type) {
39758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return NetworkTypePattern(ShillNetworkTypeToFlag(shill_network_type));
39858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
39958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
40058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool NetworkTypePattern::Equals(const NetworkTypePattern& other) const {
40158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return pattern_ == other.pattern_;
40258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
40358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
40458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool NetworkTypePattern::MatchesType(
40558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& shill_network_type) const {
40658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return MatchesPattern(Primitive(shill_network_type));
40758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
40858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
40958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool NetworkTypePattern::MatchesPattern(
41058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const NetworkTypePattern& other_pattern) const {
41158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (Equals(other_pattern))
41258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return true;
41358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
41458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return pattern_ & other_pattern.pattern_;
41558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
41658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
41758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)std::string NetworkTypePattern::ToDebugString() const {
41858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (Equals(Default()))
41958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return kPatternDefault;
42058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (Equals(Ethernet()))
42158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return kPatternEthernet;
42258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (Equals(Wireless()))
42358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return kPatternWireless;
42458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (Equals(Mobile()))
42558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return kPatternMobile;
42658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (Equals(NonVirtual()))
42758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return kPatternNonVirtual;
42858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
42958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::string str;
43058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (size_t i = 0; i < arraysize(shill_type_to_flag); ++i) {
43158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!(pattern_ & shill_type_to_flag[i].bit_flag))
43258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      continue;
43358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!str.empty())
43458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      str += "|";
43558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    str += shill_type_to_flag[i].shill_network_type;
43658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
43758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return str;
43858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
43958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
44058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)NetworkTypePattern::NetworkTypePattern(int pattern) : pattern_(pattern) {}
44158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
44258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace chromeos
443