Skip to content

perf(mtp): try parent=0xFFFFFFFF for root listing before fallback#9

Merged
vdavid merged 1 commit into
vdavid:mainfrom
num13ru:root-listing
Apr 26, 2026
Merged

perf(mtp): try parent=0xFFFFFFFF for root listing before fallback#9
vdavid merged 1 commit into
vdavid:mainfrom
num13ru:root-listing

Conversation

@num13ru
Copy link
Copy Markdown
Contributor

@num13ru num13ru commented Apr 26, 2026

Summary

  • Root listing (list_objects_stream(None)) now tries parent=0xFFFFFFFF first for all devices, not just Android. Falls back to parent=0 only when the device rejects the request with an error.
  • Fixes a 110x over-fetch on Kindle Paperwhite (and likely other non-Android MTP devices) where GetObjectHandles(parent=0) returned every object on the storage (2541) instead of the 23 root-level items.
  • Adds tests for the fast path, fallback on error, empty-storage edge case, Kindle-specific vendor extension, and subfolder-skips-fast-path.

Approach

Instead of adding device-specific detection, make the fast path universal:

  1. Root listing → try GetObjectHandles(parent=0xFFFFFFFF) first
  2. Ok(handles) → return immediately with AndroidRoot parent filter (accepts parent 0 or 0xFFFFFFFF)
  3. Ok([]) → treat as empty storage (no fallback — an empty result is valid)
  4. Err(_) → fall through to parent=0 + Exact(ROOT) filter (existing behaviour)
  5. Subfolder listing → unchanged, goes directly to the specified parent handle

Worst case for a device that rejects 0xFFFFFFFF: one extra USB round-trip before the existing path runs. Samsung InvalidObjectHandle fallback and Fuji parent filtering are preserved in the fallback path.

Tests

  • stream_root_falls_back_on_error — device rejects 0xFFFFFFFF, listing uses parent=0 with Exact(ROOT) filter
  • stream_root_empty_is_not_fallback — empty Ok([]) is accepted as empty storage
  • stream_kindle_root_uses_fast_path — non-Android vendor extension takes the fast path
  • stream_subfolder_skips_fast_path — subfolder listings don't attempt 0xFFFFFFFF
  • Existing tests updated: stream_filters_by_parent and stream_root_accepts_both_parent_values no longer require is_android()
  • Integration test on physical Kindle Paperwhite (tested manually, 2541 → 23 handles)

Closes #8

Many non-Android devices (e.g. Kindle Paperwhite) behave like Android:
parent=0 returns every object on the storage while 0xFFFFFFFF returns
only root-level items. Remove the is_android() gate and try 0xFFFFFFFF
first for all root listings, falling back to parent=0 only on Err.

- Empty Ok([]) from 0xFFFFFFFF is accepted (empty storage, no retry)
- Fallback path retains Samsung InvalidObjectHandle handling
- AndroidRoot filter on fast path accepts parent==0 and 0xFFFFFFFF
- is_android() in list_objects_recursive left unchanged (separate quirk)

Made-with: Cursor
@vdavid
Copy link
Copy Markdown
Owner

vdavid commented Apr 26, 2026

Hey @num13ru! Great work!
I ran the full suite against my Pixel 9 Pro XL, and I saw all unit+int tests and checks pass. Root listing returned 17 objects in ~1.7s on the Pixel (correct).
I'll merge this now and cut a release shortly.
Thanks for making the lib better for everyone! ❤️

@vdavid vdavid merged commit 688faa3 into vdavid:main Apr 26, 2026
8 checks passed
@vdavid
Copy link
Copy Markdown
Owner

vdavid commented Apr 26, 2026

Just shipped this in https://crates.io/crates/mtp-rs/0.13.2.

@num13ru num13ru deleted the root-listing branch April 27, 2026 08:29
@num13ru
Copy link
Copy Markdown
Contributor Author

num13ru commented Apr 27, 2026

@vdavid thanks a lot! I really like this library and I'm glad I could help improve it

I will keep testing it on real devices and will continue contributing possible correctness fixes and performance improvements when I find them

Thanks for maintaining the project and for the quick release!

@vdavid
Copy link
Copy Markdown
Owner

vdavid commented Apr 27, 2026

@num13ru, just curious, what are you building?

@num13ru
Copy link
Copy Markdown
Contributor Author

num13ru commented Apr 28, 2026

@vdavid this https://github.com/num13ru/mtp-tui
I'm constantly transferring books to my Kindle and I'm tired of OpenMTP’s clunky GUI
So I decided to build my own tool that would be faster and more user-friendly (thanks to mtp-rs & ratatui) 🙂

@vdavid
Copy link
Copy Markdown
Owner

vdavid commented Apr 29, 2026

@num13ru Nice! Not sure if you're in this for the hacking itself, but if you want to see another solution and you're on a mac, I also recommend my file manager Cmdr, built on top of this lib and 100% free for copying books to Kindles :)

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Root listing on Kindle (non-Android) fetches GetObjectInfo for all 2541 objects instead of 23 root items

2 participants