perf(mtp): try parent=0xFFFFFFFF for root listing before fallback#9
Conversation
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
|
Hey @num13ru! Great work! |
|
Just shipped this in https://crates.io/crates/mtp-rs/0.13.2. |
|
@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! |
|
@num13ru, just curious, what are you building? |
|
@vdavid this https://github.com/num13ru/mtp-tui |
Summary
list_objects_stream(None)) now triesparent=0xFFFFFFFFfirst for all devices, not just Android. Falls back toparent=0only when the device rejects the request with an error.GetObjectHandles(parent=0)returned every object on the storage (2541) instead of the 23 root-level items.Approach
Instead of adding device-specific detection, make the fast path universal:
GetObjectHandles(parent=0xFFFFFFFF)firstOk(handles)→ return immediately withAndroidRootparent filter (accepts parent0or0xFFFFFFFF)Ok([])→ treat as empty storage (no fallback — an empty result is valid)Err(_)→ fall through toparent=0+Exact(ROOT)filter (existing behaviour)Worst case for a device that rejects
0xFFFFFFFF: one extra USB round-trip before the existing path runs. SamsungInvalidObjectHandlefallback and Fuji parent filtering are preserved in the fallback path.Tests
stream_root_falls_back_on_error— device rejects0xFFFFFFFF, listing usesparent=0withExact(ROOT)filterstream_root_empty_is_not_fallback— emptyOk([])is accepted as empty storagestream_kindle_root_uses_fast_path— non-Android vendor extension takes the fast pathstream_subfolder_skips_fast_path— subfolder listings don't attempt0xFFFFFFFFstream_filters_by_parentandstream_root_accepts_both_parent_valuesno longer requireis_android()Closes #8