diff --git a/mobile/library/java/org/chromium/net/impl/BUILD b/mobile/library/java/org/chromium/net/impl/BUILD index abe6192f52d4..1e4988b359fb 100644 --- a/mobile/library/java/org/chromium/net/impl/BUILD +++ b/mobile/library/java/org/chromium/net/impl/BUILD @@ -50,8 +50,6 @@ android_library( "//library/java/io/envoyproxy/envoymobile/engine/types:envoy_c_types_lib", "//library/java/org/chromium/net", "//library/java/org/chromium/net/urlconnection", - "//library/kotlin/io/envoyproxy/envoymobile:envoy_interfaces_lib", - "//library/kotlin/io/envoyproxy/envoymobile:envoy_lib", artifact("androidx.annotation:annotation"), ], ) diff --git a/mobile/library/java/org/chromium/net/impl/CronetBidirectionalStream.java b/mobile/library/java/org/chromium/net/impl/CronetBidirectionalStream.java index 6e084441c1ea..b63d290c64de 100644 --- a/mobile/library/java/org/chromium/net/impl/CronetBidirectionalStream.java +++ b/mobile/library/java/org/chromium/net/impl/CronetBidirectionalStream.java @@ -4,7 +4,7 @@ import androidx.annotation.GuardedBy; import androidx.annotation.IntDef; import androidx.annotation.VisibleForTesting; -import io.envoyproxy.envoymobile.Engine; +import io.envoyproxy.envoymobile.engine.EnvoyEngine; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.nio.ByteBuffer; @@ -806,7 +806,7 @@ public void run() { } interface CronetBidirectionalStreamJni { - long createBidirectionalStream(CronetBidirectionalStream caller, Engine envoyEngine, + long createBidirectionalStream(CronetBidirectionalStream caller, EnvoyEngine envoyEngine, boolean sendRequestHeadersAutomatically, boolean enableMetricsCollection, boolean trafficStatsTagSet, int trafficStatsTag, boolean trafficStatsUidSet, diff --git a/mobile/library/java/org/chromium/net/impl/CronetEngineBuilderImpl.java b/mobile/library/java/org/chromium/net/impl/CronetEngineBuilderImpl.java index 8aa0e7d5c0f6..fb2720a1b58a 100644 --- a/mobile/library/java/org/chromium/net/impl/CronetEngineBuilderImpl.java +++ b/mobile/library/java/org/chromium/net/impl/CronetEngineBuilderImpl.java @@ -6,7 +6,6 @@ import android.util.Base64; import androidx.annotation.IntDef; import androidx.annotation.VisibleForTesting; -import io.envoyproxy.envoymobile.LogLevel; import java.io.File; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -82,7 +81,7 @@ final static class Pkp { protected long mMockCertVerifier; private boolean mNetworkQualityEstimatorEnabled; private int mThreadPriority = INVALID_THREAD_PRIORITY; - private LogLevel mLogLevel = LogLevel.INFO; + private String mLogLevel = "info"; /** * Default config enables SPDY and QUIC, disables SDCH and HTTP cache. @@ -362,12 +361,12 @@ int threadPriority(int defaultThreadPriority) { return mThreadPriority == INVALID_THREAD_PRIORITY ? defaultThreadPriority : mThreadPriority; } - public CronetEngineBuilderImpl setLogLevel(LogLevel logLevel) { + public CronetEngineBuilderImpl setLogLevel(String logLevel) { mLogLevel = logLevel; return this; } - public LogLevel getLogLevel() { return mLogLevel; } + public String getLogLevel() { return mLogLevel; } /** * Returns {@link Context} for builder. diff --git a/mobile/library/java/org/chromium/net/impl/CronetUrlRequest.java b/mobile/library/java/org/chromium/net/impl/CronetUrlRequest.java index 5ec9ca99e68f..f4d42affbad6 100644 --- a/mobile/library/java/org/chromium/net/impl/CronetUrlRequest.java +++ b/mobile/library/java/org/chromium/net/impl/CronetUrlRequest.java @@ -6,12 +6,9 @@ import android.util.Log; import androidx.annotation.GuardedBy; import androidx.annotation.IntDef; -import io.envoyproxy.envoymobile.RequestHeaders; -import io.envoyproxy.envoymobile.RequestHeadersBuilder; -import io.envoyproxy.envoymobile.RequestMethod; -import io.envoyproxy.envoymobile.ResponseHeaders; -import io.envoyproxy.envoymobile.Stream; -import io.envoyproxy.envoymobile.UpstreamHttpProtocol; +import io.envoyproxy.envoymobile.engine.EnvoyHTTPStream; +import io.envoyproxy.envoymobile.engine.types.EnvoyHTTPCallbacks; +import io.envoyproxy.envoymobile.engine.types.EnvoyStreamIntel; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.net.MalformedURLException; @@ -24,6 +21,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Deque; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -122,7 +120,7 @@ public final class CronetUrlRequest extends UrlRequestBase { @StatusValues private volatile int mAdditionalStatusDetails = Status.INVALID; /* These change with redirects. */ - private Stream mStream; + private EnvoyHTTPStream mStream; private PausableSerializingExecutor mEnvoyCallbackExecutor; private String mCurrentUrl; private UrlResponseInfoImpl mUrlResponseInfo; @@ -278,7 +276,7 @@ private final class OutputStreamDataSink extends CronetUploadDataStream { @Override protected void finishEmptyBody() { - mStream.close(EMPTY_BYTE_BUFFER); + mStream.sendData(EMPTY_BYTE_BUFFER, /* endStream= */ true); } @Override @@ -288,11 +286,7 @@ protected int processSuccessfulRead(ByteBuffer buffer, boolean finalChunk) { // copied to the correct size. buffer = ByteBuffer.allocateDirect(buffer.remaining()).put(buffer); } - if (finalChunk) { - mStream.close(buffer); - } else { - mStream.sendData(buffer); - } + mStream.sendData(buffer, finalChunk); return buffer.capacity(); } @@ -328,6 +322,7 @@ private void enterErrorState(final CronetException error) { if (mCancelCalled.compareAndSet(false, true)) { if (mStream != null) { mStream.cancel(); + mStream = null; } } fireCloseUploadDataProvider(); @@ -397,14 +392,14 @@ public void followRedirect() { }); } - private void onResponseHeaders(ResponseHeaders responseHeaders, boolean lastCallback) { + private void onResponseHeaders(Map> responseHeaders, boolean lastCallback) { mAdditionalStatusDetails = Status.WAITING_FOR_RESPONSE; if (mState.get() == State.CANCELLED) { return; } final List> headerList = new ArrayList<>(); String selectedTransport = "unknown"; - Set>> headers = responseHeaders.allHeaders().entrySet(); + Set>> headers = responseHeaders.entrySet(); for (Map.Entry> headerEntry : headers) { String headerKey = headerEntry.getKey(); @@ -421,8 +416,9 @@ private void onResponseHeaders(ResponseHeaders responseHeaders, boolean lastCall } } } + List statuses = responseHeaders.get(":status"); int responseCode = - responseHeaders.getHttpStatus() == null ? -1 : responseHeaders.getHttpStatus(); + statuses != null && !statuses.isEmpty() ? Integer.valueOf(statuses.get(0)) : -1; // Important to copy the list here, because although we never concurrently modify // the list ourselves, user code might iterate over it while we're redirecting, and // that would throw ConcurrentModificationException. @@ -439,6 +435,7 @@ private void onResponseHeaders(ResponseHeaders responseHeaders, boolean lastCall mStream.cancel(); // This is not technically needed. // This deals with unwanted "setOnResponseData" callbacks. By API contract, response body // on a redirect is to be silently ignored. + mStream = null; mEnvoyCallbackExecutor.shutdown(); } fireRedirectReceived(locationFields.get(0)); @@ -478,9 +475,9 @@ private void fireRedirectReceived(final String locationField) { private void fireOpenConnection() { if (mInitialMethod == null) { - mInitialMethod = RequestMethod.GET.name(); + mInitialMethod = "GET"; } - RequestHeaders envoyRequestHeaders = + Map> envoyRequestHeaders = buildEnvoyRequestHeaders(mInitialMethod, mRequestHeaders, mUploadDataProvider, mUserAgent, mCurrentUrl, mCronvoyEngine.getBuilder().http2Enabled()); // The envoyCallbackExecutor is tied to the life cycle of the stream. If the stream is not @@ -497,37 +494,53 @@ private void fireOpenConnection() { // Note: none of these "callbacks" are getting executed immediately. The envoyCallbackExecutor // is in reality a task scheduler. The execution of these tasks are serialized - concurrency // issues should not be a concern here. - mStream = mCronvoyEngine.getEnvoyEngine() - .streamClient() - .newStreamPrototype() - .setOnResponseHeaders((responseHeaders, lastCallback, ignored) -> { - onResponseHeaders(responseHeaders, lastCallback); - return null; - }) - .setOnResponseData((data, lastCallback, ignored) -> { - mEnvoyCallbackExecutor.pause(); - mEndStream = lastCallback; - if (!mMostRecentBufferRead.compareAndSet(null, data)) { - throw new IllegalStateException("mostRecentBufferRead should be clear."); - } - processReadResult(); - return null; - }) - .setOnError((error, ignored) -> { - String message = "failed with error after " + error.getAttemptCount() + - " attempts. Message=[" + error.getMessage() + "] Code=[" + - error.getErrorCode() + "]"; - Throwable throwable = new CronetExceptionImpl(message, error.getCause()); - mCronvoyExecutor.execute(() -> enterCronetErrorState(throwable)); - return null; - }) - .setOnCancel((ignored) -> { - mCancelCalled.set(true); - cancel(); - return null; - }) - .start(mEnvoyCallbackExecutor) - .sendHeaders(envoyRequestHeaders, mUploadDataProvider == null); + mStream = mCronvoyEngine.getEnvoyEngine().startStream(new EnvoyHTTPCallbacks() { + private EnvoyHTTPStream attachedStream; + + @Override + public Executor getExecutor() { + return mEnvoyCallbackExecutor; + } + + @Override + public void onHeaders(Map> headers, boolean endStream, + EnvoyStreamIntel streamIntel) { + attachedStream = mStream; + onResponseHeaders(headers, endStream); + } + + @Override + public void onData(ByteBuffer data, boolean endStream, EnvoyStreamIntel streamIntel) { + if (attachedStream != mStream) { + return; + } + mEnvoyCallbackExecutor.pause(); + mEndStream = endStream; + if (!mMostRecentBufferRead.compareAndSet(null, data)) { + throw new IllegalStateException("mostRecentBufferRead should be clear."); + } + processReadResult(); + } + + @Override + public void onTrailers(Map> trailers, EnvoyStreamIntel streamIntel) {} + + @Override + public void onError(int errorCode, String message, int attemptCount, + EnvoyStreamIntel streamIntel) { + String errorMessage = "failed with error after " + attemptCount + " attempts. Message=[" + + message + "] Code=[" + errorCode + "]"; + Throwable throwable = new CronetExceptionImpl(errorMessage, /* cause= */ null); + mCronvoyExecutor.execute(() -> enterCronetErrorState(throwable)); + } + + @Override + public void onCancel(EnvoyStreamIntel streamIntel) { + mCancelCalled.set(true); + cancel(); + } + }, false); + mStream.sendHeaders(envoyRequestHeaders, mUploadDataProvider == null); if (mUploadDataProvider != null) { mOutputStreamDataSink = new OutputStreamDataSink(); // If this is not the first time, then UploadDataProvider.rewind() will be invoked first. @@ -536,20 +549,21 @@ private void fireOpenConnection() { })); } - private static RequestHeaders buildEnvoyRequestHeaders(String initialMethod, - HeadersList headersList, - UploadDataProvider uploadDataProvider, - String userAgent, String currentUrl, - boolean isHttp2Enabled) { + private static Map> + buildEnvoyRequestHeaders(String initialMethod, HeadersList headersList, + UploadDataProvider uploadDataProvider, String userAgent, + String currentUrl, boolean isHttp2Enabled) { + Map> headers = new LinkedHashMap<>(); final URL url; try { url = new URL(currentUrl); } catch (MalformedURLException e) { throw new IllegalArgumentException("Invalid URL", e); } - RequestMethod requestMethod = RequestMethod.valueOf(initialMethod); - RequestHeadersBuilder requestHeadersBuilder = new RequestHeadersBuilder( - requestMethod, url.getProtocol(), url.getAuthority(), url.getFile()); + headers.computeIfAbsent(":authority", unused -> new ArrayList<>()).add(url.getAuthority()); + headers.computeIfAbsent(":method", unused -> new ArrayList<>()).add(initialMethod); + headers.computeIfAbsent(":path", unused -> new ArrayList<>()).add(url.getFile()); + headers.computeIfAbsent(":scheme", unused -> new ArrayList<>()).add(url.getProtocol()); boolean hasUserAgent = false; boolean hasContentType = false; for (Map.Entry header : headersList) { @@ -557,19 +571,20 @@ private static RequestHeaders buildEnvoyRequestHeaders(String initialMethod, (header.getKey().equalsIgnoreCase(USER_AGENT) && !header.getValue().isEmpty()); hasContentType = hasContentType || (header.getKey().equalsIgnoreCase(CONTENT_TYPE) && !header.getValue().isEmpty()); - requestHeadersBuilder.add(header.getKey(), header.getValue()); + headers.computeIfAbsent(header.getKey(), unused -> new ArrayList<>()).add(header.getValue()); } if (!hasUserAgent) { - requestHeadersBuilder.add(USER_AGENT, userAgent); + headers.computeIfAbsent(USER_AGENT, unused -> new ArrayList<>()).add(userAgent); } if (!hasContentType && uploadDataProvider != null) { throw new IllegalArgumentException("Requests with upload data must have a Content-Type."); } - UpstreamHttpProtocol protocol = isHttp2Enabled && url.getProtocol().equalsIgnoreCase("https") - ? UpstreamHttpProtocol.HTTP2 - : UpstreamHttpProtocol.HTTP1; - requestHeadersBuilder.addUpstreamHttpProtocol(protocol); - return requestHeadersBuilder.build(); + String protocol = + isHttp2Enabled && url.getProtocol().equalsIgnoreCase("https") ? "http2" : "http1"; + + headers.computeIfAbsent("x-envoy-mobile-upstream-protocol", unused -> new ArrayList<>()) + .add(protocol); + return headers; } private Runnable errorSetting(final CheckedRunnable delegate) { diff --git a/mobile/library/java/org/chromium/net/impl/CronetUrlRequestContext.java b/mobile/library/java/org/chromium/net/impl/CronetUrlRequestContext.java index 35675affb60f..cf84664d6100 100644 --- a/mobile/library/java/org/chromium/net/impl/CronetUrlRequestContext.java +++ b/mobile/library/java/org/chromium/net/impl/CronetUrlRequestContext.java @@ -3,11 +3,21 @@ import static android.os.Process.THREAD_PRIORITY_BACKGROUND; import static android.os.Process.THREAD_PRIORITY_MORE_FAVORABLE; +import android.content.Context; import android.os.ConditionVariable; import androidx.annotation.GuardedBy; import androidx.annotation.VisibleForTesting; -import io.envoyproxy.envoymobile.AndroidEngineBuilder; -import io.envoyproxy.envoymobile.Engine; +import io.envoyproxy.envoymobile.engine.AndroidEngineImpl; +import io.envoyproxy.envoymobile.engine.AndroidJniLibrary; +import io.envoyproxy.envoymobile.engine.AndroidNetworkMonitor; +import io.envoyproxy.envoymobile.engine.EnvoyConfiguration; +import io.envoyproxy.envoymobile.engine.EnvoyEngine; +import io.envoyproxy.envoymobile.engine.EnvoyNativeFilterConfig; +import io.envoyproxy.envoymobile.engine.types.EnvoyEventTracker; +import io.envoyproxy.envoymobile.engine.types.EnvoyHTTPFilterFactory; +import io.envoyproxy.envoymobile.engine.types.EnvoyLogger; +import io.envoyproxy.envoymobile.engine.types.EnvoyOnEngineRunning; +import io.envoyproxy.envoymobile.engine.types.EnvoyStringAccessor; import java.io.IOException; import java.net.Proxy; import java.net.URL; @@ -15,6 +25,7 @@ import java.net.URLStreamHandlerFactory; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -53,7 +64,7 @@ public final class CronetUrlRequestContext extends CronetEngineBase { private final ConditionVariable mInitCompleted = new ConditionVariable(false); private final AtomicInteger mActiveRequestCount = new AtomicInteger(0); - @GuardedBy("mLock") private Engine mEngine; + @GuardedBy("mLock") private EnvoyEngine mEngine; /** * This field is accessed without synchronization, but only for the purposes of reference * equality comparison with other threads. If such a comparison is performed on the network @@ -66,8 +77,7 @@ public final class CronetUrlRequestContext extends CronetEngineBase { private final String mUserAgent; private final ExecutorService mExecutorService; private final CronetEngineBuilderImpl mBuilder; - private final AtomicReference mInitializationCompleter = - new AtomicReference(); + private final AtomicReference mInitializationCompleter = new AtomicReference<>(); /** * Locks operations on the list of RequestFinishedInfo.Listeners, because operations can happen @@ -79,7 +89,7 @@ public final class CronetUrlRequestContext extends CronetEngineBase { private final Map mFinishedListenerMap = new HashMap<>(); - public CronetUrlRequestContext(CronetEngineBuilderImpl builder) { + public CronetUrlRequestContext(NativeCronetEngineBuilderImpl builder) { mBuilder = builder; // On android, all background threads (and all threads that are part // of background processes) are put in a cgroup that is allowed to @@ -91,19 +101,16 @@ public CronetUrlRequestContext(CronetEngineBuilderImpl builder) { builder.threadPriority(THREAD_PRIORITY_BACKGROUND + THREAD_PRIORITY_MORE_FAVORABLE); mUserAgent = builder.getUserAgent(); synchronized (mLock) { - mEngine = new AndroidEngineBuilder(builder.getContext()) - .addLogLevel(builder.getLogLevel()) - .setOnEngineRunning(() -> { - mNetworkThread = Thread.currentThread(); - mInitCompleted.open(); - Runnable taskToExecuteWhenInitializationIsCompleted = - mInitializationCompleter.getAndSet(() -> {}); - if (taskToExecuteWhenInitializationIsCompleted != null) { - taskToExecuteWhenInitializationIsCompleted.run(); - } - return null; - }) - .build(); + mEngine = builder.createEngine(() -> { + mNetworkThread = Thread.currentThread(); + mInitCompleted.open(); + Runnable taskToExecuteWhenInitializationIsCompleted = + mInitializationCompleter.getAndSet(() -> {}); + if (taskToExecuteWhenInitializationIsCompleted != null) { + taskToExecuteWhenInitializationIsCompleted.run(); + } + return null; + }); } mExecutorService = new ThreadPoolExecutor(2, 10, 50, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), @@ -114,7 +121,7 @@ public CronetUrlRequestContext(CronetEngineBuilderImpl builder) { })); } - public Engine getEnvoyEngine() { + public EnvoyEngine getEnvoyEngine() { synchronized (mLock) { if (mEngine == null) { throw new IllegalStateException("Engine is shut down."); diff --git a/mobile/library/java/org/chromium/net/impl/NativeCronetEngineBuilderImpl.java b/mobile/library/java/org/chromium/net/impl/NativeCronetEngineBuilderImpl.java index cba7e273ba12..e244345673e9 100644 --- a/mobile/library/java/org/chromium/net/impl/NativeCronetEngineBuilderImpl.java +++ b/mobile/library/java/org/chromium/net/impl/NativeCronetEngineBuilderImpl.java @@ -1,6 +1,20 @@ package org.chromium.net.impl; import android.content.Context; +import io.envoyproxy.envoymobile.engine.AndroidEngineImpl; +import io.envoyproxy.envoymobile.engine.AndroidJniLibrary; +import io.envoyproxy.envoymobile.engine.AndroidNetworkMonitor; +import io.envoyproxy.envoymobile.engine.EnvoyConfiguration; +import io.envoyproxy.envoymobile.engine.EnvoyEngine; +import io.envoyproxy.envoymobile.engine.EnvoyNativeFilterConfig; +import io.envoyproxy.envoymobile.engine.types.EnvoyEventTracker; +import io.envoyproxy.envoymobile.engine.types.EnvoyHTTPFilterFactory; +import io.envoyproxy.envoymobile.engine.types.EnvoyLogger; +import io.envoyproxy.envoymobile.engine.types.EnvoyOnEngineRunning; +import io.envoyproxy.envoymobile.engine.types.EnvoyStringAccessor; +import java.util.Collections; +import java.util.List; +import java.util.Map; import org.chromium.net.ExperimentalCronetEngine; import org.chromium.net.ICronetEngineBuilder; @@ -8,9 +22,31 @@ * Implementation of {@link ICronetEngineBuilder} that builds native Cronet engine. */ public class NativeCronetEngineBuilderImpl extends CronetEngineBuilderImpl { + + private final EnvoyLogger mEnvoyLogger = null; + private final EnvoyEventTracker mEnvoyEventTracker = null; + private boolean mAdminInterfaceEnabled = false; + private String mGrpcStatsDomain = null; + private Integer mStatsDPort = null; + private int mConnectTimeoutSeconds = 30; + private int mDnsRefreshSeconds = 60; + private int mDnsFailureRefreshSecondsBase = 2; + private int mDnsFailureRefreshSecondsMax = 10; + private int mDnsQueryTimeoutSeconds = 25; + private String mDnsPreresolveHostnames = "[]"; + private int mH2ConnectionKeepaliveIdleIntervalMilliseconds = 100000000; + private int mH2ConnectionKeepaliveTimeoutSeconds = 10; + private int mStatsFlushSeconds = 60; + private int mStreamIdleTimeoutSeconds = 15; + private String mAppVersion = "unspecified"; + private String mAppId = "unspecified"; + private String mVirtualClusters = "[]"; + private List mPlatformFilterChain = Collections.emptyList(); + private List mNativeFilterChain = Collections.emptyList(); + private Map mStringAccessors = Collections.emptyMap(); + /** - * Builder for Native Cronet Engine. - * Default config enables SPDY, disables QUIC and HTTP cache. + * Builder for Native Cronet Engine. Default config enables SPDY, disables QUIC and HTTP cache. * * @param context Android {@link Context} for engine to use. */ @@ -23,4 +59,23 @@ public ExperimentalCronetEngine build() { } return new CronetUrlRequestContext(this); } + + EnvoyEngine createEngine(EnvoyOnEngineRunning onEngineRunning) { + AndroidEngineImpl engine = + new AndroidEngineImpl(getContext(), onEngineRunning, mEnvoyLogger, mEnvoyEventTracker); + AndroidJniLibrary.load(getContext()); + AndroidNetworkMonitor.load(getContext(), engine); + engine.runWithConfig(createEnvoyConfiguration(), getLogLevel()); + return engine; + } + + private EnvoyConfiguration createEnvoyConfiguration() { + return new EnvoyConfiguration( + mAdminInterfaceEnabled, mGrpcStatsDomain, mStatsDPort, mConnectTimeoutSeconds, + mDnsRefreshSeconds, mDnsFailureRefreshSecondsBase, mDnsFailureRefreshSecondsMax, + mDnsQueryTimeoutSeconds, mDnsPreresolveHostnames, + mH2ConnectionKeepaliveIdleIntervalMilliseconds, mH2ConnectionKeepaliveTimeoutSeconds, + mStatsFlushSeconds, mStreamIdleTimeoutSeconds, mAppVersion, mAppId, mVirtualClusters, + mNativeFilterChain, mPlatformFilterChain, mStringAccessors); + } } diff --git a/mobile/test/java/org/chromium/net/impl/CronvoyEngineTest.java b/mobile/test/java/org/chromium/net/impl/CronvoyEngineTest.java index 3c167612a006..ef8d1455953b 100644 --- a/mobile/test/java/org/chromium/net/impl/CronvoyEngineTest.java +++ b/mobile/test/java/org/chromium/net/impl/CronvoyEngineTest.java @@ -64,9 +64,10 @@ public static void shutdown() { @Before public void setUp() { if (cronvoyEngine == null) { - Context appContext = ApplicationProvider.getApplicationContext(); - cronvoyEngine = new CronetUrlRequestContext( - new NativeCronetEngineBuilderImpl(appContext).setUserAgent("Cronvoy")); + NativeCronetEngineBuilderImpl nativeCronetEngineBuilder = + new NativeCronetEngineBuilderImpl(ApplicationProvider.getApplicationContext()); + nativeCronetEngineBuilder.setUserAgent("Cronvoy"); + cronvoyEngine = new CronetUrlRequestContext(nativeCronetEngineBuilder); } } diff --git a/mobile/test/java/org/chromium/net/testing/CronetTestRule.java b/mobile/test/java/org/chromium/net/testing/CronetTestRule.java index 91f43adcd205..bf44efad9e98 100644 --- a/mobile/test/java/org/chromium/net/testing/CronetTestRule.java +++ b/mobile/test/java/org/chromium/net/testing/CronetTestRule.java @@ -68,7 +68,7 @@ public static class CronetTestFramework { private static ExperimentalCronetEngine createEngine(Context context) { ExperimentalCronetEngine.Builder builder = new ExperimentalCronetEngine.Builder(context); - ((CronetEngineBuilderImpl)builder.getBuilderDelegate()).setLogLevel(LogLevel.DEBUG); + ((CronetEngineBuilderImpl)builder.getBuilderDelegate()).setLogLevel("debug"); return builder.enableQuic(true).build(); }