Chromium Code Reviews| 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; |
| 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.VisibleForTesting; | 16 import org.chromium.base.VisibleForTesting; |
| 16 import org.chromium.base.annotations.CalledByNative; | 17 import org.chromium.base.annotations.CalledByNative; |
| 17 import org.chromium.base.annotations.JNINamespace; | 18 import org.chromium.base.annotations.JNINamespace; |
| 18 import org.chromium.base.annotations.NativeClassQualifiedName; | 19 import org.chromium.base.annotations.NativeClassQualifiedName; |
| 19 import org.chromium.base.annotations.UsedByReflection; | 20 import org.chromium.base.annotations.UsedByReflection; |
| 20 | 21 |
| 21 import java.util.concurrent.Executor; | 22 import java.util.concurrent.Executor; |
| 23 import java.util.concurrent.RejectedExecutionException; | |
| 22 import java.util.concurrent.atomic.AtomicInteger; | 24 import java.util.concurrent.atomic.AtomicInteger; |
| 23 | 25 |
| 26 import javax.annotation.concurrent.GuardedBy; | |
| 27 | |
| 24 /** | 28 /** |
| 25 * UrlRequestContext using Chromium HTTP stack implementation. | 29 * UrlRequestContext using Chromium HTTP stack implementation. |
| 26 */ | 30 */ |
| 27 @JNINamespace("cronet") | 31 @JNINamespace("cronet") |
| 28 @UsedByReflection("UrlRequestContext.java") | 32 @UsedByReflection("UrlRequestContext.java") |
| 29 class CronetUrlRequestContext extends UrlRequestContext { | 33 class CronetUrlRequestContext extends UrlRequestContext { |
| 30 private static final int LOG_NONE = 3; // LOG(FATAL), no VLOG. | 34 private static final int LOG_NONE = 3; // LOG(FATAL), no VLOG. |
| 31 private static final int LOG_DEBUG = -1; // LOG(FATAL...INFO), VLOG(1) | 35 private static final int LOG_DEBUG = -1; // LOG(FATAL...INFO), VLOG(1) |
| 32 private static final int LOG_VERBOSE = -2; // LOG(FATAL...INFO), VLOG(2) | 36 private static final int LOG_VERBOSE = -2; // LOG(FATAL...INFO), VLOG(2) |
| 33 static final String LOG_TAG = "ChromiumNetwork"; | 37 static final String LOG_TAG = "ChromiumNetwork"; |
| 34 | 38 |
| 35 /** | 39 /** |
| 36 * Synchronize access to mUrlRequestContextAdapter and shutdown routine. | 40 * Synchronize access to mUrlRequestContextAdapter and shutdown routine. |
| 37 */ | 41 */ |
| 38 private final Object mLock = new Object(); | 42 private final Object mLock = new Object(); |
| 39 private final ConditionVariable mInitCompleted = new ConditionVariable(false ); | 43 private final ConditionVariable mInitCompleted = new ConditionVariable(false ); |
| 40 private final AtomicInteger mActiveRequestCount = new AtomicInteger(0); | 44 private final AtomicInteger mActiveRequestCount = new AtomicInteger(0); |
| 41 | 45 |
| 42 private long mUrlRequestContextAdapter = 0; | 46 private long mUrlRequestContextAdapter = 0; |
| 43 private Thread mNetworkThread; | 47 private Thread mNetworkThread; |
| 44 | 48 |
| 49 private Executor mNetworkQualityExecutor; | |
| 50 private boolean mNetworkQualityEstimatorEnabled; | |
| 51 | |
| 52 /** Locks operations on network quality listeners, because listener | |
| 53 * addition and removal may occur on a different thread from notification. | |
| 54 */ | |
| 55 private final Object mNetworkQualityLock = new Object(); | |
| 56 | |
| 57 @GuardedBy("mNetworkQualityLock") | |
| 58 private final ObserverList<NetworkQualityRttListener> mRttListenerList = | |
| 59 new ObserverList<NetworkQualityRttListener>(); | |
| 60 | |
| 61 @GuardedBy("mNetworkQualityLock") | |
| 62 private final ObserverList<NetworkQualityThroughputListener> mThroughputList enerList = | |
| 63 new ObserverList<NetworkQualityThroughputListener>(); | |
| 64 | |
| 45 @UsedByReflection("UrlRequestContext.java") | 65 @UsedByReflection("UrlRequestContext.java") |
| 46 public CronetUrlRequestContext(Context context, | 66 public CronetUrlRequestContext(Context context, |
| 47 UrlRequestContextConfig config) { | 67 UrlRequestContextConfig config) { |
| 48 CronetLibraryLoader.ensureInitialized(context, config); | 68 CronetLibraryLoader.ensureInitialized(context, config); |
| 49 nativeSetMinLogLevel(getLoggingLevel()); | 69 nativeSetMinLogLevel(getLoggingLevel()); |
| 50 mUrlRequestContextAdapter = nativeCreateRequestContextAdapter(config.toS tring()); | 70 mUrlRequestContextAdapter = nativeCreateRequestContextAdapter(config.toS tring()); |
| 51 if (mUrlRequestContextAdapter == 0) { | 71 if (mUrlRequestContextAdapter == 0) { |
| 52 throw new NullPointerException("Context Adapter creation failed."); | 72 throw new NullPointerException("Context Adapter creation failed."); |
| 53 } | 73 } |
| 54 | 74 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 141 } | 161 } |
| 142 | 162 |
| 143 @Override | 163 @Override |
| 144 public void stopNetLog() { | 164 public void stopNetLog() { |
| 145 synchronized (mLock) { | 165 synchronized (mLock) { |
| 146 checkHaveAdapter(); | 166 checkHaveAdapter(); |
| 147 nativeStopNetLog(mUrlRequestContextAdapter); | 167 nativeStopNetLog(mUrlRequestContextAdapter); |
| 148 } | 168 } |
| 149 } | 169 } |
| 150 | 170 |
| 171 @Override | |
| 172 public void enableNetworkQualityEstimator(Executor executor) { | |
| 173 enableNetworkQualityEstimatorForTesting(false, false, executor); | |
| 174 } | |
| 175 | |
| 176 @VisibleForTesting | |
| 177 @Override | |
| 178 void enableNetworkQualityEstimatorForTesting( | |
| 179 boolean useLocalHostRequests, boolean useSmallerResponses, Executor executor) { | |
| 180 if (mNetworkQualityEstimatorEnabled) { | |
| 181 throw new IllegalStateException("Network quality estimator already e nabled"); | |
| 182 } | |
| 183 mNetworkQualityEstimatorEnabled = true; | |
| 184 if (executor == null) { | |
| 185 throw new NullPointerException("Network quality estimator requires a n executor"); | |
| 186 } | |
| 187 mNetworkQualityExecutor = executor; | |
| 188 synchronized (mLock) { | |
| 189 checkHaveAdapter(); | |
| 190 nativeEnableNetworkQualityEstimator( | |
| 191 mUrlRequestContextAdapter, useLocalHostRequests, useSmallerR esponses); | |
| 192 } | |
| 193 } | |
| 194 | |
| 195 @Override | |
| 196 public void addRttListener(NetworkQualityRttListener listener) { | |
| 197 if (!mNetworkQualityEstimatorEnabled) { | |
| 198 throw new IllegalStateException("Network quality estimator must be e nabled"); | |
| 199 } | |
| 200 synchronized (mNetworkQualityLock) { | |
| 201 if (mRttListenerList.isEmpty()) { | |
| 202 synchronized (mLock) { | |
| 203 checkHaveAdapter(); | |
| 204 nativeProvideRTTObservations(mUrlRequestContextAdapter, true ); | |
| 205 } | |
| 206 } | |
| 207 mRttListenerList.addObserver(listener); | |
| 208 } | |
| 209 } | |
| 210 | |
| 211 @Override | |
| 212 public void removeRttListener(NetworkQualityRttListener listener) { | |
| 213 if (!mNetworkQualityEstimatorEnabled) { | |
| 214 throw new IllegalStateException("Network quality estimator must be e nabled"); | |
| 215 } | |
| 216 synchronized (mNetworkQualityLock) { | |
| 217 mRttListenerList.removeObserver(listener); | |
| 218 if (mRttListenerList.isEmpty()) { | |
| 219 synchronized (mLock) { | |
| 220 checkHaveAdapter(); | |
| 221 nativeProvideRTTObservations(mUrlRequestContextAdapter, fals e); | |
| 222 } | |
| 223 } | |
| 224 } | |
| 225 } | |
| 226 | |
| 227 @Override | |
| 228 public void addThroughputListener(NetworkQualityThroughputListener listener) { | |
| 229 if (!mNetworkQualityEstimatorEnabled) { | |
| 230 throw new IllegalStateException("Network quality estimator must be e nabled"); | |
| 231 } | |
| 232 synchronized (mNetworkQualityLock) { | |
| 233 if (mThroughputListenerList.isEmpty()) { | |
| 234 synchronized (mLock) { | |
| 235 checkHaveAdapter(); | |
| 236 nativeProvideThroughputObservations(mUrlRequestContextAdapte r, true); | |
| 237 } | |
| 238 } | |
| 239 mThroughputListenerList.addObserver(listener); | |
| 240 } | |
| 241 } | |
| 242 | |
| 243 @Override | |
| 244 public void removeThroughputListener(NetworkQualityThroughputListener listen er) { | |
| 245 if (!mNetworkQualityEstimatorEnabled) { | |
| 246 throw new IllegalStateException("Network quality estimator must be e nabled"); | |
| 247 } | |
| 248 synchronized (mNetworkQualityLock) { | |
| 249 mThroughputListenerList.removeObserver(listener); | |
| 250 if (mThroughputListenerList.isEmpty()) { | |
| 251 synchronized (mLock) { | |
| 252 checkHaveAdapter(); | |
| 253 nativeProvideThroughputObservations(mUrlRequestContextAdapte r, false); | |
| 254 } | |
| 255 } | |
| 256 } | |
| 257 } | |
| 258 | |
| 151 /** | 259 /** |
| 152 * Mark request as started to prevent shutdown when there are active | 260 * Mark request as started to prevent shutdown when there are active |
| 153 * requests. | 261 * requests. |
| 154 */ | 262 */ |
| 155 void onRequestStarted(UrlRequest urlRequest) { | 263 void onRequestStarted(UrlRequest urlRequest) { |
| 156 mActiveRequestCount.incrementAndGet(); | 264 mActiveRequestCount.incrementAndGet(); |
| 157 } | 265 } |
| 158 | 266 |
| 159 /** | 267 /** |
| 160 * Mark request as completed to allow shutdown when there are no active | 268 * Mark request as completed to allow shutdown when there are no active |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 202 @CalledByNative | 310 @CalledByNative |
| 203 private void initNetworkThread() { | 311 private void initNetworkThread() { |
| 204 synchronized (mLock) { | 312 synchronized (mLock) { |
| 205 mNetworkThread = Thread.currentThread(); | 313 mNetworkThread = Thread.currentThread(); |
| 206 mInitCompleted.open(); | 314 mInitCompleted.open(); |
| 207 } | 315 } |
| 208 Thread.currentThread().setName("ChromiumNet"); | 316 Thread.currentThread().setName("ChromiumNet"); |
| 209 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); | 317 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); |
| 210 } | 318 } |
| 211 | 319 |
| 320 @SuppressWarnings("unused") | |
| 321 @CalledByNative | |
| 322 private void onRttObservation(final int rttMs, final long whenMs, final int source) { | |
| 323 Runnable task = new Runnable() { | |
| 324 @Override | |
| 325 public void run() { | |
| 326 synchronized (mNetworkQualityLock) { | |
| 327 for (NetworkQualityRttListener listener : mRttListenerList) { | |
| 328 listener.onRttObservation(rttMs, whenMs, source); | |
| 329 } | |
| 330 } | |
| 331 } | |
| 332 }; | |
| 333 postObservationTaskToExecutor(task); | |
| 334 } | |
| 335 | |
| 336 @SuppressWarnings("unused") | |
| 337 @CalledByNative | |
| 338 private void onThroughputObservation( | |
| 339 final int throughputKbps, final long whenMs, final int source) { | |
| 340 Runnable task = new Runnable() { | |
| 341 @Override | |
| 342 public void run() { | |
| 343 synchronized (mNetworkQualityLock) { | |
| 344 for (NetworkQualityThroughputListener listener : mThroughput ListenerList) { | |
| 345 listener.onThroughputObservation(throughputKbps, whenMs, source); | |
| 346 } | |
| 347 } | |
| 348 } | |
| 349 }; | |
| 350 postObservationTaskToExecutor(task); | |
| 351 } | |
| 352 | |
| 353 void postObservationTaskToExecutor(Runnable task) { | |
|
pauljensen
2015/10/06 19:10:28
Executor->NetworkQualityExecutor
so as to differen
pauljensen
2015/10/06 20:06:09
You didn't address this.
bengr
2015/10/06 20:33:14
Done.
| |
| 354 try { | |
| 355 mNetworkQualityExecutor.execute(task); | |
| 356 } catch (RejectedExecutionException failException) { | |
| 357 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception posting task to ex ecutor", | |
| 358 failException); | |
| 359 } | |
| 360 } | |
| 361 | |
| 212 // Native methods are implemented in cronet_url_request_context.cc. | 362 // Native methods are implemented in cronet_url_request_context.cc. |
| 213 private static native long nativeCreateRequestContextAdapter(String config); | 363 private static native long nativeCreateRequestContextAdapter(String config); |
| 214 | 364 |
| 215 private static native int nativeSetMinLogLevel(int loggingLevel); | 365 private static native int nativeSetMinLogLevel(int loggingLevel); |
| 216 | 366 |
| 217 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 367 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
| 218 private native void nativeDestroy(long nativePtr); | 368 private native void nativeDestroy(long nativePtr); |
| 219 | 369 |
| 220 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 370 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
| 221 private native void nativeStartNetLogToFile(long nativePtr, | 371 private native void nativeStartNetLogToFile(long nativePtr, |
| 222 String fileName, boolean logAll); | 372 String fileName, boolean logAll); |
| 223 | 373 |
| 224 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 374 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
| 225 private native void nativeStopNetLog(long nativePtr); | 375 private native void nativeStopNetLog(long nativePtr); |
| 226 | 376 |
| 227 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 377 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
| 228 private native void nativeInitRequestContextOnMainThread(long nativePtr); | 378 private native void nativeInitRequestContextOnMainThread(long nativePtr); |
| 379 | |
| 380 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | |
| 381 private native void nativeEnableNetworkQualityEstimator( | |
| 382 long nativePtr, boolean useLocalHostRequests, boolean useSmallerResp onses); | |
| 383 | |
| 384 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | |
| 385 private native void nativeProvideRTTObservations(long nativePtr, boolean sho uld); | |
| 386 | |
| 387 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | |
| 388 private native void nativeProvideThroughputObservations(long nativePtr, bool ean should); | |
| 229 } | 389 } |
| OLD | NEW |