Skip to content

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

@gubatron

Description

@gubatron

[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());
    }
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions