1 /* 2 * Copyright (C) 2018 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 17 package com.android.internal.usb; 18 19 import static android.hardware.usb.UsbPortStatus.MODE_AUDIO_ACCESSORY; 20 import static android.hardware.usb.UsbPortStatus.MODE_DEBUG_ACCESSORY; 21 import static android.hardware.usb.UsbPortStatus.MODE_DFP; 22 import static android.hardware.usb.UsbPortStatus.MODE_DUAL; 23 import static android.hardware.usb.UsbPortStatus.MODE_NONE; 24 import static android.hardware.usb.UsbPortStatus.MODE_UFP; 25 26 import static com.android.internal.util.dump.DumpUtils.writeStringIfNotNull; 27 28 import android.annotation.NonNull; 29 import android.hardware.usb.UsbAccessory; 30 import android.hardware.usb.UsbConfiguration; 31 import android.hardware.usb.UsbDevice; 32 import android.hardware.usb.UsbEndpoint; 33 import android.hardware.usb.UsbInterface; 34 import android.hardware.usb.UsbPort; 35 import android.hardware.usb.UsbPortStatus; 36 import android.hardware.usb.V1_0.Constants; 37 import android.service.usb.UsbAccessoryProto; 38 import android.service.usb.UsbConfigurationProto; 39 import android.service.usb.UsbDeviceProto; 40 import android.service.usb.UsbEndPointProto; 41 import android.service.usb.UsbInterfaceProto; 42 import android.service.usb.UsbPortProto; 43 import android.service.usb.UsbPortStatusProto; 44 import android.service.usb.UsbPortStatusRoleCombinationProto; 45 46 import com.android.internal.util.dump.DualDumpOutputStream; 47 48 /** Dump methods for public USB classes */ 49 public class DumpUtils { writeAccessory(@onNull DualDumpOutputStream dump, @NonNull String idName, long id, @NonNull UsbAccessory accessory)50 public static void writeAccessory(@NonNull DualDumpOutputStream dump, @NonNull String idName, 51 long id, @NonNull UsbAccessory accessory) { 52 long token = dump.start(idName, id); 53 54 dump.write("manufacturer", UsbAccessoryProto.MANUFACTURER, accessory.getManufacturer()); 55 dump.write("model", UsbAccessoryProto.MODEL, accessory.getModel()); 56 writeStringIfNotNull(dump, "description", UsbAccessoryProto.DESCRIPTION, 57 accessory.getManufacturer()); 58 dump.write("version", UsbAccessoryProto.VERSION, accessory.getVersion()); 59 writeStringIfNotNull(dump, "uri", UsbAccessoryProto.URI, accessory.getUri()); 60 dump.write("serial", UsbAccessoryProto.SERIAL, accessory.getSerial()); 61 62 dump.end(token); 63 } 64 writeDevice(@onNull DualDumpOutputStream dump, @NonNull String idName, long id, @NonNull UsbDevice device)65 public static void writeDevice(@NonNull DualDumpOutputStream dump, @NonNull String idName, 66 long id, @NonNull UsbDevice device) { 67 long token = dump.start(idName, id); 68 69 dump.write("name", UsbDeviceProto.NAME, device.getDeviceName()); 70 dump.write("vendor_id", UsbDeviceProto.VENDOR_ID, device.getVendorId()); 71 dump.write("product_id", UsbDeviceProto.PRODUCT_ID, device.getProductId()); 72 dump.write("class", UsbDeviceProto.CLASS, device.getDeviceClass()); 73 dump.write("subclass", UsbDeviceProto.SUBCLASS, device.getDeviceSubclass()); 74 dump.write("protocol", UsbDeviceProto.PROTOCOL, device.getDeviceProtocol()); 75 dump.write("manufacturer_name", UsbDeviceProto.MANUFACTURER_NAME, 76 device.getManufacturerName()); 77 dump.write("product_name", UsbDeviceProto.PRODUCT_NAME, device.getProductName()); 78 dump.write("version", UsbDeviceProto.VERSION, device.getVersion()); 79 dump.write("serial_number", UsbDeviceProto.SERIAL_NUMBER, device.getSerialNumber()); 80 81 int numConfigurations = device.getConfigurationCount(); 82 for (int i = 0; i < numConfigurations; i++) { 83 writeConfiguration(dump, "configurations", UsbDeviceProto.CONFIGURATIONS, 84 device.getConfiguration(i)); 85 } 86 87 dump.end(token); 88 } 89 writeConfiguration(@onNull DualDumpOutputStream dump, @NonNull String idName, long id, @NonNull UsbConfiguration configuration)90 private static void writeConfiguration(@NonNull DualDumpOutputStream dump, 91 @NonNull String idName, long id, @NonNull UsbConfiguration configuration) { 92 long token = dump.start(idName, id); 93 dump.write("id", UsbConfigurationProto.ID, configuration.getId()); 94 dump.write("name", UsbConfigurationProto.NAME, configuration.getName()); 95 dump.write("attributes", UsbConfigurationProto.ATTRIBUTES, configuration.getAttributes()); 96 dump.write("max_power", UsbConfigurationProto.MAX_POWER, configuration.getMaxPower()); 97 98 int numInterfaces = configuration.getInterfaceCount(); 99 for (int i = 0; i < numInterfaces; i++) { 100 writeInterface(dump, "interfaces", UsbConfigurationProto.INTERFACES, 101 configuration.getInterface(i)); 102 } 103 dump.end(token); 104 } 105 writeInterface(@onNull DualDumpOutputStream dump, @NonNull String idName, long id, @NonNull UsbInterface iface)106 private static void writeInterface(@NonNull DualDumpOutputStream dump, @NonNull String idName, 107 long id, @NonNull UsbInterface iface) { 108 long token = dump.start(idName, id); 109 110 dump.write("id", UsbInterfaceProto.ID, iface.getId()); 111 dump.write("alternate_settings", UsbInterfaceProto.ALTERNATE_SETTINGS, 112 iface.getAlternateSetting()); 113 dump.write("name", UsbInterfaceProto.NAME, iface.getName()); 114 dump.write("class", UsbInterfaceProto.CLASS, iface.getInterfaceClass()); 115 dump.write("subclass", UsbInterfaceProto.SUBCLASS, iface.getInterfaceSubclass()); 116 dump.write("protocol", UsbInterfaceProto.PROTOCOL, iface.getInterfaceProtocol()); 117 118 int numEndpoints = iface.getEndpointCount(); 119 for (int i = 0; i < numEndpoints; i++) { 120 writeEndpoint(dump, "endpoints", UsbInterfaceProto.ENDPOINTS, iface.getEndpoint(i)); 121 } 122 dump.end(token); 123 } 124 writeEndpoint(@onNull DualDumpOutputStream dump, @NonNull String idName, long id, @NonNull UsbEndpoint endpoint)125 private static void writeEndpoint(@NonNull DualDumpOutputStream dump, @NonNull String idName, 126 long id, @NonNull UsbEndpoint endpoint) { 127 long token = dump.start(idName, id); 128 129 dump.write("endpoint_number", UsbEndPointProto.ENDPOINT_NUMBER, 130 endpoint.getEndpointNumber()); 131 dump.write("direction", UsbEndPointProto.DIRECTION, endpoint.getDirection()); 132 dump.write("address", UsbEndPointProto.ADDRESS, endpoint.getAddress()); 133 dump.write("type", UsbEndPointProto.TYPE, endpoint.getType()); 134 dump.write("attributes", UsbEndPointProto.ATTRIBUTES, 135 endpoint.getAttributes()); 136 dump.write("max_packet_size", UsbEndPointProto.MAX_PACKET_SIZE, 137 endpoint.getMaxPacketSize()); 138 dump.write("interval", UsbEndPointProto.INTERVAL, endpoint.getInterval()); 139 140 dump.end(token); 141 } 142 writePort(@onNull DualDumpOutputStream dump, @NonNull String idName, long id, @NonNull UsbPort port)143 public static void writePort(@NonNull DualDumpOutputStream dump, @NonNull String idName, 144 long id, @NonNull UsbPort port) { 145 long token = dump.start(idName, id); 146 147 dump.write("id", UsbPortProto.ID, port.getId()); 148 149 int mode = port.getSupportedModes(); 150 if (dump.isProto()) { 151 if (mode == MODE_NONE) { 152 dump.write("supported_modes", UsbPortProto.SUPPORTED_MODES, MODE_NONE); 153 } else { 154 if ((mode & MODE_DUAL) == MODE_DUAL) { 155 dump.write("supported_modes", UsbPortProto.SUPPORTED_MODES, MODE_DUAL); 156 } else { 157 if ((mode & MODE_DFP) == MODE_DFP) { 158 dump.write("supported_modes", UsbPortProto.SUPPORTED_MODES, MODE_DFP); 159 } else if ((mode & MODE_UFP) == MODE_UFP) { 160 dump.write("supported_modes", UsbPortProto.SUPPORTED_MODES, MODE_UFP); 161 } 162 } 163 164 if ((mode & MODE_AUDIO_ACCESSORY) == MODE_AUDIO_ACCESSORY) { 165 dump.write("supported_modes", UsbPortProto.SUPPORTED_MODES, 166 MODE_AUDIO_ACCESSORY); 167 } 168 169 if ((mode & MODE_DEBUG_ACCESSORY) == MODE_DEBUG_ACCESSORY) { 170 dump.write("supported_modes", UsbPortProto.SUPPORTED_MODES, 171 MODE_DEBUG_ACCESSORY); 172 } 173 } 174 } else { 175 dump.write("supported_modes", UsbPortProto.SUPPORTED_MODES, UsbPort.modeToString(mode)); 176 } 177 178 dump.end(token); 179 } 180 writePowerRole(@onNull DualDumpOutputStream dump, @NonNull String idName, long id, int powerRole)181 private static void writePowerRole(@NonNull DualDumpOutputStream dump, @NonNull String idName, 182 long id, int powerRole) { 183 if (dump.isProto()) { 184 dump.write(idName, id, powerRole); 185 } else { 186 dump.write(idName, id, UsbPort.powerRoleToString(powerRole)); 187 } 188 } 189 writeDataRole(@onNull DualDumpOutputStream dump, @NonNull String idName, long id, int dataRole)190 private static void writeDataRole(@NonNull DualDumpOutputStream dump, @NonNull String idName, 191 long id, int dataRole) { 192 if (dump.isProto()) { 193 dump.write(idName, id, dataRole); 194 } else { 195 dump.write(idName, id, UsbPort.dataRoleToString(dataRole)); 196 } 197 } 198 writeContaminantPresenceStatus(@onNull DualDumpOutputStream dump, @NonNull String idName, long id, int contaminantPresenceStatus)199 private static void writeContaminantPresenceStatus(@NonNull DualDumpOutputStream dump, 200 @NonNull String idName, long id, int contaminantPresenceStatus) { 201 if (dump.isProto()) { 202 dump.write(idName, id, contaminantPresenceStatus); 203 } else { 204 dump.write(idName, id, 205 UsbPort.contaminantPresenceStatusToString(contaminantPresenceStatus)); 206 } 207 } 208 writePortStatus(@onNull DualDumpOutputStream dump, @NonNull String idName, long id, @NonNull UsbPortStatus status)209 public static void writePortStatus(@NonNull DualDumpOutputStream dump, @NonNull String idName, 210 long id, @NonNull UsbPortStatus status) { 211 long token = dump.start(idName, id); 212 213 dump.write("connected", UsbPortStatusProto.CONNECTED, status.isConnected()); 214 215 if (dump.isProto()) { 216 dump.write("current_mode", UsbPortStatusProto.CURRENT_MODE, status.getCurrentMode()); 217 } else { 218 dump.write("current_mode", UsbPortStatusProto.CURRENT_MODE, 219 UsbPort.modeToString(status.getCurrentMode())); 220 } 221 222 writePowerRole(dump, "power_role", UsbPortStatusProto.POWER_ROLE, 223 status.getCurrentPowerRole()); 224 writeDataRole(dump, "data_role", UsbPortStatusProto.DATA_ROLE, status.getCurrentDataRole()); 225 226 int undumpedCombinations = status.getSupportedRoleCombinations(); 227 while (undumpedCombinations != 0) { 228 int index = Integer.numberOfTrailingZeros(undumpedCombinations); 229 undumpedCombinations &= ~(1 << index); 230 231 int powerRole = (index / Constants.PortDataRole.NUM_DATA_ROLES 232 + Constants.PortPowerRole.NONE); 233 int dataRole = index % Constants.PortDataRole.NUM_DATA_ROLES; 234 235 long roleCombinationToken = dump.start("role_combinations", 236 UsbPortStatusProto.ROLE_COMBINATIONS); 237 writePowerRole(dump, "power_role", UsbPortStatusRoleCombinationProto.POWER_ROLE, 238 powerRole); 239 writeDataRole(dump, "data_role", UsbPortStatusRoleCombinationProto.DATA_ROLE, 240 dataRole); 241 dump.end(roleCombinationToken); 242 } 243 244 writeContaminantPresenceStatus(dump, "contaminant_presence_status", 245 UsbPortStatusProto.CONTAMINANT_PRESENCE_STATUS, 246 status.getContaminantDetectionStatus()); 247 248 dump.end(token); 249 } 250 } 251