当前位置: 首页 > 工具软件 > USBManager > 使用案例 >

[RK3399][industry-71] Usb身份证模块导致 usbmanager.getDeviceList获取异常

太叔睿
2023-12-01

测试平台

Platform: RK3399
OS: industry-71

现象

客户反馈使用他们的usb身份证模块上电之后,usbmanager.getDeviceList获取异常.具体的测试流程是

客户流程:插着Usb身份证模块上电,getDeviceList获取设备个数为1,拔出身份证模块后,getDeviceList获取设备个数为0;再次接入身份证模块,getDeviceList获取设备个数为0;插上U盘,getDeviceList获取设备个数为0
实测:插着身份证模块上电后getDeviceList为1.此时插入u盘,getDeviceList仍为1.

发现只要插着身份证模块上电,后续的usb插入拔出,getDeviceList获取的数值都是异常

分析

查看插入u盘时的log,发现

01-18 09:39:17.787   486   809 E UsbHostManager: mNewDevice is not null in endUsbDeviceAdded

查看对应的代码,发现添加设备流程是在beginUsbDeviceAdded中new 一个mNewDevice,当设备添加完成后会在endUsbDeviceAdded释放

 //frameworks/base/services/usb/java/com/android/server/usb/UsbHostManager.java
 //开始添加设备
 private boolean beginUsbDeviceAdded(String deviceName, int vendorID, int productID,
            int deviceClass, int deviceSubclass, int deviceProtocol,
            String manufacturerName, String productName, int version, String serialNumber) {

        if (DEBUG) {
            Slog.d(TAG, "usb:UsbHostManager.beginUsbDeviceAdded(" + deviceName + ")");
            // Audio Class Codes:
            // Audio: 0x01
            // Audio Subclass Codes:
            // undefined: 0x00
            // audio control: 0x01
            // audio streaming: 0x02
            // midi streaming: 0x03

            // some useful debugging info
            Slog.d(TAG, "usb: nm:" + deviceName + " vnd:" + vendorID + " prd:" + productID + " cls:"
                    + deviceClass + " sub:" + deviceSubclass + " proto:" + deviceProtocol);
        }

        // OK this is non-obvious, but true. One can't tell if the device being attached is even
        // potentially an audio device without parsing the interface descriptors, so punt on any
        // such test until endUsbDeviceAdded() when we have that info.

        if (isBlackListed(deviceName) ||
                isBlackListed(deviceClass, deviceSubclass, deviceProtocol)) {
            return false;
        }

        synchronized (mLock) {
            if (mDevices.get(deviceName) != null) {
                Slog.w(TAG, "device already on mDevices list: " + deviceName);
                return false;
            }

            if (mNewDevice != null) {
                Slog.e(TAG, "mNewDevice is not null in endUsbDeviceAdded");
                return false;
            }

            // Create version string in "%.%" format
            String versionString = Integer.toString(version >> 8) + "." + (version & 0xFF);

            mNewDevice = new UsbDevice(deviceName, vendorID, productID,
                    deviceClass, deviceSubclass, deviceProtocol,
                    manufacturerName, productName, versionString, serialNumber);

            mNewConfigurations = new ArrayList<UsbConfiguration>();
            mNewInterfaces = new ArrayList<UsbInterface>();
            mNewEndpoints = new ArrayList<UsbEndpoint>();
        }

        return true;
    }
 //结束添加设备
 private void endUsbDeviceAdded() {
        if (DEBUG) {
            Slog.d(TAG, "usb:UsbHostManager.endUsbDeviceAdded()");
        }
        if (mNewInterface != null) {
            mNewInterface.setEndpoints(
                    mNewEndpoints.toArray(new UsbEndpoint[mNewEndpoints.size()]));
        }
        if (mNewConfiguration != null) {
            mNewConfiguration.setInterfaces(
                    mNewInterfaces.toArray(new UsbInterface[mNewInterfaces.size()]));
        }


        synchronized (mLock) {
            if (mNewDevice != null) {
                mNewDevice.setConfigurations(
                        mNewConfigurations.toArray(new UsbConfiguration[mNewConfigurations.size()]));
                mDevices.put(mNewDevice.getDeviceName(), mNewDevice);
                Slog.d(TAG, "Added device " + mNewDevice);
                getCurrentSettings().deviceAttached(mNewDevice);
                mUsbAlsaManager.usbDeviceAdded(mNewDevice);
				checkUsbCameraStatus(mNewDevice, true);
            } else {
                Slog.e(TAG, "mNewDevice is null in endUsbDeviceAdded");
            }
            mNewDevice = null;
            mNewConfigurations = null;
            mNewInterfaces = null;
            mNewEndpoints = null;
            mNewConfiguration = null;
            mNewInterface = null;
        }
    }

