xref: /aosp_15_r20/external/cronet/net/proxy_resolution/proxy_config_service_android.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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