1 // Copyright 2023 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 package org.chromium.net.impl; 6 7 import static org.chromium.net.impl.HttpEngineNativeProvider.EXT_API_LEVEL; 8 import static org.chromium.net.impl.HttpEngineNativeProvider.EXT_VERSION; 9 10 import android.net.Network; 11 import android.net.http.HttpEngine; 12 13 import androidx.annotation.RequiresExtension; 14 15 import org.chromium.net.ExperimentalCronetEngine; 16 17 import java.io.IOException; 18 import java.net.Proxy; 19 import java.net.URL; 20 import java.net.URLConnection; 21 import java.net.URLStreamHandlerFactory; 22 import java.util.concurrent.Executor; 23 24 @RequiresExtension(extension = EXT_API_LEVEL, version = EXT_VERSION) 25 class AndroidHttpEngineWrapper extends ExperimentalCronetEngine { 26 private final HttpEngine mBackend; 27 AndroidHttpEngineWrapper(HttpEngine backend)28 public AndroidHttpEngineWrapper(HttpEngine backend) { 29 this.mBackend = backend; 30 } 31 32 @Override getVersionString()33 public String getVersionString() { 34 return HttpEngine.getVersionString(); 35 } 36 37 @Override shutdown()38 public void shutdown() { 39 mBackend.shutdown(); 40 } 41 42 @Override startNetLogToFile(String fileName, boolean logAll)43 public void startNetLogToFile(String fileName, boolean logAll) { 44 // TODO(danstahr): Hidden API access 45 } 46 47 @Override stopNetLog()48 public void stopNetLog() { 49 // TODO(danstahr): Hidden API access 50 } 51 52 @Override getGlobalMetricsDeltas()53 public byte[] getGlobalMetricsDeltas() { 54 // TODO(danstahr): Hidden API access 55 return new byte[0]; 56 } 57 58 @Override bindToNetwork(long networkHandle)59 public void bindToNetwork(long networkHandle) { 60 // Network#fromNetworkHandle throws IAE if networkHandle does not translate to a valid 61 // Network. Though, this can only happen if we're given a fake networkHandle (in which case 62 // we will throw, which is fine). 63 Network network = 64 networkHandle == UNBIND_NETWORK_HANDLE 65 ? null 66 : Network.fromNetworkHandle(networkHandle); 67 mBackend.bindToNetwork(network); 68 } 69 70 @Override openConnection(URL url)71 public URLConnection openConnection(URL url) throws IOException { 72 return CronetExceptionTranslationUtils.executeTranslatingCronetExceptions( 73 () -> mBackend.openConnection(url), IOException.class); 74 } 75 76 @Override openConnection(URL url, Proxy proxy)77 public URLConnection openConnection(URL url, Proxy proxy) throws IOException { 78 // HttpEngine doesn't expose an openConnection(URL, Proxy) method. To maintain compatibility 79 // copy-paste CronetUrlRequestContext's logic here. 80 if (proxy.type() != Proxy.Type.DIRECT) { 81 throw new UnsupportedOperationException(); 82 } 83 String protocol = url.getProtocol(); 84 if ("http".equals(protocol) || "https".equals(protocol)) { 85 return openConnection(url); 86 } 87 throw new UnsupportedOperationException("Unexpected protocol:" + protocol); 88 } 89 90 @Override createURLStreamHandlerFactory()91 public URLStreamHandlerFactory createURLStreamHandlerFactory() { 92 return mBackend.createUrlStreamHandlerFactory(); 93 } 94 95 @Override newBidirectionalStreamBuilder( String url, org.chromium.net.BidirectionalStream.Callback callback, Executor executor)96 public org.chromium.net.ExperimentalBidirectionalStream.Builder newBidirectionalStreamBuilder( 97 String url, org.chromium.net.BidirectionalStream.Callback callback, Executor executor) { 98 return new AndroidBidirectionalStreamBuilderWrapper( 99 mBackend.newBidirectionalStreamBuilder( 100 url, executor, new AndroidBidirectionalStreamCallbackWrapper(callback))); 101 } 102 103 @Override newUrlRequestBuilder( String url, org.chromium.net.UrlRequest.Callback callback, Executor executor)104 public org.chromium.net.ExperimentalUrlRequest.Builder newUrlRequestBuilder( 105 String url, org.chromium.net.UrlRequest.Callback callback, Executor executor) { 106 return new AndroidUrlRequestBuilderWrapper( 107 mBackend.newUrlRequestBuilder( 108 url, executor, new AndroidUrlRequestCallbackWrapper(callback))); 109 } 110 } 111