Repository navigation
fix(android): check item text before URI and avoid coercing URI items to text - #31
Conversation
thtbee
left a comment
There was a problem hiding this comment.
Thanks for splitting this out. The .filter { it.uri == null } before coerceToText is exactly the fix for #27.
A few things before it goes in:
isImageUriByMagicopens the file insideread(), which runs fromSendActivity.onWindowFocusChangedon the main thread. A slow provider (a cloud file, or a big file on an SD card) can stall the UI there. WhengetTypedoesn't say it's an image, treating it as not an image is fine: with the filter above, the worst case is that nothing gets sent, not garbled text. So I'd drop the sniffing, here and inreadImage, whereBitmapFactoryalready covers other formats.- The URI is now checked before the item's text. An item can carry both, and
descHasImagelooks at the whole clip rather than that item, so a text item in a clip that also holds an image would go out as an image. Checking the text first, as before, avoids that. - The title says it retries transient empty reads, but I don't see a retry in the diff. Could you update the title, or add the missing part?
For a test, there's no Robolectric in the project, so pulling the decision (text, URI, MIME type) into a small pure function and testing that with JUnit would cover the actual bug better than the header checks.
f374865 to
feb9d12
Compare
feb9d12 to
5a5991e
Compare
Signed-off-by: Jochen Kirstätter <7329802+jochenkirstaetter@users.noreply.github.com>
5a5991e to
bf2dee7
Compare
thtbee
left a comment
There was a problem hiding this comment.
Thanks, this reads really well now. selectClipItem as a pure function with those tests is a nice way to pin the bug down, and the text-first order and no sniffing are exactly what I hoped for.
Two small things, then I'm happy to merge:
descHasImagestill wins when Android knows the item isn't an image. In a clip with an image and a PDF, the PDF would come back asImageand fail later as unreadable. Using it only when the type is unknown keeps your untyped-image case working:mime?.startsWith("image/") == true || (mime == null && descHasImage).- The description still mentions retries and
sniffImageMime. Could you update it to match? It ends up as the record of the change.
When ContentResolver returns a non-image MIME type (e.g. application/pdf) for a clipboard URI, do not let descHasImage override it in selectClipItem. Signed-off-by: Jochen Kirstätter <7329802+jochenkirstaetter@users.noreply.github.com>
thtbee
left a comment
There was a problem hiding this comment.
Thanks, this looks right now. Text first, the image hint only when the resolver has no type, and no more coercing URIs. The tests cover the cases I was worried about.
What and why
Addresses #27:
PhoneClipboard.selectClipItem, checkitem.textbeforeitem.uriso clipboard items that carry both text and a URI keep their text rather than being misclassified as images.ClipDescription's image MIME hint (descHasImage) whenContentResolver.getType(uri)returnsnull, so non-image typed URIs (e.g.application/pdf) are not treated as images.coerceToTexton URI-backed clipboard items so Android does not stream raw binary content (or turn non-image URIs into raw content addresses).How it was tested
PhoneClipboardTest.ktcoveringPhoneClipboard.selectClipItemacross text+URI items, resolver-typed and untyped image URIs, non-image typed URIs (application/pdfwithdescHasImagebothfalseandtrue), andcoercedTextfallback for URI-less items.Checklist
./scripts/check.ps1passes (or the CI equivalent for the parts I changed)git commit -s), see CONTRIBUTING.md