| Index: chromeos/network/network_state.cc
|
| diff --git a/chromeos/network/network_state.cc b/chromeos/network/network_state.cc
|
| index bd0f0d7b35910ca2d62047c53976b79ff979397e..62c701907bc9fb63d7953a5511c1cfef45d36638 100644
|
| --- a/chromeos/network/network_state.cc
|
| +++ b/chromeos/network/network_state.cc
|
| @@ -29,6 +29,47 @@ bool ConvertListValueToStringVector(const base::ListValue& string_list,
|
| return true;
|
| }
|
|
|
| +bool IsCaptivePortalState(const base::DictionaryValue& properties, bool log) {
|
| + std::string state;
|
| + properties.GetStringWithoutPathExpansion(shill::kStateProperty, &state);
|
| + if (state != shill::kStatePortal)
|
| + return false;
|
| + std::string portal_detection_phase, portal_detection_status;
|
| + if (!properties.GetStringWithoutPathExpansion(
|
| + shill::kPortalDetectionFailedPhaseProperty,
|
| + &portal_detection_phase) ||
|
| + !properties.GetStringWithoutPathExpansion(
|
| + shill::kPortalDetectionFailedStatusProperty,
|
| + &portal_detection_status)) {
|
| + // If Shill (or a stub) has not set PortalDetectionFailedStatus
|
| + // or PortalDetectionFailedPhase, assume we are in captive portal state.
|
| + return true;
|
| + }
|
| +
|
| + // Shill reports the phase in which it determined that the device is behind a
|
| + // captive portal. We only want to rely only on incorrect content being
|
| + // returned and ignore other reasons.
|
| + bool is_captive_portal =
|
| + portal_detection_phase == shill::kPortalDetectionPhaseContent &&
|
| + portal_detection_status == shill::kPortalDetectionStatusFailure;
|
| +
|
| + if (log) {
|
| + std::string name;
|
| + properties.GetStringWithoutPathExpansion(shill::kNameProperty, &name);
|
| + if (name.empty())
|
| + properties.GetStringWithoutPathExpansion(shill::kSSIDProperty, &name);
|
| + if (!is_captive_portal) {
|
| + NET_LOG(EVENT) << "State is 'portal' but not in captive portal state:"
|
| + << " name=" << name << " phase=" << portal_detection_phase
|
| + << " status=" << portal_detection_status;
|
| + } else {
|
| + NET_LOG(EVENT) << "Network is in captive portal state: " << name;
|
| + }
|
| + }
|
| +
|
| + return is_captive_portal;
|
| +}
|
| +
|
| } // namespace
|
|
|
| namespace chromeos {
|
| @@ -36,8 +77,9 @@ namespace chromeos {
|
| NetworkState::NetworkState(const std::string& path)
|
| : ManagedState(MANAGED_TYPE_NETWORK, path),
|
| visible_(false),
|
| - connectable_(false),
|
| prefix_length_(0),
|
| + connectable_(false),
|
| + is_captive_portal_(false),
|
| signal_strength_(0),
|
| cellular_out_of_credits_(false) {
|
| }
|
| @@ -141,9 +183,13 @@ bool NetworkState::InitialPropertiesReceived(
|
| // SignalStrength > 0.
|
| if ((type() == shill::kTypeWifi || type() == shill::kTypeWimax) &&
|
| visible() && signal_strength_ <= 0) {
|
| - signal_strength_ = 1;
|
| + signal_strength_ = 1;
|
| }
|
|
|
| + // Any change to connection state will trigger a complete property update,
|
| + // so we update is_captive_portal_ here.
|
| + is_captive_portal_ = IsCaptivePortalState(properties, true /* log */);
|
| +
|
| // Ensure that the network has a valid name.
|
| return UpdateName(properties);
|
| }
|
| @@ -182,9 +228,8 @@ void NetworkState::GetStateProperties(base::DictionaryValue* dictionary) const {
|
|
|
| // Mobile properties
|
| if (NetworkTypePattern::Mobile().MatchesType(type())) {
|
| - dictionary->SetStringWithoutPathExpansion(
|
| - shill::kNetworkTechnologyProperty,
|
| - network_technology());
|
| + dictionary->SetStringWithoutPathExpansion(shill::kNetworkTechnologyProperty,
|
| + network_technology());
|
| dictionary->SetStringWithoutPathExpansion(shill::kActivationStateProperty,
|
| activation_state());
|
| dictionary->SetStringWithoutPathExpansion(shill::kRoamingStateProperty,
|
| @@ -196,8 +241,8 @@ void NetworkState::GetStateProperties(base::DictionaryValue* dictionary) const {
|
|
|
| void NetworkState::IPConfigPropertiesChanged(
|
| const base::DictionaryValue& properties) {
|
| - for (base::DictionaryValue::Iterator iter(properties);
|
| - !iter.IsAtEnd(); iter.Advance()) {
|
| + for (base::DictionaryValue::Iterator iter(properties); !iter.IsAtEnd();
|
| + iter.Advance()) {
|
| std::string key = iter.key();
|
| const base::Value& value = iter.value();
|
|
|
| @@ -262,7 +307,7 @@ bool NetworkState::IsInProfile() const {
|
|
|
| bool NetworkState::IsPrivate() const {
|
| return !profile_path_.empty() &&
|
| - profile_path_ != NetworkProfileHandler::GetSharedProfilePath();
|
| + profile_path_ != NetworkProfileHandler::GetSharedProfilePath();
|
| }
|
|
|
| std::string NetworkState::GetDnsServersAsString() const {
|
| @@ -281,7 +326,7 @@ std::string NetworkState::GetNetmask() const {
|
|
|
| std::string NetworkState::GetSpecifier() const {
|
| if (!update_received()) {
|
| - NET_LOG(ERROR) << "GetSpecifier called before update: " << path();
|
| + NET_LOG(ERROR) << "GetSpecifier called before update: " << path();
|
| return std::string();
|
| }
|
| if (type() == shill::kTypeWifi)
|
| @@ -320,6 +365,12 @@ bool NetworkState::StateIsConnecting(const std::string& connection_state) {
|
| }
|
|
|
| // static
|
| +bool NetworkState::NetworkStateIsCaptivePortal(
|
| + const base::DictionaryValue& shill_properties) {
|
| + return IsCaptivePortalState(shill_properties, false /* log */);
|
| +}
|
| +
|
| +// static
|
| bool NetworkState::ErrorIsValid(const std::string& error) {
|
| // Shill uses "Unknown" to indicate an unset or cleared error state.
|
| return !error.empty() && error != kErrorUnknown;
|
|
|