1 // Copyright (c) 2012 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.
4
5 #include "net/proxy_resolution/proxy_config_service_android.h"
6
7 #include <sys/system_properties.h>
8
9 #include "base/android/jni_array.h"
10 #include "base/android/jni_string.h"
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "base/compiler_specific.h"
14 #include "base/location.h"
15 #include "base/logging.h"
16 #include "base/macros.h"
17 #include "base/memory/ref_counted.h"
18 #include "base/observer_list.h"
19 #include "base/sequenced_task_runner.h"
20 #include "base/strings/string_tokenizer.h"
21 #include "base/strings/string_util.h"
22 #include "base/strings/stringprintf.h"
23 #include "net/base/host_port_pair.h"
24 #include "net/net_jni_headers/ProxyChangeListener_jni.h"
25 #include "net/proxy_resolution/proxy_config_with_annotation.h"
26 #include "url/third_party/mozilla/url_parse.h"
27
28 using base::android::AttachCurrentThread;
29 using base::android::ConvertUTF8ToJavaString;
30 using base::android::ConvertJavaStringToUTF8;
31 using base::android::CheckException;
32 using base::android::ClearException;
33 using base::android::JavaParamRef;
34 using base::android::ScopedJavaGlobalRef;
35 using base::android::ScopedJavaLocalRef;
36
37 namespace net {
38
39 namespace {
40
41 typedef ProxyConfigServiceAndroid::GetPropertyCallback GetPropertyCallback;
42
43 // Returns whether the provided string was successfully converted to a port.
ConvertStringToPort(const std::string & port,int * output)44 bool ConvertStringToPort(const std::string& port, int* output) {
45 url::Component component(0, port.size());
46 int result = url::ParsePort(port.c_str(), component);
47 if (result == url::PORT_INVALID || result == url::PORT_UNSPECIFIED)
48 return false;
49 *output = result;
50 return true;
51 }
52
ConstructProxyServer(ProxyServer::Scheme scheme,const std::string & proxy_host,const std::string & proxy_port)53 ProxyServer ConstructProxyServer(ProxyServer::Scheme scheme,
54 const std::string& proxy_host,
55 const std::string& proxy_port) {
56 DCHECK(!proxy_host.empty());
57 int port_as_int = 0;
58 if (proxy_port.empty())
59 port_as_int = ProxyServer::GetDefaultPortForScheme(scheme);
60 else if (!ConvertStringToPort(proxy_port, &port_as_int))
61 return ProxyServer();
62 DCHECK(port_as_int > 0);
63 return ProxyServer(
64 scheme, HostPortPair(proxy_host, static_cast<uint16_t>(port_as_int)));
65 }
66
LookupProxy(const std::string & prefix,const GetPropertyCallback & get_property,ProxyServer::Scheme scheme)67 ProxyServer LookupProxy(const std::string& prefix,
68 const GetPropertyCallback& get_property,
69 ProxyServer::Scheme scheme) {
70 DCHECK(!prefix.empty());
71 std::string proxy_host = get_property.Run(prefix + ".proxyHost");
72 if (!proxy_host.empty()) {
73 std::string proxy_port = get_property.Run(prefix + ".proxyPort");
74 return ConstructProxyServer(scheme, proxy_host, proxy_port);
75 }
76 // Fall back to default proxy, if any.
77 proxy_host = get_property.Run("proxyHost");
78 if (!proxy_host.empty()) {
79 std::string proxy_port = get_property.Run("proxyPort");
80 return ConstructProxyServer(scheme, proxy_host, proxy_port);
81 }
82 return ProxyServer();
83 }
84
LookupSocksProxy(const GetPropertyCallback & get_property)85 ProxyServer LookupSocksProxy(const GetPropertyCallback& get_property) {
86 std::string proxy_host = get_property.Run("socksProxyHost");
87 if (!proxy_host.empty()) {
88 std::string proxy_port = get_property.Run("socksProxyPort");
89 return ConstructProxyServer(ProxyServer::SCHEME_SOCKS5, proxy_host,
90 proxy_port);
91 }
92 return ProxyServer();
93 }
94
AddBypassRules(const std::string & scheme,const GetPropertyCallback & get_property,ProxyBypassRules * bypass_rules)95 void AddBypassRules(const std::string& scheme,
96 const GetPropertyCallback& get_property,
97 ProxyBypassRules* bypass_rules) {
98 // The format of a hostname pattern is a list of hostnames that are separated
99 // by | and that use * as a wildcard. For example, setting the
100 // http.nonProxyHosts property to *.android.com|*.kernel.org will cause
101 // requests to http://developer.android.com to be made without a proxy.
102
103 std::string non_proxy_hosts =
104 get_property.Run(scheme + ".nonProxyHosts");
105 if (non_proxy_hosts.empty())
106 return;
107 base::StringTokenizer tokenizer(non_proxy_hosts, "|");
108 while (tokenizer.GetNext()) {
109 std::string token = tokenizer.token();
110 std::string pattern;
111 base::TrimWhitespaceASCII(token, base::TRIM_ALL, &pattern);
112 if (pattern.empty())
113 continue;
114 // '?' is not one of the specified pattern characters above.
115 DCHECK_EQ(std::string::npos, pattern.find('?'));
116 bypass_rules->AddRuleFromString(scheme + "://" + pattern);
117 }
118 }
119
120 // Returns true if a valid proxy was found.
GetProxyRules(const GetPropertyCallback & get_property,ProxyConfig::ProxyRules * rules)121 bool GetProxyRules(const GetPropertyCallback& get_property,
122 ProxyConfig::ProxyRules* rules) {
123 // See libcore/luni/src/main/java/java/net/ProxySelectorImpl.java for the
124 // mostly equivalent Android implementation. There is one intentional
125 // difference: by default Chromium uses the HTTP port (80) for HTTPS
126 // connections via proxy. This default is identical on other platforms.
127 // On the opposite, Java spec suggests to use HTTPS port (443) by default (the
128 // default value of https.proxyPort).
129 rules->type = ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME;
130 rules->proxies_for_http.SetSingleProxyServer(
131 LookupProxy("http", get_property, ProxyServer::SCHEME_HTTP));
132 rules->proxies_for_https.SetSingleProxyServer(
133 LookupProxy("https", get_property, ProxyServer::SCHEME_HTTP));
134 rules->proxies_for_ftp.SetSingleProxyServer(
135 LookupProxy("ftp", get_property, ProxyServer::SCHEME_HTTP));
136 rules->fallback_proxies.SetSingleProxyServer(LookupSocksProxy(get_property));
137 rules->bypass_rules.Clear();
138 AddBypassRules("ftp", get_property, &rules->bypass_rules);
139 AddBypassRules("http", get_property, &rules->bypass_rules);
140 AddBypassRules("https", get_property, &rules->bypass_rules);
141 // We know a proxy was found if not all of the proxy lists are empty.
142 return !(rules->proxies_for_http.IsEmpty() &&
143 rules->proxies_for_https.IsEmpty() &&
144 rules->proxies_for_ftp.IsEmpty() &&
145 rules->fallback_proxies.IsEmpty());
146 }
147
GetLatestProxyConfigInternal(const GetPropertyCallback & get_property,ProxyConfigWithAnnotation * config)148 void GetLatestProxyConfigInternal(const GetPropertyCallback& get_property,
149 ProxyConfigWithAnnotation* config) {
150 ProxyConfig proxy_config;
151 if (GetProxyRules(get_property, &proxy_config.proxy_rules())) {
152 *config =
153 ProxyConfigWithAnnotation(proxy_config, NO_TRAFFIC_ANNOTATION_YET);
154 } else {
155 *config = ProxyConfigWithAnnotation::CreateDirect();
156 }
157 }
158
GetJavaProperty(const std::string & property)159 std::string GetJavaProperty(const std::string& property) {
160 // Use Java System.getProperty to get configuration information.
161 // TODO(pliard): Conversion to/from UTF8 ok here?
162 JNIEnv* env = AttachCurrentThread();
163 ScopedJavaLocalRef<jstring> str = ConvertUTF8ToJavaString(env, property);
164 ScopedJavaLocalRef<jstring> result =
165 Java_ProxyChangeListener_getProperty(env, str);
166 return result.is_null() ?
167 std::string() : ConvertJavaStringToUTF8(env, result.obj());
168 }
169
CreateStaticProxyConfig(const std::string & host,int port,const std::string & pac_url,const std::vector<std::string> & exclusion_list,ProxyConfigWithAnnotation * config)170 void CreateStaticProxyConfig(const std::string& host,
171 int port,
172 const std::string& pac_url,
173 const std::vector<std::string>& exclusion_list,
174 ProxyConfigWithAnnotation* config) {
175 ProxyConfig proxy_config;
176 if (!pac_url.empty()) {
177 proxy_config.set_pac_url(GURL(pac_url));
178 proxy_config.set_pac_mandatory(false);
179 *config =
180 ProxyConfigWithAnnotation(proxy_config, NO_TRAFFIC_ANNOTATION_YET);
181 } else if (port != 0) {
182 std::string rules = base::StringPrintf("%s:%d", host.c_str(), port);
183 proxy_config.proxy_rules().ParseFromString(rules);
184 proxy_config.proxy_rules().bypass_rules.Clear();
185
186 std::vector<std::string>::const_iterator it;
187 for (it = exclusion_list.begin(); it != exclusion_list.end(); ++it) {
188 std::string pattern;
189 base::TrimWhitespaceASCII(*it, base::TRIM_ALL, &pattern);
190 if (pattern.empty())
191 continue;
192 proxy_config.proxy_rules().bypass_rules.AddRuleFromString(pattern);
193 }
194 *config =
195 ProxyConfigWithAnnotation(proxy_config, NO_TRAFFIC_ANNOTATION_YET);
196 } else {
197 *config = ProxyConfigWithAnnotation::CreateDirect();
198 }
199 }
200
ParseOverrideRules(const std::vector<ProxyConfigServiceAndroid::ProxyOverrideRule> & override_rules,ProxyConfig::ProxyRules * proxy_rules)201 std::string ParseOverrideRules(
202 const std::vector<ProxyConfigServiceAndroid::ProxyOverrideRule>&
203 override_rules,
204 ProxyConfig::ProxyRules* proxy_rules) {
205 // If no rules were specified, use DIRECT for everything.
206 if (override_rules.empty()) {
207 DCHECK(proxy_rules->empty());
208 return "";
209 }
210
211 // Otherwise use a proxy list per URL scheme.
212 proxy_rules->type = ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME;
213
214 for (const auto& rule : override_rules) {
215 // Parse the proxy URL.
216 ProxyServer proxy_server =
217 ProxyServer::FromURI(rule.proxy_url, ProxyServer::Scheme::SCHEME_HTTP);
218 if (!proxy_server.is_valid()) {
219 return "Invalid Proxy URL: " + rule.proxy_url;
220 } else if (proxy_server.is_quic()) {
221 return "Unsupported proxy scheme: " + rule.proxy_url;
222 }
223
224 // Parse the URL scheme.
225 if (base::EqualsCaseInsensitiveASCII(rule.url_scheme, "http")) {
226 proxy_rules->proxies_for_http.AddProxyServer(proxy_server);
227 } else if (base::EqualsCaseInsensitiveASCII(rule.url_scheme, "https")) {
228 proxy_rules->proxies_for_https.AddProxyServer(proxy_server);
229 } else if (rule.url_scheme == "*") {
230 proxy_rules->fallback_proxies.AddProxyServer(proxy_server);
231 } else {
232 return "Unsupported URL scheme: " + rule.url_scheme;
233 }
234 }
235
236 // If there is no per-URL scheme distinction simplify the ProxyRules.
237 if (proxy_rules->proxies_for_http.IsEmpty() &&
238 proxy_rules->proxies_for_https.IsEmpty() &&
239 !proxy_rules->fallback_proxies.IsEmpty()) {
240 proxy_rules->type = ProxyConfig::ProxyRules::Type::PROXY_LIST;
241 std::swap(proxy_rules->single_proxies, proxy_rules->fallback_proxies);
242 }
243
244 return "";
245 }
246
CreateOverrideProxyConfig(const std::vector<ProxyConfigServiceAndroid::ProxyOverrideRule> & proxy_rules,const std::vector<std::string> & bypass_rules,ProxyConfigWithAnnotation * config)247 std::string CreateOverrideProxyConfig(
248 const std::vector<ProxyConfigServiceAndroid::ProxyOverrideRule>&
249 proxy_rules,
250 const std::vector<std::string>& bypass_rules,
251 ProxyConfigWithAnnotation* config) {
252 ProxyConfig proxy_config;
253 auto result = ParseOverrideRules(proxy_rules, &proxy_config.proxy_rules());
254 if (!result.empty()) {
255 return result;
256 }
257
258 for (const auto& bypass_rule : bypass_rules) {
259 if (!proxy_config.proxy_rules().bypass_rules.AddRuleFromString(
260 bypass_rule)) {
261 return "Invalid bypass rule " + bypass_rule;
262 }
263 }
264 *config = ProxyConfigWithAnnotation(proxy_config, NO_TRAFFIC_ANNOTATION_YET);
265 return "";
266 }
267
268 } // namespace
269
270 class ProxyConfigServiceAndroid::Delegate
271 : public base::RefCountedThreadSafe<Delegate> {
272 public:
Delegate(const scoped_refptr<base::SequencedTaskRunner> & main_task_runner,const scoped_refptr<base::SequencedTaskRunner> & jni_task_runner,const GetPropertyCallback & get_property_callback)273 Delegate(const scoped_refptr<base::SequencedTaskRunner>& main_task_runner,
274 const scoped_refptr<base::SequencedTaskRunner>& jni_task_runner,
275 const GetPropertyCallback& get_property_callback)
276 : jni_delegate_(this),
277 main_task_runner_(main_task_runner),
278 jni_task_runner_(jni_task_runner),
279 get_property_callback_(get_property_callback),
280 exclude_pac_url_(false),
281 has_proxy_override_(false) {}
282
SetupJNI()283 void SetupJNI() {
284 DCHECK(InJNISequence());
285 JNIEnv* env = AttachCurrentThread();
286 if (java_proxy_change_listener_.is_null()) {
287 java_proxy_change_listener_.Reset(Java_ProxyChangeListener_create(env));
288 CHECK(!java_proxy_change_listener_.is_null());
289 }
290 Java_ProxyChangeListener_start(env, java_proxy_change_listener_,
291 reinterpret_cast<intptr_t>(&jni_delegate_));
292 }
293
FetchInitialConfig()294 void FetchInitialConfig() {
295 DCHECK(InJNISequence());
296 ProxyConfigWithAnnotation proxy_config;
297 GetLatestProxyConfigInternal(get_property_callback_, &proxy_config);
298 main_task_runner_->PostTask(
299 FROM_HERE, base::BindOnce(&Delegate::SetNewConfigInMainSequence, this,
300 proxy_config));
301 }
302
Shutdown()303 void Shutdown() {
304 if (InJNISequence()) {
305 ShutdownInJNISequence();
306 } else {
307 jni_task_runner_->PostTask(
308 FROM_HERE, base::BindOnce(&Delegate::ShutdownInJNISequence, this));
309 }
310 }
311
312 // Called only in the network sequence.
AddObserver(Observer * observer)313 void AddObserver(Observer* observer) {
314 DCHECK(InMainSequence());
315 observers_.AddObserver(observer);
316 }
317
RemoveObserver(Observer * observer)318 void RemoveObserver(Observer* observer) {
319 DCHECK(InMainSequence());
320 observers_.RemoveObserver(observer);
321 }
322
GetLatestProxyConfig(ProxyConfigWithAnnotation * config)323 ConfigAvailability GetLatestProxyConfig(ProxyConfigWithAnnotation* config) {
324 DCHECK(InMainSequence());
325 if (!config)
326 return ProxyConfigService::CONFIG_UNSET;
327 *config = proxy_config_;
328 return ProxyConfigService::CONFIG_VALID;
329 }
330
331 // Called in the JNI sequence.
ProxySettingsChanged()332 void ProxySettingsChanged() {
333 DCHECK(InJNISequence());
334 if (has_proxy_override_)
335 return;
336
337 ProxyConfigWithAnnotation proxy_config;
338 GetLatestProxyConfigInternal(get_property_callback_, &proxy_config);
339 main_task_runner_->PostTask(
340 FROM_HERE, base::BindOnce(&Delegate::SetNewConfigInMainSequence, this,
341 proxy_config));
342 }
343
344 // Called in the JNI sequence.
ProxySettingsChangedTo(const std::string & host,int port,const std::string & pac_url,const std::vector<std::string> & exclusion_list)345 void ProxySettingsChangedTo(const std::string& host,
346 int port,
347 const std::string& pac_url,
348 const std::vector<std::string>& exclusion_list) {
349 DCHECK(InJNISequence());
350 if (has_proxy_override_)
351 return;
352
353 ProxyConfigWithAnnotation proxy_config;
354 if (exclude_pac_url_) {
355 CreateStaticProxyConfig(host, port, "", exclusion_list, &proxy_config);
356 } else {
357 CreateStaticProxyConfig(host, port, pac_url, exclusion_list,
358 &proxy_config);
359 }
360 main_task_runner_->PostTask(
361 FROM_HERE, base::BindOnce(&Delegate::SetNewConfigInMainSequence, this,
362 proxy_config));
363 }
364
set_exclude_pac_url(bool enabled)365 void set_exclude_pac_url(bool enabled) {
366 exclude_pac_url_ = enabled;
367 }
368
369 // Called in the JNI sequence.
SetProxyOverride(const std::vector<ProxyOverrideRule> & proxy_rules,const std::vector<std::string> & bypass_rules,base::OnceClosure callback)370 std::string SetProxyOverride(
371 const std::vector<ProxyOverrideRule>& proxy_rules,
372 const std::vector<std::string>& bypass_rules,
373 base::OnceClosure callback) {
374 DCHECK(InJNISequence());
375 has_proxy_override_ = true;
376
377 // Creates a new proxy config
378 ProxyConfigWithAnnotation proxy_config;
379 std::string result =
380 CreateOverrideProxyConfig(proxy_rules, bypass_rules, &proxy_config);
381 if (!result.empty()) {
382 return result;
383 }
384
385 main_task_runner_->PostTaskAndReply(
386 FROM_HERE,
387 base::BindOnce(&Delegate::SetNewConfigInMainSequence, this,
388 proxy_config),
389 std::move(callback));
390
391 return "";
392 }
393
394 // Called in the JNI sequence.
ClearProxyOverride(base::OnceClosure callback)395 void ClearProxyOverride(base::OnceClosure callback) {
396 DCHECK(InJNISequence());
397 if (!has_proxy_override_) {
398 std::move(callback).Run();
399 return;
400 }
401
402 ProxyConfigWithAnnotation proxy_config;
403 GetLatestProxyConfigInternal(get_property_callback_, &proxy_config);
404 main_task_runner_->PostTaskAndReply(
405 FROM_HERE,
406 base::BindOnce(&Delegate::SetNewConfigInMainSequence, this,
407 proxy_config),
408 std::move(callback));
409 has_proxy_override_ = false;
410 }
411
412 private:
413 friend class base::RefCountedThreadSafe<Delegate>;
414
415 class JNIDelegateImpl : public ProxyConfigServiceAndroid::JNIDelegate {
416 public:
JNIDelegateImpl(Delegate * delegate)417 explicit JNIDelegateImpl(Delegate* delegate) : delegate_(delegate) {}
418
419 // ProxyConfigServiceAndroid::JNIDelegate overrides.
ProxySettingsChangedTo(JNIEnv * env,const JavaParamRef<jobject> & jself,const JavaParamRef<jstring> & jhost,jint jport,const JavaParamRef<jstring> & jpac_url,const JavaParamRef<jobjectArray> & jexclusion_list)420 void ProxySettingsChangedTo(
421 JNIEnv* env,
422 const JavaParamRef<jobject>& jself,
423 const JavaParamRef<jstring>& jhost,
424 jint jport,
425 const JavaParamRef<jstring>& jpac_url,
426 const JavaParamRef<jobjectArray>& jexclusion_list) override {
427 std::string host = ConvertJavaStringToUTF8(env, jhost);
428 std::string pac_url;
429 if (jpac_url)
430 ConvertJavaStringToUTF8(env, jpac_url, &pac_url);
431 std::vector<std::string> exclusion_list;
432 base::android::AppendJavaStringArrayToStringVector(
433 env, jexclusion_list, &exclusion_list);
434 delegate_->ProxySettingsChangedTo(host, jport, pac_url, exclusion_list);
435 }
436
ProxySettingsChanged(JNIEnv * env,const JavaParamRef<jobject> & self)437 void ProxySettingsChanged(JNIEnv* env,
438 const JavaParamRef<jobject>& self) override {
439 delegate_->ProxySettingsChanged();
440 }
441
442 private:
443 Delegate* const delegate_;
444 };
445
~Delegate()446 virtual ~Delegate() {}
447
ShutdownInJNISequence()448 void ShutdownInJNISequence() {
449 if (java_proxy_change_listener_.is_null())
450 return;
451 JNIEnv* env = AttachCurrentThread();
452 Java_ProxyChangeListener_stop(env, java_proxy_change_listener_);
453 }
454
455 // Called on the network sequence.
SetNewConfigInMainSequence(const ProxyConfigWithAnnotation & proxy_config)456 void SetNewConfigInMainSequence(
457 const ProxyConfigWithAnnotation& proxy_config) {
458 DCHECK(InMainSequence());
459 proxy_config_ = proxy_config;
460 for (auto& observer : observers_) {
461 observer.OnProxyConfigChanged(proxy_config,
462 ProxyConfigService::CONFIG_VALID);
463 }
464 }
465
InJNISequence() const466 bool InJNISequence() const {
467 return jni_task_runner_->RunsTasksInCurrentSequence();
468 }
469
InMainSequence() const470 bool InMainSequence() const {
471 return main_task_runner_->RunsTasksInCurrentSequence();
472 }
473
474 ScopedJavaGlobalRef<jobject> java_proxy_change_listener_;
475
476 JNIDelegateImpl jni_delegate_;
477 base::ObserverList<Observer>::Unchecked observers_;
478 scoped_refptr<base::SequencedTaskRunner> main_task_runner_;
479 scoped_refptr<base::SequencedTaskRunner> jni_task_runner_;
480 GetPropertyCallback get_property_callback_;
481 ProxyConfigWithAnnotation proxy_config_;
482 bool exclude_pac_url_;
483 // This may only be accessed or modified on the JNI thread
484 bool has_proxy_override_;
485
486 DISALLOW_COPY_AND_ASSIGN(Delegate);
487 };
488
ProxyConfigServiceAndroid(const scoped_refptr<base::SequencedTaskRunner> & main_task_runner,const scoped_refptr<base::SequencedTaskRunner> & jni_task_runner)489 ProxyConfigServiceAndroid::ProxyConfigServiceAndroid(
490 const scoped_refptr<base::SequencedTaskRunner>& main_task_runner,
491 const scoped_refptr<base::SequencedTaskRunner>& jni_task_runner)
492 : delegate_(new Delegate(main_task_runner,
493 jni_task_runner,
494 base::BindRepeating(&GetJavaProperty))) {
495 delegate_->SetupJNI();
496 delegate_->FetchInitialConfig();
497 }
498
~ProxyConfigServiceAndroid()499 ProxyConfigServiceAndroid::~ProxyConfigServiceAndroid() {
500 delegate_->Shutdown();
501 }
502
set_exclude_pac_url(bool enabled)503 void ProxyConfigServiceAndroid::set_exclude_pac_url(bool enabled) {
504 delegate_->set_exclude_pac_url(enabled);
505 }
506
AddObserver(Observer * observer)507 void ProxyConfigServiceAndroid::AddObserver(Observer* observer) {
508 delegate_->AddObserver(observer);
509 }
510
RemoveObserver(Observer * observer)511 void ProxyConfigServiceAndroid::RemoveObserver(Observer* observer) {
512 delegate_->RemoveObserver(observer);
513 }
514
515 ProxyConfigService::ConfigAvailability
GetLatestProxyConfig(ProxyConfigWithAnnotation * config)516 ProxyConfigServiceAndroid::GetLatestProxyConfig(
517 ProxyConfigWithAnnotation* config) {
518 return delegate_->GetLatestProxyConfig(config);
519 }
520
ProxyConfigServiceAndroid(const scoped_refptr<base::SequencedTaskRunner> & main_task_runner,const scoped_refptr<base::SequencedTaskRunner> & jni_task_runner,GetPropertyCallback get_property_callback)521 ProxyConfigServiceAndroid::ProxyConfigServiceAndroid(
522 const scoped_refptr<base::SequencedTaskRunner>& main_task_runner,
523 const scoped_refptr<base::SequencedTaskRunner>& jni_task_runner,
524 GetPropertyCallback get_property_callback)
525 : delegate_(new Delegate(main_task_runner,
526 jni_task_runner,
527 get_property_callback)) {
528 delegate_->SetupJNI();
529 delegate_->FetchInitialConfig();
530 }
531
ProxySettingsChangedTo(const std::string & host,int port,const std::string & pac_url,const std::vector<std::string> & exclusion_list)532 void ProxyConfigServiceAndroid::ProxySettingsChangedTo(
533 const std::string& host,
534 int port,
535 const std::string& pac_url,
536 const std::vector<std::string>& exclusion_list) {
537 delegate_->ProxySettingsChangedTo(host, port, pac_url, exclusion_list);
538 }
539
ProxySettingsChanged()540 void ProxyConfigServiceAndroid::ProxySettingsChanged() {
541 delegate_->ProxySettingsChanged();
542 }
543
SetProxyOverride(const std::vector<ProxyOverrideRule> & proxy_rules,const std::vector<std::string> & bypass_rules,base::OnceClosure callback)544 std::string ProxyConfigServiceAndroid::SetProxyOverride(
545 const std::vector<ProxyOverrideRule>& proxy_rules,
546 const std::vector<std::string>& bypass_rules,
547 base::OnceClosure callback) {
548 return delegate_->SetProxyOverride(proxy_rules, bypass_rules,
549 std::move(callback));
550 }
551
ClearProxyOverride(base::OnceClosure callback)552 void ProxyConfigServiceAndroid::ClearProxyOverride(base::OnceClosure callback) {
553 delegate_->ClearProxyOverride(std::move(callback));
554 }
555
556 } // namespace net
557