| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.net; | 5 package org.chromium.net.impl; |
| 6 | 6 |
| 7 import android.content.Context; | 7 import android.content.Context; |
| 8 import android.os.Build; | 8 import android.os.Build; |
| 9 import android.os.ConditionVariable; | 9 import android.os.ConditionVariable; |
| 10 import android.os.Handler; | 10 import android.os.Handler; |
| 11 import android.os.Looper; | 11 import android.os.Looper; |
| 12 import android.os.Process; | 12 import android.os.Process; |
| 13 import android.util.Log; | 13 import android.util.Log; |
| 14 | 14 |
| 15 import org.chromium.base.ObserverList; | 15 import org.chromium.base.ObserverList; |
| 16 import org.chromium.base.VisibleForTesting; | 16 import org.chromium.base.VisibleForTesting; |
| 17 import org.chromium.base.annotations.CalledByNative; | 17 import org.chromium.base.annotations.CalledByNative; |
| 18 import org.chromium.base.annotations.JNINamespace; | 18 import org.chromium.base.annotations.JNINamespace; |
| 19 import org.chromium.base.annotations.NativeClassQualifiedName; | 19 import org.chromium.base.annotations.NativeClassQualifiedName; |
| 20 import org.chromium.base.annotations.UsedByReflection; | 20 import org.chromium.base.annotations.UsedByReflection; |
| 21 import org.chromium.net.BidirectionalStream; |
| 22 import org.chromium.net.CronetEngine; |
| 23 import org.chromium.net.NetworkQualityRttListener; |
| 24 import org.chromium.net.NetworkQualityThroughputListener; |
| 25 import org.chromium.net.UrlRequest; |
| 21 import org.chromium.net.urlconnection.CronetHttpURLConnection; | 26 import org.chromium.net.urlconnection.CronetHttpURLConnection; |
| 22 import org.chromium.net.urlconnection.CronetURLStreamHandlerFactory; | 27 import org.chromium.net.urlconnection.CronetURLStreamHandlerFactory; |
| 23 | 28 |
| 24 import java.net.Proxy; | 29 import java.net.Proxy; |
| 25 import java.net.URL; | 30 import java.net.URL; |
| 26 import java.net.URLConnection; | 31 import java.net.URLConnection; |
| 27 import java.net.URLStreamHandlerFactory; | 32 import java.net.URLStreamHandlerFactory; |
| 28 import java.util.Collection; | 33 import java.util.Collection; |
| 29 import java.util.List; | 34 import java.util.List; |
| 30 import java.util.Map; | 35 import java.util.Map; |
| 31 import java.util.concurrent.Executor; | 36 import java.util.concurrent.Executor; |
| 32 import java.util.concurrent.RejectedExecutionException; | 37 import java.util.concurrent.RejectedExecutionException; |
| 33 import java.util.concurrent.atomic.AtomicInteger; | 38 import java.util.concurrent.atomic.AtomicInteger; |
| 34 | 39 |
| 35 import javax.annotation.concurrent.GuardedBy; | 40 import javax.annotation.concurrent.GuardedBy; |
| 36 | 41 |
| 37 /** | 42 /** |
| 38 * CronetEngine using Chromium HTTP stack implementation. | 43 * CronetEngine using Chromium HTTP stack implementation. |
| 39 */ | 44 */ |
| 40 @JNINamespace("cronet") | 45 @JNINamespace("cronet") |
| 41 @UsedByReflection("CronetEngine.java") | 46 @UsedByReflection("CronetEngine.java") |
| 42 class CronetUrlRequestContext extends CronetEngine { | 47 @VisibleForTesting |
| 43 private static final int LOG_NONE = 3; // LOG(FATAL), no VLOG. | 48 public class CronetUrlRequestContext extends CronetEngine { |
| 44 private static final int LOG_DEBUG = -1; // LOG(FATAL...INFO), VLOG(1) | 49 private static final int LOG_NONE = 3; // LOG(FATAL), no VLOG. |
| 45 private static final int LOG_VERBOSE = -2; // LOG(FATAL...INFO), VLOG(2) | 50 private static final int LOG_DEBUG = -1; // LOG(FATAL...INFO), VLOG(1) |
| 51 private static final int LOG_VERBOSE = -2; // LOG(FATAL...INFO), VLOG(2) |
| 46 static final String LOG_TAG = "ChromiumNetwork"; | 52 static final String LOG_TAG = "ChromiumNetwork"; |
| 47 | 53 |
| 48 /** | 54 /** |
| 49 * Synchronize access to mUrlRequestContextAdapter and shutdown routine. | 55 * Synchronize access to mUrlRequestContextAdapter and shutdown routine. |
| 50 */ | 56 */ |
| 51 private final Object mLock = new Object(); | 57 private final Object mLock = new Object(); |
| 52 private final ConditionVariable mInitCompleted = new ConditionVariable(false
); | 58 private final ConditionVariable mInitCompleted = new ConditionVariable(false
); |
| 53 private final AtomicInteger mActiveRequestCount = new AtomicInteger(0); | 59 private final AtomicInteger mActiveRequestCount = new AtomicInteger(0); |
| 54 | 60 |
| 55 private long mUrlRequestContextAdapter = 0; | 61 private long mUrlRequestContextAdapter = 0; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 } | 116 } |
| 111 }; | 117 }; |
| 112 // Run task immediately or post it to the UI thread. | 118 // Run task immediately or post it to the UI thread. |
| 113 if (Looper.getMainLooper() == Looper.myLooper()) { | 119 if (Looper.getMainLooper() == Looper.myLooper()) { |
| 114 task.run(); | 120 task.run(); |
| 115 } else { | 121 } else { |
| 116 new Handler(Looper.getMainLooper()).post(task); | 122 new Handler(Looper.getMainLooper()).post(task); |
| 117 } | 123 } |
| 118 } | 124 } |
| 119 | 125 |
| 120 static long createNativeUrlRequestContextConfig( | 126 @VisibleForTesting |
| 127 public static long createNativeUrlRequestContextConfig( |
| 121 final Context context, CronetEngine.Builder builder) { | 128 final Context context, CronetEngine.Builder builder) { |
| 122 final long urlRequestContextConfig = nativeCreateRequestContextConfig( | 129 final long urlRequestContextConfig = nativeCreateRequestContextConfig( |
| 123 builder.getUserAgent(), builder.storagePath(), builder.quicEnabl
ed(), | 130 builder.getUserAgent(), builder.storagePath(), builder.quicEnabl
ed(), |
| 124 builder.getDefaultQuicUserAgentId(context), builder.http2Enabled
(), | 131 builder.getDefaultQuicUserAgentId(context), builder.http2Enabled
(), |
| 125 builder.sdchEnabled(), builder.dataReductionProxyKey(), | 132 builder.sdchEnabled(), builder.dataReductionProxyKey(), |
| 126 builder.dataReductionProxyPrimaryProxy(), builder.dataReductionP
roxyFallbackProxy(), | 133 builder.dataReductionProxyPrimaryProxy(), builder.dataReductionP
roxyFallbackProxy(), |
| 127 builder.dataReductionProxySecureProxyCheckUrl(), builder.cacheDi
sabled(), | 134 builder.dataReductionProxySecureProxyCheckUrl(), builder.cacheDi
sabled(), |
| 128 builder.httpCacheMode(), builder.httpCacheMaxSize(), builder.exp
erimentalOptions(), | 135 builder.httpCacheMode(), builder.httpCacheMaxSize(), builder.exp
erimentalOptions(), |
| 129 builder.mockCertVerifier(), builder.networkQualityEstimatorEnabl
ed(), | 136 builder.mockCertVerifier(), builder.networkQualityEstimatorEnabl
ed(), |
| 130 builder.publicKeyPinningBypassForLocalTrustAnchorsEnabled(), | 137 builder.publicKeyPinningBypassForLocalTrustAnchorsEnabled(), |
| (...skipping 20 matching lines...) Expand all Loading... |
| 151 synchronized (mNetworkQualityLock) { | 158 synchronized (mNetworkQualityLock) { |
| 152 metricsCollectionEnabled = !mFinishedListenerList.isEmpty(); | 159 metricsCollectionEnabled = !mFinishedListenerList.isEmpty(); |
| 153 } | 160 } |
| 154 } | 161 } |
| 155 return new CronetUrlRequest(this, url, priority, callback, executor,
requestAnnotations, | 162 return new CronetUrlRequest(this, url, priority, callback, executor,
requestAnnotations, |
| 156 metricsCollectionEnabled, disableCache, disableConnectionMig
ration); | 163 metricsCollectionEnabled, disableCache, disableConnectionMig
ration); |
| 157 } | 164 } |
| 158 } | 165 } |
| 159 | 166 |
| 160 @Override | 167 @Override |
| 161 BidirectionalStream createBidirectionalStream(String url, BidirectionalStrea
m.Callback callback, | 168 public BidirectionalStream createBidirectionalStream(String url, |
| 162 Executor executor, String httpMethod, List<Map.Entry<String, String>
> requestHeaders, | 169 BidirectionalStream.Callback callback, Executor executor, String htt
pMethod, |
| 170 List<Map.Entry<String, String>> requestHeaders, |
| 163 @BidirectionalStream.Builder.StreamPriority int priority, boolean di
sableAutoFlush, | 171 @BidirectionalStream.Builder.StreamPriority int priority, boolean di
sableAutoFlush, |
| 164 boolean delayRequestHeadersUntilFirstFlush) { | 172 boolean delayRequestHeadersUntilFirstFlush) { |
| 165 synchronized (mLock) { | 173 synchronized (mLock) { |
| 166 checkHaveAdapter(); | 174 checkHaveAdapter(); |
| 167 return new CronetBidirectionalStream(this, url, priority, callback,
executor, | 175 return new CronetBidirectionalStream(this, url, priority, callback,
executor, |
| 168 httpMethod, requestHeaders, disableAutoFlush, | 176 httpMethod, requestHeaders, disableAutoFlush, |
| 169 delayRequestHeadersUntilFirstFlush); | 177 delayRequestHeadersUntilFirstFlush); |
| 170 } | 178 } |
| 171 } | 179 } |
| 172 | 180 |
| 173 @Override | 181 @Override |
| 174 public boolean isEnabled() { | 182 public boolean isEnabled() { |
| 175 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH; | 183 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH; |
| 176 } | 184 } |
| 177 | 185 |
| 178 @Override | 186 @Override |
| 179 public String getVersionString() { | 187 public String getVersionString() { |
| 180 return "Cronet/" + Version.getVersion(); | 188 return "Cronet/" + ImplVersion.getVersion(); |
| 181 } | 189 } |
| 182 | 190 |
| 183 @Override | 191 @Override |
| 184 public void shutdown() { | 192 public void shutdown() { |
| 185 synchronized (mLock) { | 193 synchronized (mLock) { |
| 186 checkHaveAdapter(); | 194 checkHaveAdapter(); |
| 187 if (mActiveRequestCount.get() != 0) { | 195 if (mActiveRequestCount.get() != 0) { |
| 188 throw new IllegalStateException( | 196 throw new IllegalStateException("Cannot shutdown with active req
uests."); |
| 189 "Cannot shutdown with active requests."); | |
| 190 } | 197 } |
| 191 // Destroying adapter stops the network thread, so it cannot be | 198 // Destroying adapter stops the network thread, so it cannot be |
| 192 // called on network thread. | 199 // called on network thread. |
| 193 if (Thread.currentThread() == mNetworkThread) { | 200 if (Thread.currentThread() == mNetworkThread) { |
| 194 throw new IllegalThreadStateException( | 201 throw new IllegalThreadStateException("Cannot shutdown from netw
ork thread."); |
| 195 "Cannot shutdown from network thread."); | |
| 196 } | 202 } |
| 197 } | 203 } |
| 198 // Wait for init to complete on main and network thread (without lock, | 204 // Wait for init to complete on main and network thread (without lock, |
| 199 // so other thread could access it). | 205 // so other thread could access it). |
| 200 mInitCompleted.block(); | 206 mInitCompleted.block(); |
| 201 | 207 |
| 202 synchronized (mLock) { | 208 synchronized (mLock) { |
| 203 // It is possible that adapter is already destroyed on another threa
d. | 209 // It is possible that adapter is already destroyed on another threa
d. |
| 204 if (!haveRequestContextAdapter()) { | 210 if (!haveRequestContextAdapter()) { |
| 205 return; | 211 return; |
| 206 } | 212 } |
| 207 nativeDestroy(mUrlRequestContextAdapter); | 213 nativeDestroy(mUrlRequestContextAdapter); |
| 208 mUrlRequestContextAdapter = 0; | 214 mUrlRequestContextAdapter = 0; |
| 209 } | 215 } |
| 210 } | 216 } |
| 211 | 217 |
| 212 @Override | 218 @Override |
| 213 public void startNetLogToFile(String fileName, boolean logAll) { | 219 public void startNetLogToFile(String fileName, boolean logAll) { |
| 214 synchronized (mLock) { | 220 synchronized (mLock) { |
| 215 checkHaveAdapter(); | 221 checkHaveAdapter(); |
| 216 nativeStartNetLogToFile(mUrlRequestContextAdapter, fileName, | 222 nativeStartNetLogToFile(mUrlRequestContextAdapter, fileName, logAll)
; |
| 217 logAll); | |
| 218 } | 223 } |
| 219 } | 224 } |
| 220 | 225 |
| 221 @Override | 226 @Override |
| 222 public void stopNetLog() { | 227 public void stopNetLog() { |
| 223 synchronized (mLock) { | 228 synchronized (mLock) { |
| 224 checkHaveAdapter(); | 229 checkHaveAdapter(); |
| 225 nativeStopNetLog(mUrlRequestContextAdapter); | 230 nativeStopNetLog(mUrlRequestContextAdapter); |
| 226 } | 231 } |
| 227 } | 232 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 } | 289 } |
| 285 mNetworkQualityExecutor = executor; | 290 mNetworkQualityExecutor = executor; |
| 286 synchronized (mLock) { | 291 synchronized (mLock) { |
| 287 checkHaveAdapter(); | 292 checkHaveAdapter(); |
| 288 nativeEnableNetworkQualityEstimator(mUrlRequestContextAdapter); | 293 nativeEnableNetworkQualityEstimator(mUrlRequestContextAdapter); |
| 289 } | 294 } |
| 290 } | 295 } |
| 291 | 296 |
| 292 @VisibleForTesting | 297 @VisibleForTesting |
| 293 @Override | 298 @Override |
| 294 void configureNetworkQualityEstimatorForTesting( | 299 public void configureNetworkQualityEstimatorForTesting( |
| 295 boolean useLocalHostRequests, boolean useSmallerResponses) { | 300 boolean useLocalHostRequests, boolean useSmallerResponses) { |
| 296 if (!mNetworkQualityEstimatorEnabled) { | 301 if (!mNetworkQualityEstimatorEnabled) { |
| 297 throw new IllegalStateException("Network quality estimator must be e
nabled"); | 302 throw new IllegalStateException("Network quality estimator must be e
nabled"); |
| 298 } | 303 } |
| 299 synchronized (mLock) { | 304 synchronized (mLock) { |
| 300 checkHaveAdapter(); | 305 checkHaveAdapter(); |
| 301 nativeConfigureNetworkQualityEstimatorForTesting( | 306 nativeConfigureNetworkQualityEstimatorForTesting( |
| 302 mUrlRequestContextAdapter, useLocalHostRequests, useSmallerR
esponses); | 307 mUrlRequestContextAdapter, useLocalHostRequests, useSmallerR
esponses); |
| 303 } | 308 } |
| 304 } | 309 } |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 | 436 |
| 432 /** | 437 /** |
| 433 * Mark request as finished to allow shutdown when there are no active | 438 * Mark request as finished to allow shutdown when there are no active |
| 434 * requests. | 439 * requests. |
| 435 */ | 440 */ |
| 436 void onRequestDestroyed() { | 441 void onRequestDestroyed() { |
| 437 mActiveRequestCount.decrementAndGet(); | 442 mActiveRequestCount.decrementAndGet(); |
| 438 } | 443 } |
| 439 | 444 |
| 440 @VisibleForTesting | 445 @VisibleForTesting |
| 441 long getUrlRequestContextAdapter() { | 446 public long getUrlRequestContextAdapter() { |
| 442 synchronized (mLock) { | 447 synchronized (mLock) { |
| 443 checkHaveAdapter(); | 448 checkHaveAdapter(); |
| 444 return mUrlRequestContextAdapter; | 449 return mUrlRequestContextAdapter; |
| 445 } | 450 } |
| 446 } | 451 } |
| 447 | 452 |
| 448 private void checkHaveAdapter() throws IllegalStateException { | 453 private void checkHaveAdapter() throws IllegalStateException { |
| 449 if (!haveRequestContextAdapter()) { | 454 if (!haveRequestContextAdapter()) { |
| 450 throw new IllegalStateException("Engine is shut down."); | 455 throw new IllegalStateException("Engine is shut down."); |
| 451 } | 456 } |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 private static native long nativeCreateRequestContextAdapter(long urlRequest
ContextConfig); | 582 private static native long nativeCreateRequestContextAdapter(long urlRequest
ContextConfig); |
| 578 | 583 |
| 579 private static native int nativeSetMinLogLevel(int loggingLevel); | 584 private static native int nativeSetMinLogLevel(int loggingLevel); |
| 580 | 585 |
| 581 private static native byte[] nativeGetHistogramDeltas(); | 586 private static native byte[] nativeGetHistogramDeltas(); |
| 582 | 587 |
| 583 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 588 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
| 584 private native void nativeDestroy(long nativePtr); | 589 private native void nativeDestroy(long nativePtr); |
| 585 | 590 |
| 586 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 591 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
| 587 private native void nativeStartNetLogToFile(long nativePtr, | 592 private native void nativeStartNetLogToFile(long nativePtr, String fileName,
boolean logAll); |
| 588 String fileName, boolean logAll); | |
| 589 | 593 |
| 590 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 594 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
| 591 private native void nativeStopNetLog(long nativePtr); | 595 private native void nativeStopNetLog(long nativePtr); |
| 592 | 596 |
| 593 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 597 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
| 594 private native void nativeGetCertVerifierData(long nativePtr); | 598 private native void nativeGetCertVerifierData(long nativePtr); |
| 595 | 599 |
| 596 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 600 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
| 597 private native void nativeInitRequestContextOnMainThread(long nativePtr); | 601 private native void nativeInitRequestContextOnMainThread(long nativePtr); |
| 598 | 602 |
| 599 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 603 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
| 600 private native void nativeConfigureNetworkQualityEstimatorForTesting( | 604 private native void nativeConfigureNetworkQualityEstimatorForTesting( |
| 601 long nativePtr, boolean useLocalHostRequests, boolean useSmallerResp
onses); | 605 long nativePtr, boolean useLocalHostRequests, boolean useSmallerResp
onses); |
| 602 | 606 |
| 603 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 607 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
| 604 private native void nativeEnableNetworkQualityEstimator(long nativePtr); | 608 private native void nativeEnableNetworkQualityEstimator(long nativePtr); |
| 605 | 609 |
| 606 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 610 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
| 607 private native void nativeProvideRTTObservations(long nativePtr, boolean sho
uld); | 611 private native void nativeProvideRTTObservations(long nativePtr, boolean sho
uld); |
| 608 | 612 |
| 609 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 613 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
| 610 private native void nativeProvideThroughputObservations(long nativePtr, bool
ean should); | 614 private native void nativeProvideThroughputObservations(long nativePtr, bool
ean should); |
| 611 } | 615 } |
| OLD | NEW |