firebase/firebase-android-sdk

StrictMode policy violation: `android.os.strictmode.UnbufferedIoViolation` when upgrading to `targetSdkVersion 34`

gubatron opened this issue · 4 comments

[REQUIRED] Step 2: Describe your environment

  • Android Studio version: Android Studio Meerkat | 2024.3.1 Canary 3
  • Firebase Component: com.google.firebase:firebase-bom:33.7.0, com.google.firebase:firebase-crashlytics
  • Component version: 33.7.0

[REQUIRED] Step 3: Describe the problem

Firebase crashlytics incurrs in an Unbuffered IO Violation when building our app for target SDK 34 upon loading the library on app startup.

Steps to reproduce:

Start the app, this comes out in the logs:

D  Initializing WorkManager with default configuration.
2024-12-05 12:41:26.080  6029-6062  StrictMode              com.frostwire.android                D  StrictMode policy violation: android.os.strictmode.UnbufferedIoViolation
                                                                                                    	at android.os.StrictMode$AndroidBlockGuardPolicy.onUnbufferedIO(StrictMode.java:1655)
                                                                                                    	at libcore.io.IoTracker.trackIo(IoTracker.java:35)
                                                                                                    	at libcore.io.IoTracker.trackIo(IoTracker.java:45)
                                                                                                    	at java.io.FileInputStream.read(FileInputStream.java:325)
                                                                                                    	at android.os.ParcelFileDescriptor$AutoCloseInputStream.read(ParcelFileDescriptor.java:1032)
                                                                                                    	at java.util.zip.InflaterInputStream.fill(InflaterInputStream.java:263)
                                                                                                    	at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:178)
                                                                                                    	at java.util.zip.GZIPInputStream.read(GZIPInputStream.java:135)
                                                                                                    	at java.io.FilterInputStream.read(FilterInputStream.java:107)
                                                                                                    	at com.google.firebase.crashlytics.internal.common.SessionReportingCoordinator.convertInputStreamToString(SessionReportingCoordinator.java:425)
                                                                                                    	at com.google.firebase.crashlytics.internal.common.SessionReportingCoordinator.convertApplicationExitInfo(SessionReportingCoordinator.java:396)
                                                                                                    	at com.google.firebase.crashlytics.internal.common.SessionReportingCoordinator.persistRelevantAppExitInfoEvent(SessionReportingCoordinator.java:152)
                                                                                                    	at com.google.firebase.crashlytics.internal.common.CrashlyticsController.writeApplicationExitInfoEventIfRelevant(CrashlyticsController.java:910)
                                                                                                    	at com.google.firebase.crashlytics.internal.common.CrashlyticsController.doCloseSessions(CrashlyticsController.java:578)
                                                                                                    	at com.google.firebase.crashlytics.internal.common.CrashlyticsController.finalizeSessions(CrashlyticsController.java:506)
                                                                                                    	at com.google.firebase.crashlytics.internal.common.CrashlyticsCore.doBackgroundInitialization(CrashlyticsCore.java:250)
                                                                                                    	at com.google.firebase.crashlytics.internal.common.CrashlyticsCore.lambda$doBackgroundInitializationAsync$0(CrashlyticsCore.java:227)
                                                                                                    	at com.google.firebase.crashlytics.internal.common.CrashlyticsCore.$r8$lambda$knH5rP9MzxyK2lsYoMqMtYQH4kA(CrashlyticsCore.java:0)
                                                                                                    	at com.google.firebase.crashlytics.internal.common.CrashlyticsCore$$ExternalSyntheticLambda0.run(R8$$SyntheticClass:0)
                                                                                                    	at com.google.firebase.crashlytics.internal.concurrency.CrashlyticsWorker.lambda$submit$1(CrashlyticsWorker.java:96)
                                                                                                    	at com.google.firebase.crashlytics.internal.concurrency.CrashlyticsWorker.$r8$lambda$QmZlDkBlDR5w6hZfr1BjiCUvNrE(CrashlyticsWorker.java:0)
                                                                                                    	at com.google.firebase.crashlytics.internal.concurrency.CrashlyticsWorker$$ExternalSyntheticLambda1.then(R8$$SyntheticClass:0)
                                                                                                    	at com.google.android.gms.tasks.zze.run(com.google.android.gms:play-services-tasks@@18.1.0:1)
                                                                                                    	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
                                                                                                    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
                                                                                                    	at com.google.firebase.concurrent.CustomThreadFactory.lambda$newThread$0(CustomThreadFactory.java:47)
                                                                                                    	at com.google.firebase.concurrent.CustomThreadFactory.$r8$lambda$XB8AY3Hcio74byWuTzgVEC3Hiek(CustomThreadFactory.java:0)
                                                                                                    	at com.google.firebase.concurrent.CustomThreadFactory$$ExternalSyntheticLambda0.run(R8$$SyntheticClass:0)
                                                                                                    	at java.lang.Thread.run(Thread.java:1012)

Relevant Code:

In your SessionReportingCoordinator.java you're not using Buffered IO:

 @VisibleForTesting
  @RequiresApi(api = Build.VERSION_CODES.KITKAT)
  public static String convertInputStreamToString(InputStream inputStream) throws IOException {
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    byte[] bytes = new byte[DEFAULT_BUFFER_SIZE];
    int length;
    while ((length = inputStream.read(bytes)) != -1) {
      byteArrayOutputStream.write(bytes, 0, length);
    }
    return byteArrayOutputStream.toString(StandardCharsets.UTF_8.name());
  }

Your code should be more like this to avoid the triggers in Android 14+

@VisibleForTesting
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public static String convertInputStreamToString(InputStream inputStream) throws IOException {
    try (BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
         ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
        byte[] bytes = new byte[DEFAULT_BUFFER_SIZE];
        int length;
        while ((length = bufferedInputStream.read(bytes)) != -1) {
            byteArrayOutputStream.write(bytes, 0, length);
        }
        return byteArrayOutputStream.toString(StandardCharsets.UTF_8.name());
    }
}

I found a few problems with this issue:

  • I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
  • This issue does not seem to follow the issue template. Make sure you provide all the required information.

previously dismissed here, I'm sure you'll get more reports as more developers need to start upgrading target sdk

Hi @gubatron, thank you for reporting the issue and submitting a pull request. I'll inform our engineers about the PR for review. Thanks!