1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.server.usb.descriptors; 17 18 import android.hardware.usb.UsbEndpoint; 19 import android.hardware.usb.UsbInterface; 20 import android.util.Log; 21 22 import com.android.server.usb.descriptors.report.ReportCanvas; 23 import com.android.server.usb.descriptors.report.UsbStrings; 24 25 import java.util.ArrayList; 26 27 /** 28 * @hide 29 * A common super-class for all USB Interface Descritor subtypes. 30 * see usb11.pdf section 9.6.3 31 */ 32 public class UsbInterfaceDescriptor extends UsbDescriptor { 33 private static final String TAG = "UsbInterfaceDescriptor"; 34 private static final boolean DEBUG = false; 35 36 protected int mInterfaceNumber; // 2:1 Number of Interface 37 protected byte mAlternateSetting; // 3:1 Value used to select alternative setting 38 protected byte mNumEndpoints; // 4:1 Number of Endpoints used for this interface 39 protected int mUsbClass; // 5:1 Class Code 40 protected int mUsbSubclass; // 6:1 Subclass Code 41 protected int mProtocol; // 7:1 Protocol Code 42 protected byte mDescrIndex; // 8:1 Index of String Descriptor Describing this interface 43 44 private ArrayList<UsbEndpointDescriptor> mEndpointDescriptors = 45 new ArrayList<UsbEndpointDescriptor>(); 46 UsbInterfaceDescriptor(int length, byte type)47 UsbInterfaceDescriptor(int length, byte type) { 48 super(length, type); 49 mHierarchyLevel = 3; 50 } 51 52 @Override parseRawDescriptors(ByteStream stream)53 public int parseRawDescriptors(ByteStream stream) { 54 mInterfaceNumber = stream.getUnsignedByte(); 55 mAlternateSetting = stream.getByte(); 56 mNumEndpoints = stream.getByte(); 57 mUsbClass = stream.getUnsignedByte(); 58 mUsbSubclass = stream.getUnsignedByte(); 59 mProtocol = stream.getUnsignedByte(); 60 mDescrIndex = stream.getByte(); 61 62 return mLength; 63 } 64 getInterfaceNumber()65 public int getInterfaceNumber() { 66 return mInterfaceNumber; 67 } 68 getAlternateSetting()69 public byte getAlternateSetting() { 70 return mAlternateSetting; 71 } 72 getNumEndpoints()73 public byte getNumEndpoints() { 74 return mNumEndpoints; 75 } 76 getUsbClass()77 public int getUsbClass() { 78 return mUsbClass; 79 } 80 getUsbSubclass()81 public int getUsbSubclass() { 82 return mUsbSubclass; 83 } 84 getProtocol()85 public int getProtocol() { 86 return mProtocol; 87 } 88 getDescrIndex()89 public byte getDescrIndex() { 90 return mDescrIndex; 91 } 92 addEndpointDescriptor(UsbEndpointDescriptor endpoint)93 void addEndpointDescriptor(UsbEndpointDescriptor endpoint) { 94 mEndpointDescriptors.add(endpoint); 95 } 96 toAndroid(UsbDescriptorParser parser)97 UsbInterface toAndroid(UsbDescriptorParser parser) { 98 if (DEBUG) { 99 Log.d(TAG, "toAndroid() class:" + Integer.toHexString(mUsbClass) 100 + " subclass:" + Integer.toHexString(mUsbSubclass) 101 + " " + mEndpointDescriptors.size() + " endpoints."); 102 } 103 String name = parser.getDescriptorString(mDescrIndex); 104 UsbInterface ntrface = new UsbInterface( 105 mInterfaceNumber, mAlternateSetting, name, mUsbClass, mUsbSubclass, mProtocol); 106 UsbEndpoint[] endpoints = new UsbEndpoint[mEndpointDescriptors.size()]; 107 for (int index = 0; index < mEndpointDescriptors.size(); index++) { 108 endpoints[index] = mEndpointDescriptors.get(index).toAndroid(parser); 109 } 110 ntrface.setEndpoints(endpoints); 111 return ntrface; 112 } 113 114 @Override report(ReportCanvas canvas)115 public void report(ReportCanvas canvas) { 116 super.report(canvas); 117 118 int usbClass = getUsbClass(); 119 int usbSubclass = getUsbSubclass(); 120 int protocol = getProtocol(); 121 String className = UsbStrings.getClassName(usbClass); 122 String subclassName = ""; 123 if (usbClass == UsbDescriptor.CLASSID_AUDIO) { 124 subclassName = UsbStrings.getAudioSubclassName(usbSubclass); 125 } 126 127 canvas.openList(); 128 canvas.writeListItem("Interface #" + getInterfaceNumber()); 129 canvas.writeListItem("Class: " + ReportCanvas.getHexString(usbClass) + ": " + className); 130 canvas.writeListItem("Subclass: " 131 + ReportCanvas.getHexString(usbSubclass) + ": " + subclassName); 132 canvas.writeListItem("Protocol: " + protocol + ": " + ReportCanvas.getHexString(protocol)); 133 canvas.writeListItem("Endpoints: " + getNumEndpoints()); 134 canvas.closeList(); 135 } 136 } 137