mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Deprecate CronetEngineWrapper
PiperOrigin-RevId: 381239971
This commit is contained in:
parent
1cc62c65a7
commit
bcd4bb87e5
@ -23,7 +23,7 @@ import com.google.android.exoplayer2.RenderersFactory;
|
|||||||
import com.google.android.exoplayer2.database.DatabaseProvider;
|
import com.google.android.exoplayer2.database.DatabaseProvider;
|
||||||
import com.google.android.exoplayer2.database.ExoDatabaseProvider;
|
import com.google.android.exoplayer2.database.ExoDatabaseProvider;
|
||||||
import com.google.android.exoplayer2.ext.cronet.CronetDataSource;
|
import com.google.android.exoplayer2.ext.cronet.CronetDataSource;
|
||||||
import com.google.android.exoplayer2.ext.cronet.CronetEngineWrapper;
|
import com.google.android.exoplayer2.ext.cronet.CronetUtil;
|
||||||
import com.google.android.exoplayer2.offline.ActionFileUpgradeUtil;
|
import com.google.android.exoplayer2.offline.ActionFileUpgradeUtil;
|
||||||
import com.google.android.exoplayer2.offline.DefaultDownloadIndex;
|
import com.google.android.exoplayer2.offline.DefaultDownloadIndex;
|
||||||
import com.google.android.exoplayer2.offline.DownloadManager;
|
import com.google.android.exoplayer2.offline.DownloadManager;
|
||||||
@ -44,6 +44,8 @@ import java.net.CookieManager;
|
|||||||
import java.net.CookiePolicy;
|
import java.net.CookiePolicy;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
import org.chromium.net.CronetEngine;
|
||||||
|
|
||||||
/** Utility methods for the demo app. */
|
/** Utility methods for the demo app. */
|
||||||
public final class DemoUtil {
|
public final class DemoUtil {
|
||||||
@ -102,11 +104,16 @@ public final class DemoUtil {
|
|||||||
if (httpDataSourceFactory == null) {
|
if (httpDataSourceFactory == null) {
|
||||||
if (USE_CRONET_FOR_NETWORKING) {
|
if (USE_CRONET_FOR_NETWORKING) {
|
||||||
context = context.getApplicationContext();
|
context = context.getApplicationContext();
|
||||||
CronetEngineWrapper cronetEngineWrapper =
|
@Nullable
|
||||||
new CronetEngineWrapper(context, USER_AGENT, /* preferGMSCoreCronet= */ false);
|
CronetEngine cronetEngine =
|
||||||
httpDataSourceFactory =
|
CronetUtil.buildCronetEngine(context, USER_AGENT, /* preferGMSCoreCronet= */ false);
|
||||||
new CronetDataSource.Factory(cronetEngineWrapper, Executors.newSingleThreadExecutor());
|
if (cronetEngine != null) {
|
||||||
} else {
|
httpDataSourceFactory =
|
||||||
|
new CronetDataSource.Factory(cronetEngine, Executors.newSingleThreadExecutor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (httpDataSourceFactory == null) {
|
||||||
|
// We don't want to use Cronet, or we failed to instantiate a CronetEngine.
|
||||||
CookieManager cookieManager = new CookieManager();
|
CookieManager cookieManager = new CookieManager();
|
||||||
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);
|
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);
|
||||||
CookieHandler.setDefault(cookieManager);
|
CookieHandler.setDefault(cookieManager);
|
||||||
|
@ -18,16 +18,16 @@ package com.google.android.exoplayer2.ext.cronet;
|
|||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import com.google.android.exoplayer2.testutil.DataSourceContractTest;
|
import com.google.android.exoplayer2.testutil.DataSourceContractTest;
|
||||||
import com.google.android.exoplayer2.testutil.HttpDataSourceTestEnv;
|
import com.google.android.exoplayer2.testutil.HttpDataSourceTestEnv;
|
||||||
import com.google.android.exoplayer2.upstream.DataSource;
|
import com.google.android.exoplayer2.upstream.DataSource;
|
||||||
import com.google.android.exoplayer2.upstream.HttpDataSource;
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
import org.chromium.net.CronetEngine;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@ -46,15 +46,14 @@ public class CronetDataSourceContractTest extends DataSourceContractTest {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DataSource createDataSource() {
|
protected DataSource createDataSource() {
|
||||||
CronetEngineWrapper cronetEngineWrapper =
|
@Nullable
|
||||||
new CronetEngineWrapper(
|
CronetEngine cronetEngine =
|
||||||
|
CronetUtil.buildCronetEngine(
|
||||||
ApplicationProvider.getApplicationContext(),
|
ApplicationProvider.getApplicationContext(),
|
||||||
/* userAgent= */ "test-agent",
|
/* userAgent= */ "test-agent",
|
||||||
/* preferGMSCoreCronet= */ false);
|
/* preferGMSCoreCronet= */ false);
|
||||||
assertThat(cronetEngineWrapper.getCronetEngine()).isNotNull();
|
assertThat(cronetEngine).isNotNull();
|
||||||
return new CronetDataSource.Factory(cronetEngineWrapper.getCronetEngine(), executorService)
|
return new CronetDataSource.Factory(cronetEngine, executorService).createDataSource();
|
||||||
.setFallbackFactory(new InvalidDataSourceFactory())
|
|
||||||
.createDataSource();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -66,26 +65,4 @@ public class CronetDataSourceContractTest extends DataSourceContractTest {
|
|||||||
protected Uri getNotFoundUri() {
|
protected Uri getNotFoundUri() {
|
||||||
return Uri.parse(httpDataSourceTestEnv.getNonexistentUrl());
|
return Uri.parse(httpDataSourceTestEnv.getNonexistentUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* An {@link HttpDataSource.Factory} that throws {@link UnsupportedOperationException} on every
|
|
||||||
* interaction.
|
|
||||||
*/
|
|
||||||
private static class InvalidDataSourceFactory implements HttpDataSource.Factory {
|
|
||||||
@Override
|
|
||||||
public HttpDataSource createDataSource() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpDataSource.RequestProperties getDefaultRequestProperties() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpDataSource.Factory setDefaultRequestProperties(
|
|
||||||
Map<String, String> defaultRequestProperties) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,9 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource {
|
|||||||
/**
|
/**
|
||||||
* Creates an instance.
|
* Creates an instance.
|
||||||
*
|
*
|
||||||
* @param cronetEngine A {@link CronetEngine} to make the requests.
|
* @param cronetEngine A {@link CronetEngine} to make the requests. This should <em>not</em> be
|
||||||
|
* a fallback instance obtained from {@code JavaCronetProvider}. It's more efficient to use
|
||||||
|
* {@link DefaultHttpDataSource} instead in this case.
|
||||||
* @param executor The {@link java.util.concurrent.Executor} that will handle responses. This
|
* @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
|
* 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.
|
* thread hop from Cronet's internal network thread to the response handling thread.
|
||||||
|
@ -15,24 +15,23 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.ext.cronet;
|
package com.google.android.exoplayer2.ext.cronet;
|
||||||
|
|
||||||
import static java.lang.Math.min;
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.util.Log;
|
|
||||||
import com.google.android.exoplayer2.util.Util;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
|
||||||
import org.chromium.net.CronetEngine;
|
import org.chromium.net.CronetEngine;
|
||||||
import org.chromium.net.CronetProvider;
|
import org.chromium.net.CronetProvider;
|
||||||
|
|
||||||
/** A wrapper class for a {@link CronetEngine}. */
|
/**
|
||||||
|
* A wrapper class for a {@link CronetEngine}.
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link CronetEngine} directly. See the <a
|
||||||
|
* href="https://developer.android.com/guide/topics/connectivity/cronet/start">Android developer
|
||||||
|
* guide</a> to learn how to instantiate a {@link CronetEngine} for use by your application. You
|
||||||
|
* can also use {@link CronetUtil#buildCronetEngine} to build a {@link CronetEngine} suitable
|
||||||
|
* for use by ExoPlayer.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public final class CronetEngineWrapper {
|
public final class CronetEngineWrapper {
|
||||||
|
|
||||||
private static final String TAG = "CronetEngineWrapper";
|
|
||||||
|
|
||||||
@Nullable private final CronetEngine cronetEngine;
|
@Nullable private final CronetEngine cronetEngine;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,43 +58,7 @@ public final class CronetEngineWrapper {
|
|||||||
*/
|
*/
|
||||||
public CronetEngineWrapper(
|
public CronetEngineWrapper(
|
||||||
Context context, @Nullable String userAgent, boolean preferGMSCoreCronet) {
|
Context context, @Nullable String userAgent, boolean preferGMSCoreCronet) {
|
||||||
@Nullable CronetEngine cronetEngine = null;
|
cronetEngine = CronetUtil.buildCronetEngine(context, userAgent, preferGMSCoreCronet);
|
||||||
List<CronetProvider> cronetProviders = new ArrayList<>(CronetProvider.getAllProviders(context));
|
|
||||||
// Remove disabled and fallback Cronet providers from list
|
|
||||||
for (int i = cronetProviders.size() - 1; i >= 0; i--) {
|
|
||||||
if (!cronetProviders.get(i).isEnabled()
|
|
||||||
|| CronetProvider.PROVIDER_NAME_FALLBACK.equals(cronetProviders.get(i).getName())) {
|
|
||||||
cronetProviders.remove(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Sort remaining providers by type and version.
|
|
||||||
CronetProviderComparator providerComparator = new CronetProviderComparator(preferGMSCoreCronet);
|
|
||||||
Collections.sort(cronetProviders, providerComparator);
|
|
||||||
for (int i = 0; i < cronetProviders.size() && cronetEngine == null; i++) {
|
|
||||||
String providerName = cronetProviders.get(i).getName();
|
|
||||||
try {
|
|
||||||
CronetEngine.Builder cronetEngineBuilder = cronetProviders.get(i).createBuilder();
|
|
||||||
if (userAgent != null) {
|
|
||||||
cronetEngineBuilder.setUserAgent(userAgent);
|
|
||||||
}
|
|
||||||
cronetEngine = cronetEngineBuilder.build();
|
|
||||||
Log.d(TAG, "CronetEngine built using " + providerName);
|
|
||||||
} catch (SecurityException e) {
|
|
||||||
Log.w(
|
|
||||||
TAG,
|
|
||||||
"Failed to build CronetEngine. Please check if current process has "
|
|
||||||
+ "android.permission.ACCESS_NETWORK_STATE.");
|
|
||||||
} catch (UnsatisfiedLinkError e) {
|
|
||||||
Log.w(
|
|
||||||
TAG,
|
|
||||||
"Failed to link Cronet binaries. Please check if native Cronet binaries are "
|
|
||||||
+ "bundled into your app.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cronetEngine == null) {
|
|
||||||
Log.w(TAG, "CronetEngine could not be built.");
|
|
||||||
}
|
|
||||||
this.cronetEngine = cronetEngine;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,67 +79,4 @@ public final class CronetEngineWrapper {
|
|||||||
/* package */ CronetEngine getCronetEngine() {
|
/* package */ CronetEngine getCronetEngine() {
|
||||||
return cronetEngine;
|
return cronetEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class CronetProviderComparator implements Comparator<CronetProvider> {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copy of com.google.android.gms.net.CronetProviderInstaller.PROVIDER_NAME. We have our own
|
|
||||||
* copy because GMSCore CronetProvider classes are unavailable in some (internal to Google)
|
|
||||||
* build configurations.
|
|
||||||
*/
|
|
||||||
private static final String GMS_CORE_PROVIDER_NAME = "Google-Play-Services-Cronet-Provider";
|
|
||||||
|
|
||||||
private final boolean preferGMSCoreCronet;
|
|
||||||
|
|
||||||
public CronetProviderComparator(boolean preferGMSCoreCronet) {
|
|
||||||
this.preferGMSCoreCronet = preferGMSCoreCronet;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compare(CronetProvider providerLeft, CronetProvider providerRight) {
|
|
||||||
int providerComparison = getPriority(providerLeft) - getPriority(providerRight);
|
|
||||||
if (providerComparison != 0) {
|
|
||||||
return providerComparison;
|
|
||||||
}
|
|
||||||
return -compareVersionStrings(providerLeft.getVersion(), providerRight.getVersion());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the priority score for a Cronet provider, where a smaller score indicates higher
|
|
||||||
* priority.
|
|
||||||
*/
|
|
||||||
private int getPriority(CronetProvider provider) {
|
|
||||||
String providerName = provider.getName();
|
|
||||||
if (CronetProvider.PROVIDER_NAME_APP_PACKAGED.equals(providerName)) {
|
|
||||||
return 1;
|
|
||||||
} else if (GMS_CORE_PROVIDER_NAME.equals(providerName)) {
|
|
||||||
return preferGMSCoreCronet ? 0 : 2;
|
|
||||||
} else {
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Compares version strings of format "12.123.35.23". */
|
|
||||||
private static int compareVersionStrings(
|
|
||||||
@Nullable String versionLeft, @Nullable String versionRight) {
|
|
||||||
if (versionLeft == null || versionRight == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
String[] versionStringsLeft = Util.split(versionLeft, "\\.");
|
|
||||||
String[] versionStringsRight = Util.split(versionRight, "\\.");
|
|
||||||
int minLength = min(versionStringsLeft.length, versionStringsRight.length);
|
|
||||||
for (int i = 0; i < minLength; i++) {
|
|
||||||
if (!versionStringsLeft[i].equals(versionStringsRight[i])) {
|
|
||||||
try {
|
|
||||||
int versionIntLeft = Integer.parseInt(versionStringsLeft[i]);
|
|
||||||
int versionIntRight = Integer.parseInt(versionStringsRight[i]);
|
|
||||||
return versionIntLeft - versionIntRight;
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.google.android.exoplayer2.ext.cronet;
|
||||||
|
|
||||||
|
import static java.lang.Math.min;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
|
||||||
|
import com.google.android.exoplayer2.util.Log;
|
||||||
|
import com.google.android.exoplayer2.util.Util;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import org.chromium.net.CronetEngine;
|
||||||
|
import org.chromium.net.CronetProvider;
|
||||||
|
|
||||||
|
/** Cronet utility methods. */
|
||||||
|
public final class CronetUtil {
|
||||||
|
|
||||||
|
private static final String TAG = "CronetUtil";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a {@link CronetEngine} suitable for use with ExoPlayer. When choosing a {@link
|
||||||
|
* CronetProvider Cronet provider} to build the {@link CronetEngine}, disabled providers are not
|
||||||
|
* considered. Neither are fallback providers, since it's more efficient to use {@link
|
||||||
|
* DefaultHttpDataSource} than it is to use {@link CronetDataSource} with a fallback {@link
|
||||||
|
* CronetEngine}.
|
||||||
|
*
|
||||||
|
* <p>Note that it's recommended for applications to create only one instance of {@link
|
||||||
|
* CronetEngine}, so if your application already has an instance for performing other networking,
|
||||||
|
* then that instance should be used and calling this method is unnecessary. See the <a
|
||||||
|
* href="https://developer.android.com/guide/topics/connectivity/cronet/start">Android developer
|
||||||
|
* guide</a> to learn more about using Cronet for network operations.
|
||||||
|
*
|
||||||
|
* @param context A context.
|
||||||
|
* @param userAgent A default user agent, or {@code null} to use a default user agent of the
|
||||||
|
* {@link CronetEngine}.
|
||||||
|
* @param preferGMSCoreCronet Whether Cronet from GMSCore should be preferred over natively
|
||||||
|
* bundled Cronet, if both are available.
|
||||||
|
* @return The {@link CronetEngine}, or {@code null} if no suitable engine could be built.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static CronetEngine buildCronetEngine(
|
||||||
|
Context context, @Nullable String userAgent, boolean preferGMSCoreCronet) {
|
||||||
|
List<CronetProvider> cronetProviders = new ArrayList<>(CronetProvider.getAllProviders(context));
|
||||||
|
// Remove disabled and fallback Cronet providers from list.
|
||||||
|
for (int i = cronetProviders.size() - 1; i >= 0; i--) {
|
||||||
|
if (!cronetProviders.get(i).isEnabled()
|
||||||
|
|| CronetProvider.PROVIDER_NAME_FALLBACK.equals(cronetProviders.get(i).getName())) {
|
||||||
|
cronetProviders.remove(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Sort remaining providers by type and version.
|
||||||
|
CronetProviderComparator providerComparator = new CronetProviderComparator(preferGMSCoreCronet);
|
||||||
|
Collections.sort(cronetProviders, providerComparator);
|
||||||
|
for (int i = 0; i < cronetProviders.size(); i++) {
|
||||||
|
String providerName = cronetProviders.get(i).getName();
|
||||||
|
try {
|
||||||
|
CronetEngine.Builder cronetEngineBuilder = cronetProviders.get(i).createBuilder();
|
||||||
|
if (userAgent != null) {
|
||||||
|
cronetEngineBuilder.setUserAgent(userAgent);
|
||||||
|
}
|
||||||
|
CronetEngine cronetEngine = cronetEngineBuilder.build();
|
||||||
|
Log.d(TAG, "CronetEngine built using " + providerName);
|
||||||
|
return cronetEngine;
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
Log.w(
|
||||||
|
TAG,
|
||||||
|
"Failed to build CronetEngine. Please check if current process has "
|
||||||
|
+ "android.permission.ACCESS_NETWORK_STATE.");
|
||||||
|
} catch (UnsatisfiedLinkError e) {
|
||||||
|
Log.w(
|
||||||
|
TAG,
|
||||||
|
"Failed to link Cronet binaries. Please check if native Cronet binaries are "
|
||||||
|
+ "bundled into your app.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.w(TAG, "CronetEngine could not be built.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CronetUtil() {}
|
||||||
|
|
||||||
|
private static class CronetProviderComparator implements Comparator<CronetProvider> {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy of com.google.android.gms.net.CronetProviderInstaller.PROVIDER_NAME. We have our own
|
||||||
|
* copy because GMSCore CronetProvider classes are unavailable in some (internal to Google)
|
||||||
|
* build configurations.
|
||||||
|
*/
|
||||||
|
private static final String GMS_CORE_PROVIDER_NAME = "Google-Play-Services-Cronet-Provider";
|
||||||
|
|
||||||
|
private final boolean preferGMSCoreCronet;
|
||||||
|
|
||||||
|
public CronetProviderComparator(boolean preferGMSCoreCronet) {
|
||||||
|
this.preferGMSCoreCronet = preferGMSCoreCronet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(CronetProvider providerLeft, CronetProvider providerRight) {
|
||||||
|
int providerComparison = getPriority(providerLeft) - getPriority(providerRight);
|
||||||
|
if (providerComparison != 0) {
|
||||||
|
return providerComparison;
|
||||||
|
}
|
||||||
|
return -compareVersionStrings(providerLeft.getVersion(), providerRight.getVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the priority score for a Cronet provider, where a smaller score indicates higher
|
||||||
|
* priority.
|
||||||
|
*/
|
||||||
|
private int getPriority(CronetProvider provider) {
|
||||||
|
String providerName = provider.getName();
|
||||||
|
if (CronetProvider.PROVIDER_NAME_APP_PACKAGED.equals(providerName)) {
|
||||||
|
return 1;
|
||||||
|
} else if (GMS_CORE_PROVIDER_NAME.equals(providerName)) {
|
||||||
|
return preferGMSCoreCronet ? 0 : 2;
|
||||||
|
} else {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Compares version strings of format "12.123.35.23". */
|
||||||
|
private static int compareVersionStrings(
|
||||||
|
@Nullable String versionLeft, @Nullable String versionRight) {
|
||||||
|
if (versionLeft == null || versionRight == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
String[] versionStringsLeft = Util.split(versionLeft, "\\.");
|
||||||
|
String[] versionStringsRight = Util.split(versionRight, "\\.");
|
||||||
|
int minLength = min(versionStringsLeft.length, versionStringsRight.length);
|
||||||
|
for (int i = 0; i < minLength; i++) {
|
||||||
|
if (!versionStringsLeft[i].equals(versionStringsRight[i])) {
|
||||||
|
try {
|
||||||
|
int versionIntLeft = Integer.parseInt(versionStringsLeft[i]);
|
||||||
|
int versionIntRight = Integer.parseInt(versionStringsRight[i]);
|
||||||
|
return versionIntLeft - versionIntRight;
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -34,7 +34,6 @@ import static org.mockito.Mockito.when;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.ConditionVariable;
|
import android.os.ConditionVariable;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||||
@ -119,7 +118,7 @@ public final class CronetDataSourceTest {
|
|||||||
executorService = Executors.newSingleThreadExecutor();
|
executorService = Executors.newSingleThreadExecutor();
|
||||||
dataSourceUnderTest =
|
dataSourceUnderTest =
|
||||||
(CronetDataSource)
|
(CronetDataSource)
|
||||||
new CronetDataSource.Factory(new CronetEngineWrapper(mockCronetEngine), executorService)
|
new CronetDataSource.Factory(mockCronetEngine, executorService)
|
||||||
.setConnectionTimeoutMs(TEST_CONNECT_TIMEOUT_MS)
|
.setConnectionTimeoutMs(TEST_CONNECT_TIMEOUT_MS)
|
||||||
.setReadTimeoutMs(TEST_READ_TIMEOUT_MS)
|
.setReadTimeoutMs(TEST_READ_TIMEOUT_MS)
|
||||||
.setResetTimeoutOnRedirects(true)
|
.setResetTimeoutOnRedirects(true)
|
||||||
@ -1174,7 +1173,7 @@ public final class CronetDataSourceTest {
|
|||||||
throws HttpDataSourceException {
|
throws HttpDataSourceException {
|
||||||
dataSourceUnderTest =
|
dataSourceUnderTest =
|
||||||
(CronetDataSource)
|
(CronetDataSource)
|
||||||
new CronetDataSource.Factory(new CronetEngineWrapper(mockCronetEngine), executorService)
|
new CronetDataSource.Factory(mockCronetEngine, executorService)
|
||||||
.setConnectionTimeoutMs(TEST_CONNECT_TIMEOUT_MS)
|
.setConnectionTimeoutMs(TEST_CONNECT_TIMEOUT_MS)
|
||||||
.setReadTimeoutMs(TEST_READ_TIMEOUT_MS)
|
.setReadTimeoutMs(TEST_READ_TIMEOUT_MS)
|
||||||
.setResetTimeoutOnRedirects(true)
|
.setResetTimeoutOnRedirects(true)
|
||||||
@ -1202,7 +1201,7 @@ public final class CronetDataSourceTest {
|
|||||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, 5000);
|
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, 5000);
|
||||||
dataSourceUnderTest =
|
dataSourceUnderTest =
|
||||||
(CronetDataSource)
|
(CronetDataSource)
|
||||||
new CronetDataSource.Factory(new CronetEngineWrapper(mockCronetEngine), executorService)
|
new CronetDataSource.Factory(mockCronetEngine, executorService)
|
||||||
.setConnectionTimeoutMs(TEST_CONNECT_TIMEOUT_MS)
|
.setConnectionTimeoutMs(TEST_CONNECT_TIMEOUT_MS)
|
||||||
.setReadTimeoutMs(TEST_READ_TIMEOUT_MS)
|
.setReadTimeoutMs(TEST_READ_TIMEOUT_MS)
|
||||||
.setResetTimeoutOnRedirects(true)
|
.setResetTimeoutOnRedirects(true)
|
||||||
@ -1239,7 +1238,7 @@ public final class CronetDataSourceTest {
|
|||||||
throws HttpDataSourceException {
|
throws HttpDataSourceException {
|
||||||
dataSourceUnderTest =
|
dataSourceUnderTest =
|
||||||
(CronetDataSource)
|
(CronetDataSource)
|
||||||
new CronetDataSource.Factory(new CronetEngineWrapper(mockCronetEngine), executorService)
|
new CronetDataSource.Factory(mockCronetEngine, executorService)
|
||||||
.setConnectionTimeoutMs(TEST_CONNECT_TIMEOUT_MS)
|
.setConnectionTimeoutMs(TEST_CONNECT_TIMEOUT_MS)
|
||||||
.setReadTimeoutMs(TEST_READ_TIMEOUT_MS)
|
.setReadTimeoutMs(TEST_READ_TIMEOUT_MS)
|
||||||
.setResetTimeoutOnRedirects(true)
|
.setResetTimeoutOnRedirects(true)
|
||||||
@ -1450,6 +1449,7 @@ public final class CronetDataSourceTest {
|
|||||||
verify(mockUrlRequestBuilder).allowDirectExecutor();
|
verify(mockUrlRequestBuilder).allowDirectExecutor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") // Tests deprecated fallback functionality.
|
||||||
@Test
|
@Test
|
||||||
public void factorySetFallbackHttpDataSourceFactory_cronetNotAvailable_usesFallbackFactory()
|
public void factorySetFallbackHttpDataSourceFactory_cronetNotAvailable_usesFallbackFactory()
|
||||||
throws HttpDataSourceException, InterruptedException {
|
throws HttpDataSourceException, InterruptedException {
|
||||||
@ -1470,10 +1470,11 @@ public final class CronetDataSourceTest {
|
|||||||
assertThat(headers.get("user-agent")).isEqualTo("customFallbackFactoryUserAgent");
|
assertThat(headers.get("user-agent")).isEqualTo("customFallbackFactoryUserAgent");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") // Tests deprecated fallback functionality.
|
||||||
@Test
|
@Test
|
||||||
public void
|
public void
|
||||||
factory_noFallbackFactoryCronetNotAvailable_delegateTransferListenerToInternalFallbackFactory()
|
factory_noFallbackFactoryCronetNotAvailable_delegateTransferListenerToInternalFallbackFactory()
|
||||||
throws HttpDataSourceException, InterruptedException {
|
throws HttpDataSourceException {
|
||||||
MockWebServer mockWebServer = new MockWebServer();
|
MockWebServer mockWebServer = new MockWebServer();
|
||||||
mockWebServer.enqueue(new MockResponse());
|
mockWebServer.enqueue(new MockResponse());
|
||||||
CronetEngineWrapper cronetEngineWrapper = new CronetEngineWrapper((CronetEngine) null);
|
CronetEngineWrapper cronetEngineWrapper = new CronetEngineWrapper((CronetEngine) null);
|
||||||
@ -1492,14 +1493,14 @@ public final class CronetDataSourceTest {
|
|||||||
.onTransferStart(eq(dataSourceUnderTest), eq(dataSpec), /* isNetwork= */ eq(true));
|
.onTransferStart(eq(dataSourceUnderTest), eq(dataSpec), /* isNetwork= */ eq(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") // Tests deprecated fallback functionality.
|
||||||
@Test
|
@Test
|
||||||
public void
|
public void
|
||||||
factory_noFallbackFactoryCronetNotAvailable_delegateDefaultRequestPropertiesToInternalFallbackFactory()
|
factory_noFallbackFactoryCronetNotAvailable_delegateDefaultRequestPropertiesToInternalFallbackFactory()
|
||||||
throws HttpDataSourceException, InterruptedException {
|
throws HttpDataSourceException, InterruptedException {
|
||||||
MockWebServer mockWebServer = new MockWebServer();
|
MockWebServer mockWebServer = new MockWebServer();
|
||||||
mockWebServer.enqueue(new MockResponse());
|
mockWebServer.enqueue(new MockResponse());
|
||||||
CronetEngineWrapper cronetEngineWrapper =
|
CronetEngineWrapper cronetEngineWrapper = new CronetEngineWrapper((CronetEngine) null);
|
||||||
new CronetEngineWrapper(ApplicationProvider.getApplicationContext());
|
|
||||||
Map<String, String> defaultRequestProperties = new HashMap<>();
|
Map<String, String> defaultRequestProperties = new HashMap<>();
|
||||||
defaultRequestProperties.put("0", "defaultRequestProperty0");
|
defaultRequestProperties.put("0", "defaultRequestProperty0");
|
||||||
HttpDataSource dataSourceUnderTest =
|
HttpDataSource dataSourceUnderTest =
|
||||||
@ -1515,6 +1516,7 @@ public final class CronetDataSourceTest {
|
|||||||
assertThat(dataSourceUnderTest).isInstanceOf(DefaultHttpDataSource.class);
|
assertThat(dataSourceUnderTest).isInstanceOf(DefaultHttpDataSource.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") // Tests deprecated fallback functionality.
|
||||||
@Test
|
@Test
|
||||||
public void
|
public void
|
||||||
factory_noFallbackFactoryCronetNotAvailable_delegateDefaultRequestPropertiesToInternalFallbackFactoryAfterCreation()
|
factory_noFallbackFactoryCronetNotAvailable_delegateDefaultRequestPropertiesToInternalFallbackFactoryAfterCreation()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user