diff options
27 files changed, 1151 insertions, 201 deletions
diff --git a/core/java/android/hardware/usb/AccessoryFilter.java b/core/java/android/hardware/usb/AccessoryFilter.java index d9b7c5be7ddd..00070fe363be 100644 --- a/core/java/android/hardware/usb/AccessoryFilter.java +++ b/core/java/android/hardware/usb/AccessoryFilter.java @@ -16,6 +16,11 @@ package android.hardware.usb; +import android.annotation.NonNull; +import android.service.usb.UsbAccessoryFilterProto; + +import com.android.internal.util.dump.DualDumpOutputStream; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; @@ -142,4 +147,17 @@ public class AccessoryFilter { "\", mModel=\"" + mModel + "\", mVersion=\"" + mVersion + "\"]"; } + + /** + * Write a description of the filter to a dump stream. + */ + public void dump(@NonNull DualDumpOutputStream dump, String idName, long id) { + long token = dump.start(idName, id); + + dump.write("manufacturer", UsbAccessoryFilterProto.MANUFACTURER, mManufacturer); + dump.write("model", UsbAccessoryFilterProto.MODEL, mModel); + dump.write("version", UsbAccessoryFilterProto.VERSION, mVersion); + + dump.end(token); + } } diff --git a/core/java/android/hardware/usb/DeviceFilter.java b/core/java/android/hardware/usb/DeviceFilter.java index 439c629758b0..6f1aff71b2f3 100644 --- a/core/java/android/hardware/usb/DeviceFilter.java +++ b/core/java/android/hardware/usb/DeviceFilter.java @@ -16,8 +16,12 @@ package android.hardware.usb; +import android.annotation.NonNull; +import android.service.usb.UsbDeviceFilterProto; import android.util.Slog; +import com.android.internal.util.dump.DualDumpOutputStream; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; @@ -310,4 +314,22 @@ public class DeviceFilter { ",mProductName=" + mProductName + ",mSerialNumber=" + mSerialNumber + "]"; } + + /** + * Write a description of the filter to a dump stream. + */ + public void dump(@NonNull DualDumpOutputStream dump, String idName, long id) { + long token = dump.start(idName, id); + + dump.write("vendor_id", UsbDeviceFilterProto.VENDOR_ID, mVendorId); + dump.write("product_id", UsbDeviceFilterProto.PRODUCT_ID, mProductId); + dump.write("class", UsbDeviceFilterProto.CLASS, mClass); + dump.write("subclass", UsbDeviceFilterProto.SUBCLASS, mSubclass); + dump.write("protocol", UsbDeviceFilterProto.PROTOCOL, mProtocol); + dump.write("manufacturer_name", UsbDeviceFilterProto.MANUFACTURER_NAME, mManufacturerName); + dump.write("product_name", UsbDeviceFilterProto.PRODUCT_NAME, mProductName); + dump.write("serial_number", UsbDeviceFilterProto.SERIAL_NUMBER, mSerialNumber); + + dump.end(token); + } } diff --git a/core/java/android/hardware/usb/UsbConfiguration.java b/core/java/android/hardware/usb/UsbConfiguration.java index a17157087a61..6ce420191ed3 100644 --- a/core/java/android/hardware/usb/UsbConfiguration.java +++ b/core/java/android/hardware/usb/UsbConfiguration.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; + import com.android.internal.util.Preconditions; /** @@ -106,6 +107,17 @@ public class UsbConfiguration implements Parcelable { } /** + * Returns the attributes of this configuration + * + * @return the configuration's attributes + * + * @hide + */ + public int getAttributes() { + return mAttributes; + } + + /** * Returns the configuration's max power consumption, in milliamps. * * @return the configuration's max power diff --git a/core/java/android/hardware/usb/UsbConstants.java b/core/java/android/hardware/usb/UsbConstants.java index 0e8d47ca1304..215e9d5fa94b 100644 --- a/core/java/android/hardware/usb/UsbConstants.java +++ b/core/java/android/hardware/usb/UsbConstants.java @@ -16,6 +16,8 @@ package android.hardware.usb; +import android.service.ServiceProtoEnums; + /** * Contains constants for the USB protocol. * These constants correspond to definitions in linux/usb/ch9.h in the linux kernel. @@ -35,12 +37,12 @@ public final class UsbConstants { * Used to signify direction of data for a {@link UsbEndpoint} is OUT (host to device) * @see UsbEndpoint#getDirection */ - public static final int USB_DIR_OUT = 0; + public static final int USB_DIR_OUT = ServiceProtoEnums.USB_ENDPOINT_DIR_OUT; // 0 /** * Used to signify direction of data for a {@link UsbEndpoint} is IN (device to host) * @see UsbEndpoint#getDirection */ - public static final int USB_DIR_IN = 0x80; + public static final int USB_DIR_IN = ServiceProtoEnums.USB_ENDPOINT_DIR_IN; // 0x80 /** * Bitmask used for extracting the {@link UsbEndpoint} number its address field. @@ -63,22 +65,26 @@ public final class UsbConstants { * Control endpoint type (endpoint zero) * @see UsbEndpoint#getType */ - public static final int USB_ENDPOINT_XFER_CONTROL = 0; + public static final int USB_ENDPOINT_XFER_CONTROL = + ServiceProtoEnums.USB_ENDPOINT_TYPE_XFER_CONTROL; // 0 /** * Isochronous endpoint type (currently not supported) * @see UsbEndpoint#getType */ - public static final int USB_ENDPOINT_XFER_ISOC = 1; + public static final int USB_ENDPOINT_XFER_ISOC = + ServiceProtoEnums.USB_ENDPOINT_TYPE_XFER_ISOC; // 1 /** * Bulk endpoint type * @see UsbEndpoint#getType */ - public static final int USB_ENDPOINT_XFER_BULK = 2; + public static final int USB_ENDPOINT_XFER_BULK = + ServiceProtoEnums.USB_ENDPOINT_TYPE_XFER_BULK; // 2 /** * Interrupt endpoint type * @see UsbEndpoint#getType */ - public static final int USB_ENDPOINT_XFER_INT = 3; + public static final int USB_ENDPOINT_XFER_INT = + ServiceProtoEnums.USB_ENDPOINT_TYPE_XFER_INT; // 3 /** diff --git a/core/java/com/android/internal/print/DumpUtils.java b/core/java/com/android/internal/print/DumpUtils.java index 3192d5cbbd1d..1916c11e9c9d 100644 --- a/core/java/com/android/internal/print/DumpUtils.java +++ b/core/java/com/android/internal/print/DumpUtils.java @@ -16,10 +16,9 @@ package com.android.internal.print; +import static com.android.internal.util.dump.DumpUtils.writeComponentName; + import android.annotation.NonNull; -import android.annotation.Nullable; -import android.content.ComponentName; -import android.content.ComponentNameProto; import android.content.Context; import android.print.PageRange; import android.print.PrintAttributes; @@ -40,42 +39,13 @@ import android.service.print.PrinterIdProto; import android.service.print.PrinterInfoProto; import android.service.print.ResolutionProto; +import com.android.internal.util.dump.DualDumpOutputStream; + /** * Utilities for dumping print related proto buffer */ public class DumpUtils { /** - * Write a string to a proto if the string is not {@code null}. - * - * @param proto The proto to write to - * @param idName Clear text name of the proto-id - * @param id The proto-id of the string - * @param string The string to write - */ - public static void writeStringIfNotNull(@NonNull DualDumpOutputStream proto, String idName, - long id, @Nullable String string) { - if (string != null) { - proto.write(idName, id, string); - } - } - - /** - * Write a {@link ComponentName} to a proto. - * - * @param proto The proto to write to - * @param idName Clear text name of the proto-id - * @param id The proto-id of the component name - * @param component The component name to write - */ - public static void writeComponentName(@NonNull DualDumpOutputStream proto, String idName, - long id, @NonNull ComponentName component) { - long token = proto.start(idName, id); - proto.write("package_name", ComponentNameProto.PACKAGE_NAME, component.getPackageName()); - proto.write("class_name", ComponentNameProto.CLASS_NAME, component.getClassName()); - proto.end(token); - } - - /** * Write a {@link PrinterId} to a proto. * * @param proto The proto to write to diff --git a/core/java/com/android/internal/usb/DumpUtils.java b/core/java/com/android/internal/usb/DumpUtils.java new file mode 100644 index 000000000000..cac22652ebd7 --- /dev/null +++ b/core/java/com/android/internal/usb/DumpUtils.java @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.usb; + +import static android.hardware.usb.UsbPort.MODE_AUDIO_ACCESSORY; +import static android.hardware.usb.UsbPort.MODE_DEBUG_ACCESSORY; +import static android.hardware.usb.UsbPort.MODE_DFP; +import static android.hardware.usb.UsbPort.MODE_DUAL; +import static android.hardware.usb.UsbPort.MODE_NONE; +import static android.hardware.usb.UsbPort.MODE_UFP; + +import static com.android.internal.util.dump.DumpUtils.writeStringIfNotNull; + +import android.annotation.NonNull; +import android.hardware.usb.UsbAccessory; +import android.hardware.usb.UsbConfiguration; +import android.hardware.usb.UsbDevice; +import android.hardware.usb.UsbEndpoint; +import android.hardware.usb.UsbInterface; +import android.hardware.usb.UsbPort; +import android.hardware.usb.UsbPortStatus; +import android.hardware.usb.V1_0.Constants; +import android.service.usb.UsbAccessoryProto; +import android.service.usb.UsbConfigurationProto; +import android.service.usb.UsbDeviceProto; +import android.service.usb.UsbEndPointProto; +import android.service.usb.UsbInterfaceProto; +import android.service.usb.UsbPortProto; +import android.service.usb.UsbPortStatusProto; +import android.service.usb.UsbPortStatusRoleCombinationProto; + +import com.android.internal.util.dump.DualDumpOutputStream; + +/** Dump methods for public USB classes */ +public class DumpUtils { + public static void writeAccessory(@NonNull DualDumpOutputStream dump, @NonNull String idName, + long id, @NonNull UsbAccessory accessory) { + long token = dump.start(idName, id); + + dump.write("manufacturer", UsbAccessoryProto.MANUFACTURER, accessory.getManufacturer()); + dump.write("model", UsbAccessoryProto.MODEL, accessory.getModel()); + writeStringIfNotNull(dump, "description", UsbAccessoryProto.DESCRIPTION, + accessory.getManufacturer()); + dump.write("version", UsbAccessoryProto.VERSION, accessory.getVersion()); + writeStringIfNotNull(dump, "uri", UsbAccessoryProto.URI, accessory.getUri()); + dump.write("serial", UsbAccessoryProto.SERIAL, accessory.getSerial()); + + dump.end(token); + } + + public static void writeDevice(@NonNull DualDumpOutputStream dump, @NonNull String idName, + long id, @NonNull UsbDevice device) { + long token = dump.start(idName, id); + + dump.write("name", UsbDeviceProto.NAME, device.getDeviceName()); + dump.write("vendor_id", UsbDeviceProto.VENDOR_ID, device.getVendorId()); + dump.write("product_id", UsbDeviceProto.PRODUCT_ID, device.getProductId()); + dump.write("class", UsbDeviceProto.CLASS, device.getDeviceClass()); + dump.write("subclass", UsbDeviceProto.SUBCLASS, device.getDeviceSubclass()); + dump.write("protocol", UsbDeviceProto.PROTOCOL, device.getDeviceProtocol()); + dump.write("manufacturer_name", UsbDeviceProto.MANUFACTURER_NAME, + device.getManufacturerName()); + dump.write("product_name", UsbDeviceProto.PRODUCT_NAME, device.getProductName()); + dump.write("version", UsbDeviceProto.VERSION, device.getVersion()); + dump.write("serial_number", UsbDeviceProto.SERIAL_NUMBER, device.getSerialNumber()); + + int numConfigurations = device.getConfigurationCount(); + for (int i = 0; i < numConfigurations; i++) { + writeConfiguration(dump, "configurations", UsbDeviceProto.CONFIGURATIONS, + device.getConfiguration(i)); + } + + dump.end(token); + } + + private static void writeConfiguration(@NonNull DualDumpOutputStream dump, + @NonNull String idName, long id, @NonNull UsbConfiguration configuration) { + long token = dump.start(idName, id); + dump.write("id", UsbConfigurationProto.ID, configuration.getId()); + dump.write("name", UsbConfigurationProto.NAME, configuration.getName()); + dump.write("attributes", UsbConfigurationProto.ATTRIBUTES, configuration.getAttributes()); + dump.write("max_power", UsbConfigurationProto.MAX_POWER, configuration.getMaxPower()); + + int numInterfaces = configuration.getInterfaceCount(); + for (int i = 0; i < numInterfaces; i++) { + writeInterface(dump, "interfaces", UsbConfigurationProto.INTERFACES, + configuration.getInterface(i)); + } + dump.end(token); + } + + private static void writeInterface(@NonNull DualDumpOutputStream dump, @NonNull String idName, + long id, @NonNull UsbInterface iface) { + long token = dump.start(idName, id); + + dump.write("id", UsbInterfaceProto.ID, iface.getId()); + dump.write("alternate_settings", UsbInterfaceProto.ALTERNATE_SETTINGS, + iface.getAlternateSetting()); + dump.write("name", UsbInterfaceProto.NAME, iface.getName()); + dump.write("class", UsbInterfaceProto.CLASS, iface.getInterfaceClass()); + dump.write("subclass", UsbInterfaceProto.SUBCLASS, iface.getInterfaceSubclass()); + dump.write("protocol", UsbInterfaceProto.PROTOCOL, iface.getInterfaceProtocol()); + + int numEndpoints = iface.getEndpointCount(); + for (int i = 0; i < numEndpoints; i++) { + writeEndpoint(dump, "endpoints", UsbInterfaceProto.ENDPOINTS, iface.getEndpoint(i)); + } + dump.end(token); + } + + private static void writeEndpoint(@NonNull DualDumpOutputStream dump, @NonNull String idName, + long id, @NonNull UsbEndpoint endpoint) { + long token = dump.start(idName, id); + + dump.write("endpoint_number", UsbEndPointProto.ENDPOINT_NUMBER, + endpoint.getEndpointNumber()); + dump.write("direction", UsbEndPointProto.DIRECTION, endpoint.getDirection()); + dump.write("address", UsbEndPointProto.ADDRESS, endpoint.getAddress()); + dump.write("type", UsbEndPointProto.TYPE, endpoint.getType()); + dump.write("attributes", UsbEndPointProto.ATTRIBUTES, + endpoint.getAttributes()); + dump.write("max_packet_size", UsbEndPointProto.MAX_PACKET_SIZE, + endpoint.getMaxPacketSize()); + dump.write("interval", UsbEndPointProto.INTERVAL, endpoint.getInterval()); + + dump.end(token); + } + + public static void writePort(@NonNull DualDumpOutputStream dump, @NonNull String idName, + long id, @NonNull UsbPort port) { + long token = dump.start(idName, id); + + dump.write("id", UsbPortProto.ID, port.getId()); + + int mode = port.getSupportedModes(); + if (dump.isProto()) { + if (mode == MODE_NONE) { + dump.write("supported_modes", UsbPortProto.SUPPORTED_MODES, MODE_NONE); + } else { + if ((mode & MODE_DUAL) == MODE_DUAL) { + dump.write("supported_modes", UsbPortProto.SUPPORTED_MODES, MODE_DUAL); + } else { + if ((mode & MODE_DFP) == MODE_DFP) { + dump.write("supported_modes", UsbPortProto.SUPPORTED_MODES, MODE_DFP); + } else if ((mode & MODE_UFP) == MODE_UFP) { + dump.write("supported_modes", UsbPortProto.SUPPORTED_MODES, MODE_UFP); + } + } + + if ((mode & MODE_AUDIO_ACCESSORY) == MODE_AUDIO_ACCESSORY) { + dump.write("supported_modes", UsbPortProto.SUPPORTED_MODES, + MODE_AUDIO_ACCESSORY); + } + + if ((mode & MODE_DEBUG_ACCESSORY) == MODE_DEBUG_ACCESSORY) { + dump.write("supported_modes", UsbPortProto.SUPPORTED_MODES, + MODE_DEBUG_ACCESSORY); + } + } + } else { + dump.write("supported_modes", UsbPortProto.SUPPORTED_MODES, UsbPort.modeToString(mode)); + } + + dump.end(token); + } + + private static void writePowerRole(@NonNull DualDumpOutputStream dump, @NonNull String idName, + long id, int powerRole) { + if (dump.isProto()) { + dump.write(idName, id, powerRole); + } else { + dump.write(idName, id, UsbPort.powerRoleToString(powerRole)); + } + } + + private static void writeDataRole(@NonNull DualDumpOutputStream dump, @NonNull String idName, + long id, int dataRole) { + if (dump.isProto()) { + dump.write(idName, id, dataRole); + } else { + dump.write(idName, id, UsbPort.dataRoleToString(dataRole)); + } + } + + + public static void writePortStatus(@NonNull DualDumpOutputStream dump, @NonNull String idName, + long id, @NonNull UsbPortStatus status) { + long token = dump.start(idName, id); + + dump.write("connected", UsbPortStatusProto.CONNECTED, status.isConnected()); + + if (dump.isProto()) { + dump.write("current_mode", UsbPortStatusProto.CURRENT_MODE, status.getCurrentMode()); + } else { + dump.write("current_mode", UsbPortStatusProto.CURRENT_MODE, + UsbPort.modeToString(status.getCurrentMode())); + } + + writePowerRole(dump, "power_role", UsbPortStatusProto.POWER_ROLE, + status.getCurrentPowerRole()); + writeDataRole(dump, "data_role", UsbPortStatusProto.DATA_ROLE, status.getCurrentDataRole()); + + int undumpedCombinations = status.getSupportedRoleCombinations(); + while (undumpedCombinations != 0) { + int index = Integer.numberOfTrailingZeros(undumpedCombinations); + undumpedCombinations &= ~(1 << index); + + int powerRole = (index / Constants.PortDataRole.NUM_DATA_ROLES + + Constants.PortPowerRole.NONE); + int dataRole = index % Constants.PortDataRole.NUM_DATA_ROLES; + + long roleCombinationToken = dump.start("role_combinations", + UsbPortStatusProto.ROLE_COMBINATIONS); + writePowerRole(dump, "power_role", UsbPortStatusRoleCombinationProto.POWER_ROLE, + powerRole); + writeDataRole(dump, "data_role", UsbPortStatusRoleCombinationProto.DATA_ROLE, + dataRole); + dump.end(roleCombinationToken); + } + + dump.end(token); + } +} diff --git a/core/java/com/android/internal/print/DualDumpOutputStream.java b/core/java/com/android/internal/util/dump/DualDumpOutputStream.java index 4b10ef2facbb..3ac38edaddb4 100644 --- a/core/java/com/android/internal/print/DualDumpOutputStream.java +++ b/core/java/com/android/internal/util/dump/DualDumpOutputStream.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.internal.print; +package com.android.internal.util.dump; import android.annotation.NonNull; import android.annotation.Nullable; @@ -131,27 +131,27 @@ public class DualDumpOutputStream { } } - /** - * Create a new DualDumpOutputStream. Only one output should be set. + * Create a new DualDumpOutputStream. * - * @param proto If dumping to proto the {@link ProtoOutputStream} - * @param ipw If dumping to a print writer, the {@link IndentingPrintWriter} + * @param proto the {@link ProtoOutputStream} */ - public DualDumpOutputStream(@Nullable ProtoOutputStream proto, - @Nullable IndentingPrintWriter ipw) { - if ((proto == null) == (ipw == null)) { - Log.e(LOG_TAG, "Cannot dump to clear text and proto at once. Ignoring proto"); - proto = null; - } - + public DualDumpOutputStream(@NonNull ProtoOutputStream proto) { mProtoStream = proto; + mIpw = null; + } + + /** + * Create a new DualDumpOutputStream. + * + * @param ipw the {@link IndentingPrintWriter} + */ + public DualDumpOutputStream(@NonNull IndentingPrintWriter ipw) { + mProtoStream = null; mIpw = ipw; - if (!isProto()) { - // Add root object - mDumpObjects.add(new DumpObject(null)); - } + // Add root object + mDumpObjects.add(new DumpObject(null)); } public void write(@NonNull String fieldName, long fieldId, double val) { diff --git a/core/java/com/android/internal/util/dump/DumpUtils.java b/core/java/com/android/internal/util/dump/DumpUtils.java new file mode 100644 index 000000000000..0ee204e1acac --- /dev/null +++ b/core/java/com/android/internal/util/dump/DumpUtils.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.util.dump; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.content.ComponentName; +import android.content.ComponentNameProto; + +public class DumpUtils { + /** + * Write a string to a proto if the string is not {@code null}. + * + * @param proto The proto to write to + * @param idName Clear text name of the proto-id + * @param id The proto-id of the string + * @param string The string to write + */ + public static void writeStringIfNotNull(@NonNull DualDumpOutputStream proto, String idName, + long id, @Nullable String string) { + if (string != null) { + proto.write(idName, id, string); + } + } + + /** + * Write a {@link ComponentName} to a proto. + * + * @param proto The proto to write to + * @param idName Clear text name of the proto-id + * @param id The proto-id of the component name + * @param component The component name to write + */ + public static void writeComponentName(@NonNull DualDumpOutputStream proto, String idName, + long id, @NonNull ComponentName component) { + long token = proto.start(idName, id); + proto.write("package_name", ComponentNameProto.PACKAGE_NAME, component.getPackageName()); + proto.write("class_name", ComponentNameProto.CLASS_NAME, component.getClassName()); + proto.end(token); + } +} diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto index 8a04bf7253e4..0b0ed8386c60 100644 --- a/core/proto/android/os/incident.proto +++ b/core/proto/android/os/incident.proto @@ -42,6 +42,7 @@ import "frameworks/base/core/proto/android/service/notification.proto"; import "frameworks/base/core/proto/android/service/package.proto"; import "frameworks/base/core/proto/android/service/print.proto"; import "frameworks/base/core/proto/android/service/procstats.proto"; +import "frameworks/base/core/proto/android/service/usb.proto"; import "frameworks/base/core/proto/android/util/event_log_tags.proto"; import "frameworks/base/core/proto/android/util/log.proto"; import "frameworks/base/libs/incident/proto/android/os/header.proto"; @@ -254,4 +255,9 @@ message IncidentProto { (section).type = SECTION_DUMPSYS, (section).args = "jobscheduler --proto" ]; + + optional android.service.usb.UsbServiceDumpProto usb = 3021 [ + (section).type = SECTION_DUMPSYS, + (section).args = "usb --proto" + ]; } diff --git a/core/proto/android/service/enums.proto b/core/proto/android/service/enums.proto new file mode 100644 index 000000000000..b64e685104b7 --- /dev/null +++ b/core/proto/android/service/enums.proto @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto2"; +package android.service; + +option java_outer_classname = "ServiceProtoEnums"; +option java_multiple_files = true; + +enum UsbEndPointType { + USB_ENDPOINT_TYPE_XFER_CONTROL = 0; + USB_ENDPOINT_TYPE_XFER_ISOC = 1; + USB_ENDPOINT_TYPE_XFER_BULK = 2; + USB_ENDPOINT_TYPE_XFER_INT = 3; +} + +enum UsbEndPointDirection { + USB_ENDPOINT_DIR_OUT = 0; + USB_ENDPOINT_DIR_IN = 0x80; +} + +enum UsbConnectionRecordMode { + USB_CONNECTION_RECORD_MODE_CONNECT = 0; + USB_CONNECTION_RECORD_MODE_CONNECT_BADPARSE = 1; + USB_CONNECTION_RECORD_MODE_CONNECT_BADDEVICE = 2; + USB_CONNECTION_RECORD_MODE_DISCONNECT = -1; +}
\ No newline at end of file diff --git a/core/proto/android/service/usb.proto b/core/proto/android/service/usb.proto new file mode 100644 index 000000000000..b60c56995223 --- /dev/null +++ b/core/proto/android/service/usb.proto @@ -0,0 +1,342 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto2"; +package android.service.usb; + +option java_multiple_files = true; +option java_outer_classname = "UsbServiceProto"; + +import "frameworks/base/core/proto/android/content/component_name.proto"; +import "frameworks/base/core/proto/android/service/enums.proto"; +import "frameworks/base/libs/incident/proto/android/privacy.proto"; + +message UsbServiceDumpProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional UsbDeviceManagerProto device_manager = 1; + optional UsbHostManagerProto host_manager = 2; + optional UsbPortManagerProto port_manager = 3; + optional UsbAlsaManagerProto alsa_manager = 4; + optional UsbSettingsManagerProto settings_manager = 5; +} + +message UsbDeviceManagerProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional UsbHandlerProto handler = 1; + optional UsbDebuggingManagerProto debugging_manager = 2; +} + +message UsbHandlerProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + /* Same as android.hardware.usb.gadget.V1_0.GadgetFunction.* */ + enum Function { + FUNCTION_ADB = 1; + FUNCTION_ACCESSORY = 2; + FUNCTION_MTP = 4; + FUNCTION_MIDI = 8; + FUNCTION_PTP = 16; + FUNCTION_RNDIS = 32; + FUNCTION_AUDIO_SOURCE = 64; + } + + repeated Function current_functions = 1; + optional bool current_functions_applied = 2; + repeated Function screen_unlocked_functions = 3; + optional bool screen_locked = 4; + optional bool connected = 5; + optional bool configured = 6; + optional UsbAccessoryProto current_accessory = 7; + optional bool host_connected = 8; + optional bool source_power = 9; + optional bool sink_power = 10; + optional bool usb_charging = 11; + optional bool hide_usb_notification = 12; + optional bool audio_accessory_connected = 13; + optional bool adb_enabled = 14; + optional string kernel_state = 15; + optional string kernel_function_list = 16; +} + +message UsbAccessoryProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional string manufacturer = 1; + optional string model = 2; + optional string description = 3; + optional string version = 4; + optional string uri = 5; + optional string serial = 6 [ (android.privacy).dest = DEST_EXPLICIT ]; +} + +message UsbDebuggingManagerProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional bool connected_to_adb = 1; + optional string last_key_recevied = 2 [ (android.privacy).dest = DEST_EXPLICIT ]; + optional string user_keys = 3 [ (android.privacy).dest = DEST_LOCAL ]; + optional string system_keys = 4 [ (android.privacy).dest = DEST_LOCAL ]; +} + +message UsbHostManagerProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional android.content.ComponentNameProto default_usb_host_connection_handler = 1; + repeated UsbDeviceProto devices = 2; + optional int32 num_connects = 3; + repeated UsbConnectionRecordProto connections = 4; +} + +message UsbDeviceProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional string name = 1; + optional int32 vendor_id = 2; + optional int32 product_id = 3; + optional int32 class = 4; + optional int32 subclass = 5; + optional int32 protocol = 6; + optional string manufacturer_name = 7; + optional string product_name = 8; + optional string version = 9; + optional string serial_number = 10 [ (android.privacy).dest = DEST_EXPLICIT ]; + repeated UsbConfigurationProto configurations = 11; +} + +message UsbConfigurationProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional int32 id = 1; + optional string name = 2; + optional uint32 attributes = 3; + optional int32 max_power = 4; + repeated UsbInterfaceProto interfaces = 5; +} + +message UsbInterfaceProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional int32 id = 1; + optional int32 alternate_settings = 2; + optional string name = 3; + optional int32 class = 4; + optional int32 subclass = 5; + optional int32 protocol = 6; + repeated UsbEndPointProto endpoints = 7; +} + +message UsbEndPointProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional int32 endpoint_number = 1; + optional android.service.UsbEndPointDirection direction = 2; + optional int32 address = 3; + optional android.service.UsbEndPointType type = 4; + optional uint32 attributes = 5; + optional int32 max_packet_size = 6; + optional int32 interval = 7; +} + +message UsbConnectionRecordProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional string device_address = 1; + optional android.service.UsbConnectionRecordMode mode = 2; + optional int64 timestamp = 3; + optional int32 manufacturer = 4; + optional int32 product = 5; + optional UsbIsHeadsetProto is_headset = 6; +} + +message UsbIsHeadsetProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional bool in = 1; + optional bool out = 2; +} + +message UsbPortManagerProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional bool is_simulation_active = 1; + repeated UsbPortInfoProto usb_ports = 2; +} + +message UsbPortInfoProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional UsbPortProto port = 1; + optional UsbPortStatusProto status = 2; + optional bool can_change_mode = 3; + optional bool can_change_power_role = 4; + optional bool can_change_data_role = 5; +} + +message UsbPortProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + /* Same as android.hardware.usb.V1_1.Constants.PortMode_1_1 */ + enum Mode { + MODE_NONE = 0; + MODE_UFP = 1; + MODE_DFP = 2; + MODE_DRP = 3; + MODE_AUDIO_ACCESSORY = 4; + MODE_DEBUG_ACCESSORY = 8; + } + + optional string id = 1; + repeated Mode supported_modes = 2; +} + +message UsbPortStatusProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + /* Same as android.hardware.usb.V1_0.Constants.PortPowerRole */ + enum PowerRole { + POWER_ROLE_NONE = 0; + POWER_ROLE_SOURCE = 1; + POWER_ROLE_SINK = 2; + } + + /* Same as android.hardware.usb.V1_0.Constants.PortDataRole */ + enum DataRole { + DATA_ROLE_NONE = 0; + DATA_ROLE_HOST = 1; + DATA_ROLE_DEVICE = 2; + } + + optional bool connected = 1; + optional UsbPortProto.Mode current_mode = 2; + optional PowerRole power_role = 3; + optional DataRole data_role = 4; + repeated UsbPortStatusRoleCombinationProto role_combinations = 5; +} + +message UsbPortStatusRoleCombinationProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional UsbPortStatusProto.PowerRole power_role = 1; + optional UsbPortStatusProto.DataRole data_role = 2; +} + +message UsbAlsaManagerProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional int32 cards_parser = 1; + repeated UsbAlsaDeviceProto alsa_devices = 2; + repeated UsbMidiDeviceProto midi_devices = 3; +} + +message UsbAlsaDeviceProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional int32 card = 1; + optional int32 device = 2; + optional string name = 3; + optional bool has_playback = 4; + optional bool has_capture = 5; + optional string address = 6; +} + +message UsbMidiDeviceProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional int32 card = 1; + optional int32 device = 2; + optional string device_address = 3; +} + +message UsbSettingsManagerProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + repeated UsbUserSettingsManagerProto user_settings = 1; + repeated UsbProfileGroupSettingsManagerProto profile_group_settings = 2; +} + +message UsbUserSettingsManagerProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional int32 user_id = 1; + repeated UsbSettingsDevicePermissionProto device_permissions = 2; + repeated UsbSettingsAccessoryPermissionProto accessory_permissions = 3; +} + +message UsbSettingsDevicePermissionProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional string device_name = 1; + repeated int32 uids = 2; +} + +message UsbSettingsAccessoryPermissionProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional string accessory_description = 1; + repeated int32 uids = 2; +} + +message UsbProfileGroupSettingsManagerProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional int32 parent_user_id = 1; + repeated UsbSettingsDevicePreferenceProto device_preferences = 2; + repeated UsbSettingsAccessoryPreferenceProto accessory_preferences = 3; +} + +message UsbSettingsDevicePreferenceProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional UsbDeviceFilterProto filter = 1; + optional UserPackageProto user_package = 2; +} + +message UsbDeviceFilterProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional int32 vendor_id = 1; + optional int32 product_id = 2; + optional int32 class = 3; + optional int32 subclass = 4; + optional int32 protocol = 5; + optional string manufacturer_name = 6; + optional string product_name = 7; + optional string serial_number = 8 [ (android.privacy).dest = DEST_EXPLICIT ]; +} + +message UserPackageProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional int32 user_id = 1; + optional string package_name =2; +} + +message UsbSettingsAccessoryPreferenceProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional UsbAccessoryFilterProto filter = 1; + optional UserPackageProto user_package = 2; +} + +message UsbAccessoryFilterProto { + option (android.msg_privacy).dest = DEST_AUTOMATIC; + + optional string manufacturer = 1; + optional string model = 2; + optional string version = 3; +}
\ No newline at end of file diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java index f6a259dbf982..53e8813c7363 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java +++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java @@ -16,8 +16,8 @@ package com.android.printspooler.model; -import static com.android.internal.print.DumpUtils.writeComponentName; import static com.android.internal.print.DumpUtils.writePrintJobInfo; +import static com.android.internal.util.dump.DumpUtils.writeComponentName; import android.annotation.FloatRange; import android.annotation.NonNull; @@ -59,10 +59,10 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.logging.MetricsLogger; import com.android.internal.os.HandlerCaller; -import com.android.internal.print.DualDumpOutputStream; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; +import com.android.internal.util.dump.DualDumpOutputStream; import com.android.printspooler.R; import com.android.printspooler.util.ApprovedPrintServices; @@ -214,12 +214,11 @@ public final class PrintSpoolerService extends Service { try { synchronized (mLock) { if (dumpAsProto) { - dumpLocked(new DualDumpOutputStream(new ProtoOutputStream(fd), null)); + dumpLocked(new DualDumpOutputStream(new ProtoOutputStream(fd))); } else { try (FileOutputStream out = new FileOutputStream(fd)) { try (PrintWriter w = new PrintWriter(out)) { - dumpLocked(new DualDumpOutputStream(null, new IndentingPrintWriter(w, - " "))); + dumpLocked(new DualDumpOutputStream(new IndentingPrintWriter(w, " "))); } } catch (IOException ignored) { } diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java index d6cc80516485..e1c1eb298e31 100644 --- a/services/print/java/com/android/server/print/PrintManagerService.java +++ b/services/print/java/com/android/server/print/PrintManagerService.java @@ -61,10 +61,10 @@ import android.widget.Toast; import com.android.internal.content.PackageMonitor; import com.android.internal.os.BackgroundThread; -import com.android.internal.print.DualDumpOutputStream; import com.android.internal.util.DumpUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; +import com.android.internal.util.dump.DualDumpOutputStream; import com.android.server.LocalServices; import com.android.server.SystemService; @@ -708,12 +708,12 @@ public final class PrintManagerService extends SystemService { final long identity = Binder.clearCallingIdentity(); try { if (dumpAsProto) { - dump(new DualDumpOutputStream(new ProtoOutputStream(fd), null), + dump(new DualDumpOutputStream(new ProtoOutputStream(fd)), userStatesToDump); } else { pw.println("PRINT MANAGER STATE (dumpsys print)"); - dump(new DualDumpOutputStream(null, new IndentingPrintWriter(pw, " ")), + dump(new DualDumpOutputStream(new IndentingPrintWriter(pw, " ")), userStatesToDump); } } finally { diff --git a/services/print/java/com/android/server/print/RemotePrintService.java b/services/print/java/com/android/server/print/RemotePrintService.java index 80b97cf995ae..f72d8eee7b9b 100644 --- a/services/print/java/com/android/server/print/RemotePrintService.java +++ b/services/print/java/com/android/server/print/RemotePrintService.java @@ -16,8 +16,8 @@ package com.android.server.print; -import static com.android.internal.print.DumpUtils.writeComponentName; import static com.android.internal.print.DumpUtils.writePrinterId; +import static com.android.internal.util.dump.DumpUtils.writeComponentName; import android.annotation.FloatRange; import android.annotation.NonNull; @@ -49,7 +49,7 @@ import android.service.print.ActivePrintServiceProto; import android.util.Slog; import com.android.internal.annotations.GuardedBy; -import com.android.internal.print.DualDumpOutputStream; +import com.android.internal.util.dump.DualDumpOutputStream; import java.lang.ref.WeakReference; import java.util.ArrayList; diff --git a/services/print/java/com/android/server/print/RemotePrintSpooler.java b/services/print/java/com/android/server/print/RemotePrintSpooler.java index a69baa110f5a..ba5dde04897f 100644 --- a/services/print/java/com/android/server/print/RemotePrintSpooler.java +++ b/services/print/java/com/android/server/print/RemotePrintSpooler.java @@ -46,7 +46,7 @@ import android.util.TimedRemoteCaller; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.TransferPipe; -import com.android.internal.print.DualDumpOutputStream; +import com.android.internal.util.dump.DualDumpOutputStream; import libcore.io.IoUtils; diff --git a/services/print/java/com/android/server/print/UserState.java b/services/print/java/com/android/server/print/UserState.java index e2808e8245e5..84c1bb272b5a 100644 --- a/services/print/java/com/android/server/print/UserState.java +++ b/services/print/java/com/android/server/print/UserState.java @@ -20,11 +20,11 @@ import static android.content.pm.PackageManager.GET_META_DATA; import static android.content.pm.PackageManager.GET_SERVICES; import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING; -import static com.android.internal.print.DumpUtils.writeComponentName; import static com.android.internal.print.DumpUtils.writePrintJobInfo; import static com.android.internal.print.DumpUtils.writePrinterId; import static com.android.internal.print.DumpUtils.writePrinterInfo; -import static com.android.internal.print.DumpUtils.writeStringIfNotNull; +import static com.android.internal.util.dump.DumpUtils.writeComponentName; +import static com.android.internal.util.dump.DumpUtils.writeStringIfNotNull; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; import android.annotation.NonNull; @@ -81,7 +81,7 @@ import com.android.internal.R; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.os.BackgroundThread; -import com.android.internal.print.DualDumpOutputStream; +import com.android.internal.util.dump.DualDumpOutputStream; import com.android.server.print.RemotePrintService.PrintServiceCallbacks; import com.android.server.print.RemotePrintServiceRecommendationService .RemotePrintServiceRecommendationServiceCallbacks; diff --git a/services/usb/java/com/android/server/usb/UsbAlsaDevice.java b/services/usb/java/com/android/server/usb/UsbAlsaDevice.java index 74280fff2dfc..7480e5662d7a 100644 --- a/services/usb/java/com/android/server/usb/UsbAlsaDevice.java +++ b/services/usb/java/com/android/server/usb/UsbAlsaDevice.java @@ -16,6 +16,11 @@ package com.android.server.usb; +import android.annotation.NonNull; +import android.service.usb.UsbAlsaDeviceProto; + +import com.android.internal.util.dump.DualDumpOutputStream; + /** * Represents the ALSA specification, and attributes of an ALSA device. */ @@ -109,6 +114,22 @@ public final class UsbAlsaDevice { + ", hasCapture: " + mHasCapture + "]"; } + /** + * Write a description of the device to a dump stream. + */ + public void dump(@NonNull DualDumpOutputStream dump, String idName, long id) { + long token = dump.start(idName, id); + + dump.write("card", UsbAlsaDeviceProto.CARD, mCardNum); + dump.write("device", UsbAlsaDeviceProto.DEVICE, mDeviceNum); + dump.write("name", UsbAlsaDeviceProto.NAME, mDeviceName); + dump.write("has_playback", UsbAlsaDeviceProto.HAS_PLAYBACK, mHasPlayback); + dump.write("has_capture", UsbAlsaDeviceProto.HAS_CAPTURE, mHasCapture); + dump.write("address", UsbAlsaDeviceProto.ADDRESS, mDeviceAddress); + + dump.end(token); + } + // called by logDevices String toShortString() { return "[card:" + mCardNum + " device:" + mDeviceNum + " " + mDeviceName + "]"; diff --git a/services/usb/java/com/android/server/usb/UsbAlsaManager.java b/services/usb/java/com/android/server/usb/UsbAlsaManager.java index 0a94828e595e..0c5f8f113adc 100644 --- a/services/usb/java/com/android/server/usb/UsbAlsaManager.java +++ b/services/usb/java/com/android/server/usb/UsbAlsaManager.java @@ -27,10 +27,11 @@ import android.os.Bundle; import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; +import android.service.usb.UsbAlsaManagerProto; import android.util.Slog; import com.android.internal.alsa.AlsaCardsParser; -import com.android.internal.util.IndentingPrintWriter; +import com.android.internal.util.dump.DualDumpOutputStream; import com.android.server.audio.AudioService; import com.android.server.usb.descriptors.UsbDescriptorParser; @@ -304,22 +305,38 @@ public final class UsbAlsaManager { } // - // Logging + // Devices List // - // called by UsbService.dump - public void dump(IndentingPrintWriter pw) { - pw.println("Parsers Scan Status:"); - pw.println(" Cards Parser: " + mCardsParser.getScanStatus()); -// pw.println(" Devices Parser: " + mDevicesParser.getScanStatus()); - pw.println("USB Audio Devices:"); +/* + //import java.util.ArrayList; + public ArrayList<UsbAudioDevice> getConnectedDevices() { + ArrayList<UsbAudioDevice> devices = new ArrayList<UsbAudioDevice>(mAudioDevices.size()); + for (HashMap.Entry<UsbDevice,UsbAudioDevice> entry : mAudioDevices.entrySet()) { + devices.add(entry.getValue()); + } + return devices; + } +*/ + + /** + * Dump the USB alsa state. + */ + public void dump(DualDumpOutputStream dump, String idName, long id) { + long token = dump.start(idName, id); + + dump.write("cards_parser", UsbAlsaManagerProto.CARDS_PARSER, mCardsParser.getScanStatus()); + for (UsbAlsaDevice usbAlsaDevice : mAlsaDevices) { - pw.println(" " + usbAlsaDevice.getDeviceAddress() + ": " + usbAlsaDevice); + usbAlsaDevice.dump(dump, "alsa_devices", UsbAlsaManagerProto.ALSA_DEVICES); } - pw.println("USB MIDI Devices:"); + for (String deviceAddr : mMidiDevices.keySet()) { - UsbMidiDevice midiDevice = mMidiDevices.get(deviceAddr); - pw.println(" " + deviceAddr + ": " + midiDevice); + // A UsbMidiDevice does not have a handle to the UsbDevice anymore + mMidiDevices.get(deviceAddr).dump(deviceAddr, dump, "midi_devices", + UsbAlsaManagerProto.MIDI_DEVICES); } + + dump.end(token); } /* diff --git a/services/usb/java/com/android/server/usb/UsbDebuggingManager.java b/services/usb/java/com/android/server/usb/UsbDebuggingManager.java index 703f1a1ca656..74d8e129901a 100644 --- a/services/usb/java/com/android/server/usb/UsbDebuggingManager.java +++ b/services/usb/java/com/android/server/usb/UsbDebuggingManager.java @@ -16,6 +16,8 @@ package com.android.server.usb; +import static com.android.internal.util.dump.DumpUtils.writeStringIfNotNull; + import android.app.ActivityManager; import android.content.ActivityNotFoundException; import android.content.ComponentName; @@ -35,11 +37,12 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; +import android.service.usb.UsbDebuggingManagerProto; import android.util.Base64; import android.util.Slog; import com.android.internal.R; -import com.android.internal.util.IndentingPrintWriter; +import com.android.internal.util.dump.DualDumpOutputStream; import com.android.server.FgThread; import java.io.File; @@ -451,21 +454,30 @@ public class UsbDebuggingManager { mHandler.sendEmptyMessage(UsbDebuggingHandler.MESSAGE_ADB_CLEAR); } - public void dump(IndentingPrintWriter pw) { - pw.println("USB Debugging State:"); - pw.println(" Connected to adbd: " + (mThread != null)); - pw.println(" Last key received: " + mFingerprints); - pw.println(" User keys:"); + /** + * Dump the USB debugging state. + */ + public void dump(DualDumpOutputStream dump, String idName, long id) { + long token = dump.start(idName, id); + + dump.write("connected_to_adb", UsbDebuggingManagerProto.CONNECTED_TO_ADB, mThread != null); + writeStringIfNotNull(dump, "last_key_received", UsbDebuggingManagerProto.LAST_KEY_RECEVIED, + mFingerprints); + try { - pw.println(FileUtils.readTextFile(new File("/data/misc/adb/adb_keys"), 0, null)); + dump.write("user_keys", UsbDebuggingManagerProto.USER_KEYS, + FileUtils.readTextFile(new File("/data/misc/adb/adb_keys"), 0, null)); } catch (IOException e) { - pw.println("IOException: " + e); + Slog.e(TAG, "Cannot read user keys", e); } - pw.println(" System keys:"); + try { - pw.println(FileUtils.readTextFile(new File("/adb_keys"), 0, null)); + dump.write("system_keys", UsbDebuggingManagerProto.SYSTEM_KEYS, + FileUtils.readTextFile(new File("/adb_keys"), 0, null)); } catch (IOException e) { - pw.println("IOException: " + e); + Slog.e(TAG, "Cannot read system keys", e); } + + dump.end(token); } } diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index a67e7f37f947..e5f50dedc6bb 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -16,6 +16,9 @@ package com.android.server.usb; +import static com.android.internal.usb.DumpUtils.writeAccessory; +import static com.android.internal.util.dump.DumpUtils.writeStringIfNotNull; + import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.KeyguardManager; @@ -41,6 +44,7 @@ import android.hardware.usb.UsbInterface; import android.hardware.usb.UsbManager; import android.hardware.usb.UsbPort; import android.hardware.usb.UsbPortStatus; +import android.hardware.usb.gadget.V1_0.GadgetFunction; import android.hardware.usb.gadget.V1_0.IUsbGadget; import android.hardware.usb.gadget.V1_0.IUsbGadgetCallback; import android.hardware.usb.gadget.V1_0.Status; @@ -63,6 +67,8 @@ import android.os.UserManager; import android.os.storage.StorageManager; import android.os.storage.StorageVolume; import android.provider.Settings; +import android.service.usb.UsbDeviceManagerProto; +import android.service.usb.UsbHandlerProto; import android.util.Pair; import android.util.Slog; @@ -72,7 +78,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.SomeArgs; -import com.android.internal.util.IndentingPrintWriter; +import com.android.internal.util.dump.DualDumpOutputStream; import com.android.server.FgThread; import com.android.server.LocalServices; @@ -1244,32 +1250,66 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver return mScreenUnlockedFunctions; } + /** + * Dump a functions mask either as proto-enums (if dumping to proto) or a string (if dumping + * to a print writer) + */ + private void dumpFunctions(DualDumpOutputStream dump, String idName, long id, + long functions) { + // UsbHandlerProto.UsbFunction matches GadgetFunction + for (int i = 0; i < 63; i++) { + if ((functions & (1L << i)) != 0) { + if (dump.isProto()) { + dump.write(idName, id, 1L << i); + } else { + dump.write(idName, id, GadgetFunction.toString(1L << i)); + } + } + } + } + + public void dump(DualDumpOutputStream dump, String idName, long id) { + long token = dump.start(idName, id); - public void dump(IndentingPrintWriter pw) { - pw.println("USB Device State:"); - pw.println(" mCurrentFunctions: " + mCurrentFunctions); - pw.println(" mCurrentFunctionsApplied: " + mCurrentFunctionsApplied); - pw.println(" mScreenUnlockedFunctions: " + mScreenUnlockedFunctions); - pw.println(" mScreenLocked: " + mScreenLocked); - pw.println(" mConnected: " + mConnected); - pw.println(" mConfigured: " + mConfigured); - pw.println(" mCurrentAccessory: " + mCurrentAccessory); - pw.println(" mHostConnected: " + mHostConnected); - pw.println(" mSourcePower: " + mSourcePower); - pw.println(" mSinkPower: " + mSinkPower); - pw.println(" mUsbCharging: " + mUsbCharging); - pw.println(" mHideUsbNotification: " + mHideUsbNotification); - pw.println(" mAudioAccessoryConnected: " + mAudioAccessoryConnected); - pw.println(" mAdbEnabled: " + mAdbEnabled); + dumpFunctions(dump, "current_functions", UsbHandlerProto.CURRENT_FUNCTIONS, + mCurrentFunctions); + dump.write("current_functions_applied", UsbHandlerProto.CURRENT_FUNCTIONS_APPLIED, + mCurrentFunctionsApplied); + dumpFunctions(dump, "screen_unlocked_functions", + UsbHandlerProto.SCREEN_UNLOCKED_FUNCTIONS, mScreenUnlockedFunctions); + dump.write("screen_locked", UsbHandlerProto.SCREEN_LOCKED, mScreenLocked); + dump.write("connected", UsbHandlerProto.CONNECTED, mConnected); + dump.write("configured", UsbHandlerProto.CONFIGURED, mConfigured); + if (mCurrentAccessory != null) { + writeAccessory(dump, "current_accessory", UsbHandlerProto.CURRENT_ACCESSORY, + mCurrentAccessory); + } + dump.write("host_connected", UsbHandlerProto.HOST_CONNECTED, mHostConnected); + dump.write("source_power", UsbHandlerProto.SOURCE_POWER, mSourcePower); + dump.write("sink_power", UsbHandlerProto.SINK_POWER, mSinkPower); + dump.write("usb_charging", UsbHandlerProto.USB_CHARGING, mUsbCharging); + dump.write("hide_usb_notification", UsbHandlerProto.HIDE_USB_NOTIFICATION, + mHideUsbNotification); + dump.write("audio_accessory_connected", UsbHandlerProto.AUDIO_ACCESSORY_CONNECTED, + mAudioAccessoryConnected); + dump.write("adb_enabled", UsbHandlerProto.ADB_ENABLED, mAdbEnabled); try { - pw.println(" Kernel state: " - + FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim()); - pw.println(" Kernel function list: " - + FileUtils.readTextFile(new File(FUNCTIONS_PATH), 0, null).trim()); - } catch (IOException e) { - pw.println("IOException: " + e); + writeStringIfNotNull(dump, "kernel_state", UsbHandlerProto.KERNEL_STATE, + FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim()); + } catch (Exception e) { + Slog.e(TAG, "Could not read kernel state", e); + } + + try { + writeStringIfNotNull(dump, "kernel_function_list", + UsbHandlerProto.KERNEL_FUNCTION_LIST, + FileUtils.readTextFile(new File(FUNCTIONS_PATH), 0, null).trim()); + } catch (Exception e) { + Slog.e(TAG, "Could not read kernel function list", e); } + + dump.end(token); } /** @@ -2000,13 +2040,21 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver } } - public void dump(IndentingPrintWriter pw) { + /** + * Write the state to a dump stream. + */ + public void dump(DualDumpOutputStream dump, String idName, long id) { + long token = dump.start(idName, id); + if (mHandler != null) { - mHandler.dump(pw); + mHandler.dump(dump, "handler", UsbDeviceManagerProto.HANDLER); } if (mDebuggingManager != null) { - mDebuggingManager.dump(pw); + mDebuggingManager.dump(dump, "debugging_manager", + UsbDeviceManagerProto.DEBUGGING_MANAGER); } + + dump.end(token); } private native String[] nativeGetAccessoryStrings(); diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java index 58f914773071..0fcd075e8200 100644 --- a/services/usb/java/com/android/server/usb/UsbHostManager.java +++ b/services/usb/java/com/android/server/usb/UsbHostManager.java @@ -16,6 +16,10 @@ package com.android.server.usb; +import static com.android.internal.usb.DumpUtils.writeDevice; +import static com.android.internal.util.dump.DumpUtils.writeComponentName; + +import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ComponentName; import android.content.Context; @@ -23,11 +27,16 @@ import android.hardware.usb.UsbConstants; import android.hardware.usb.UsbDevice; import android.os.Bundle; import android.os.ParcelFileDescriptor; +import android.service.ServiceProtoEnums; +import android.service.usb.UsbConnectionRecordProto; +import android.service.usb.UsbHostManagerProto; +import android.service.usb.UsbIsHeadsetProto; import android.text.TextUtils; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; +import com.android.internal.util.dump.DualDumpOutputStream; import com.android.server.usb.descriptors.UsbDescriptor; import com.android.server.usb.descriptors.UsbDescriptorParser; import com.android.server.usb.descriptors.UsbDeviceDescriptor; @@ -84,10 +93,13 @@ public class UsbHostManager { long mTimestamp; // Same time-base as system log. String mDeviceAddress; - static final int CONNECT = 0; - static final int CONNECT_BADPARSE = 1; - static final int CONNECT_BADDEVICE = 2; - static final int DISCONNECT = -1; + static final int CONNECT = ServiceProtoEnums.USB_CONNECTION_RECORD_MODE_CONNECT; // 0 + static final int CONNECT_BADPARSE = + ServiceProtoEnums.USB_CONNECTION_RECORD_MODE_CONNECT_BADPARSE; // 1 + static final int CONNECT_BADDEVICE = + ServiceProtoEnums.USB_CONNECTION_RECORD_MODE_CONNECT_BADDEVICE; // 2 + static final int DISCONNECT = + ServiceProtoEnums.USB_CONNECTION_RECORD_MODE_DISCONNECT; // -1 final int mMode; final byte[] mDescriptors; @@ -103,6 +115,31 @@ public class UsbHostManager { return (new StringBuilder(sFormat.format(new Date(mTimestamp)))).toString(); } + void dump(@NonNull DualDumpOutputStream dump, String idName, long id) { + long token = dump.start(idName, id); + + dump.write("device_address", UsbConnectionRecordProto.DEVICE_ADDRESS, mDeviceAddress); + dump.write("mode", UsbConnectionRecordProto.MODE, mMode); + dump.write("timestamp", UsbConnectionRecordProto.TIMESTAMP, mTimestamp); + + if (mMode != DISCONNECT) { + UsbDescriptorParser parser = new UsbDescriptorParser(mDeviceAddress, mDescriptors); + + UsbDeviceDescriptor deviceDescriptor = parser.getDeviceDescriptor(); + + dump.write("manufacturer", UsbConnectionRecordProto.MANUFACTURER, + deviceDescriptor.getVendorID()); + dump.write("product", UsbConnectionRecordProto.PRODUCT, + deviceDescriptor.getProductID()); + long isHeadSetToken = dump.start("is_headset", UsbConnectionRecordProto.IS_HEADSET); + dump.write("in", UsbIsHeadsetProto.IN, parser.isInputHeadset()); + dump.write("out", UsbIsHeadsetProto.OUT, parser.isOutputHeadset()); + dump.end(isHeadSetToken); + } + + dump.end(token); + } + void dumpShort(IndentingPrintWriter pw) { if (mMode != DISCONNECT) { pw.println(formatTime() + " Connect " + mDeviceAddress + " mode:" + mMode); @@ -394,30 +431,30 @@ public class UsbHostManager { /** * Dump out various information about the state of USB device connections. - * */ - public void dump(IndentingPrintWriter pw, String[] args) { - pw.println("USB Host State:"); + public void dump(DualDumpOutputStream dump, String idName, long id) { + long token = dump.start(idName, id); + synchronized (mHandlerLock) { if (mUsbDeviceConnectionHandler != null) { - pw.println("Default USB Host Connection handler: " + mUsbDeviceConnectionHandler); + writeComponentName(dump, "default_usb_host_connection_handler", + UsbHostManagerProto.DEFAULT_USB_HOST_CONNECTION_HANDLER, + mUsbDeviceConnectionHandler); } } synchronized (mLock) { for (String name : mDevices.keySet()) { - pw.println(" " + name + ": " + mDevices.get(name)); + writeDevice(dump, "devices", UsbHostManagerProto.DEVICES, mDevices.get(name)); } - // Connections - pw.println("" + mNumConnects + " total connects/disconnects"); - pw.println("Last " + mConnections.size() + " connections/disconnections"); + dump.write("num_connects", UsbHostManagerProto.NUM_CONNECTS, mNumConnects); + for (ConnectionRecord rec : mConnections) { - rec.dumpShort(pw); + rec.dump(dump, "connections", UsbHostManagerProto.CONNECTIONS); } - } - mUsbAlsaManager.dump(pw); + dump.end(token); } /** diff --git a/services/usb/java/com/android/server/usb/UsbMidiDevice.java b/services/usb/java/com/android/server/usb/UsbMidiDevice.java index cd19795747f5..f47636ed8ea4 100644 --- a/services/usb/java/com/android/server/usb/UsbMidiDevice.java +++ b/services/usb/java/com/android/server/usb/UsbMidiDevice.java @@ -16,14 +16,15 @@ package com.android.server.usb; +import android.annotation.NonNull; import android.content.Context; import android.media.midi.MidiDeviceInfo; import android.media.midi.MidiDeviceServer; import android.media.midi.MidiDeviceStatus; import android.media.midi.MidiManager; import android.media.midi.MidiReceiver; -import android.media.midi.MidiSender; import android.os.Bundle; +import android.service.usb.UsbMidiDeviceProto; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; @@ -32,6 +33,7 @@ import android.util.Log; import com.android.internal.midi.MidiEventScheduler; import com.android.internal.midi.MidiEventScheduler.MidiEvent; +import com.android.internal.util.dump.DualDumpOutputStream; import libcore.io.IoUtils; @@ -338,6 +340,20 @@ public final class UsbMidiDevice implements Closeable { mIsOpen = false; } + /** + * Write a description of the device to a dump stream. + */ + public void dump(String deviceAddr, @NonNull DualDumpOutputStream dump, @NonNull String idName, + long id) { + long token = dump.start(idName, id); + + dump.write("device_address", UsbMidiDeviceProto.DEVICE_ADDRESS, deviceAddr); + dump.write("card", UsbMidiDeviceProto.CARD, mAlsaCard); + dump.write("device", UsbMidiDeviceProto.DEVICE, mAlsaDevice); + + dump.end(token); + } + private static native int nativeGetSubdeviceCount(int card, int device); private native FileDescriptor[] nativeOpen(int card, int device, int subdeviceCount); private native void nativeClose(FileDescriptor[] fileDescriptors); diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java index e28513a29a3a..ddb4f04200b8 100644 --- a/services/usb/java/com/android/server/usb/UsbPortManager.java +++ b/services/usb/java/com/android/server/usb/UsbPortManager.java @@ -16,6 +16,10 @@ package com.android.server.usb; +import static com.android.internal.usb.DumpUtils.writePort; +import static com.android.internal.usb.DumpUtils.writePortStatus; + +import android.annotation.NonNull; import android.content.Context; import android.content.Intent; import android.hardware.usb.UsbManager; @@ -38,12 +42,15 @@ import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; import android.os.UserHandle; +import android.service.usb.UsbPortInfoProto; +import android.service.usb.UsbPortManagerProto; import android.util.ArrayMap; import android.util.Log; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; +import com.android.internal.util.dump.DualDumpOutputStream; import com.android.server.FgThread; import java.util.ArrayList; @@ -390,22 +397,22 @@ public class UsbPortManager { } } - public void dump(IndentingPrintWriter pw) { + /** + * Dump the USB port state. + */ + public void dump(DualDumpOutputStream dump, String idName, long id) { + long token = dump.start(idName, id); + synchronized (mLock) { - pw.print("USB Port State:"); - if (!mSimulatedPorts.isEmpty()) { - pw.print(" (simulation active; end with 'dumpsys usb reset')"); - } - pw.println(); + dump.write("is_simulation_active", UsbPortManagerProto.IS_SIMULATION_ACTIVE, + !mSimulatedPorts.isEmpty()); - if (mPorts.isEmpty()) { - pw.println(" <no ports>"); - } else { - for (PortInfo portInfo : mPorts.values()) { - pw.println(" " + portInfo.mUsbPort.getId() + ": " + portInfo); - } + for (PortInfo portInfo : mPorts.values()) { + portInfo.dump(dump, "usb_ports", UsbPortManagerProto.USB_PORTS); } } + + dump.end(token); } private static class HALCallback extends IUsbCallback.Stub { @@ -765,6 +772,20 @@ public class UsbPortManager { return false; } + void dump(@NonNull DualDumpOutputStream dump, @NonNull String idName, long id) { + long token = dump.start(idName, id); + + writePort(dump, "port", UsbPortInfoProto.PORT, mUsbPort); + writePortStatus(dump, "status", UsbPortInfoProto.STATUS, mUsbPortStatus); + dump.write("can_change_mode", UsbPortInfoProto.CAN_CHANGE_MODE, mCanChangeMode); + dump.write("can_change_power_role", UsbPortInfoProto.CAN_CHANGE_POWER_ROLE, + mCanChangePowerRole); + dump.write("can_change_data_role", UsbPortInfoProto.CAN_CHANGE_DATA_ROLE, + mCanChangeDataRole); + + dump.end(token); + } + @Override public String toString() { return "port=" + mUsbPort + ", status=" + mUsbPortStatus diff --git a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java index 5f1f5e496de1..4b2d9b9adbbb 100644 --- a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java +++ b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java @@ -41,6 +41,10 @@ import android.os.AsyncTask; import android.os.Environment; import android.os.UserHandle; import android.os.UserManager; +import android.service.usb.UsbProfileGroupSettingsManagerProto; +import android.service.usb.UsbSettingsAccessoryPreferenceProto; +import android.service.usb.UsbSettingsDevicePreferenceProto; +import android.service.usb.UserPackageProto; import android.util.AtomicFile; import android.util.Log; import android.util.Slog; @@ -52,8 +56,8 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.Immutable; import com.android.internal.content.PackageMonitor; import com.android.internal.util.FastXmlSerializer; -import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.XmlUtils; +import com.android.internal.util.dump.DualDumpOutputStream; import libcore.io.IoUtils; @@ -154,6 +158,15 @@ class UsbProfileGroupSettingsManager { public String toString() { return user.getIdentifier() + "/" + packageName; } + + public void dump(DualDumpOutputStream dump, String idName, long id) { + long token = dump.start(idName, id); + + dump.write("user_id", UserPackageProto.USER_ID, user.getIdentifier()); + dump.write("package_name", UserPackageProto.PACKAGE_NAME, packageName); + + dump.end(token); + } } private class MyPackageMonitor extends PackageMonitor { @@ -1109,17 +1122,38 @@ class UsbProfileGroupSettingsManager { } } - public void dump(IndentingPrintWriter pw) { + public void dump(@NonNull DualDumpOutputStream dump, @NonNull String idName, long id) { + long token = dump.start(idName, id); + synchronized (mLock) { - pw.println("Device preferences:"); + dump.write("parent_user_id", UsbProfileGroupSettingsManagerProto.PARENT_USER_ID, + mParentUser.getIdentifier()); + for (DeviceFilter filter : mDevicePreferenceMap.keySet()) { - pw.println(" " + filter + ": " + mDevicePreferenceMap.get(filter)); + long devicePrefToken = dump.start("device_preferences", + UsbProfileGroupSettingsManagerProto.DEVICE_PREFERENCES); + + filter.dump(dump, "filter", UsbSettingsDevicePreferenceProto.FILTER); + + mDevicePreferenceMap.get(filter).dump(dump, "user_package", + UsbSettingsDevicePreferenceProto.USER_PACKAGE); + + dump.end(devicePrefToken); } - pw.println("Accessory preferences:"); for (AccessoryFilter filter : mAccessoryPreferenceMap.keySet()) { - pw.println(" " + filter + ": " + mAccessoryPreferenceMap.get(filter)); + long accessoryPrefToken = dump.start("accessory_preferences", + UsbProfileGroupSettingsManagerProto.ACCESSORY_PREFERENCES); + + filter.dump(dump, "filter", UsbSettingsAccessoryPreferenceProto.FILTER); + + mAccessoryPreferenceMap.get(filter).dump(dump, "user_package", + UsbSettingsAccessoryPreferenceProto.USER_PACKAGE); + + dump.end(accessoryPrefToken); } } + + dump.end(token); } private static Intent createDeviceAttachedIntent(UsbDevice device) { diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java index 2f6e53143312..1edc46967495 100644 --- a/services/usb/java/com/android/server/usb/UsbService.java +++ b/services/usb/java/com/android/server/usb/UsbService.java @@ -37,17 +37,22 @@ import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.os.UserHandle; import android.os.UserManager; +import android.service.usb.UsbServiceDumpProto; +import android.util.ArraySet; import android.util.Slog; +import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.DumpUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; +import com.android.internal.util.dump.DualDumpOutputStream; import com.android.server.SystemService; import java.io.File; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.Collections; /** * UsbService manages all USB related state, including both host and device support. @@ -503,21 +508,38 @@ public class UsbService extends IUsbManager.Stub { final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); final long ident = Binder.clearCallingIdentity(); try { - if (args == null || args.length == 0 || "-a".equals(args[0])) { - pw.println("USB Manager State:"); - pw.increaseIndent(); + ArraySet<String> argsSet = new ArraySet<>(); + Collections.addAll(argsSet, args); + + boolean dumpAsProto = false; + if (argsSet.contains("--proto")) { + dumpAsProto = true; + } + + if (args == null || args.length == 0 || args[0].equals("-a") || dumpAsProto) { + DualDumpOutputStream dump; + if (dumpAsProto) { + dump = new DualDumpOutputStream(new ProtoOutputStream(fd)); + } else { + pw.println("USB MANAGER STATE (dumpsys usb):"); + + dump = new DualDumpOutputStream(new IndentingPrintWriter(pw, " ")); + } + if (mDeviceManager != null) { - mDeviceManager.dump(pw); + mDeviceManager.dump(dump, "device_manager", UsbServiceDumpProto.DEVICE_MANAGER); } if (mHostManager != null) { - mHostManager.dump(pw, args); + mHostManager.dump(dump, "host_manager", UsbServiceDumpProto.HOST_MANAGER); } if (mPortManager != null) { - mPortManager.dump(pw); + mPortManager.dump(dump, "port_manager", UsbServiceDumpProto.PORT_MANAGER); } - mAlsaManager.dump(pw); + mAlsaManager.dump(dump, "alsa_manager", UsbServiceDumpProto.ALSA_MANAGER); - mSettingsManager.dump(pw); + mSettingsManager.dump(dump, "settings_manager", + UsbServiceDumpProto.SETTINGS_MANAGER); + dump.flush(); } else if ("set-port-roles".equals(args[0]) && args.length == 4) { final String portId = args[1]; final int powerRole; @@ -558,7 +580,8 @@ public class UsbService extends IUsbManager.Stub { // during debugging, it might be worth adding a sleep here before // dumping the new state. pw.println(); - mPortManager.dump(pw); + mPortManager.dump(new DualDumpOutputStream(new IndentingPrintWriter(pw, " ")), + "", 0); } } else if ("add-port".equals(args[0]) && args.length == 3) { final String portId = args[1]; @@ -583,7 +606,8 @@ public class UsbService extends IUsbManager.Stub { if (mPortManager != null) { mPortManager.addSimulatedPort(portId, supportedModes, pw); pw.println(); - mPortManager.dump(pw); + mPortManager.dump(new DualDumpOutputStream(new IndentingPrintWriter(pw, " ")), + "", 0); } } else if ("connect-port".equals(args[0]) && args.length == 5) { final String portId = args[1]; @@ -630,31 +654,36 @@ public class UsbService extends IUsbManager.Stub { mPortManager.connectSimulatedPort(portId, mode, canChangeMode, powerRole, canChangePowerRole, dataRole, canChangeDataRole, pw); pw.println(); - mPortManager.dump(pw); + mPortManager.dump(new DualDumpOutputStream(new IndentingPrintWriter(pw, " ")), + "", 0); } } else if ("disconnect-port".equals(args[0]) && args.length == 2) { final String portId = args[1]; if (mPortManager != null) { mPortManager.disconnectSimulatedPort(portId, pw); pw.println(); - mPortManager.dump(pw); + mPortManager.dump(new DualDumpOutputStream(new IndentingPrintWriter(pw, " ")), + "", 0); } } else if ("remove-port".equals(args[0]) && args.length == 2) { final String portId = args[1]; if (mPortManager != null) { mPortManager.removeSimulatedPort(portId, pw); pw.println(); - mPortManager.dump(pw); + mPortManager.dump(new DualDumpOutputStream(new IndentingPrintWriter(pw, " ")), + "", 0); } } else if ("reset".equals(args[0]) && args.length == 1) { if (mPortManager != null) { mPortManager.resetSimulation(pw); pw.println(); - mPortManager.dump(pw); + mPortManager.dump(new DualDumpOutputStream(new IndentingPrintWriter(pw, " ")), + "", 0); } } else if ("ports".equals(args[0]) && args.length == 1) { if (mPortManager != null) { - mPortManager.dump(pw); + mPortManager.dump(new DualDumpOutputStream(new IndentingPrintWriter(pw, " ")), + "", 0); } } else if ("dump-descriptors".equals(args[0])) { mHostManager.dumpDescriptors(pw, args); diff --git a/services/usb/java/com/android/server/usb/UsbSettingsManager.java b/services/usb/java/com/android/server/usb/UsbSettingsManager.java index c7e5998db70d..caf05a3538ec 100644 --- a/services/usb/java/com/android/server/usb/UsbSettingsManager.java +++ b/services/usb/java/com/android/server/usb/UsbSettingsManager.java @@ -26,11 +26,12 @@ import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbManager; import android.os.UserHandle; import android.os.UserManager; +import android.service.usb.UsbSettingsManagerProto; import android.util.Slog; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; -import com.android.internal.util.IndentingPrintWriter; +import com.android.internal.util.dump.DualDumpOutputStream; /** * Maintains all {@link UsbUserSettingsManager} for all users. @@ -134,39 +135,27 @@ class UsbSettingsManager { /** * Dump all settings of all users. - * - * @param pw The writer to dump to */ - void dump(@NonNull IndentingPrintWriter pw) { + void dump(@NonNull DualDumpOutputStream dump, String idName, long id) { + long token = dump.start(idName, id); + synchronized (mSettingsByUser) { int numUsers = mSettingsByUser.size(); for (int i = 0; i < numUsers; i++) { - final int userId = mSettingsByUser.keyAt(i); - final UsbUserSettingsManager settings = mSettingsByUser.valueAt(i); - pw.println("Settings for user " + userId + ":"); - pw.increaseIndent(); - try { - settings.dump(pw); - } finally { - pw.decreaseIndent(); - } + mSettingsByUser.valueAt(i).dump(dump, "user_settings", + UsbSettingsManagerProto.USER_SETTINGS); } } synchronized (mSettingsByProfileGroup) { int numProfileGroups = mSettingsByProfileGroup.size(); for (int i = 0; i < numProfileGroups; i++) { - final int parentUserId = mSettingsByProfileGroup.keyAt(i); - final UsbProfileGroupSettingsManager settings = mSettingsByProfileGroup.valueAt(i); - pw.println("Settings for profile group " + parentUserId + ":"); - pw.increaseIndent(); - try { - settings.dump(pw); - } finally { - pw.decreaseIndent(); - } + mSettingsByProfileGroup.valueAt(i).dump(dump, "profile_group_settings", + UsbSettingsManagerProto.PROFILE_GROUP_SETTINGS); } } + + dump.end(token); } /** diff --git a/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java b/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java index 11e43e308e8a..840950679903 100644 --- a/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java +++ b/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java @@ -25,17 +25,20 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.hardware.usb.UsbAccessory; +import android.hardware.usb.UsbConstants; import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbInterface; -import android.hardware.usb.UsbConstants; import android.hardware.usb.UsbManager; import android.os.Binder; import android.os.Process; import android.os.UserHandle; +import android.service.usb.UsbSettingsAccessoryPermissionProto; +import android.service.usb.UsbSettingsDevicePermissionProto; +import android.service.usb.UsbUserSettingsManagerProto; import android.util.Slog; import android.util.SparseBooleanArray; -import com.android.internal.util.IndentingPrintWriter; +import com.android.internal.util.dump.DualDumpOutputStream; import java.util.HashMap; @@ -302,28 +305,44 @@ class UsbUserSettingsManager { } } - public void dump(IndentingPrintWriter pw) { + public void dump(@NonNull DualDumpOutputStream dump, @NonNull String idName, long id) { + long token = dump.start(idName, id); + synchronized (mLock) { - pw.println("Device permissions:"); + dump.write("user_id", UsbUserSettingsManagerProto.USER_ID, mUser.getIdentifier()); + for (String deviceName : mDevicePermissionMap.keySet()) { - pw.print(" " + deviceName + ": "); + long devicePermissionToken = dump.start("device_permissions", + UsbUserSettingsManagerProto.DEVICE_PERMISSIONS); + + dump.write("device_name", UsbSettingsDevicePermissionProto.DEVICE_NAME, deviceName); + SparseBooleanArray uidList = mDevicePermissionMap.get(deviceName); int count = uidList.size(); for (int i = 0; i < count; i++) { - pw.print(Integer.toString(uidList.keyAt(i)) + " "); + dump.write("uids", UsbSettingsDevicePermissionProto.UIDS, uidList.keyAt(i)); } - pw.println(); + + dump.end(devicePermissionToken); } - pw.println("Accessory permissions:"); for (UsbAccessory accessory : mAccessoryPermissionMap.keySet()) { - pw.print(" " + accessory + ": "); + long accessoryPermissionToken = dump.start("accessory_permissions", + UsbUserSettingsManagerProto.ACCESSORY_PERMISSIONS); + + dump.write("accessory_description", + UsbSettingsAccessoryPermissionProto.ACCESSORY_DESCRIPTION, + accessory.getDescription()); + SparseBooleanArray uidList = mAccessoryPermissionMap.get(accessory); int count = uidList.size(); for (int i = 0; i < count; i++) { - pw.print(Integer.toString(uidList.keyAt(i)) + " "); + dump.write("uids", UsbSettingsAccessoryPermissionProto.UIDS, uidList.keyAt(i)); } - pw.println(); + + dump.end(accessoryPermissionToken); } } + + dump.end(token); } } |