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