diff --git a/extensions/cronet/src/androidTest/java/com/google/android/exoplayer2/ext/cronet/CronetDataSourceTest.java b/extensions/cronet/src/androidTest/java/com/google/android/exoplayer2/ext/cronet/CronetDataSourceTest.java index 246e23e172..06a356487e 100644 --- a/extensions/cronet/src/androidTest/java/com/google/android/exoplayer2/ext/cronet/CronetDataSourceTest.java +++ b/extensions/cronet/src/androidTest/java/com/google/android/exoplayer2/ext/cronet/CronetDataSourceTest.java @@ -124,6 +124,7 @@ public final class CronetDataSourceTest { when(mockCronetEngine.newUrlRequestBuilder( anyString(), any(UrlRequest.Callback.class), any(Executor.class))) .thenReturn(mockUrlRequestBuilder); + when(mockUrlRequestBuilder.allowDirectExecutor()).thenReturn(mockUrlRequestBuilder); when(mockUrlRequestBuilder.build()).thenReturn(mockUrlRequest); mockStatusResponse(); @@ -683,6 +684,15 @@ public final class CronetDataSourceTest { } } + @Test + public void testAllowDirectExecutor() throws HttpDataSourceException { + testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, 5000, null); + mockResponseStartSuccess(); + + dataSourceUnderTest.open(testDataSpec); + verify(mockUrlRequestBuilder).allowDirectExecutor(); + } + // Helper methods. private void mockStatusResponse() { diff --git a/extensions/cronet/src/main/java/com/google/android/exoplayer2/ext/cronet/CronetDataSource.java b/extensions/cronet/src/main/java/com/google/android/exoplayer2/ext/cronet/CronetDataSource.java index 4f15a6eabc..008a95abec 100644 --- a/extensions/cronet/src/main/java/com/google/android/exoplayer2/ext/cronet/CronetDataSource.java +++ b/extensions/cronet/src/main/java/com/google/android/exoplayer2/ext/cronet/CronetDataSource.java @@ -127,7 +127,11 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou /** * @param cronetEngine A CronetEngine. - * @param executor The {@link java.util.concurrent.Executor} that will perform the requests. + * @param executor The {@link java.util.concurrent.Executor} that will handle responses. + * This may be a direct executor (i.e. executes tasks on the calling thread) in order + * to avoid a thread hop from Cronet's internal network thread to the response handling + * thread. However, to avoid slowing down overall network performance, care must be taken + * to make sure response handling is a fast operation when using a direct executor. * @param contentTypePredicate An optional {@link Predicate}. If a content type is rejected by the * predicate then an {@link InvalidContentTypeException} is thrown from * {@link #open(DataSpec)}. @@ -141,7 +145,11 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou /** * @param cronetEngine A CronetEngine. - * @param executor The {@link java.util.concurrent.Executor} that will perform the requests. + * @param executor The {@link java.util.concurrent.Executor} that will handle responses. + * This may be a direct executor (i.e. executes tasks on the calling thread) in order + * to avoid a thread hop from Cronet's internal network thread to the response handling + * thread. However, to avoid slowing down overall network performance, care must be taken + * to make sure response handling is a fast operation when using a direct executor. * @param contentTypePredicate An optional {@link Predicate}. If a content type is rejected by the * predicate then an {@link InvalidContentTypeException} is thrown from * {@link #open(DataSpec)}. @@ -416,8 +424,8 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou // Internal methods. private UrlRequest buildRequest(DataSpec dataSpec) throws OpenException { - UrlRequest.Builder requestBuilder = cronetEngine.newUrlRequestBuilder(dataSpec.uri.toString(), - this, executor); + UrlRequest.Builder requestBuilder = cronetEngine.newUrlRequestBuilder( + dataSpec.uri.toString(), this, executor).allowDirectExecutor(); // Set the headers. boolean isContentTypeHeaderSet = false; if (defaultRequestProperties != null) {