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 |
| 24 /** | 26 /** |
| 25 * UrlRequestContext using Chromium HTTP stack implementation. | 27 * UrlRequestContext using Chromium HTTP stack implementation. |
| 26 */ | 28 */ |
| 27 @JNINamespace("cronet") | 29 @JNINamespace("cronet") |
| 28 @UsedByReflection("UrlRequestContext.java") | 30 @UsedByReflection("UrlRequestContext.java") |
| 29 class CronetUrlRequestContext extends UrlRequestContext { | 31 class CronetUrlRequestContext extends UrlRequestContext { |
| 30 private static final int LOG_NONE = 3; // LOG(FATAL), no VLOG. | 32 private static final int LOG_NONE = 3; // LOG(FATAL), no VLOG. |
| 31 private static final int LOG_DEBUG = -1; // LOG(FATAL...INFO), VLOG(1) | 33 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) | 34 private static final int LOG_VERBOSE = -2; // LOG(FATAL...INFO), VLOG(2) |
| 33 static final String LOG_TAG = "ChromiumNetwork"; | 35 static final String LOG_TAG = "ChromiumNetwork"; |
| 34 | 36 |
| 35 /** | 37 /** |
| 36 * Synchronize access to mUrlRequestContextAdapter and shutdown routine. | 38 * Synchronize access to mUrlRequestContextAdapter and shutdown routine. |
| 37 */ | 39 */ |
| 38 private final Object mLock = new Object(); | 40 private final Object mLock = new Object(); |
| 39 private final ConditionVariable mInitCompleted = new ConditionVariable(false ); | 41 private final ConditionVariable mInitCompleted = new ConditionVariable(false ); |
| 40 private final AtomicInteger mActiveRequestCount = new AtomicInteger(0); | 42 private final AtomicInteger mActiveRequestCount = new AtomicInteger(0); |
| 41 | 43 |
| 42 private long mUrlRequestContextAdapter = 0; | 44 private long mUrlRequestContextAdapter = 0; |
| 43 private Thread mNetworkThread; | 45 private Thread mNetworkThread; |
| 44 | 46 |
| 47 private Executor mNetworkQualityExecutor; | |
| 48 private final Object mNetworkQualityLock = new Object(); | |
|
pauljensen
2015/09/02 16:54:48
Please add a comment about what this is locking.
bengr
2015/09/14 21:04:35
Done.
| |
| 49 | |
| 50 private final ObserverList<NetworkQualityRTTObserver> mRTTObserverList = | |
|
pauljensen
2015/09/02 16:54:48
Can we use @GuardedBy?
bengr
2015/09/14 21:04:35
Done.
| |
| 51 new ObserverList<NetworkQualityRTTObserver>(); | |
| 52 private final ObserverList<NetworkQualityThroughputObserver> mThroughputObse rverList = | |
| 53 new ObserverList<NetworkQualityThroughputObserver>(); | |
| 54 | |
| 45 @UsedByReflection("UrlRequestContext.java") | 55 @UsedByReflection("UrlRequestContext.java") |
| 46 public CronetUrlRequestContext(Context context, | 56 public CronetUrlRequestContext(Context context, |
| 47 UrlRequestContextConfig config) { | 57 UrlRequestContextConfig config) { |
| 48 CronetLibraryLoader.ensureInitialized(context, config); | 58 CronetLibraryLoader.ensureInitialized(context, config); |
| 49 nativeSetMinLogLevel(getLoggingLevel()); | 59 nativeSetMinLogLevel(getLoggingLevel()); |
| 50 mUrlRequestContextAdapter = nativeCreateRequestContextAdapter(config.toS tring()); | 60 mUrlRequestContextAdapter = nativeCreateRequestContextAdapter(config.toS tring()); |
| 51 if (mUrlRequestContextAdapter == 0) { | 61 if (mUrlRequestContextAdapter == 0) { |
| 52 throw new NullPointerException("Context Adapter creation failed."); | 62 throw new NullPointerException("Context Adapter creation failed."); |
| 53 } | 63 } |
| 54 | 64 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 141 } | 151 } |
| 142 | 152 |
| 143 @Override | 153 @Override |
| 144 public void stopNetLog() { | 154 public void stopNetLog() { |
| 145 synchronized (mLock) { | 155 synchronized (mLock) { |
| 146 checkHaveAdapter(); | 156 checkHaveAdapter(); |
| 147 nativeStopNetLog(mUrlRequestContextAdapter); | 157 nativeStopNetLog(mUrlRequestContextAdapter); |
| 148 } | 158 } |
| 149 } | 159 } |
| 150 | 160 |
| 161 @Override | |
| 162 public void enableNetworkQualityEstimator(Executor executor) { | |
| 163 enableNetworkQualityEstimator(false, false, executor); | |
| 164 } | |
| 165 | |
| 166 @Override | |
| 167 void enableNetworkQualityEstimator( | |
| 168 boolean useLocalHostRequests, boolean useSmallerResponses, Executor executor) { | |
| 169 mNetworkQualityExecutor = executor; | |
| 170 synchronized (mLock) { | |
| 171 checkHaveAdapter(); | |
| 172 nativeEnableNetworkQualityEstimator( | |
| 173 mUrlRequestContextAdapter, useLocalHostRequests, useSmallerR esponses); | |
| 174 } | |
| 175 } | |
| 176 | |
| 177 @Override | |
| 178 public void addRTTObserver(NetworkQualityRTTObserver observer) { | |
| 179 if (mRTTObserverList.isEmpty()) { | |
|
pauljensen
2015/09/02 16:54:48
You lock mRTTObserverList on line 186 but not here
bengr
2015/09/14 21:04:35
Good catch. Thanks.
| |
| 180 synchronized (mLock) { | |
| 181 checkHaveAdapter(); | |
| 182 nativeProvideRTTObservations(mUrlRequestContextAdapter, true); | |
| 183 } | |
| 184 } | |
| 185 synchronized (mNetworkQualityLock) { | |
| 186 mRTTObserverList.addObserver(observer); | |
| 187 } | |
| 188 } | |
| 189 | |
| 190 @Override | |
| 191 public void removeRTTObserver(NetworkQualityRTTObserver observer) { | |
| 192 synchronized (mNetworkQualityLock) { | |
| 193 mRTTObserverList.removeObserver(observer); | |
| 194 } | |
| 195 if (mRTTObserverList.isEmpty()) { | |
| 196 synchronized (mLock) { | |
| 197 checkHaveAdapter(); | |
| 198 nativeProvideRTTObservations(mUrlRequestContextAdapter, false); | |
| 199 } | |
| 200 } | |
| 201 } | |
| 202 | |
| 203 @Override | |
| 204 public void addThroughputObserver(NetworkQualityThroughputObserver observer) { | |
| 205 if (mThroughputObserverList.isEmpty()) { | |
| 206 synchronized (mLock) { | |
| 207 checkHaveAdapter(); | |
| 208 nativeProvideThroughputObservations(mUrlRequestContextAdapter, t rue); | |
| 209 } | |
| 210 } | |
| 211 synchronized (mNetworkQualityLock) { | |
| 212 mThroughputObserverList.addObserver(observer); | |
| 213 } | |
| 214 } | |
| 215 | |
| 216 @Override | |
| 217 public void removeThroughputObserver(NetworkQualityThroughputObserver observ er) { | |
| 218 synchronized (mNetworkQualityLock) { | |
| 219 mThroughputObserverList.removeObserver(observer); | |
| 220 } | |
| 221 if (mThroughputObserverList.isEmpty()) { | |
| 222 synchronized (mLock) { | |
| 223 checkHaveAdapter(); | |
| 224 nativeProvideThroughputObservations(mUrlRequestContextAdapter, f alse); | |
| 225 } | |
| 226 } | |
| 227 } | |
| 228 | |
| 151 /** | 229 /** |
| 152 * Mark request as started to prevent shutdown when there are active | 230 * Mark request as started to prevent shutdown when there are active |
| 153 * requests. | 231 * requests. |
| 154 */ | 232 */ |
| 155 void onRequestStarted(UrlRequest urlRequest) { | 233 void onRequestStarted(UrlRequest urlRequest) { |
| 156 mActiveRequestCount.incrementAndGet(); | 234 mActiveRequestCount.incrementAndGet(); |
| 157 } | 235 } |
| 158 | 236 |
| 159 /** | 237 /** |
| 160 * Mark request as completed to allow shutdown when there are no active | 238 * 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 | 280 @CalledByNative |
| 203 private void initNetworkThread() { | 281 private void initNetworkThread() { |
| 204 synchronized (mLock) { | 282 synchronized (mLock) { |
| 205 mNetworkThread = Thread.currentThread(); | 283 mNetworkThread = Thread.currentThread(); |
| 206 mInitCompleted.open(); | 284 mInitCompleted.open(); |
| 207 } | 285 } |
| 208 Thread.currentThread().setName("ChromiumNet"); | 286 Thread.currentThread().setName("ChromiumNet"); |
| 209 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); | 287 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); |
| 210 } | 288 } |
| 211 | 289 |
| 290 @SuppressWarnings("unused") | |
| 291 @CalledByNative | |
| 292 private void onRTTObservation(final int value, final long when, final int so urce) { | |
| 293 Runnable task = new Runnable() { | |
| 294 @Override | |
| 295 public void run() { | |
| 296 for (NetworkQualityRTTObserver observer : mRTTObserverList) { | |
| 297 observer.onRTTObservation(value, when, source); | |
| 298 } | |
| 299 } | |
| 300 }; | |
| 301 postObservationTaskToExecutor(task); | |
| 302 } | |
| 303 | |
| 304 @SuppressWarnings("unused") | |
| 305 @CalledByNative | |
| 306 private void onThroughputObservation(final int value, final long when, final int source) { | |
| 307 Runnable task = new Runnable() { | |
| 308 @Override | |
| 309 public void run() { | |
| 310 for (NetworkQualityThroughputObserver observer : mThroughputObse rverList) { | |
| 311 observer.onThroughputObservation(value, when, source); | |
| 312 } | |
| 313 } | |
| 314 }; | |
| 315 postObservationTaskToExecutor(task); | |
| 316 } | |
| 317 | |
| 318 void postObservationTaskToExecutor(Runnable task) { | |
| 319 try { | |
| 320 synchronized (mNetworkQualityLock) { | |
| 321 mNetworkQualityExecutor.execute(task); | |
| 322 } | |
| 323 } catch (RejectedExecutionException failException) { | |
| 324 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception posting task to ex ecutor", | |
| 325 failException); | |
| 326 } | |
| 327 } | |
| 328 | |
| 212 // Native methods are implemented in cronet_url_request_context.cc. | 329 // Native methods are implemented in cronet_url_request_context.cc. |
| 213 private static native long nativeCreateRequestContextAdapter(String config); | 330 private static native long nativeCreateRequestContextAdapter(String config); |
| 214 | 331 |
| 215 private static native int nativeSetMinLogLevel(int loggingLevel); | 332 private static native int nativeSetMinLogLevel(int loggingLevel); |
| 216 | 333 |
| 217 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 334 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
| 218 private native void nativeDestroy(long nativePtr); | 335 private native void nativeDestroy(long nativePtr); |
| 219 | 336 |
| 220 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 337 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
| 221 private native void nativeStartNetLogToFile(long nativePtr, | 338 private native void nativeStartNetLogToFile(long nativePtr, |
| 222 String fileName, boolean logAll); | 339 String fileName, boolean logAll); |
| 223 | 340 |
| 224 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 341 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
| 225 private native void nativeStopNetLog(long nativePtr); | 342 private native void nativeStopNetLog(long nativePtr); |
| 226 | 343 |
| 227 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 344 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
| 228 private native void nativeInitRequestContextOnMainThread(long nativePtr); | 345 private native void nativeInitRequestContextOnMainThread(long nativePtr); |
| 346 | |
| 347 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | |
| 348 private native void nativeEnableNetworkQualityEstimator( | |
| 349 long nativePtr, boolean useLocalHostRequests, boolean useSmallerResp onses); | |
| 350 | |
| 351 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | |
| 352 private native void nativeProvideRTTObservations(long nativePtr, boolean sho uld); | |
| 353 | |
| 354 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | |
| 355 private native void nativeProvideThroughputObservations(long nativePtr, bool ean should); | |
| 229 } | 356 } |
| OLD | NEW |