/*
 * 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/privacy.proto";
import "frameworks/proto_logging/stats/enums/service/enums.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;
    optional UsbPermissionsManagerProto permissions_manager = 6;
}

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.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;
        FUNCTION_UVC = 128;
    }

    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;
    optional string uevent = 17;
}

message UsbAccessoryProto {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    optional string manufacturer = 1;
    optional string model = 2;
    // For "classical" USB-accessories the manufacturer bakes this into the
    // firmware of the device. If an Android phone is configured as accessory, the
    // app that sets up the accessory side of the connection set this. Either way,
    // these are part of the detection protocol, and so they cannot be user set or
    // unique.
    optional string description = 3;
    optional string version = 4;
    optional string uri = 5 [ (android.privacy).dest = DEST_EXPLICIT ];
    // Non-resettable hardware ID.
    optional string serial = 6 [ (android.privacy).dest = DEST_LOCAL ];
}

message UsbDebuggingManagerProto {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    optional bool connected_to_adb = 1;
    // A workstation that connects to the phone for debugging is identified by
    // this key.
    optional string last_key_received = 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;
    repeated UsbDirectMidiDeviceProto midi_devices = 5;
}

message UsbDeviceProto {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    // Generic USB name, not user-provided.
    optional string name = 1;
    // ID specific to the vendor, not the device.
    optional int32 vendor_id = 2;
    // ID of this product type: Each vendor gives each product a unique ID. E.g.
    // all mice of the same model would have the same ID.
    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;
    // Non-resettable hardware ID.
    optional string serial_number = 10 [ (android.privacy).dest = DEST_LOCAL ];
    repeated UsbConfigurationProto configurations = 11;
}

message UsbConfigurationProto {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    // A single USB device can have several configurations and the app accessing
    // the USB device can switch between them. At any time only one can be active.
    // Each configuration can present completely different interfaces end
    // endpoints, i.e. a completely different behavior.
    optional int32 id = 1;
    // Hardware-defined name, not set by the user.
    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;

    // Hardware defined. This is the id used by the app to identify the interface.
    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;
      // The address of the endpoint. Needed to read and write to the endpoint.
    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;

    // usb device's address, e.g. 001/002, nothing about the phone
    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;

    enum HalVersion {
        V_UNKNOWN = 0;
        V1_0 = 10;
        V1_1 = 11;
        V1_2 = 12;
        V1_3 = 13;
        V2 = 20;
    }

    optional bool is_simulation_active = 1;
    repeated UsbPortInfoProto usb_ports = 2;
    optional bool enable_usb_data_signaling = 3;
    optional HalVersion hal_version = 4;
}

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;
    optional int64 connected_at_millis = 6;
    optional int64 last_connect_duration_millis = 7;
}

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;
    }

    enum AltMode {
        ALT_MODE_DISPLAYPORT = 1;
    }

    // ID of the port. A device (eg: Chromebooks) might have multiple ports.
    optional string id = 1;
    repeated Mode supported_modes = 2;
    optional bool supports_compliance_warnings = 3;
    repeated AltMode supported_alt_modes = 4;
}

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;
    optional android.service.ContaminantPresenceStatus contaminant_presence_status = 6;
    optional string usb_data_status = 7;
    optional bool is_power_transfer_limited = 8;
    optional string usb_power_brick_status = 9;
    optional string compliance_warnings_string = 10;
    optional string displayport_alt_mode_status = 11;
}

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;
    reserved 3; // previously midi_devices, now unused
    repeated UsbAlsaMidiDeviceProto alsa_midi_devices = 4;
}

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;
    // usb device's address, e.g. 001/002, nothing about the phone
    optional string address = 6;
}

message UsbAlsaMidiDeviceProto {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    optional int32 card = 1;
    optional int32 device = 2;
    // usb device's address, e.g. 001/002, nothing about the phone
    optional string device_address = 3;
}

message UsbDirectMidiDeviceProto {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    optional int32 num_inputs = 1;
    optional int32 num_outputs = 2;
    optional bool is_universal = 3;
    optional string name = 4;
    optional UsbMidiBlockParserProto block_parser = 5;
}

message UsbMidiBlockParserProto {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    optional int32 length = 1;
    optional int32 descriptor_type = 2;
    optional int32 descriptor_subtype = 3;
    optional int32 total_length = 4;
    repeated UsbGroupTerminalBlockProto block = 5;
}

message UsbGroupTerminalBlockProto {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    optional int32 length = 1;
    optional int32 descriptor_type = 2;
    optional int32 descriptor_subtype = 3;
    optional int32 group_block_id = 4;
    optional int32 group_terminal_block_type = 5;
    optional int32 group_terminal = 6;
    optional int32 num_group_terminals = 7;
    optional int32 block_item = 8;
    optional int32 midi_protocol = 9;
    optional int32 max_input_bandwidth = 10;
    optional int32 max_output_bandwidth = 11;
}

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;
    reserved 2; // previously device_permissions, now unused
    reserved 3; // previously accessory_permissions, now unused
    repeated UsbDeviceAttachedActivities device_attached_activities = 4;
    repeated UsbAccessoryAttachedActivities accessory_attached_activities = 5;
}

message UsbProfileGroupSettingsManagerProto {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    // The user id of the personal profile if the device has a work profile.
    optional int32 parent_user_id = 1;
    repeated UsbSettingsDevicePreferenceProto device_preferences = 2;
    repeated UsbSettingsAccessoryPreferenceProto accessory_preferences = 3;
    optional string intent = 4;
}

message UsbSettingsDevicePreferenceProto {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    optional UsbDeviceFilterProto filter = 1;
    optional UserPackageProto user_package = 2;
}

message UsbPermissionsManagerProto {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    repeated UsbUserPermissionsManagerProto user_permissions = 1;
}

message UsbUserPermissionsManagerProto {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    optional int32 user_id = 1;

    repeated UsbDevicePermissionProto device_permissions = 2;
    repeated UsbAccessoryPermissionProto accessory_permissions = 3;

    repeated UsbDevicePersistentPermissionProto device_persistent_permissions = 4;
    repeated UsbAccessoryPersistentPermissionProto accessory_persistent_permissions = 5;
}

message UsbDevicePermissionProto {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    // Name of device set by manufacturer
    // All devices of the same model have the same name
    optional string device_name = 1;
    repeated int32 uids = 2;
}

message UsbAccessoryPermissionProto {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    // Description of accessory set by manufacturer
    // All accessories of the same model have the same description
    optional string accessory_description = 1;
    repeated int32 uids = 2;
}

message UsbDevicePersistentPermissionProto {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    optional UsbDeviceFilterProto device_filter = 1;
    repeated UsbUidPermissionProto permission_values = 2;
}

message UsbAccessoryPersistentPermissionProto {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    optional UsbAccessoryFilterProto accessory_filter = 1;
    repeated UsbUidPermissionProto permission_values = 2;
}

message UsbUidPermissionProto {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    optional int32 uid = 1;
    optional bool is_granted = 2;
}

message UsbDeviceFilterProto {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    // Mirrors the vendor_id of UsbDeviceProto.
    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;
}

message UsbDeviceAttachedActivities {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    optional android.content.ComponentNameProto activity = 1;
    repeated UsbDeviceFilterProto filters = 2;
}

message UsbAccessoryAttachedActivities {
    option (android.msg_privacy).dest = DEST_AUTOMATIC;

    optional android.content.ComponentNameProto activity = 1;
    repeated UsbAccessoryFilterProto filters = 2;
}
