Analysis of Cronet Source Code - Java Implementation

Analysis of Cronet Source Code - Java Implementation

Based on Chromium Tag 94.0.4606.52

Products

  • cronet_api.jar
  • cronet_impl_common_java.jar
  • cronet_impl_native_java.jar
  • cronet_impl_platform_java.jar

API

  • api
  • impl_common_java
  • impl_fake_java
  • impl_native_java
  • impl_platform_java

Class Relationships

  • CronetEngineExperimentalCronetEngineCronetEngineBaseCronetUrlRequestContextICronetEngineBuilderCronetEngineBuilderImplNativeCronetEngineBuilderImplNativeCronetEngineBuilderWithLibraryLoaderImplCronetEngine.BuilderExperimentalCronetEngine.Builder

JNI Header Files

Found in the compiled product directory gen/components/cronet/android/cronet_jni_headers:

  • CronetBidirectionalStream_jni.h
  • CronetLibraryLoader_jni.h
  • CronetUploadDataStream_jni.h
  • CronetUrlRequestContext_jni.h
  • CronetUrlRequest_jni.h

Creating Engine

Kotlin

val myBuilder = ExperimentalCronetEngine.Builder(this)
val cronetEngine: ExperimentalCronetEngine = myBuilder.build()        

The engine can be created using CronetEngine.Builder or ExperimentalCronetEngine.Builder. ExperimentalCronetEngine.Builder includes 3 additional APIs compared to CronetEngine.Builder:

Java

  • enableNetworkQualityEstimator
  • setExperimentalOptions
  • setThreadPriority

New Builder Implementation

Java

public Builder(ICronetEngineBuilder builderDelegate) {
    mBuilderDelegate = builderDelegate;
}

public Builder(Context context) {
    this(createBuilderDelegate(context));
}

private static ICronetEngineBuilder createBuilderDelegate(Context context) {
    List<CronetProvider> providers = new ArrayList<>(CronetProvider.getAllProviders(context));
    CronetProvider provider = getEnabledCronetProviders(context, providers).get(0);
    return provider.createBuilder().mBuilderDelegate;
}
        

The CronetProvider is obtained and sorted by version, with JavaCronetProvider always being the last fallback option.

Java

public static List<CronetProvider> getAllProviders(Context context) {
    Set<CronetProvider> providers = new LinkedHashSet<>();
    addCronetProviderFromResourceFile(context, providers);
    addCronetProviderImplByClassName(context, PLAY_SERVICES_CRONET_PROVIDER_CLASS, providers, false);
    addCronetProviderImplByClassName(context, GMS_CORE_CRONET_PROVIDER_CLASS, providers, false);
    addCronetProviderImplByClassName(context, NATIVE_CRONET_PROVIDER_CLASS, providers, false);
    addCronetProviderImplByClassName(context, JAVA_CRONET_PROVIDER_CLASS, providers, false);
    return Collections.unmodifiableList(new ArrayList<>(providers));
}        

If dependencies are added as follows:

Groovy

implementation 'com.google.android.gms:play-services-cronet:16.0.0'        

The provider from Google Play Services is loaded. The NativeCronetProvider and JavaCronetProvider are then sorted, with the first provider usually being NativeCronetProvider.

NativeCronetProvider.createBuilder

Java

@Override
public CronetEngine.Builder createBuilder() {
    ICronetEngineBuilder impl = new NativeCronetEngineBuilderWithLibraryLoaderImpl(mContext);
    return new ExperimentalCronetEngine.Builder(impl);
}        

An ExperimentalCronetEngine.Builder is created, with its member variable mBuilderDelegate being NativeCronetEngineBuilderWithLibraryLoaderImpl.

ExperimentalCronetEngine.Builder.build()

Java

@Override
public ExperimentalCronetEngine build() {
    return mBuilderDelegate.build();
}
        

This delegates the execution to NativeCronetEngineBuilderWithLibraryLoaderImpl.build.

Java

public class NativeCronetEngineBuilderWithLibraryLoaderImpl extends NativeCronetEngineBuilderImpl {
    private VersionSafeCallbacks.LibraryLoader mLibraryLoader;

    public NativeCronetEngineBuilderWithLibraryLoaderImpl(Context context) {
        super(context);
    }

    @Override
    public CronetEngineBuilderImpl setLibraryLoader(LibraryLoader loader) {
        mLibraryLoader = new VersionSafeCallbacks.LibraryLoader(loader);
        return this;
    }

    @Override
    VersionSafeCallbacks.LibraryLoader libraryLoader() {
        return mLibraryLoader;
    }
}
        

The NativeCronetEngineBuilderWithLibraryLoaderImpl does not have a build method; it executes its parent class NativeCronetEngineBuilderImpl.build.

Java

@Override
public ExperimentalCronetEngine build() {
    if (getUserAgent() == null) {
        setUserAgent(getDefaultUserAgent());
    }

    ExperimentalCronetEngine builder = new CronetUrlRequestContext(this);
    return builder;
}
        


CronetUrlRequestContext Constructor

Java

jpublic CronetUrlRequestContext(final CronetEngineBuilderImpl builder) {
    CronetLibraryLoader.ensureInitialized(builder.getContext(), builder);
    CronetUrlRequestContextJni.get().setMinLogLevel(getLoggingLevel());
    
    if (builder.httpCacheMode() == HttpCacheType.DISK) {
        mInUseStoragePath = builder.storagePath();
        synchronized (sInUseStoragePaths) {
            if (!sInUseStoragePaths.add(mInUseStoragePath)) {
                throw new IllegalStateException("Disk cache storage path already in use");
            }
        }
    } else {
        mInUseStoragePath = null;
    }
    mUrlRequestContextAdapter = 
}        

This constructor initializes the native library, sets the logging level, and configures the cache path, ultimately passing the configuration to the C++ layer to create RequestContextConfig and RequestContextAdapter.

This provides a basic overview of the key components and methods involved in creating and configuring a CronetEngine in Java.

要查看或添加评论,请登录

社区洞察

其他会员也浏览了