Loading services/usb/java/com/android/server/usb/UsbHostManager.java +104 −22 Original line number Diff line number Diff line Loading @@ -29,18 +29,21 @@ import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; import com.android.server.usb.descriptors.UsbDescriptorParser; import com.android.server.usb.descriptors.UsbDeviceDescriptor; import com.android.server.usb.descriptors.report.TextReportCanvas; import com.android.server.usb.descriptors.tree.UsbDescriptorsTree; import java.util.Collection; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.LinkedList; /** * UsbHostManager manages USB state in host mode. */ public class UsbHostManager { private static final String TAG = UsbHostManager.class.getSimpleName(); private static final boolean DEBUG = false; private static final boolean DEBUG = true; private final Context mContext; Loading @@ -63,6 +66,76 @@ public class UsbHostManager { @GuardedBy("mHandlerLock") private ComponentName mUsbDeviceConnectionHandler; /* * Member used for tracking connections & disconnections */ static final SimpleDateFormat sFormat = new SimpleDateFormat("MM-dd HH:mm:ss:SSS"); private static final int MAX_CONNECT_RECORDS = 32; private int mNumConnects; // TOTAL # of connect/disconnect private final LinkedList<ConnectionRecord> mConnections = new LinkedList<ConnectionRecord>(); private ConnectionRecord mLastConnect; /* * ConnectionRecord * Stores connection/disconnection data. */ class ConnectionRecord { long mTimestamp; // Same time-base as system log. String mDeviceAddress; static final int CONNECT = 0; static final int DISCONNECT = 1; final int mMode; final byte[] mDescriptors; ConnectionRecord(String deviceAddress, int mode, byte[] descriptors) { mTimestamp = System.currentTimeMillis(); mDeviceAddress = deviceAddress; mMode = mode; mDescriptors = descriptors; } private String formatTime() { return (new StringBuilder(sFormat.format(new Date(mTimestamp)))).toString(); } void dumpShort(IndentingPrintWriter pw) { if (mMode == CONNECT) { pw.println(formatTime() + " Connect " + mDeviceAddress); UsbDescriptorParser parser = new UsbDescriptorParser(mDeviceAddress, mDescriptors); UsbDeviceDescriptor deviceDescriptor = parser.getDeviceDescriptor(); pw.println("manfacturer:0x" + Integer.toHexString(deviceDescriptor.getVendorID()) + " product:" + Integer.toHexString(deviceDescriptor.getProductID())); pw.println("isHeadset[in: " + parser.isInputHeadset() + " , out: " + parser.isOutputHeadset() + "]"); } else { pw.println(formatTime() + " Disconnect " + mDeviceAddress); } } void dumpLong(IndentingPrintWriter pw) { if (mMode == CONNECT) { pw.println(formatTime() + " Connect " + mDeviceAddress); UsbDescriptorParser parser = new UsbDescriptorParser(mDeviceAddress, mDescriptors); StringBuilder stringBuilder = new StringBuilder(); UsbDescriptorsTree descriptorTree = new UsbDescriptorsTree(); descriptorTree.parse(parser); descriptorTree.report(new TextReportCanvas(parser, stringBuilder)); stringBuilder.append("isHeadset[in: " + parser.isInputHeadset() + " , out: " + parser.isOutputHeadset() + "]"); pw.println(stringBuilder.toString()); } else { pw.println(formatTime() + " Disconnect " + mDeviceAddress); } } } /* * UsbHostManager */ public UsbHostManager(Context context, UsbAlsaManager alsaManager, UsbSettingsManager settingsManager) { mContext = context; Loading Loading @@ -124,6 +197,19 @@ public class UsbHostManager { } private void addConnectionRecord(String deviceAddress, int mode, byte[] rawDescriptors) { mNumConnects++; while (mConnections.size() >= MAX_CONNECT_RECORDS) { mConnections.removeFirst(); } ConnectionRecord rec = new ConnectionRecord(deviceAddress, mode, rawDescriptors); mConnections.add(rec); if (mode == ConnectionRecord.CONNECT) { mLastConnect = rec; } } /* Called from JNI in monitorUsbHostBus() to report new USB devices Returns true if successful, i.e. the USB Audio device descriptors are correctly parsed and the unique device is added to the audio device list. Loading Loading @@ -174,6 +260,10 @@ public class UsbHostManager { + " , out: " + isOutputHeadset + "]"); mUsbAlsaManager.usbDeviceAdded(newDevice, isInputHeadset, isOutputHeadset); // Tracking addConnectionRecord(deviceAddress, ConnectionRecord.CONNECT, parser.getRawDescriptors()); } else { Slog.e(TAG, "Error parsing USB device descriptors for " + deviceAddress); return false; Loading @@ -196,6 +286,9 @@ public class UsbHostManager { mUsbAlsaManager.usbDeviceRemoved(device); mSettingsManager.usbDeviceRemoved(device); getCurrentUserSettings().usbDeviceRemoved(device); // Tracking addConnectionRecord(deviceAddress, ConnectionRecord.DISCONNECT, null); } } } Loading Loading @@ -249,26 +342,15 @@ public class UsbHostManager { pw.println(" " + name + ": " + mDevices.get(name)); } Collection<UsbDevice> devices = mDevices.values(); if (devices.size() != 0) { pw.println("USB Peripheral Descriptors"); for (UsbDevice device : devices) { StringBuilder stringBuilder = new StringBuilder(); UsbDescriptorParser parser = new UsbDescriptorParser(device.getDeviceName()); if (parser.parseDevice()) { UsbDescriptorsTree descriptorTree = new UsbDescriptorsTree(); descriptorTree.parse(parser); descriptorTree.report(new TextReportCanvas(parser, stringBuilder)); stringBuilder.append("isHeadset[in: " + parser.isInputHeadset() + " , out: " + parser.isOutputHeadset() + "]"); } else { stringBuilder.append("Error Parsing USB Descriptors"); } pw.println(stringBuilder.toString()); pw.println("" + mNumConnects + " total connects/disconnects"); pw.println("Last " + mConnections.size() + " connections/disconnections"); for (ConnectionRecord rec : mConnections) { rec.dumpShort(pw); } if (mLastConnect != null) { pw.println("Last Connected USB Device:"); mLastConnect.dumpLong(pw); } } Loading services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java +24 −4 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ public final class UsbDescriptorParser { // Descriptor Objects private static final int DESCRIPTORS_ALLOC_SIZE = 128; private ArrayList<UsbDescriptor> mDescriptors = new ArrayList<UsbDescriptor>(); private final ArrayList<UsbDescriptor> mDescriptors; private UsbDeviceDescriptor mDeviceDescriptor; private UsbConfigDescriptor mCurConfigDescriptor; Loading @@ -45,6 +45,28 @@ public final class UsbDescriptorParser { public UsbDescriptorParser(String deviceAddr) { mDeviceAddr = deviceAddr; mDescriptors = new ArrayList<UsbDescriptor>(DESCRIPTORS_ALLOC_SIZE); } /** * Connect this parser to an existing set of already parsed descriptors. * This is useful for reporting. */ public UsbDescriptorParser(String deviceAddr, ArrayList<UsbDescriptor> descriptors) { mDeviceAddr = deviceAddr; mDescriptors = descriptors; //TODO some error checking here.... mDeviceDescriptor = (UsbDeviceDescriptor) descriptors.get(0); } /** * Connect this parser to an byte array containing unparsed (raw) device descriptors * to be parsed (and parse them). Useful for parsing a stored descriptor buffer. */ public UsbDescriptorParser(String deviceAddr, byte[] rawDescriptors) { mDeviceAddr = deviceAddr; mDescriptors = new ArrayList<UsbDescriptor>(DESCRIPTORS_ALLOC_SIZE); parseDescriptors(rawDescriptors); } public String getDeviceAddr() { Loading Loading @@ -196,8 +218,6 @@ public final class UsbDescriptorParser { if (DEBUG) { Log.d(TAG, "parseDescriptors() - start"); } // This will allow us to (probably) alloc mDescriptors just once. mDescriptors = new ArrayList<UsbDescriptor>(DESCRIPTORS_ALLOC_SIZE); ByteStream stream = new ByteStream(descriptors); while (stream.available() > 0) { Loading Loading @@ -241,7 +261,7 @@ public final class UsbDescriptorParser { ? parseDescriptors(rawDescriptors) : false; } private byte[] getRawDescriptors() { public byte[] getRawDescriptors() { return getRawDescriptors_native(mDeviceAddr); } Loading Loading
services/usb/java/com/android/server/usb/UsbHostManager.java +104 −22 Original line number Diff line number Diff line Loading @@ -29,18 +29,21 @@ import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; import com.android.server.usb.descriptors.UsbDescriptorParser; import com.android.server.usb.descriptors.UsbDeviceDescriptor; import com.android.server.usb.descriptors.report.TextReportCanvas; import com.android.server.usb.descriptors.tree.UsbDescriptorsTree; import java.util.Collection; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.LinkedList; /** * UsbHostManager manages USB state in host mode. */ public class UsbHostManager { private static final String TAG = UsbHostManager.class.getSimpleName(); private static final boolean DEBUG = false; private static final boolean DEBUG = true; private final Context mContext; Loading @@ -63,6 +66,76 @@ public class UsbHostManager { @GuardedBy("mHandlerLock") private ComponentName mUsbDeviceConnectionHandler; /* * Member used for tracking connections & disconnections */ static final SimpleDateFormat sFormat = new SimpleDateFormat("MM-dd HH:mm:ss:SSS"); private static final int MAX_CONNECT_RECORDS = 32; private int mNumConnects; // TOTAL # of connect/disconnect private final LinkedList<ConnectionRecord> mConnections = new LinkedList<ConnectionRecord>(); private ConnectionRecord mLastConnect; /* * ConnectionRecord * Stores connection/disconnection data. */ class ConnectionRecord { long mTimestamp; // Same time-base as system log. String mDeviceAddress; static final int CONNECT = 0; static final int DISCONNECT = 1; final int mMode; final byte[] mDescriptors; ConnectionRecord(String deviceAddress, int mode, byte[] descriptors) { mTimestamp = System.currentTimeMillis(); mDeviceAddress = deviceAddress; mMode = mode; mDescriptors = descriptors; } private String formatTime() { return (new StringBuilder(sFormat.format(new Date(mTimestamp)))).toString(); } void dumpShort(IndentingPrintWriter pw) { if (mMode == CONNECT) { pw.println(formatTime() + " Connect " + mDeviceAddress); UsbDescriptorParser parser = new UsbDescriptorParser(mDeviceAddress, mDescriptors); UsbDeviceDescriptor deviceDescriptor = parser.getDeviceDescriptor(); pw.println("manfacturer:0x" + Integer.toHexString(deviceDescriptor.getVendorID()) + " product:" + Integer.toHexString(deviceDescriptor.getProductID())); pw.println("isHeadset[in: " + parser.isInputHeadset() + " , out: " + parser.isOutputHeadset() + "]"); } else { pw.println(formatTime() + " Disconnect " + mDeviceAddress); } } void dumpLong(IndentingPrintWriter pw) { if (mMode == CONNECT) { pw.println(formatTime() + " Connect " + mDeviceAddress); UsbDescriptorParser parser = new UsbDescriptorParser(mDeviceAddress, mDescriptors); StringBuilder stringBuilder = new StringBuilder(); UsbDescriptorsTree descriptorTree = new UsbDescriptorsTree(); descriptorTree.parse(parser); descriptorTree.report(new TextReportCanvas(parser, stringBuilder)); stringBuilder.append("isHeadset[in: " + parser.isInputHeadset() + " , out: " + parser.isOutputHeadset() + "]"); pw.println(stringBuilder.toString()); } else { pw.println(formatTime() + " Disconnect " + mDeviceAddress); } } } /* * UsbHostManager */ public UsbHostManager(Context context, UsbAlsaManager alsaManager, UsbSettingsManager settingsManager) { mContext = context; Loading Loading @@ -124,6 +197,19 @@ public class UsbHostManager { } private void addConnectionRecord(String deviceAddress, int mode, byte[] rawDescriptors) { mNumConnects++; while (mConnections.size() >= MAX_CONNECT_RECORDS) { mConnections.removeFirst(); } ConnectionRecord rec = new ConnectionRecord(deviceAddress, mode, rawDescriptors); mConnections.add(rec); if (mode == ConnectionRecord.CONNECT) { mLastConnect = rec; } } /* Called from JNI in monitorUsbHostBus() to report new USB devices Returns true if successful, i.e. the USB Audio device descriptors are correctly parsed and the unique device is added to the audio device list. Loading Loading @@ -174,6 +260,10 @@ public class UsbHostManager { + " , out: " + isOutputHeadset + "]"); mUsbAlsaManager.usbDeviceAdded(newDevice, isInputHeadset, isOutputHeadset); // Tracking addConnectionRecord(deviceAddress, ConnectionRecord.CONNECT, parser.getRawDescriptors()); } else { Slog.e(TAG, "Error parsing USB device descriptors for " + deviceAddress); return false; Loading @@ -196,6 +286,9 @@ public class UsbHostManager { mUsbAlsaManager.usbDeviceRemoved(device); mSettingsManager.usbDeviceRemoved(device); getCurrentUserSettings().usbDeviceRemoved(device); // Tracking addConnectionRecord(deviceAddress, ConnectionRecord.DISCONNECT, null); } } } Loading Loading @@ -249,26 +342,15 @@ public class UsbHostManager { pw.println(" " + name + ": " + mDevices.get(name)); } Collection<UsbDevice> devices = mDevices.values(); if (devices.size() != 0) { pw.println("USB Peripheral Descriptors"); for (UsbDevice device : devices) { StringBuilder stringBuilder = new StringBuilder(); UsbDescriptorParser parser = new UsbDescriptorParser(device.getDeviceName()); if (parser.parseDevice()) { UsbDescriptorsTree descriptorTree = new UsbDescriptorsTree(); descriptorTree.parse(parser); descriptorTree.report(new TextReportCanvas(parser, stringBuilder)); stringBuilder.append("isHeadset[in: " + parser.isInputHeadset() + " , out: " + parser.isOutputHeadset() + "]"); } else { stringBuilder.append("Error Parsing USB Descriptors"); } pw.println(stringBuilder.toString()); pw.println("" + mNumConnects + " total connects/disconnects"); pw.println("Last " + mConnections.size() + " connections/disconnections"); for (ConnectionRecord rec : mConnections) { rec.dumpShort(pw); } if (mLastConnect != null) { pw.println("Last Connected USB Device:"); mLastConnect.dumpLong(pw); } } Loading
services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java +24 −4 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ public final class UsbDescriptorParser { // Descriptor Objects private static final int DESCRIPTORS_ALLOC_SIZE = 128; private ArrayList<UsbDescriptor> mDescriptors = new ArrayList<UsbDescriptor>(); private final ArrayList<UsbDescriptor> mDescriptors; private UsbDeviceDescriptor mDeviceDescriptor; private UsbConfigDescriptor mCurConfigDescriptor; Loading @@ -45,6 +45,28 @@ public final class UsbDescriptorParser { public UsbDescriptorParser(String deviceAddr) { mDeviceAddr = deviceAddr; mDescriptors = new ArrayList<UsbDescriptor>(DESCRIPTORS_ALLOC_SIZE); } /** * Connect this parser to an existing set of already parsed descriptors. * This is useful for reporting. */ public UsbDescriptorParser(String deviceAddr, ArrayList<UsbDescriptor> descriptors) { mDeviceAddr = deviceAddr; mDescriptors = descriptors; //TODO some error checking here.... mDeviceDescriptor = (UsbDeviceDescriptor) descriptors.get(0); } /** * Connect this parser to an byte array containing unparsed (raw) device descriptors * to be parsed (and parse them). Useful for parsing a stored descriptor buffer. */ public UsbDescriptorParser(String deviceAddr, byte[] rawDescriptors) { mDeviceAddr = deviceAddr; mDescriptors = new ArrayList<UsbDescriptor>(DESCRIPTORS_ALLOC_SIZE); parseDescriptors(rawDescriptors); } public String getDeviceAddr() { Loading Loading @@ -196,8 +218,6 @@ public final class UsbDescriptorParser { if (DEBUG) { Log.d(TAG, "parseDescriptors() - start"); } // This will allow us to (probably) alloc mDescriptors just once. mDescriptors = new ArrayList<UsbDescriptor>(DESCRIPTORS_ALLOC_SIZE); ByteStream stream = new ByteStream(descriptors); while (stream.available() > 0) { Loading Loading @@ -241,7 +261,7 @@ public final class UsbDescriptorParser { ? parseDescriptors(rawDescriptors) : false; } private byte[] getRawDescriptors() { public byte[] getRawDescriptors() { return getRawDescriptors_native(mDeviceAddr); } Loading