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