TeamAmaze / TeamAmaze/AmazeFileManager

Support multi function USB hubs

Open
#2,633 3 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Area-USB From-telegram Issue-Feature
Dominant language
Kotlin
Stars
6.4k
Forks
1.7k
Avg merge
3d 9h
Merged PRs (30d)
1

Description

Some "modern" USB hubs, especially the Type-C ones which are also used by Macbooks, can contain multiple functions, such as HDMI output, SD card reader, Ethernet port, etc.

The one USB hub I have (Verbatim 7-in-1 hub, model number VAPCH047), when listing devices with UsbManager.getDeviceList(), will have such output. This is the case of plugging in both an USB thumbdrive and SD card onto the hub.

result = {HashMap@14377}  size = 2
 "/dev/bus/usb/001/004" -> {UsbDevice@14383} "UsbDevice[mName=/dev/bus/usb/001/004,mVendorId=1423,mProductId=25479,mClass=0,mSubclass=0,mProtocol=0,mManufacturerName=Generic,mProductName=Mass Storage,mVersion=1.03,mSerialNumber=993207CA,mConfigurations=[\nUsbConfiguration[mId=1,mName=null,mAttributes=128,mMaxPower=50,mInterfaces=[\nUsbInterface[mId=0,mAlternateSetting=0,mName=null,mClass=8,mSubclass=6,mProtocol=80,mEndpoints=[\nUsbEndpoint[mAddress=1,mAttributes=2,mMaxPacketSize=512,mInterval=0]\nUsbEndpoint[mAddress=130,mAttributes=2,mMaxPacketSize=512,mInterval=0]]]]"
  key = "/dev/bus/usb/001/004"
  value = {UsbDevice@14383} "UsbDevice[mName=/dev/bus/usb/001/004,mVendorId=1423,mProductId=25479,mClass=0,mSubclass=0,mProtocol=0,mManufacturerName=Generic,mProductName=Mass Storage,mVersion=1.03,mSerialNumber=993207CA,mConfigurations=[\nUsbConfiguration[mId=1,mName=null,mAttributes=128,mMaxPower=50,mInterfaces=[\nUsbInterface[mId=0,mAlternateSetting=0,mName=null,mClass=8,mSubclass=6,mProtocol=80,mEndpoints=[\nUsbEndpoint[mAddress=1,mAttributes=2,mMaxPacketSize=512,mInterval=0]\nUsbEndpoint[mAddress=130,mAttributes=2,mMaxPacketSize=512,mInterval=0]]]]"
   mClass = 0
   mConfigurations = {Parcelable[1]@14413} 
   mInterfaces = null
   mManufacturerName = "Generic"
   mName = "/dev/bus/usb/001/004"
   mProductId = 25479
   mProductName = "Mass Storage"
   mProtocol = 0
   mSerialNumber = "993207CA"
   mSubclass = 0
   mVendorId = 1423
   mVersion = "1.03"
   shadow$_klass_ = {Class@1323} "class android.hardware.usb.UsbDevice"
   shadow$_monitor_ = 0
 "/dev/bus/usb/001/003" -> {UsbDevice@14385} "UsbDevice[mName=/dev/bus/usb/001/003,mVendorId=1507,mProductId=1865,mClass=0,mSubclass=0,mProtocol=0,mManufacturerName=Generic,mProductName=USB3.0 Card Reader,mVersion=15.39,mSerialNumber=000000001539,mConfigurations=[\nUsbConfiguration[mId=1,mName=null,mAttributes=128,mMaxPower=250,mInterfaces=[\nUsbInterface[mId=0,mAlternateSetting=0,mName=null,mClass=8,mSubclass=6,mProtocol=80,mEndpoints=[\nUsbEndpoint[mAddress=129,mAttributes=2,mMaxPacketSize=512,mInterval=0]\nUsbEndpoint[mAddress=2,mAttributes=2,mMaxPacketSize=512,mInterval=0]]]]"
  key = "/dev/bus/usb/001/003"
  value = {UsbDevice@14385} "UsbDevice[mName=/dev/bus/usb/001/003,mVendorId=1507,mProductId=1865,mClass=0,mSubclass=0,mProtocol=0,mManufacturerName=Generic,mProductName=USB3.0 Card Reader,mVersion=15.39,mSerialNumber=000000001539,mConfigurations=[\nUsbConfiguration[mId=1,mName=null,mAttributes=128,mMaxPower=250,mInterfaces=[\nUsbInterface[mId=0,mAlternateSetting=0,mName=null,mClass=8,mSubclass=6,mProtocol=80,mEndpoints=[\nUsbEndpoint[mAddress=129,mAttributes=2,mMaxPacketSize=512,mInterval=0]\nUsbEndpoint[mAddress=2,mAttributes=2,mMaxPacketSize=512,mInterval=0]]]]"
   mClass = 0
   mConfigurations = {Parcelable[1]@14404} 
   mInterfaces = null
   mManufacturerName = "Generic"
   mName = "/dev/bus/usb/001/003"
   mProductId = 1865
   mProductName = "USB3.0 Card Reader"
   mProtocol = 0
   mSerialNumber = "000000001539"
   mSubclass = 0
   mVendorId = 1507
   mVersion = "15.39"
   shadow$_klass_ = {Class@1323} "class android.hardware.usb.UsbDevice"
   shadow$_monitor_ = 0

Both devices have device class = 0 (UsbConstants.USB_CLASS_PER_INTERFACE), contrary to OTGUtil's requirement of 8 (UsbConstants.USB_CLASS_MASS_STORAGE).

https://github.com/TeamAmaze/AmazeFileManager/blob/022e3b299f7bf7557930a5019153ea658ad48301/app/src/main/java/com/amaze/filemanager/utils/OTGUtil.kt#L157-L187

We should be able to support such situations. Additionally, we should be able to support multiple OTG storage plugged into the USB hub as well. This implies changing OTG's implementation to make OTG paths like otg://<storage volume> instead of just otg://.


This now has a bounty, here, bounty expires in one month from 2022-01-14, if you have been working, please alert us so that we can extend it.

Please claim after a PR fixing this issue is accepted.
Remember that you can also back the issue adding to the bounty!

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with app/src/main/java/com/amaze/filemanager/utils/OTGUtil.kt, especially lines 157-187, and trace how OTG paths are created and resolved. Check the USB device handling around the reported USB_CLASS_PER_INTERFACE case; done means multi-function hubs and multiple OTG storage devices can be listed and addressed through distinct otg:// paths.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, kotlin
Domain
mobile
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.