refactor(android): replace image path usage with image uris #906
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Platforms affected
Android
Motivation and Context
Note this contains #902 will rebase after merge.
Raw system file paths are dangerous to use nowadays since they are often restricted, especially when dealing with external filesystems or filesystems that might not even be on-device (e.g. Google Drive).
Therefore all usages of
imageFilePath
was removed and replaced withimageUri
.Code that used
imageFilePath
generally now accepts aUri
instead or anInputStream
.Description
readData / getPageSize
Utility methods to read data into memory. getPageSize is an optimization to read a page of memory, which is usually 4kb but Android 15 devices may be shipped with 16kb page size devices.
There is a lot of disk usage when processing images which might be necessary back in the day when RAM is limited but modern devices have plenty of RAM to deal with image content. It's far more efficient to read the data into memory once and provide several instances of in-memory data streams instead of constantly reading data from disk. (See notes on
getScaledAndRotatedBitmap
for more details)ExifHelper
A new method exposed to instantiate via
InputStream
.getScaledAndRotatedBitmap
No longer accepts a file path. Instead it accepts the raw binary data. It no longer opens or manages it's own stream.
It will create
ByteArrayInputStream
which is a stream that doesn't require to be closed, as it operates on in-memory data. It doesn't need to manage kernel objects like file descriptors.Older code used to create several read streams and read the input source from disk several times. It also created temporary files which was deemed a requirement when dealing with "off-device" files such as Google Drive. There is some truth to this, but temporary files isn't necessary. Data can be read from in-memory instead saving the need to constantly read and write from disk. Content Resolver APIs can also obtain some data like mime type.
Therefore lots of stream management code was removed, which allowed us to remove a lot of try/catches as well. Using the exif changes, we use a
ByteArrayInputStream
instead virtually everywheresfileStream
was previously used.Note that this is used when sourcing an image from a gallery, it has an unrelated issue that is out of scope of this PR that causes it to not use the result of the modifications and instead returns the original image anyway.
Sourcing an image from camera and applying modifications via
targetWidth
ortargetHeight
does work as expected.on save instance / on restore instance
the image file path key and serialization/restoration were removed.
processResultFromCamera
sourcePath
was replaced withInputStream input
.croppedFilePath
is still used and is wrapped by aFileInputStream
. Refactoring this file path is out of scope of this particular PR, which is only applicable ifallowEdit
is enabled.Otherwise
imageUri
is used and resolved by the content resolver.input
is then asserted for non null, and throwsIOException
otherwise.The input is then read into memory and stored in
sourceData
which is fed intogetScaledAndRotatedBitmap
. See notes above.Other Changes
I realise there's a ton of other "format" changes, which
Android Studio IDE is responsible for and I do plan on cleaning them up in another PR.
Testing
Manual testing on API 28 (for non-scoped access framework) & 34 (for scoped access framework).
Paramedic tests passes.
Checklist
(platform)
if this change only applies to one platform (e.g.(android)
)