【android9.0】没法打开usb uvc camera

背景:android9.0系统的开发板,接入双目摄像头,仅能打开其中一路摄像头,另外一路打不开android

关键log:git

从串口打印看,usb驱动有正确识别到usb hub以及两路usb camera设备框架

[ 4526.512542] usb 2-1: new high-speed USB device number 8 using ehci-platform
<6>[ 4526.512542] usb 2-1: new high-speed USB device number 8 using ehci-platform
[ 4526.637809] usb 2-1: New USB device found, idVendor=05e3, idProduct=0608<6>[ 4526.640429] hub 2-1:1.0: USB hub found
[ 45
<6>[ 4526.6240947] hub 2-1:1.0: 4 ports de6tect.ed
637857] usb 2-1: New USB device strings: Mfr=0, Product=1, SerialNumber=0
[ 4526.637868] usb 2-1: Product: USB2.0 Hub
[ 4526.640429] hub 2-1:1.0: USB hub found
[ 4526.640947] hub 2-1:1.0: 4 ports detected
[ 4526.912582] usb 2-1.1: new high-speed USB device number 9 using ehci-platform
<6>[ 4526.912582] usb 2-1.1: new high-speed USB device number 9 using ehci-platform
[ 4527.071511] usb 2-1.1: New USB device found, idVendor=735f, idProduct=2208
[<6>[ 4527.071511] usb 2 -1.1: New USB device found, idVendor=735f, idProduc4t=2208
<6>[ 45257.071564] usb 2-1.1: New 27.USB device s0trings: Mfr=2, Product=1, S7erialNumber=0
15<6>[ 4527.071576] usb 2-1.61: Product: Techshino TCF2342G Nir
<6>[ 4527.071587] usb 2-1.1: Manufacturer: Techshino] TCF232G Nir
 usb 2-1.1: New USB device str<6>[ 4527.102122] input: Techshino TCF232G Nir as /devices/platform/ff340i000.usb/usb2/n2-1/2-1.1/2-1.1:1.0/input/ignput9
s: Mfr=2, Product=1, SerialNumber=0
[ 4527.071576] usb 2-1.1: Product: Techshino TCF232G Nir
[ 4527.071587] usb 2-1.1: Manufacturer: Techshino TCF232G Nir
[ 4527.076643] uvcvideo: Found UVC 1.00 device Techshino TCF232G Nir (735f:2208)
[ 4527.102122] input: Techshino TCF232G Nir as /devices/platform/ff340000.usb/usb2/2-1/2-1.1/2-1.1:1.0/input/input9
[ 4527.182559] usb 2-1.2: new high-speed USB device number 10 using ehci-platform
<6>[ 4527.182559] usb 2-1.2: new high-speed USB device number 10 using ehci-platform
[ 4527.345527] usb 2-1.2: New USB device found, idVendor=735f, id<6>[ 4527.345527] usb 2-1.2: New USB device found,Prod idVendor=735f, iuctdProd=uct=2207
<6>[ 4527.345573] usb 2-1.2: New 220USB device string7
s: Mfr=2, Product=1, SerialNu[mber=0
<6>[ 4 527.345586] usb4 2-1.2: Product: Techshino 5TCF232G Col
<6>[ 4527.345597] usb 2-1.22: Manufacturer: Techshino TCF232G Col
7.345573] usb 2-1.2: New USB device strings: Mfr=2, Product=1, SerialNumber=0
[ 4527.345586] usb 2-1.2: Product: Techshino TCF232G Col
[ 4527.345597] usb 2-1.2: Manufacturer: Techshino TCF232G Col
[ 4527.356031] uvcvideo: Found UVC 1.00 device Techshino TCF232G Col (735f:2207)
[ 4527.391576] input: Techshino TCF232G Col as /devices/platform/ff340000.usb/usb2/2-1/2-1.2/2-1.2:1.0/input/input10

但奇怪的是android层却只能正确识别到其中一路摄像头的usb设备描述符信息,错误的那路设备,vid、pid以及Devclass、DevSubClass均读取错误。正确的信息应该是:ide

vid=0x735f pid=0x2208 DevClass=0xef DevSubClass=0x02函数

实际框架层读取到的倒是:ui

vid=0x0581 pid=0x0b20 DevClass=0 DevSubClass=0this

02-22 04:01:52.479 D/EventHub(  459): No input device configuration file found for device 'Techshino TCF232G Nir'.
02-22 04:01:52.484 D/UsbHostManager(  459): USB device attached: vidpid 0581:0b20 mfg/product/ver/serial Techshino TCF232G Nir/Techshino TCF232G Nir/9.01/Techshino TCF232G Nir hasAudio/HID/Storage: false/false/false
02-22 04:01:52.487 W/EventHub(  459): Unable to disable kernel key repeat for /dev/input/event7: Function not implemented
02-22 04:01:52.487 I/EventHub(  459): wakeMechanism=EPOLLWAKEUP, usingClockIoctl=true
02-22 04:01:52.487 I/EventHub(  459): New device: id=8, fd=240, path='/dev/input/event7', name='Techshino TCF232G Nir', classes=0x80004001, configuration='', keyLayout='/system/usr/keylayout/Generic.kl', keyCharacterMap='/system/usr/keychars/Generic.kcm', builtinKeyboard=false,
02-22 04:01:52.487 I/InputReader(  459): Device added: id=8, name='Techshino TCF232G Nir', sources=0x00002103
02-22 04:01:52.493 D/UsbDeviceDescriptor(  459):   0 configs
02-22 04:01:52.494 D/UsbHostManager(  459): Added device UsbDevice[mName=/dev/bus/usb/002/006,mVendorId=1409,mProductId=2848,mClass=0,mSubclass=0,mProtocol=7,mManufacturerName=Techshino TCF232G Nir,mProductName=Techshino TCF232G Nir,mVersion=9.01,mSerialNumber=Techshino TCF232G Nir,mConfigurations=[]
02-22 04:01:52.650 D/FinancialApplication( 2119): didRangeBeaconsInRegion called with beacon count:  0
02-22 04:01:52.751 E/UsbDescriptorParser(  459): Exception parsing USB descriptors.
02-22 04:01:52.751 E/UsbDescriptorParser(  459): java.lang.NegativeArraySizeException: -64
02-22 04:01:52.751 E/UsbDescriptorParser(  459):        at com.android.server.usb.descriptors.Usb10ACHeader.parseRawDescriptors(Usb10ACHeader.java:59)
02-22 04:01:52.751 E/UsbDescriptorParser(  459):        at com.android.server.usb.descriptors.UsbDescriptorParser.parseDescriptors(UsbDescriptorParser.java:229)
02-22 04:01:52.751 E/UsbDescriptorParser(  459):        at com.android.server.usb.descriptors.UsbDescriptorParser.<init>(UsbDescriptorParser.java:64)
02-22 04:01:52.751 E/UsbDescriptorParser(  459):        at com.android.server.usb.UsbHostManager.usbDeviceAdded(UsbHostManager.java:355)
02-22 04:01:52.751 E/UsbDescriptorParser(  459):        at com.android.server.usb.UsbHostManager.monitorUsbHostBus(Native Method)
02-22 04:01:52.751 E/UsbDescriptorParser(  459):        at com.android.server.usb.UsbHostManager.lambda$XT3F5aQci4H6VWSBYBQQNSzpnvs(Unknown Source:0)
02-22 04:01:52.751 E/UsbDescriptorParser(  459):        at com.android.server.usb.-$$Lambda$UsbHostManager$XT3F5aQci4H6VWSBYBQQNSzpnvs.run(Unknown Source:2)
02-22 04:01:52.751 E/UsbDescriptorParser(  459):        at java.lang.Thread.run(Thread.java:764)
02-22 04:01:52.751 I/UsbDescriptorParser(  459): Unknown Descriptor len: 225 type:0xffffffe4
02-22 04:01:52.751 I/UsbDescriptorParser(  459): Unknown Descriptor len: 2 type:0x0
02-22 04:01:52.751 I/UsbDescriptorParser(  459): Unknown Descriptor len: 21 type:0x16
02-22 04:01:52.751 I/UsbDescriptorParser(  459): Unknown Descriptor len: 26 type:0x30
02-22 04:01:52.751 I/UsbDescriptorParser(  459): Unknown Descriptor len: 4 type:0x30
02-22 04:01:52.751 I/UsbDescriptorParser(  459): Unknown Descriptor len: 37 type:0x30
02-22 04:01:52.751 I/UsbDescriptorParser(  459): Unknown Descriptor len: 58 type:0x0
02-22 04:01:52.751 I/UsbDescriptorParser(  459): Unknown Descriptor len: 16 type:0x0
02-22 04:01:52.751 W/UsbDescriptor(  459): UNDERRUN t:0x24 r: 6 < l: 30
02-22 04:01:52.751 I/chatty  (  459): uid=1000(system) UsbService host identical 6 lines
02-22 04:01:52.751 W/UsbDescriptor(  459): UNDERRUN t:0x24 r: 6 < l: 30
02-22 04:01:52.751 W/UsbACInterface(  459): Unknown Audio Class Interface subtype:0xd

相关代码路径:google

frameworks/base/services/usb/java/com/android/server/usb/UsbHostManager.java

frameworks/base/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java

frameworks/base/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java

frameworks/base/services/usb/java/com/android/server/usb/descriptors/UsbDescriptor.java

frameworks/base/services/core/jni/com_android_server_UsbHostManager.cpp

system/core/libusbhost/usbhost.c

驱动节点路径:spa

/sys/devices/platform/ff340000.usb/usb2/2-1/2-1.1
/sys/devices/platform/ff340000.usb/usb2/2-1/2-1.2

事件大体流程:

usb接入--》EvenHub获取usb设备信息--》唤醒UsbHostManager jni的usb_host_read_event事件线程,回调usb_device_added函数--》调用usbhost.c的usb_device_open打开设备并读取设备描述符--》回调UsbHostManager.java的usbDeviceAdded方法,增长usb设备并读取和解析usb设备描述符

具体解决过程就再也不赘述,问题的缘由是由于UsbDescriptorParser.java中解析设备的接口类型时出错,将uvc设备误判为了uac设备,致使读取的usb设备描述符信息错误

diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
old mode 100644
new mode 100755
index e615428..ee6b131
--- a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
@@ -177,13 +177,18 @@ public final class UsbDescriptorParser {
              * Audio Class Specific
              */
             case UsbDescriptor.DESCRIPTORTYPE_AUDIO_INTERFACE:
-                descriptor = UsbACInterface.allocDescriptor(this, stream, length, type);

+                if (mDeviceDescriptor.getDevClass() == UsbDescriptor.CLASSID_AUDIO) {
+                    descriptor = UsbACInterface.allocDescriptor(this, stream, length, type);
+                }
                 break;
 
             case UsbDescriptor.DESCRIPTORTYPE_AUDIO_ENDPOINT:
-                descriptor = UsbACEndpoint.allocDescriptor(this, length, type);
+                if (mDeviceDescriptor.getDevClass() == UsbDescriptor.CLASSID_AUDIO) {
+                    descriptor = UsbACEndpoint.allocDescriptor(this, length, type);
+                }
                 break;

             default:
                 break;
         }

 

转载于:https://my.oschina.net/u/3750358/blog/3049225