Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
gubatron opened this issue Dec 5, 2024 · 15 comments

Comments

@gubatron
Copy link
Contributor

gubatron commented Dec 5, 2024

[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());
    }
}
@google-oss-bot
Copy link
Contributor

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.

@gubatron
Copy link
Contributor Author

gubatron commented Dec 5, 2024

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

@gubatron
Copy link
Contributor Author

gubatron commented Dec 5, 2024

Pull Request Here

@lehcar09
Copy link
Contributor

lehcar09 commented Dec 6, 2024

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

@mrober
Copy link
Contributor

mrober commented Mar 5, 2025

Hi @gubatron, I took a look at this. I am not seeing the strict mode violation in my own test app. I am not sure what conditions are required to reproduce it, could you please provide a MCVE? Your PR looks fine, I will be happy to review it once I can reproduce the issue.

@gubatron
Copy link
Contributor Author

gubatron commented Mar 5, 2025

Oh so nice to get a response.

This is how I was setting strictPolicy mode on:

static void setStrictPolicy(boolean enable) {
        LOG.info("RunStrict.setStrictPolicy(" + enable + ") Debug.isEnabled()=" + Debug.isEnabled());
        if (!Debug.isEnabled()) {
            LOG.info("StrictMode is disabled, this is a DEBUG build");
            return; // no debug mode, do nothing
        }

        // by default, the LAX policy
        StrictMode.ThreadPolicy threadPolicy = StrictMode.ThreadPolicy.LAX;
        StrictMode.VmPolicy vmPolicy = StrictMode.VmPolicy.LAX;

        if (enable) {
            threadPolicy = new StrictMode.ThreadPolicy.Builder()
                    .detectAll()
                    .penaltyLog()
                    .penaltyDeath()
                    .build();
            vmPolicy = new StrictMode.VmPolicy.Builder()
                    .detectAll()
                    .penaltyLog()
                    .penaltyDeath()
                    .setClassInstanceLimit(Engine.class, 1)
                    .build();
        }

        StrictMode.setThreadPolicy(threadPolicy);
        StrictMode.setVmPolicy(vmPolicy);
    }

If I call setStrictPolicy(true) and just start my app, whenever it tries to talk to firebase the violation is fired, when targeting sdk version 34

@mrober
Copy link
Contributor

mrober commented Mar 6, 2025

I was able to reproduce your issue and review your PR. It LGTM. I am not sure if you'll have to jump through hoops to merge it, let me know if you run into any problems.

Oh so nice to get a response.

There are only a few of us working on this, relax.

@google-oss-bot
Copy link
Contributor

Hey @gubatron. We need more information to resolve this issue but there hasn't been an update in 5 weekdays. I'm marking the issue as stale and if there are no new updates in the next 5 days I will close it automatically.

If you have more information that will help us get to the bottom of this, just add a comment!

@gubatron
Copy link
Contributor Author

dear bot, the issue has been replicated, and the patch looks good.
Not sure what else needs to happen to merge.
Damn bureocracies.

@lehcar09
Copy link
Contributor

Hi @gubatron, it looks like there is an issue in the CLA. You would need to accept the CLA to merge the PR. Could you confirm if you have accepted the CLA?

@gubatron
Copy link
Contributor Author

gubatron commented Mar 18, 2025

Hey @lehcar09 I believe I've contributed several patches before to open source Google projects, I signed the Google Contributor License Agreement back in 2014

Image

I just updated it to now have my github username, perhaps that was the issue?

Image

Image

Is there another one for Firebase I need to sign? please send link.
The patch should now be ready to go.

@lehcar09
Copy link
Contributor

lehcar09 commented Mar 18, 2025

The CLA you signed is the right one. I'll raise this to our engineer and see if we can merge the PR on your behalf. Thanks!

@lehcar09
Copy link
Contributor

Hey @gubatron, per checking with our Engineers, you need to do some extra steps. Could you try the steps mentioned here #6565 (comment)?

Also, please update the base branch to align with the current branch. Let me know how it goes.

@gubatron
Copy link
Contributor Author

sorry for the delay, out of the country at the moment on vacation

@gubatron
Copy link
Contributor Author

I think I've done that last step with the google-services.json and a repo secret
#6565 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants