| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 package org.chromium.net; | |
| 6 | |
| 7 import android.content.Context; | |
| 8 import android.os.Build; | |
| 9 import android.os.ConditionVariable; | |
| 10 import android.os.Handler; | |
| 11 import android.os.Looper; | |
| 12 import android.os.Process; | |
| 13 import android.util.Log; | |
| 14 | |
| 15 import org.chromium.base.ObserverList; | |
| 16 import org.chromium.base.VisibleForTesting; | |
| 17 import org.chromium.base.annotations.CalledByNative; | |
| 18 import org.chromium.base.annotations.JNINamespace; | |
| 19 import org.chromium.base.annotations.NativeClassQualifiedName; | |
| 20 import org.chromium.base.annotations.UsedByReflection; | |
| 21 import org.chromium.net.urlconnection.CronetHttpURLConnection; | |
| 22 import org.chromium.net.urlconnection.CronetURLStreamHandlerFactory; | |
| 23 | |
| 24 import java.net.Proxy; | |
| 25 import java.net.URL; | |
| 26 import java.net.URLConnection; | |
| 27 import java.net.URLStreamHandlerFactory; | |
| 28 import java.util.Collection; | |
| 29 import java.util.List; | |
| 30 import java.util.Map; | |
| 31 import java.util.concurrent.Executor; | |
| 32 import java.util.concurrent.RejectedExecutionException; | |
| 33 import java.util.concurrent.atomic.AtomicInteger; | |
| 34 | |
| 35 import javax.annotation.concurrent.GuardedBy; | |
| 36 | |
| 37 /** | |
| 38 * CronetEngine using Chromium HTTP stack implementation. | |
| 39 */ | |
| 40 @JNINamespace("cronet") | |
| 41 @UsedByReflection("CronetEngine.java") | |
| 42 class CronetUrlRequestContext extends CronetEngine { | |
| 43 private static final int LOG_NONE = 3; // LOG(FATAL), no VLOG. | |
| 44 private static final int LOG_DEBUG = -1; // LOG(FATAL...INFO), VLOG(1) | |
| 45 private static final int LOG_VERBOSE = -2; // LOG(FATAL...INFO), VLOG(2) | |
| 46 static final String LOG_TAG = "ChromiumNetwork"; | |
| 47 | |
| 48 /** | |
| 49 * Synchronize access to mUrlRequestContextAdapter and shutdown routine. | |
| 50 */ | |
| 51 private final Object mLock = new Object(); | |
| 52 private final ConditionVariable mInitCompleted = new ConditionVariable(false
); | |
| 53 private final AtomicInteger mActiveRequestCount = new AtomicInteger(0); | |
| 54 | |
| 55 private long mUrlRequestContextAdapter = 0; | |
| 56 private Thread mNetworkThread; | |
| 57 | |
| 58 private Executor mNetworkQualityExecutor; | |
| 59 private boolean mNetworkQualityEstimatorEnabled; | |
| 60 | |
| 61 /** Locks operations on network quality listeners, because listener | |
| 62 * addition and removal may occur on a different thread from notification. | |
| 63 */ | |
| 64 private final Object mNetworkQualityLock = new Object(); | |
| 65 | |
| 66 @GuardedBy("mNetworkQualityLock") | |
| 67 private final ObserverList<NetworkQualityRttListener> mRttListenerList = | |
| 68 new ObserverList<NetworkQualityRttListener>(); | |
| 69 | |
| 70 @GuardedBy("mNetworkQualityLock") | |
| 71 private final ObserverList<NetworkQualityThroughputListener> mThroughputList
enerList = | |
| 72 new ObserverList<NetworkQualityThroughputListener>(); | |
| 73 | |
| 74 @GuardedBy("mNetworkQualityLock") | |
| 75 private final ObserverList<RequestFinishedListener> mFinishedListenerList = | |
| 76 new ObserverList<RequestFinishedListener>(); | |
| 77 | |
| 78 /** | |
| 79 * Synchronize access to mCertVerifierData. | |
| 80 */ | |
| 81 private ConditionVariable mWaitGetCertVerifierDataComplete = new ConditionVa
riable(); | |
| 82 | |
| 83 /** Holds CertVerifier data. */ | |
| 84 private String mCertVerifierData; | |
| 85 | |
| 86 @UsedByReflection("CronetEngine.java") | |
| 87 public CronetUrlRequestContext(final CronetEngine.Builder builder) { | |
| 88 CronetLibraryLoader.ensureInitialized(builder.getContext(), builder); | |
| 89 nativeSetMinLogLevel(getLoggingLevel()); | |
| 90 synchronized (mLock) { | |
| 91 mUrlRequestContextAdapter = nativeCreateRequestContextAdapter( | |
| 92 createNativeUrlRequestContextConfig(builder.getContext(), bu
ilder)); | |
| 93 if (mUrlRequestContextAdapter == 0) { | |
| 94 throw new NullPointerException("Context Adapter creation failed.
"); | |
| 95 } | |
| 96 mNetworkQualityEstimatorEnabled = builder.networkQualityEstimatorEna
bled(); | |
| 97 } | |
| 98 | |
| 99 // Init native Chromium URLRequestContext on main UI thread. | |
| 100 Runnable task = new Runnable() { | |
| 101 @Override | |
| 102 public void run() { | |
| 103 CronetLibraryLoader.ensureInitializedOnMainThread(builder.getCon
text()); | |
| 104 synchronized (mLock) { | |
| 105 // mUrlRequestContextAdapter is guaranteed to exist until | |
| 106 // initialization on main and network threads completes and | |
| 107 // initNetworkThread is called back on network thread. | |
| 108 nativeInitRequestContextOnMainThread(mUrlRequestContextAdapt
er); | |
| 109 } | |
| 110 } | |
| 111 }; | |
| 112 // Run task immediately or post it to the UI thread. | |
| 113 if (Looper.getMainLooper() == Looper.myLooper()) { | |
| 114 task.run(); | |
| 115 } else { | |
| 116 new Handler(Looper.getMainLooper()).post(task); | |
| 117 } | |
| 118 } | |
| 119 | |
| 120 static long createNativeUrlRequestContextConfig( | |
| 121 final Context context, CronetEngine.Builder builder) { | |
| 122 final long urlRequestContextConfig = nativeCreateRequestContextConfig( | |
| 123 builder.getUserAgent(), builder.storagePath(), builder.quicEnabl
ed(), | |
| 124 builder.getDefaultQuicUserAgentId(context), builder.http2Enabled
(), | |
| 125 builder.sdchEnabled(), builder.dataReductionProxyKey(), | |
| 126 builder.dataReductionProxyPrimaryProxy(), builder.dataReductionP
roxyFallbackProxy(), | |
| 127 builder.dataReductionProxySecureProxyCheckUrl(), builder.cacheDi
sabled(), | |
| 128 builder.httpCacheMode(), builder.httpCacheMaxSize(), builder.exp
erimentalOptions(), | |
| 129 builder.mockCertVerifier(), builder.networkQualityEstimatorEnabl
ed(), | |
| 130 builder.publicKeyPinningBypassForLocalTrustAnchorsEnabled(), | |
| 131 builder.certVerifierData()); | |
| 132 for (Builder.QuicHint quicHint : builder.quicHints()) { | |
| 133 nativeAddQuicHint(urlRequestContextConfig, quicHint.mHost, quicHint.
mPort, | |
| 134 quicHint.mAlternatePort); | |
| 135 } | |
| 136 for (Builder.Pkp pkp : builder.publicKeyPins()) { | |
| 137 nativeAddPkp(urlRequestContextConfig, pkp.mHost, pkp.mHashes, pkp.mI
ncludeSubdomains, | |
| 138 pkp.mExpirationDate.getTime()); | |
| 139 } | |
| 140 return urlRequestContextConfig; | |
| 141 } | |
| 142 | |
| 143 @Override | |
| 144 public UrlRequest createRequest(String url, UrlRequest.Callback callback, Ex
ecutor executor, | |
| 145 int priority, Collection<Object> requestAnnotations, boolean disable
Cache, | |
| 146 boolean disableConnectionMigration) { | |
| 147 synchronized (mLock) { | |
| 148 checkHaveAdapter(); | |
| 149 boolean metricsCollectionEnabled = mNetworkQualityEstimatorEnabled; | |
| 150 if (metricsCollectionEnabled) { // Collect metrics only if someone i
s listening. | |
| 151 synchronized (mNetworkQualityLock) { | |
| 152 metricsCollectionEnabled = !mFinishedListenerList.isEmpty(); | |
| 153 } | |
| 154 } | |
| 155 return new CronetUrlRequest(this, url, priority, callback, executor,
requestAnnotations, | |
| 156 metricsCollectionEnabled, disableCache, disableConnectionMig
ration); | |
| 157 } | |
| 158 } | |
| 159 | |
| 160 @Override | |
| 161 BidirectionalStream createBidirectionalStream(String url, BidirectionalStrea
m.Callback callback, | |
| 162 Executor executor, String httpMethod, List<Map.Entry<String, String>
> requestHeaders, | |
| 163 @BidirectionalStream.Builder.StreamPriority int priority, boolean di
sableAutoFlush, | |
| 164 boolean delayRequestHeadersUntilFirstFlush) { | |
| 165 synchronized (mLock) { | |
| 166 checkHaveAdapter(); | |
| 167 return new CronetBidirectionalStream(this, url, priority, callback,
executor, | |
| 168 httpMethod, requestHeaders, disableAutoFlush, | |
| 169 delayRequestHeadersUntilFirstFlush); | |
| 170 } | |
| 171 } | |
| 172 | |
| 173 @Override | |
| 174 public boolean isEnabled() { | |
| 175 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH; | |
| 176 } | |
| 177 | |
| 178 @Override | |
| 179 public String getVersionString() { | |
| 180 return "Cronet/" + Version.getVersion(); | |
| 181 } | |
| 182 | |
| 183 @Override | |
| 184 public void shutdown() { | |
| 185 synchronized (mLock) { | |
| 186 checkHaveAdapter(); | |
| 187 if (mActiveRequestCount.get() != 0) { | |
| 188 throw new IllegalStateException( | |
| 189 "Cannot shutdown with active requests."); | |
| 190 } | |
| 191 // Destroying adapter stops the network thread, so it cannot be | |
| 192 // called on network thread. | |
| 193 if (Thread.currentThread() == mNetworkThread) { | |
| 194 throw new IllegalThreadStateException( | |
| 195 "Cannot shutdown from network thread."); | |
| 196 } | |
| 197 } | |
| 198 // Wait for init to complete on main and network thread (without lock, | |
| 199 // so other thread could access it). | |
| 200 mInitCompleted.block(); | |
| 201 | |
| 202 synchronized (mLock) { | |
| 203 // It is possible that adapter is already destroyed on another threa
d. | |
| 204 if (!haveRequestContextAdapter()) { | |
| 205 return; | |
| 206 } | |
| 207 nativeDestroy(mUrlRequestContextAdapter); | |
| 208 mUrlRequestContextAdapter = 0; | |
| 209 } | |
| 210 } | |
| 211 | |
| 212 @Override | |
| 213 public void startNetLogToFile(String fileName, boolean logAll) { | |
| 214 synchronized (mLock) { | |
| 215 checkHaveAdapter(); | |
| 216 nativeStartNetLogToFile(mUrlRequestContextAdapter, fileName, | |
| 217 logAll); | |
| 218 } | |
| 219 } | |
| 220 | |
| 221 @Override | |
| 222 public void stopNetLog() { | |
| 223 synchronized (mLock) { | |
| 224 checkHaveAdapter(); | |
| 225 nativeStopNetLog(mUrlRequestContextAdapter); | |
| 226 } | |
| 227 } | |
| 228 | |
| 229 @Override | |
| 230 public String getCertVerifierData(long timeout) { | |
| 231 if (timeout < 0) { | |
| 232 throw new IllegalArgumentException("timeout must be a positive value
"); | |
| 233 } else if (timeout == 0) { | |
| 234 timeout = 100; | |
| 235 } | |
| 236 mWaitGetCertVerifierDataComplete.close(); | |
| 237 synchronized (mLock) { | |
| 238 checkHaveAdapter(); | |
| 239 nativeGetCertVerifierData(mUrlRequestContextAdapter); | |
| 240 } | |
| 241 mWaitGetCertVerifierDataComplete.block(timeout); | |
| 242 return mCertVerifierData; | |
| 243 } | |
| 244 | |
| 245 // This method is intentionally non-static to ensure Cronet native library | |
| 246 // is loaded by class constructor. | |
| 247 @Override | |
| 248 public byte[] getGlobalMetricsDeltas() { | |
| 249 return nativeGetHistogramDeltas(); | |
| 250 } | |
| 251 | |
| 252 /** | |
| 253 * TODO(tbansal): http://crbug.com/618034 Remove this API once all | |
| 254 * embedders have switched to using a request finished listener that | |
| 255 * provides its own executor. | |
| 256 */ | |
| 257 @Override | |
| 258 public void setRequestFinishedListenerExecutor(Executor executor) { | |
| 259 if (!mNetworkQualityEstimatorEnabled) { | |
| 260 throw new IllegalStateException("Network quality estimator not enabl
ed"); | |
| 261 } | |
| 262 if (executor == null) { | |
| 263 throw new NullPointerException("Request finished listener requires a
n executor"); | |
| 264 } | |
| 265 if (mNetworkQualityExecutor != null) { | |
| 266 throw new NullPointerException("Request finished listener executor a
lready set"); | |
| 267 } | |
| 268 mNetworkQualityExecutor = executor; | |
| 269 } | |
| 270 | |
| 271 /** | |
| 272 * TODO(tbansal): http://crbug.com/618034 Remove this API once all | |
| 273 * embedders have switched to using CronetEngine builder for enabling | |
| 274 * network quality estimator. | |
| 275 */ | |
| 276 @Override | |
| 277 public void enableNetworkQualityEstimator(Executor executor) { | |
| 278 if (mNetworkQualityEstimatorEnabled) { | |
| 279 throw new IllegalStateException("Network quality estimator already e
nabled"); | |
| 280 } | |
| 281 mNetworkQualityEstimatorEnabled = true; | |
| 282 if (executor == null) { | |
| 283 throw new NullPointerException("Network quality estimator requires a
n executor"); | |
| 284 } | |
| 285 mNetworkQualityExecutor = executor; | |
| 286 synchronized (mLock) { | |
| 287 checkHaveAdapter(); | |
| 288 nativeEnableNetworkQualityEstimator(mUrlRequestContextAdapter); | |
| 289 } | |
| 290 } | |
| 291 | |
| 292 @VisibleForTesting | |
| 293 @Override | |
| 294 void configureNetworkQualityEstimatorForTesting( | |
| 295 boolean useLocalHostRequests, boolean useSmallerResponses) { | |
| 296 if (!mNetworkQualityEstimatorEnabled) { | |
| 297 throw new IllegalStateException("Network quality estimator must be e
nabled"); | |
| 298 } | |
| 299 synchronized (mLock) { | |
| 300 checkHaveAdapter(); | |
| 301 nativeConfigureNetworkQualityEstimatorForTesting( | |
| 302 mUrlRequestContextAdapter, useLocalHostRequests, useSmallerR
esponses); | |
| 303 } | |
| 304 } | |
| 305 | |
| 306 @Override | |
| 307 public void addRttListener(NetworkQualityRttListener listener) { | |
| 308 if (!mNetworkQualityEstimatorEnabled) { | |
| 309 throw new IllegalStateException("Network quality estimator must be e
nabled"); | |
| 310 } | |
| 311 synchronized (mNetworkQualityLock) { | |
| 312 if (mRttListenerList.isEmpty()) { | |
| 313 synchronized (mLock) { | |
| 314 checkHaveAdapter(); | |
| 315 nativeProvideRTTObservations(mUrlRequestContextAdapter, true
); | |
| 316 } | |
| 317 } | |
| 318 mRttListenerList.addObserver(listener); | |
| 319 } | |
| 320 } | |
| 321 | |
| 322 @Override | |
| 323 public void removeRttListener(NetworkQualityRttListener listener) { | |
| 324 if (!mNetworkQualityEstimatorEnabled) { | |
| 325 throw new IllegalStateException("Network quality estimator must be e
nabled"); | |
| 326 } | |
| 327 synchronized (mNetworkQualityLock) { | |
| 328 mRttListenerList.removeObserver(listener); | |
| 329 if (mRttListenerList.isEmpty()) { | |
| 330 synchronized (mLock) { | |
| 331 checkHaveAdapter(); | |
| 332 nativeProvideRTTObservations(mUrlRequestContextAdapter, fals
e); | |
| 333 } | |
| 334 } | |
| 335 } | |
| 336 } | |
| 337 | |
| 338 @Override | |
| 339 public void addThroughputListener(NetworkQualityThroughputListener listener)
{ | |
| 340 if (!mNetworkQualityEstimatorEnabled) { | |
| 341 throw new IllegalStateException("Network quality estimator must be e
nabled"); | |
| 342 } | |
| 343 synchronized (mNetworkQualityLock) { | |
| 344 if (mThroughputListenerList.isEmpty()) { | |
| 345 synchronized (mLock) { | |
| 346 checkHaveAdapter(); | |
| 347 nativeProvideThroughputObservations(mUrlRequestContextAdapte
r, true); | |
| 348 } | |
| 349 } | |
| 350 mThroughputListenerList.addObserver(listener); | |
| 351 } | |
| 352 } | |
| 353 | |
| 354 @Override | |
| 355 public void removeThroughputListener(NetworkQualityThroughputListener listen
er) { | |
| 356 if (!mNetworkQualityEstimatorEnabled) { | |
| 357 throw new IllegalStateException("Network quality estimator must be e
nabled"); | |
| 358 } | |
| 359 synchronized (mNetworkQualityLock) { | |
| 360 mThroughputListenerList.removeObserver(listener); | |
| 361 if (mThroughputListenerList.isEmpty()) { | |
| 362 synchronized (mLock) { | |
| 363 checkHaveAdapter(); | |
| 364 nativeProvideThroughputObservations(mUrlRequestContextAdapte
r, false); | |
| 365 } | |
| 366 } | |
| 367 } | |
| 368 } | |
| 369 | |
| 370 /** | |
| 371 * TODO(tbansal): http://crbug.com/618034 Remove this API once all | |
| 372 * embedders have switched to using a request finished listener that | |
| 373 * provides its own executor. | |
| 374 */ | |
| 375 @Override | |
| 376 public void addRequestFinishedListener(RequestFinishedListener listener) { | |
| 377 if (!mNetworkQualityEstimatorEnabled) { | |
| 378 throw new IllegalStateException("Network quality estimator must be e
nabled"); | |
| 379 } | |
| 380 // RequestFinishedListener does not provide its own executor. | |
| 381 if (mNetworkQualityExecutor == null) { | |
| 382 throw new IllegalStateException("Executor must not be null"); | |
| 383 } | |
| 384 synchronized (mNetworkQualityLock) { | |
| 385 mFinishedListenerList.addObserver(listener); | |
| 386 } | |
| 387 } | |
| 388 | |
| 389 /** | |
| 390 * TODO(tbansal): http://crbug.com/618034 Remove this API. | |
| 391 */ | |
| 392 @Override | |
| 393 public void removeRequestFinishedListener(RequestFinishedListener listener)
{ | |
| 394 if (!mNetworkQualityEstimatorEnabled) { | |
| 395 throw new IllegalStateException("Network quality estimator must be e
nabled"); | |
| 396 } | |
| 397 synchronized (mNetworkQualityLock) { | |
| 398 mFinishedListenerList.removeObserver(listener); | |
| 399 } | |
| 400 } | |
| 401 | |
| 402 @Override | |
| 403 public URLConnection openConnection(URL url) { | |
| 404 return openConnection(url, Proxy.NO_PROXY); | |
| 405 } | |
| 406 | |
| 407 @Override | |
| 408 public URLConnection openConnection(URL url, Proxy proxy) { | |
| 409 if (proxy.type() != Proxy.Type.DIRECT) { | |
| 410 throw new UnsupportedOperationException(); | |
| 411 } | |
| 412 String protocol = url.getProtocol(); | |
| 413 if ("http".equals(protocol) || "https".equals(protocol)) { | |
| 414 return new CronetHttpURLConnection(url, this); | |
| 415 } | |
| 416 throw new UnsupportedOperationException("Unexpected protocol:" + protoco
l); | |
| 417 } | |
| 418 | |
| 419 @Override | |
| 420 public URLStreamHandlerFactory createURLStreamHandlerFactory() { | |
| 421 return new CronetURLStreamHandlerFactory(this); | |
| 422 } | |
| 423 | |
| 424 /** | |
| 425 * Mark request as started to prevent shutdown when there are active | |
| 426 * requests. | |
| 427 */ | |
| 428 void onRequestStarted() { | |
| 429 mActiveRequestCount.incrementAndGet(); | |
| 430 } | |
| 431 | |
| 432 /** | |
| 433 * Mark request as finished to allow shutdown when there are no active | |
| 434 * requests. | |
| 435 */ | |
| 436 void onRequestDestroyed() { | |
| 437 mActiveRequestCount.decrementAndGet(); | |
| 438 } | |
| 439 | |
| 440 @VisibleForTesting | |
| 441 long getUrlRequestContextAdapter() { | |
| 442 synchronized (mLock) { | |
| 443 checkHaveAdapter(); | |
| 444 return mUrlRequestContextAdapter; | |
| 445 } | |
| 446 } | |
| 447 | |
| 448 private void checkHaveAdapter() throws IllegalStateException { | |
| 449 if (!haveRequestContextAdapter()) { | |
| 450 throw new IllegalStateException("Engine is shut down."); | |
| 451 } | |
| 452 } | |
| 453 | |
| 454 private boolean haveRequestContextAdapter() { | |
| 455 return mUrlRequestContextAdapter != 0; | |
| 456 } | |
| 457 | |
| 458 /** | |
| 459 * @return loggingLevel see {@link #LOG_NONE}, {@link #LOG_DEBUG} and | |
| 460 * {@link #LOG_VERBOSE}. | |
| 461 */ | |
| 462 private int getLoggingLevel() { | |
| 463 int loggingLevel; | |
| 464 if (Log.isLoggable(LOG_TAG, Log.VERBOSE)) { | |
| 465 loggingLevel = LOG_VERBOSE; | |
| 466 } else if (Log.isLoggable(LOG_TAG, Log.DEBUG)) { | |
| 467 loggingLevel = LOG_DEBUG; | |
| 468 } else { | |
| 469 loggingLevel = LOG_NONE; | |
| 470 } | |
| 471 return loggingLevel; | |
| 472 } | |
| 473 | |
| 474 @SuppressWarnings("unused") | |
| 475 @CalledByNative | |
| 476 private void initNetworkThread() { | |
| 477 synchronized (mLock) { | |
| 478 mNetworkThread = Thread.currentThread(); | |
| 479 mInitCompleted.open(); | |
| 480 } | |
| 481 Thread.currentThread().setName("ChromiumNet"); | |
| 482 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); | |
| 483 } | |
| 484 | |
| 485 @SuppressWarnings("unused") | |
| 486 @CalledByNative | |
| 487 private void onRttObservation(final int rttMs, final long whenMs, final int
source) { | |
| 488 synchronized (mNetworkQualityLock) { | |
| 489 for (final NetworkQualityRttListener listener : mRttListenerList) { | |
| 490 Runnable task = new Runnable() { | |
| 491 @Override | |
| 492 public void run() { | |
| 493 listener.onRttObservation(rttMs, whenMs, source); | |
| 494 } | |
| 495 }; | |
| 496 postObservationTaskToExecutor(listener.getExecutor(), task); | |
| 497 } | |
| 498 } | |
| 499 } | |
| 500 | |
| 501 @SuppressWarnings("unused") | |
| 502 @CalledByNative | |
| 503 private void onThroughputObservation( | |
| 504 final int throughputKbps, final long whenMs, final int source) { | |
| 505 synchronized (mNetworkQualityLock) { | |
| 506 for (final NetworkQualityThroughputListener listener : mThroughputLi
stenerList) { | |
| 507 Runnable task = new Runnable() { | |
| 508 @Override | |
| 509 public void run() { | |
| 510 listener.onThroughputObservation(throughputKbps, whenMs,
source); | |
| 511 } | |
| 512 }; | |
| 513 postObservationTaskToExecutor(listener.getExecutor(), task); | |
| 514 } | |
| 515 } | |
| 516 } | |
| 517 | |
| 518 @SuppressWarnings("unused") | |
| 519 @CalledByNative | |
| 520 private void onGetCertVerifierData(String certVerifierData) { | |
| 521 mCertVerifierData = certVerifierData; | |
| 522 mWaitGetCertVerifierDataComplete.open(); | |
| 523 } | |
| 524 | |
| 525 void reportFinished(final CronetUrlRequest request) { | |
| 526 if (!mNetworkQualityEstimatorEnabled) { | |
| 527 return; | |
| 528 } | |
| 529 // If no request finished listener has been added, then mNetworkQualityE
xecutor may be | |
| 530 // null. Exit early to avoid posting to a null executor. | |
| 531 synchronized (mNetworkQualityLock) { | |
| 532 if (mFinishedListenerList.isEmpty()) { | |
| 533 return; | |
| 534 } | |
| 535 } | |
| 536 Runnable task = new Runnable() { | |
| 537 @Override | |
| 538 public void run() { | |
| 539 synchronized (mNetworkQualityLock) { | |
| 540 UrlRequestInfo requestInfo = request.getRequestInfo(); | |
| 541 for (RequestFinishedListener listener : mFinishedListenerLis
t) { | |
| 542 listener.onRequestFinished(requestInfo); | |
| 543 } | |
| 544 } | |
| 545 } | |
| 546 }; | |
| 547 // Use {@link mNetworkQualityExecutor} since | |
| 548 // RequestFInishedListeners do not provide an executor. | |
| 549 postObservationTaskToExecutor(mNetworkQualityExecutor, task); | |
| 550 } | |
| 551 | |
| 552 private static void postObservationTaskToExecutor(Executor executor, Runnabl
e task) { | |
| 553 try { | |
| 554 executor.execute(task); | |
| 555 } catch (RejectedExecutionException failException) { | |
| 556 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception posting task to ex
ecutor", | |
| 557 failException); | |
| 558 } | |
| 559 } | |
| 560 | |
| 561 // Native methods are implemented in cronet_url_request_context_adapter.cc. | |
| 562 private static native long nativeCreateRequestContextConfig(String userAgent
, | |
| 563 String storagePath, boolean quicEnabled, String quicUserAgentId, boo
lean http2Enabled, | |
| 564 boolean sdchEnabled, String dataReductionProxyKey, | |
| 565 String dataReductionProxyPrimaryProxy, String dataReductionProxyFall
backProxy, | |
| 566 String dataReductionProxySecureProxyCheckUrl, boolean disableCache,
int httpCacheMode, | |
| 567 long httpCacheMaxSize, String experimentalOptions, long mockCertVeri
fier, | |
| 568 boolean enableNetworkQualityEstimator, | |
| 569 boolean bypassPublicKeyPinningForLocalTrustAnchors, String certVerif
ierData); | |
| 570 | |
| 571 private static native void nativeAddQuicHint( | |
| 572 long urlRequestContextConfig, String host, int port, int alternatePo
rt); | |
| 573 | |
| 574 private static native void nativeAddPkp(long urlRequestContextConfig, String
host, | |
| 575 byte[][] hashes, boolean includeSubdomains, long expirationTime); | |
| 576 | |
| 577 private static native long nativeCreateRequestContextAdapter(long urlRequest
ContextConfig); | |
| 578 | |
| 579 private static native int nativeSetMinLogLevel(int loggingLevel); | |
| 580 | |
| 581 private static native byte[] nativeGetHistogramDeltas(); | |
| 582 | |
| 583 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | |
| 584 private native void nativeDestroy(long nativePtr); | |
| 585 | |
| 586 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | |
| 587 private native void nativeStartNetLogToFile(long nativePtr, | |
| 588 String fileName, boolean logAll); | |
| 589 | |
| 590 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | |
| 591 private native void nativeStopNetLog(long nativePtr); | |
| 592 | |
| 593 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | |
| 594 private native void nativeGetCertVerifierData(long nativePtr); | |
| 595 | |
| 596 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | |
| 597 private native void nativeInitRequestContextOnMainThread(long nativePtr); | |
| 598 | |
| 599 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | |
| 600 private native void nativeConfigureNetworkQualityEstimatorForTesting( | |
| 601 long nativePtr, boolean useLocalHostRequests, boolean useSmallerResp
onses); | |
| 602 | |
| 603 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | |
| 604 private native void nativeEnableNetworkQualityEstimator(long nativePtr); | |
| 605 | |
| 606 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | |
| 607 private native void nativeProvideRTTObservations(long nativePtr, boolean sho
uld); | |
| 608 | |
| 609 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | |
| 610 private native void nativeProvideThroughputObservations(long nativePtr, bool
ean should); | |
| 611 } | |
| OLD | NEW |