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