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.UsbConfiguration; 19 import android.hardware.usb.UsbInterface; 20 import android.util.Log; 21 22 import com.android.server.usb.descriptors.report.ReportCanvas; 23 24 import java.util.ArrayList; 25 26 /** 27 * @hide 28 * An USB Config Descriptor. 29 * see usb11.pdf section 9.6.2 30 */ 31 public final class UsbConfigDescriptor extends UsbDescriptor { 32 private static final String TAG = "UsbConfigDescriptor"; 33 34 private int mTotalLength; // 2:2 Total length in bytes of data returned 35 private byte mNumInterfaces; // 4:1 Number of Interfaces 36 private int mConfigValue; // 5:1 Value to use as an argument to select this configuration 37 private byte mConfigIndex; // 6:1 Index of String Descriptor describing this configuration 38 private int mAttribs; // 7:1 D7 Reserved, set to 1. (USB 1.0 Bus Powered) 39 // D6 Self Powered 40 // D5 Remote Wakeup 41 // D4..0 Reserved, set to 0. 42 private int mMaxPower; // 8:1 Maximum Power Consumption in 2mA units 43 44 private boolean mBlockAudio; // leave it off for now. We be replace with a "Developer Option" 45 46 private ArrayList<UsbInterfaceDescriptor> mInterfaceDescriptors = 47 new ArrayList<UsbInterfaceDescriptor>(); 48 UsbConfigDescriptor(int length, byte type)49 UsbConfigDescriptor(int length, byte type) { 50 super(length, type); 51 mHierarchyLevel = 2; 52 } 53 getTotalLength()54 public int getTotalLength() { 55 return mTotalLength; 56 } 57 getNumInterfaces()58 public byte getNumInterfaces() { 59 return mNumInterfaces; 60 } 61 getConfigValue()62 public int getConfigValue() { 63 return mConfigValue; 64 } 65 getConfigIndex()66 public byte getConfigIndex() { 67 return mConfigIndex; 68 } 69 getAttribs()70 public int getAttribs() { 71 return mAttribs; 72 } 73 getMaxPower()74 public int getMaxPower() { 75 return mMaxPower; 76 } 77 addInterfaceDescriptor(UsbInterfaceDescriptor interfaceDesc)78 void addInterfaceDescriptor(UsbInterfaceDescriptor interfaceDesc) { 79 mInterfaceDescriptors.add(interfaceDesc); 80 } 81 getInterfaceDescriptors()82 ArrayList<UsbInterfaceDescriptor> getInterfaceDescriptors() { 83 return mInterfaceDescriptors; 84 } 85 isAudioInterface(UsbInterfaceDescriptor descriptor)86 private boolean isAudioInterface(UsbInterfaceDescriptor descriptor) { 87 return descriptor.getUsbClass() == UsbDescriptor.CLASSID_AUDIO 88 && descriptor.getUsbSubclass() == UsbDescriptor.AUDIO_AUDIOSTREAMING; 89 } 90 toAndroid(UsbDescriptorParser parser)91 UsbConfiguration toAndroid(UsbDescriptorParser parser) { 92 if (UsbDescriptorParser.DEBUG) { 93 Log.d(TAG, " toAndroid()"); 94 } 95 96 // NOTE - This code running in the server process. 97 //TODO (pmclean@) - remove this 98 // int pid = android.os.Process.myPid(); 99 // int uid = android.os.Process.myUid(); 100 // Log.d(TAG, " ---- pid:" + pid + " uid:" + uid); 101 102 String name = parser.getDescriptorString(mConfigIndex); 103 UsbConfiguration config = new 104 UsbConfiguration(mConfigValue, name, mAttribs, mMaxPower); 105 106 ArrayList<UsbInterface> filteredInterfaces = new ArrayList<UsbInterface>(); 107 for (UsbInterfaceDescriptor descriptor : mInterfaceDescriptors) { 108 if (!mBlockAudio || !isAudioInterface(descriptor)) { 109 filteredInterfaces.add(descriptor.toAndroid(parser)); 110 } 111 } 112 UsbInterface[] interfaceArray = new UsbInterface[0]; 113 interfaceArray = filteredInterfaces.toArray(interfaceArray); 114 config.setInterfaces(interfaceArray); 115 return config; 116 } 117 118 @Override parseRawDescriptors(ByteStream stream)119 public int parseRawDescriptors(ByteStream stream) { 120 mTotalLength = stream.unpackUsbShort(); 121 mNumInterfaces = stream.getByte(); 122 mConfigValue = stream.getUnsignedByte(); 123 mConfigIndex = stream.getByte(); 124 mAttribs = stream.getUnsignedByte(); 125 mMaxPower = stream.getUnsignedByte(); 126 127 return mLength; 128 } 129 130 @Override report(ReportCanvas canvas)131 public void report(ReportCanvas canvas) { 132 super.report(canvas); 133 134 canvas.openList(); 135 canvas.writeListItem("Config # " + getConfigValue()); 136 canvas.writeListItem(getNumInterfaces() + " Interfaces."); 137 canvas.writeListItem("Attributes: " + ReportCanvas.getHexString(getAttribs())); 138 canvas.closeList(); 139 } 140 } 141