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 ProxyServer proxy_server =
220 ProxyUriToProxyServer(rule.proxy_url, ProxyServer::Scheme::SCHEME_HTTP);
221 if (!proxy_server.is_valid()) {
222 return "Invalid Proxy URL: " + rule.proxy_url;
223 } else if (proxy_server.is_quic()) {
224 return "Unsupported proxy scheme: " + rule.proxy_url;
225 }
226
227 // Parse the URL scheme.
228 if (base::EqualsCaseInsensitiveASCII(rule.url_scheme, "http")) {
229 proxy_rules->proxies_for_http.AddProxyServer(proxy_server);
230 } else if (base::EqualsCaseInsensitiveASCII(rule.url_scheme, "https")) {
231 proxy_rules->proxies_for_https.AddProxyServer(proxy_server);
232 } else if (rule.url_scheme == "*") {
233 proxy_rules->fallback_proxies.AddProxyServer(proxy_server);
234 } else {
235 return "Unsupported URL scheme: " + rule.url_scheme;
236 }
237 }
238
239 // If there is no per-URL scheme distinction simplify the ProxyRules.
240 if (proxy_rules->proxies_for_http.IsEmpty() &&
241 proxy_rules->proxies_for_https.IsEmpty() &&
242 !proxy_rules->fallback_proxies.IsEmpty()) {
243 proxy_rules->type = ProxyConfig::ProxyRules::Type::PROXY_LIST;
244 std::swap(proxy_rules->single_proxies, proxy_rules->fallback_proxies);
245 }
246
247 return "";
248 }
249
CreateOverrideProxyConfig(const std::vector<ProxyConfigServiceAndroid::ProxyOverrideRule> & proxy_rules,const std::vector<std::string> & bypass_rules,const bool reverse_bypass,ProxyConfigWithAnnotation * config)250 std::string CreateOverrideProxyConfig(
251 const std::vector<ProxyConfigServiceAndroid::ProxyOverrideRule>&
252 proxy_rules,
253 const std::vector<std::string>& bypass_rules,
254 const bool reverse_bypass,
255 ProxyConfigWithAnnotation* config) {
256 ProxyConfig proxy_config;
257 auto result = ParseOverrideRules(proxy_rules, &proxy_config.proxy_rules());
258 if (!result.empty()) {
259 return result;
260 }
261
262 proxy_config.proxy_rules().reverse_bypass = reverse_bypass;
263
264 for (const auto& bypass_rule : bypass_rules) {
265 if (!proxy_config.proxy_rules().bypass_rules.AddRuleFromString(
266 bypass_rule)) {
267 return "Invalid bypass rule " + bypass_rule;
268 }
269 }
270 *config = ProxyConfigWithAnnotation(proxy_config, MISSING_TRAFFIC_ANNOTATION);
271 return "";
272 }
273
274 } // namespace
275
276 class ProxyConfigServiceAndroid::Delegate
277 : public base::RefCountedThreadSafe<Delegate> {
278 public:
Delegate(const scoped_refptr<base::SequencedTaskRunner> & main_task_runner,const scoped_refptr<base::SequencedTaskRunner> & jni_task_runner,const GetPropertyCallback & get_property_callback)279 Delegate(const scoped_refptr<base::SequencedTaskRunner>& main_task_runner,
280 const scoped_refptr<base::SequencedTaskRunner>& jni_task_runner,
281 const GetPropertyCallback& get_property_callback)
282 : jni_delegate_(this),
283 main_task_runner_(main_task_runner),
284 jni_task_runner_(jni_task_runner),
285 get_property_callback_(get_property_callback) {}
286
287 Delegate(const Delegate&) = delete;
288 Delegate& operator=(const Delegate&) = delete;
289
SetupJNI()290 void SetupJNI() {
291 DCHECK(InJNISequence());
292 JNIEnv* env = AttachCurrentThread();
293 if (java_proxy_change_listener_.is_null()) {
294 java_proxy_change_listener_.Reset(Java_ProxyChangeListener_create(env));
295 CHECK(!java_proxy_change_listener_.is_null());
296 }
297 Java_ProxyChangeListener_start(env, java_proxy_change_listener_,
298 reinterpret_cast<intptr_t>(&jni_delegate_));
299 }
300
FetchInitialConfig()301 void FetchInitialConfig() {
302 DCHECK(InJNISequence());
303 ProxyConfigWithAnnotation proxy_config;
304 GetLatestProxyConfigInternal(get_property_callback_, &proxy_config);
305 main_task_runner_->PostTask(
306 FROM_HERE, base::BindOnce(&Delegate::SetNewConfigInMainSequence, this,
307 proxy_config));
308 }
309
Shutdown()310 void Shutdown() {
311 if (InJNISequence()) {
312 ShutdownInJNISequence();
313 } else {
314 jni_task_runner_->PostTask(
315 FROM_HERE, base::BindOnce(&Delegate::ShutdownInJNISequence, this));
316 }
317 }
318
319 // Called only in the network sequence.
AddObserver(Observer * observer)320 void AddObserver(Observer* observer) {
321 DCHECK(InMainSequence());
322 observers_.AddObserver(observer);
323 }
324
RemoveObserver(Observer * observer)325 void RemoveObserver(Observer* observer) {
326 DCHECK(InMainSequence());
327 observers_.RemoveObserver(observer);
328 }
329
GetLatestProxyConfig(ProxyConfigWithAnnotation * config)330 ConfigAvailability GetLatestProxyConfig(ProxyConfigWithAnnotation* config) {
331 DCHECK(InMainSequence());
332 if (!config)
333 return ProxyConfigService::CONFIG_UNSET;
334 *config = proxy_config_;
335 return ProxyConfigService::CONFIG_VALID;
336 }
337
338 // Called in the JNI sequence.
ProxySettingsChanged()339 void ProxySettingsChanged() {
340 DCHECK(InJNISequence());
341 if (has_proxy_override_)
342 return;
343
344 ProxyConfigWithAnnotation proxy_config;
345 GetLatestProxyConfigInternal(get_property_callback_, &proxy_config);
346 main_task_runner_->PostTask(
347 FROM_HERE, base::BindOnce(&Delegate::SetNewConfigInMainSequence, this,
348 proxy_config));
349 }
350
351 // Called in the JNI sequence.
ProxySettingsChangedTo(const std::string & host,int port,const std::string & pac_url,const std::vector<std::string> & exclusion_list)352 void ProxySettingsChangedTo(const std::string& host,
353 int port,
354 const std::string& pac_url,
355 const std::vector<std::string>& exclusion_list) {
356 DCHECK(InJNISequence());
357 if (has_proxy_override_)
358 return;
359
360 ProxyConfigWithAnnotation proxy_config;
361 if (exclude_pac_url_) {
362 CreateStaticProxyConfig(host, port, "", exclusion_list, &proxy_config);
363 } else {
364 CreateStaticProxyConfig(host, port, pac_url, exclusion_list,
365 &proxy_config);
366 }
367 main_task_runner_->PostTask(
368 FROM_HERE, base::BindOnce(&Delegate::SetNewConfigInMainSequence, this,
369 proxy_config));
370 }
371
set_exclude_pac_url(bool enabled)372 void set_exclude_pac_url(bool enabled) {
373 exclude_pac_url_ = enabled;
374 }
375
376 // 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)377 std::string SetProxyOverride(
378 const std::vector<ProxyOverrideRule>& proxy_rules,
379 const std::vector<std::string>& bypass_rules,
380 const bool reverse_bypass,
381 base::OnceClosure callback) {
382 DCHECK(InJNISequence());
383 has_proxy_override_ = true;
384
385 // Creates a new proxy config
386 ProxyConfigWithAnnotation proxy_config;
387 std::string result = CreateOverrideProxyConfig(
388 proxy_rules, bypass_rules, reverse_bypass, &proxy_config);
389 if (!result.empty()) {
390 return result;
391 }
392
393 main_task_runner_->PostTaskAndReply(
394 FROM_HERE,
395 base::BindOnce(&Delegate::SetNewConfigInMainSequence, this,
396 proxy_config),
397 std::move(callback));
398
399 return "";
400 }
401
402 // Called in the JNI sequence.
ClearProxyOverride(base::OnceClosure callback)403 void ClearProxyOverride(base::OnceClosure callback) {
404 DCHECK(InJNISequence());
405 if (!has_proxy_override_) {
406 std::move(callback).Run();
407 return;
408 }
409
410 ProxyConfigWithAnnotation proxy_config;
411 GetLatestProxyConfigInternal(get_property_callback_, &proxy_config);
412 main_task_runner_->PostTaskAndReply(
413 FROM_HERE,
414 base::BindOnce(&Delegate::SetNewConfigInMainSequence, this,
415 proxy_config),
416 std::move(callback));
417 has_proxy_override_ = false;
418 }
419
420 private:
421 friend class base::RefCountedThreadSafe<Delegate>;
422
423 class JNIDelegateImpl : public ProxyConfigServiceAndroid::JNIDelegate {
424 public:
JNIDelegateImpl(Delegate * delegate)425 explicit JNIDelegateImpl(Delegate* delegate) : delegate_(delegate) {}
426
427 // 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)428 void ProxySettingsChangedTo(
429 JNIEnv* env,
430 const JavaParamRef<jobject>& jself,
431 const JavaParamRef<jstring>& jhost,
432 jint jport,
433 const JavaParamRef<jstring>& jpac_url,
434 const JavaParamRef<jobjectArray>& jexclusion_list) override {
435 std::string host = ConvertJavaStringToUTF8(env, jhost);
436 std::string pac_url;
437 if (jpac_url)
438 ConvertJavaStringToUTF8(env, jpac_url, &pac_url);
439 std::vector<std::string> exclusion_list;
440 base::android::AppendJavaStringArrayToStringVector(
441 env, jexclusion_list, &exclusion_list);
442 delegate_->ProxySettingsChangedTo(host, jport, pac_url, exclusion_list);
443 }
444
ProxySettingsChanged(JNIEnv * env,const JavaParamRef<jobject> & self)445 void ProxySettingsChanged(JNIEnv* env,
446 const JavaParamRef<jobject>& self) override {
447 delegate_->ProxySettingsChanged();
448 }
449
450 private:
451 const raw_ptr<Delegate> delegate_;
452 };
453
454 virtual ~Delegate() = default;
455
ShutdownInJNISequence()456 void ShutdownInJNISequence() {
457 if (java_proxy_change_listener_.is_null())
458 return;
459 JNIEnv* env = AttachCurrentThread();
460 Java_ProxyChangeListener_stop(env, java_proxy_change_listener_);
461 }
462
463 // Called on the network sequence.
SetNewConfigInMainSequence(const ProxyConfigWithAnnotation & proxy_config)464 void SetNewConfigInMainSequence(
465 const ProxyConfigWithAnnotation& proxy_config) {
466 DCHECK(InMainSequence());
467 proxy_config_ = proxy_config;
468 for (auto& observer : observers_) {
469 observer.OnProxyConfigChanged(proxy_config,
470 ProxyConfigService::CONFIG_VALID);
471 }
472 }
473
InJNISequence() const474 bool InJNISequence() const {
475 return jni_task_runner_->RunsTasksInCurrentSequence();
476 }
477
InMainSequence() const478 bool InMainSequence() const {
479 return main_task_runner_->RunsTasksInCurrentSequence();
480 }
481
482 ScopedJavaGlobalRef<jobject> java_proxy_change_listener_;
483
484 JNIDelegateImpl jni_delegate_;
485 base::ObserverList<Observer>::Unchecked observers_;
486 scoped_refptr<base::SequencedTaskRunner> main_task_runner_;
487 scoped_refptr<base::SequencedTaskRunner> jni_task_runner_;
488 GetPropertyCallback get_property_callback_;
489 ProxyConfigWithAnnotation proxy_config_;
490 bool exclude_pac_url_ = false;
491 // This may only be accessed or modified on the JNI thread
492 bool has_proxy_override_ = false;
493 };
494
ProxyConfigServiceAndroid(const scoped_refptr<base::SequencedTaskRunner> & main_task_runner,const scoped_refptr<base::SequencedTaskRunner> & jni_task_runner)495 ProxyConfigServiceAndroid::ProxyConfigServiceAndroid(
496 const scoped_refptr<base::SequencedTaskRunner>& main_task_runner,
497 const scoped_refptr<base::SequencedTaskRunner>& jni_task_runner)
498 : delegate_(base::MakeRefCounted<Delegate>(
499 main_task_runner,
500 jni_task_runner,
501 base::BindRepeating(&GetJavaProperty))) {
502 delegate_->SetupJNI();
503 delegate_->FetchInitialConfig();
504 }
505
~ProxyConfigServiceAndroid()506 ProxyConfigServiceAndroid::~ProxyConfigServiceAndroid() {
507 delegate_->Shutdown();
508 }
509
set_exclude_pac_url(bool enabled)510 void ProxyConfigServiceAndroid::set_exclude_pac_url(bool enabled) {
511 delegate_->set_exclude_pac_url(enabled);
512 }
513
AddObserver(Observer * observer)514 void ProxyConfigServiceAndroid::AddObserver(Observer* observer) {
515 delegate_->AddObserver(observer);
516 }
517
RemoveObserver(Observer * observer)518 void ProxyConfigServiceAndroid::RemoveObserver(Observer* observer) {
519 delegate_->RemoveObserver(observer);
520 }
521
522 ProxyConfigService::ConfigAvailability
GetLatestProxyConfig(ProxyConfigWithAnnotation * config)523 ProxyConfigServiceAndroid::GetLatestProxyConfig(
524 ProxyConfigWithAnnotation* config) {
525 return delegate_->GetLatestProxyConfig(config);
526 }
527
ProxyConfigServiceAndroid(const scoped_refptr<base::SequencedTaskRunner> & main_task_runner,const scoped_refptr<base::SequencedTaskRunner> & jni_task_runner,GetPropertyCallback get_property_callback)528 ProxyConfigServiceAndroid::ProxyConfigServiceAndroid(
529 const scoped_refptr<base::SequencedTaskRunner>& main_task_runner,
530 const scoped_refptr<base::SequencedTaskRunner>& jni_task_runner,
531 GetPropertyCallback get_property_callback)
532 : delegate_(base::MakeRefCounted<Delegate>(main_task_runner,
533 jni_task_runner,
534 get_property_callback)) {
535 delegate_->SetupJNI();
536 delegate_->FetchInitialConfig();
537 }
538
ProxySettingsChangedTo(const std::string & host,int port,const std::string & pac_url,const std::vector<std::string> & exclusion_list)539 void ProxyConfigServiceAndroid::ProxySettingsChangedTo(
540 const std::string& host,
541 int port,
542 const std::string& pac_url,
543 const std::vector<std::string>& exclusion_list) {
544 delegate_->ProxySettingsChangedTo(host, port, pac_url, exclusion_list);
545 }
546
ProxySettingsChanged()547 void ProxyConfigServiceAndroid::ProxySettingsChanged() {
548 delegate_->ProxySettingsChanged();
549 }
550
SetProxyOverride(const std::vector<ProxyOverrideRule> & proxy_rules,const std::vector<std::string> & bypass_rules,const bool reverse_bypass,base::OnceClosure callback)551 std::string ProxyConfigServiceAndroid::SetProxyOverride(
552 const std::vector<ProxyOverrideRule>& proxy_rules,
553 const std::vector<std::string>& bypass_rules,
554 const bool reverse_bypass,
555 base::OnceClosure callback) {
556 return delegate_->SetProxyOverride(proxy_rules, bypass_rules, reverse_bypass,
557 std::move(callback));
558 }
559
ClearProxyOverride(base::OnceClosure callback)560 void ProxyConfigServiceAndroid::ClearProxyOverride(base::OnceClosure callback) {
561 delegate_->ClearProxyOverride(std::move(callback));
562 }
563
564 } // namespace net
565