Skip to content
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

[MEDIUM] [Android] Large images crashing the App - 'Canvas trying to draw too large' #34372

Closed
Julesssss opened this issue Jan 11, 2024 · 19 comments
Assignees
Labels
Engineering Internal Requires API changes or must be handled by Expensify staff SmartScan Wave5-free-submitters Weekly KSv2

Comments

@Julesssss
Copy link
Contributor

Julesssss commented Jan 11, 2024

Problem

The Android app crashes due to a Canvas OOM exception when the image dimensions are extremely large. This has been fixed in the past, but we recently switched to Expo Image so I believe we'll need a new solution.

FATAL EXCEPTION: main
    Process: com.expensify.chat, PID: 28882
    java.lang.RuntimeException: Canvas: trying to draw too large(149730560bytes) bitmap.
    	at android.graphics.RecordingCanvas.throwIfCannotDraw(RecordingCanvas.java:266)
    	at android.graphics.BaseRecordingCanvas.drawBitmap(BaseRecordingCanvas.java:94)
    	at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:549)
    	at android.widget.ImageView.onDraw(ImageView.java:1446)
    	at expo.modules.image.ExpoImageView.onDraw(ExpoImageView.kt:204)
    	at android.view.View.draw(View.java:23900)
    	at expo.modules.image.ExpoImageView.draw(ExpoImageView.kt:200)
    	at android.view.View.updateDisplayListIfDirty(View.java:22767)
    	at android.view.View.draw(View.java:23631)
    	at android.view.ViewGroup.drawChild(ViewGroup.java:4559)
    	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4320)
    	at android.view.View.updateDisplayListIfDirty(View.java:22758)
    	at android.view.View.draw(View.java:23631)
    	at android.view.ViewGroup.drawChild(ViewGroup.java:4559)
    	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4320)

We have spent time on different image libraries and many related issues, and I am now trying to combine our current issues and resolve the remaining canvas OOM exception.

  • Share a large image similar to this
  • Attempt to view the image as either a receipt upload or a regular image attachment

Solution

Collect all past attempts, recent merged PRs, and determine the best path forward for resolving the crash:

  • Here's where we merged Expo-Image
  • Here was a prior attempt to fix the image in react-native-fast-image
  • Another PR which attempted to fix the issue with an upstream react-native-fast-image PR
  • We introduced AttachmentGallary as an improvement to image scaling and a replacement to ImageZoom

Next question: Do we need a fix in Expo Image?

@Julesssss Julesssss changed the title [Android] Large images crashing the App -- Canvas trying to draw too large(149730560bytes) [Android] Large images crashing the App -- Canvas trying to draw too large Jan 11, 2024
@Julesssss Julesssss self-assigned this Jan 11, 2024
@Julesssss Julesssss added Daily KSv2 Engineering Internal Requires API changes or must be handled by Expensify staff SmartScan Wave5-free-submitters labels Jan 11, 2024
@Expensify Expensify deleted a comment from melvin-bot bot Jan 11, 2024
@Expensify Expensify deleted a comment from melvin-bot bot Jan 11, 2024
@Julesssss
Copy link
Contributor Author

No C+ required yet

@Julesssss Julesssss changed the title [Android] Large images crashing the App -- Canvas trying to draw too large [Android] Large images crashing the App - Canvas trying to draw too large Jan 11, 2024
@Julesssss Julesssss changed the title [Android] Large images crashing the App - Canvas trying to draw too large [Android] Large images crashing the App - 'Canvas trying to draw too large' Jan 11, 2024
@Julesssss Julesssss moved this to Release 5: Best in Class in [#whatsnext] Wave 05 - Deprecate Free Jan 11, 2024
@Julesssss
Copy link
Contributor Author

I reached out 1:1 to @WojtekBoman who implemented Expo Image, as I'm not 100% sure whether the exception is fixable within Expo Image or not. I can see some people suggesting that we disable native Android hardware acceleration -- but this worries me as this will likely reduce performance elsewhere...

I'm thinking that we might need to enable it just for the React Views that render potentially lage images

@Julesssss
Copy link
Contributor Author

I'm going to generate a couple of test builds to verify the fix and compare performance.

@Julesssss
Copy link
Contributor Author

Julesssss commented Jan 12, 2024

The crash is resolved... but at great cost.

As expected, disabling hardware acceleration leads to horrendous performance. We can't make this an app-wide change. My plan is to disable hardware acceleration just for the specific View/Window that displays image attachments -- this should resolve the crash without harming app performance.

@Julesssss
Copy link
Contributor Author

Before:

android-perf-before.mp4

After:

android-perf-after.mp4

@Julesssss
Copy link
Contributor Author

My plan is to disable hardware acceleration just for the specific View/Window that displays image attachments

To achieve this we could build our own module, or use this existing (but unknown) HardwareAccelerationViewManager library.

I'd much prefer to resolve this upstream within the Expo Image library though, so I'm going to ask SWM for help.

@melvin-bot melvin-bot bot removed the Overdue label Jan 15, 2024
@Julesssss
Copy link
Contributor Author

This is being passed onto the Expo team, we'll hopefully hear back soon.

@chrispader
Copy link
Contributor

Can't we just add a similar ResizeTransformation class to the expo-image library like in DylanVann/react-native-fast-image#1017 ?

expo-image also uses Glide, so shouldn't we just be able to attach it with .transform(new ResizeTransformation()) here, or somewhere else ?

(i just looked up this spot, might be a different line file/line)

@chrispader
Copy link
Contributor

Either upstream or in a patch, since i'm not sure if this would be the ideal fix for all users. But it most likely should fix the problem for E/App

@Julesssss
Copy link
Contributor Author

Can't we just add a similar ResizeTransformation class to the expo-image library like in DylanVann/react-native-fast-image#1017 ?

That sounds good, but let's first see what Expo team says 👍

@melvin-bot melvin-bot bot added the Overdue label Jan 29, 2024
@Julesssss
Copy link
Contributor Author

Waiting on response.

@Julesssss
Copy link
Contributor Author

Expo have released expo-image version 1.10.6, which should resolve this exception with changes to the native Android canvas.

This PR bumps the expo-image library and resolves the issue, but I'm having unrelated issues trying to build the Android app...

@Julesssss
Copy link
Contributor Author

The fix seemed to have not resolved our issue. We're in contact with the Expo team again

@melvin-bot melvin-bot bot removed the Overdue label Feb 14, 2024
@Julesssss
Copy link
Contributor Author

No update yet

@greg-schroeder greg-schroeder changed the title [Android] Large images crashing the App - 'Canvas trying to draw too large' [MEDIUM] [Android] Large images crashing the App - 'Canvas trying to draw too large' Feb 20, 2024
@Julesssss
Copy link
Contributor Author

Hey @chrispader, just wondering if you've heard anything else from Expo, or whether this conversation is taking place on a public GH repo?

@melvin-bot melvin-bot bot added the Overdue label Feb 28, 2024
@Julesssss
Copy link
Contributor Author

Awaiting response from Expo and @chrispader

@Julesssss
Copy link
Contributor Author

Asked for an update here

@melvin-bot melvin-bot bot removed the Overdue label Mar 13, 2024
@Julesssss
Copy link
Contributor Author

Fixed by #38671

@chrispader
Copy link
Contributor

Nice stuff! Sorry for not replying fast enough 🥲 I think this solution is valid, as long as expo-image takes care of the downsampling

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Engineering Internal Requires API changes or must be handled by Expensify staff SmartScan Wave5-free-submitters Weekly KSv2
Projects
No open projects
Development

No branches or pull requests

3 participants