• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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