而从log mNewDevice is not null in endUsbDeviceAdded可知,U盘无法加载的原因是前一个usb设备(身份证模块)在加载时可能出现问题,没有在endUsbDeviceAdded释放mNewDevice,导致U盘没有添加到usbmanager.getDeviceList中

继续查找log,发现插着身份证模块开机时有如下log

01-18 09:51:53.561   488   801 E UsbHostManagerJNI: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.toLowerCase()' on a null object reference
01-18 09:51:53.561   488   801 E UsbHostManagerJNI: 	at com.android.server.usb.UsbHostManager.checkUsbCameraStatus(UsbHostManager.java:263)
01-18 09:51:53.561   488   801 E UsbHostManagerJNI: 	at com.android.server.usb.UsbHostManager.endUsbDeviceAdded(UsbHostManager.java:233)
01-18 09:51:53.561   488   801 E UsbHostManagerJNI: 	at com.android.server.usb.UsbHostManager.monitorUsbHostBus(Native Method)
01-18 09:51:53.561   488   801 E UsbHostManagerJNI: 	at com.android.server.usb.UsbHostManager.-wrap0(UsbHostManager.java)
01-18 09:51:53.561   488   801 E UsbHostManagerJNI: 	at com.android.server.usb.UsbHostManager$1.run(UsbHostManager.java:315)
01-18 09:51:53.561   488   801 E UsbHostManagerJNI: 	at java.lang.Thread.run(Thread.java:761)
01-18 09:51:53.561   488   801 D UsbHostManager: usb:UsbHostManager.beginUsbDeviceAdded(/dev/bus/usb/007/001)
01-18 09:51:53.561   488   801 D UsbHostManager: usb: nm:/dev/bus/usb/007/001 vnd:7531 prd:2 cls:9 sub:0 proto:1
01-18 09:51:53.562   488   801 D UsbHostManager: usb:UsbHostManager.beginUsbDeviceAdded(/dev/bus/usb/001/001)
01-18 09:51:53.562   488   801 D UsbHostManager: usb: nm:/dev/bus/usb/001/001 vnd:7531 prd:2 cls:9 sub:0 proto:0

查看对应代码,发现是rk在这里添加了一个usb类型检测的代码,用于热拔插usb摄像头的处理,但是没有考虑productname为null的情况,导致抛空出错

 private void checkUsbCameraStatus(UsbDevice device, boolean added) {
        if (device != null && !mBootCompleted) {
            String devicename = device.getDeviceName();
            String productname = device.getProductName();
		 	if( productname.toLowerCase().contains("wlan")) //263行
			{
				//For ROC+ Usb Wlan Error Detech	
				Slog.d(TAG,"This is Usb Wlan");
				Slog.d(TAG,"WLAN Devicename = "+devicename);
				Slog.d(TAG,"WLAN Productname = "+productname);                                                                                                   
				return ;
			}

解决

添加productname != null 判断后,编译固件测试正常

diff --git a/frameworks/base/services/usb/java/com/android/server/usb/UsbHostManager.java b/frameworks/base/services/usb/java/com/android/server/usb/UsbHostManager.java
index 083eeaa..9ac1fb1 100644
--- a/frameworks/base/services/usb/java/com/android/server/usb/UsbHostManager.java
+++ b/frameworks/base/services/usb/java/com/android/server/usb/UsbHostManager.java
@@ -260,7 +260,7 @@ public class UsbHostManager {
         if (device != null && !mBootCompleted) {
             String devicename = device.getDeviceName();
             String productname = device.getProductName();
-                       if(productname.toLowerCase().contains("wlan"))
+                       if(productname != null && productname.toLowerCase().contains("wlan"))
                        {
                                //For ROC+ Usb Wlan Error Detech        
                                Slog.d(TAG,"This is Usb Wlan");

 类似资料: