Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chromeos / network / host_resolver_impl_chromeos.cc
blob05def379adddbe158d979dcf8392ac5dcfe17942
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromeos/network/host_resolver_impl_chromeos.h"
7 #include "base/location.h"
8 #include "base/single_thread_task_runner.h"
9 #include "base/sys_info.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "base/values.h"
12 #include "chromeos/network/device_state.h"
13 #include "chromeos/network/network_handler.h"
14 #include "chromeos/network/network_state.h"
15 #include "chromeos/network/network_state_handler.h"
16 #include "chromeos/network/network_state_handler_observer.h"
17 #include "net/base/address_list.h"
18 #include "net/base/net_errors.h"
19 #include "net/base/net_util.h"
20 #include "third_party/cros_system_api/dbus/service_constants.h"
22 namespace chromeos {
24 // HostResolverImplChromeOS::NetworkStateHandlerObserver
26 // An instance of this class is created on the NetworkHandler (UI) thread and
27 // manages its own lifetime, destroying itself when NetworkStateHandlerObserver
28 // ::IsShuttingDown() gets called.
30 class HostResolverImplChromeOS::NetworkObserver
31 : public chromeos::NetworkStateHandlerObserver {
32 public:
33 static void Create(
34 const base::WeakPtr<HostResolverImplChromeOS>& resolver,
35 scoped_refptr<base::SingleThreadTaskRunner> resolver_task_runner,
36 NetworkStateHandler* network_state_handler) {
37 new NetworkObserver(resolver, resolver_task_runner, network_state_handler);
40 NetworkObserver(
41 const base::WeakPtr<HostResolverImplChromeOS>& resolver,
42 scoped_refptr<base::SingleThreadTaskRunner> resolver_task_runner,
43 NetworkStateHandler* network_state_handler)
44 : resolver_(resolver),
45 resolver_task_runner_(resolver_task_runner),
46 network_state_handler_(network_state_handler),
47 weak_ptr_factory_resolver_thread_(this) {
48 network_state_handler_->AddObserver(this, FROM_HERE);
49 DefaultNetworkChanged(network_state_handler_->DefaultNetwork());
52 private:
53 ~NetworkObserver() override {
54 network_state_handler_->RemoveObserver(this, FROM_HERE);
57 // NetworkStateHandlerObserver
58 void DefaultNetworkChanged(const NetworkState* network) override {
59 if (!network) {
60 DVLOG(2) << "DefaultNetworkChanged: No Network.";
61 CallResolverSetIpAddress("", "");
62 return;
64 std::string ipv4_address, ipv6_address;
65 const DeviceState* device_state =
66 network_state_handler_->GetDeviceState(network->device_path());
67 if (!device_state) {
68 LOG_IF(ERROR, base::SysInfo::IsRunningOnChromeOS())
69 << "DefaultNetworkChanged: Network missing device: "
70 << network->path();
71 CallResolverSetIpAddress("", "");
72 return;
74 for (base::DictionaryValue::Iterator iter(device_state->ip_configs());
75 !iter.IsAtEnd(); iter.Advance()) {
76 const base::DictionaryValue* ip_config;
77 if (!iter.value().GetAsDictionary(&ip_config)) {
78 LOG(ERROR) << "Badly formatted IPConfigs: " << network->path();
79 continue;
81 std::string method, address;
82 if (ip_config->GetString(shill::kMethodProperty, &method) &&
83 ip_config->GetString(shill::kAddressProperty, &address)) {
84 if (method == shill::kTypeIPv4 || method == shill::kTypeDHCP)
85 ipv4_address = address;
86 else if (method == shill::kTypeIPv6 || method == shill::kTypeDHCP6)
87 ipv6_address = address;
88 } else {
89 LOG(ERROR) << "DefaultNetworkChanged: IPConfigs missing properties: "
90 << network->path();
93 DVLOG(2) << "DefaultNetworkChanged: " << network->name()
94 << " IPv4: " << ipv4_address << " IPv6: " << ipv6_address;
95 CallResolverSetIpAddress(ipv4_address, ipv6_address);
98 void IsShuttingDown() override { delete this; }
100 void CallResolverSetIpAddress(const std::string& ipv4_address,
101 const std::string& ipv6_address) {
102 resolver_task_runner_->PostTask(
103 FROM_HERE, base::Bind(&NetworkObserver::SetIpAddressOnResolverThread,
104 weak_ptr_factory_resolver_thread_.GetWeakPtr(),
105 ipv4_address, ipv6_address));
108 void SetIpAddressOnResolverThread(const std::string& ipv4_address,
109 const std::string& ipv6_address) {
110 if (resolver_)
111 resolver_->SetIPAddresses(ipv4_address, ipv6_address);
114 base::WeakPtr<HostResolverImplChromeOS> resolver_;
115 scoped_refptr<base::SingleThreadTaskRunner> resolver_task_runner_;
116 NetworkStateHandler* network_state_handler_;
117 base::WeakPtrFactory<NetworkObserver> weak_ptr_factory_resolver_thread_;
119 DISALLOW_COPY_AND_ASSIGN(NetworkObserver);
122 // HostResolverImplChromeOS
124 HostResolverImplChromeOS::HostResolverImplChromeOS(
125 scoped_refptr<base::SingleThreadTaskRunner> network_handler_task_runner,
126 NetworkStateHandler* network_state_handler,
127 const Options& options,
128 net::NetLog* net_log)
129 : HostResolverImpl(options, net_log),
130 network_handler_task_runner_(network_handler_task_runner),
131 weak_ptr_factory_(this) {
132 network_handler_task_runner->PostTask(
133 FROM_HERE,
134 base::Bind(&NetworkObserver::Create, weak_ptr_factory_.GetWeakPtr(),
135 base::ThreadTaskRunnerHandle::Get(), network_state_handler));
138 HostResolverImplChromeOS::~HostResolverImplChromeOS() {
141 int HostResolverImplChromeOS::Resolve(const RequestInfo& info,
142 net::RequestPriority priority,
143 net::AddressList* addresses,
144 const net::CompletionCallback& callback,
145 RequestHandle* out_req,
146 const net::BoundNetLog& source_net_log) {
147 DCHECK(thread_checker_.CalledOnValidThread());
148 if (ResolveLocalIPAddress(info, addresses))
149 return net::OK;
150 return net::HostResolverImpl::Resolve(
151 info, priority, addresses, callback, out_req, source_net_log);
154 void HostResolverImplChromeOS::SetIPAddresses(const std::string& ipv4_address,
155 const std::string& ipv6_address) {
156 DCHECK(thread_checker_.CalledOnValidThread());
157 ipv4_address_ = ipv4_address;
158 ipv6_address_ = ipv6_address;
161 bool HostResolverImplChromeOS::ResolveLocalIPAddress(
162 const RequestInfo& info,
163 net::AddressList* addresses) {
164 DCHECK(thread_checker_.CalledOnValidThread());
165 if (!info.is_my_ip_address() || ipv4_address_.empty())
166 return false;
168 // Use IPConfig data for localhost address lookup.
169 addresses->clear();
171 if (info.address_family() != net::ADDRESS_FAMILY_IPV4 &&
172 !ipv6_address_.empty()) {
173 net::IPAddressNumber ipv6;
174 if (net::ParseIPLiteralToNumber(ipv6_address_, &ipv6))
175 addresses->push_back(net::IPEndPoint(ipv6, 0));
178 net::IPAddressNumber ipv4;
179 if (net::ParseIPLiteralToNumber(ipv4_address_, &ipv4))
180 addresses->push_back(net::IPEndPoint(ipv4, 0));
182 DVLOG(2) << "ResolveLocalIPAddress("
183 << static_cast<int>(info.address_family()) << "): "
184 << addresses->size()
185 << " IPv4: " << ipv4_address_ << " IPv6: " << ipv6_address_;
186 addresses->SetDefaultCanonicalName();
187 return true;
190 // static
191 scoped_ptr<net::HostResolver> HostResolverImplChromeOS::CreateSystemResolver(
192 const Options& options,
193 net::NetLog* net_log) {
194 return scoped_ptr<net::HostResolver>(new HostResolverImplChromeOS(
195 NetworkHandler::Get()->task_runner(),
196 NetworkHandler::Get()->network_state_handler(), options, net_log));
199 // static
200 scoped_ptr<net::HostResolver>
201 HostResolverImplChromeOS::CreateHostResolverForTest(
202 scoped_refptr<base::SingleThreadTaskRunner> network_handler_task_runner,
203 NetworkStateHandler* network_state_handler) {
204 Options options;
205 return scoped_ptr<net::HostResolver>(new HostResolverImplChromeOS(
206 network_handler_task_runner, network_state_handler, options, NULL));
209 } // namespace chromeos