1 /* 2 * Copyright 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.webkit; 18 19 import androidx.annotation.AnyThread; 20 import androidx.annotation.RequiresFeature; 21 import androidx.annotation.RestrictTo; 22 import androidx.webkit.internal.ProxyControllerImpl; 23 24 import org.jspecify.annotations.NonNull; 25 26 import java.util.concurrent.Executor; 27 28 /** 29 * Manages setting and clearing a process-specific override for the Android system-wide proxy 30 * settings that govern network requests made by {@link android.webkit.WebView}. 31 * <p> 32 * WebView may make network requests in order to fetch content that is not otherwise read from 33 * the file system or provided directly by application code. In this case by default the 34 * system-wide Android network proxy settings are used to redirect requests to appropriate proxy 35 * servers. 36 * <p> 37 * In the rare case that it is necessary for an application to explicitly specify its proxy 38 * configuration, this API may be used to explicitly specify the proxy rules that govern WebView 39 * initiated network requests. 40 * 41 * <p> 42 * Example usage: 43 * <pre class="prettyprint"> 44 * ProxyConfig proxyConfig = new ProxyConfig.Builder().addProxyRule("myproxy.com") 45 * .addBypassRule("www.excluded.*") 46 * .build(); 47 * Executor executor = ... 48 * Runnable listener = ... 49 * ProxyController.getInstance().setProxyOverride(proxyConfig, executor, listener); 50 * ... 51 * ProxyController.getInstance().clearProxyOverride(executor, listener); 52 * </pre> 53 */ 54 @AnyThread 55 public abstract class ProxyController { 56 /** 57 */ 58 @RestrictTo(RestrictTo.Scope.LIBRARY) ProxyController()59 public ProxyController() {} 60 61 /** 62 * Returns the {@link ProxyController} instance. 63 * 64 * <p> 65 * This method should only be called if {@link WebViewFeature#isFeatureSupported(String)} 66 * returns {@code true} for {@link WebViewFeature#PROXY_OVERRIDE}. 67 */ 68 @RequiresFeature(name = WebViewFeature.PROXY_OVERRIDE, 69 enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported") getInstance()70 public static @NonNull ProxyController getInstance() { 71 if (!WebViewFeature.isFeatureSupported(WebViewFeature.PROXY_OVERRIDE)) { 72 throw new UnsupportedOperationException("Proxy override not supported"); 73 } 74 return LAZY_HOLDER.INSTANCE; 75 } 76 77 private static class LAZY_HOLDER { 78 static final ProxyController INSTANCE = new ProxyControllerImpl(); 79 } 80 81 /** 82 * Sets {@link ProxyConfig} which will be used by all WebViews in the app. URLs that match 83 * patterns in the bypass list will not be directed to any proxy. Instead, the request will be 84 * made directly to the origin specified by the URL. Network connections are not guaranteed to 85 * immediately use the new proxy setting; wait for the listener before loading a page. This 86 * listener will be called in the provided executor. 87 * 88 * <p class="note"><b>Note:</b> calling setProxyOverride will cause any existing system wide 89 * setting to be ignored. 90 * 91 * @param proxyConfig Proxy config to be applied 92 * @param executor Executor for the listener to be executed in 93 * @param listener Listener called when the proxy setting change has been applied 94 * 95 * @throws IllegalArgumentException If the proxyConfig is invalid 96 */ setProxyOverride(@onNull ProxyConfig proxyConfig, @NonNull Executor executor, @NonNull Runnable listener)97 public abstract void setProxyOverride(@NonNull ProxyConfig proxyConfig, 98 @NonNull Executor executor, @NonNull Runnable listener); 99 100 /** 101 * Clears the proxy settings. Network connections are not guaranteed to immediately use the 102 * new proxy setting; wait for the listener before loading a page. This listener will be called 103 * in the provided executor. 104 * 105 * @param executor Executor for the listener to be executed in 106 * @param listener Listener called when the proxy setting change has been applied 107 */ clearProxyOverride(@onNull Executor executor, @NonNull Runnable listener)108 public abstract void clearProxyOverride(@NonNull Executor executor, 109 @NonNull Runnable listener); 110 } 111