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