dio icon indicating copy to clipboard operation
dio copied to clipboard

[native_dio_adapter] All network requests fail when Google Play services are unavailable

Open LukasMirbt opened this issue 3 months ago • 5 comments

Package

native_dio_adapter

Version

1.5.0

Operating-System

Android

Adapter

NativeAdapter

Steps to Reproduce

  1. Create an Android emulator that does not have access to Google Play Services (select Services -> Android Open Source)
  2. Make a network request on a Dio instance with a NativeAdapter
  3. Note that the request fails and an exception is thrown when initializing the CronetEngine.

Expected Result

NativeAdapter should gracefully handle devices without Google Play services (for example by falling back on IOClient).

Cronet can be embedded as a workaround but in my opinion it's quite a big footgun that all network requests fail on certain devices if the developer is not aware of how cronet_http interacts with Google Play services.

I created a draft PR with a possible approach for handling the issue.

Actual Result

NativeAdapter throws an exception and network requests fail.

JniException (Exception in Java code called through JNI: java.lang.RuntimeException: All available Cronet providers are disabled. A provider should be enabled before it can be used.
      
      java.lang.RuntimeException: All available Cronet providers are disabled. A provider should be enabled before it can be used.
      	at org.chromium.net.CronetEngine$Builder.getEnabledCronetProviders(CronetEngine.java:365)
      	at org.chromium.net.CronetEngine$Builder.createBuilderDelegate(CronetEngine.java:327)
      	at org.chromium.net.CronetEngine$Builder.<init>(CronetEngine.java:75)
      	at android.os.MessageQueue.nativePollOnce(Native Method)
      	at android.os.MessageQueue.next(MessageQueue.java:346)
      	at android.os.Looper.loopOnce(Looper.java:189)
      	at android.os.Looper.loop(Looper.java:317)
      	at android.app.ActivityThread.main(ActivityThread.java:8705)
      	at java.lang.reflect.Method.invoke(Native Method)
      	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
      	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:886)
      )

LukasMirbt avatar Sep 17 '25 17:09 LukasMirbt

Please check https://pub.dev/packages/cronet_http#use-embedded-cronet and cronets general documentation.

kuhnroyal avatar Sep 17 '25 20:09 kuhnroyal

Please check https://pub.dev/packages/cronet_http#use-embedded-cronet and cronets general documentation.

Hi! Yes, as mentioned:

Cronet can be embedded as a workaround but in my opinion it's quite a big footgun that all network requests fail on certain devices if the developer is not aware of how cronet_http interacts with Google Play services.

In my opinion, it would be a better experience for developers if native_dio_adapter gracefully falls back to IOClient instead of breaking users on certain devices. Let me know if you disagree!

LukasMirbt avatar Sep 17 '25 20:09 LukasMirbt

I think providing the fallback would be helpful, but maybe opt-in rather by default. Developers should have a chance to realize what they are doing is rely on a thrid-party service.

AlexV525 avatar Sep 18 '25 01:09 AlexV525

I think providing the fallback would be helpful, but maybe opt-in rather by default. Developers should have a chance to realize what they are doing is rely on a thrid-party service.

One important aspect of the fallback is to prevent breaking the app for developers that don't realize that this issue exists. By making it opt-in, only developers aware of the issue would benefit from the fallback.

I do think the fallback behavior also is useful for developers that want to support devices without Google Play services but do not want to add the extra ~5mb app size from embedding Cronet.

But in my opinion, the number one priority should be to never break any apps.

LukasMirbt avatar Sep 18 '25 12:09 LukasMirbt

I do think the fallback behavior also is useful for developers that want to support devices without Google Play services but do not want to add the extra ~5mb app size from embedding Cronet.

There are many useful things, but their gain could be minor. Adding such abilities as a default would bring mental baggage that developers would have more time to obtain precise info from a request, such as determine whether it's coming from native or Dart, or if it's caused by unavailable Play Service or underlying initialization error.

The initiative of the package was to provide only a bridge to native implementation, and that is how cronet_http and cupertino_http are designed to fit http. Please consider adding more tips/warnings or even a clear exception class to http that can be helpful to indicate No Cronet Service available through Google Play Service. I don't think we should cover so many cases.

EDIT: Sorry, I accidentally hit the close button.

AlexV525 avatar Sep 21 '25 12:09 AlexV525