mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Merge changes from topics "199357330", "200993386"
* changes: Add Vts test for limitPowerTransfer interface Add limitPowerTransfer API to IUsb VTS tests for USB AIDL interface Migrate IUsb to AIDL
This commit is contained in:
committed by
Android (Google) Code Review
commit
36675ba54c
@@ -752,6 +752,13 @@
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="aidl" optional="true">
|
||||
<name>android.hardware.usb</name>
|
||||
<interface>
|
||||
<name>IUsb</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="hidl" optional="true">
|
||||
<name>android.hardware.usb.gadget</name>
|
||||
<version>1.0-2</version>
|
||||
|
||||
33
usb/aidl/Android.bp
Normal file
33
usb/aidl/Android.bp
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright (C) 2021 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.
|
||||
|
||||
aidl_interface {
|
||||
name: "android.hardware.usb",
|
||||
vendor_available: true,
|
||||
srcs: ["android/hardware/usb/*.aidl"],
|
||||
stability: "vintf",
|
||||
backend: {
|
||||
cpp: {
|
||||
enabled: false,
|
||||
},
|
||||
java: {
|
||||
sdk_version: "module_current",
|
||||
},
|
||||
ndk: {
|
||||
vndk: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
|
||||
// two cases:
|
||||
// 1). this is a frozen version file - do not edit this in any case.
|
||||
// 2). this is a 'current' file. If you make a backwards compatible change to
|
||||
// the interface (from the latest frozen version), the build system will
|
||||
// prompt you to update this file with `m <name>-update-api`.
|
||||
//
|
||||
// You must not make a backward incompatible change to any AIDL file built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.usb;
|
||||
@VintfStability
|
||||
enum ContaminantDetectionStatus {
|
||||
NOT_SUPPORTED = 0,
|
||||
DISABLED = 1,
|
||||
NOT_DETECTED = 2,
|
||||
DETECTED = 3,
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
|
||||
// two cases:
|
||||
// 1). this is a frozen version file - do not edit this in any case.
|
||||
// 2). this is a 'current' file. If you make a backwards compatible change to
|
||||
// the interface (from the latest frozen version), the build system will
|
||||
// prompt you to update this file with `m <name>-update-api`.
|
||||
//
|
||||
// You must not make a backward incompatible change to any AIDL file built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.usb;
|
||||
@VintfStability
|
||||
enum ContaminantProtectionMode {
|
||||
NONE = 0,
|
||||
FORCE_SINK = 1,
|
||||
FORCE_SOURCE = 2,
|
||||
FORCE_DISABLE = 3,
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
|
||||
// two cases:
|
||||
// 1). this is a frozen version file - do not edit this in any case.
|
||||
// 2). this is a 'current' file. If you make a backwards compatible change to
|
||||
// the interface (from the latest frozen version), the build system will
|
||||
// prompt you to update this file with `m <name>-update-api`.
|
||||
//
|
||||
// You must not make a backward incompatible change to any AIDL file built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.usb;
|
||||
@VintfStability
|
||||
enum ContaminantProtectionStatus {
|
||||
NONE = 0,
|
||||
FORCE_SINK = 1,
|
||||
FORCE_SOURCE = 2,
|
||||
FORCE_DISABLE = 3,
|
||||
DISABLED = 4,
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
|
||||
// two cases:
|
||||
// 1). this is a frozen version file - do not edit this in any case.
|
||||
// 2). this is a 'current' file. If you make a backwards compatible change to
|
||||
// the interface (from the latest frozen version), the build system will
|
||||
// prompt you to update this file with `m <name>-update-api`.
|
||||
//
|
||||
// You must not make a backward incompatible change to any AIDL file built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.usb;
|
||||
@VintfStability
|
||||
interface IUsb {
|
||||
oneway void enableContaminantPresenceDetection(in String portName, in boolean enable, long transactionId);
|
||||
oneway void enableUsbData(in String portName, boolean enable, long transactionId);
|
||||
oneway void queryPortStatus(long transactionId);
|
||||
oneway void setCallback(in android.hardware.usb.IUsbCallback callback);
|
||||
oneway void switchRole(in String portName, in android.hardware.usb.PortRole role, long transactionId);
|
||||
oneway void limitPowerTransfer(in String portName, boolean limit, long transactionId);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
|
||||
// two cases:
|
||||
// 1). this is a frozen version file - do not edit this in any case.
|
||||
// 2). this is a 'current' file. If you make a backwards compatible change to
|
||||
// the interface (from the latest frozen version), the build system will
|
||||
// prompt you to update this file with `m <name>-update-api`.
|
||||
//
|
||||
// You must not make a backward incompatible change to any AIDL file built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.usb;
|
||||
@VintfStability
|
||||
interface IUsbCallback {
|
||||
oneway void notifyPortStatusChange(in android.hardware.usb.PortStatus[] currentPortStatus, in android.hardware.usb.Status retval);
|
||||
oneway void notifyRoleSwitchStatus(in String portName, in android.hardware.usb.PortRole newRole, in android.hardware.usb.Status retval, long transactionId);
|
||||
oneway void notifyEnableUsbDataStatus(in String portName, boolean enable, in android.hardware.usb.Status retval, long transactionId);
|
||||
oneway void notifyContaminantEnabledStatus(in String portName, boolean enable, in android.hardware.usb.Status retval, long transactionId);
|
||||
oneway void notifyQueryPortStatus(in String portName, in android.hardware.usb.Status retval, long transactionId);
|
||||
oneway void notifyLimitPowerTransferStatus(in String portName, boolean limit, in android.hardware.usb.Status retval, long transactionId);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
|
||||
// two cases:
|
||||
// 1). this is a frozen version file - do not edit this in any case.
|
||||
// 2). this is a 'current' file. If you make a backwards compatible change to
|
||||
// the interface (from the latest frozen version), the build system will
|
||||
// prompt you to update this file with `m <name>-update-api`.
|
||||
//
|
||||
// You must not make a backward incompatible change to any AIDL file built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.usb;
|
||||
@VintfStability
|
||||
enum PortDataRole {
|
||||
NONE = 0,
|
||||
HOST = 1,
|
||||
DEVICE = 2,
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
|
||||
// two cases:
|
||||
// 1). this is a frozen version file - do not edit this in any case.
|
||||
// 2). this is a 'current' file. If you make a backwards compatible change to
|
||||
// the interface (from the latest frozen version), the build system will
|
||||
// prompt you to update this file with `m <name>-update-api`.
|
||||
//
|
||||
// You must not make a backward incompatible change to any AIDL file built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.usb;
|
||||
@VintfStability
|
||||
enum PortMode {
|
||||
NONE = 0,
|
||||
UFP = 1,
|
||||
DFP = 2,
|
||||
DRP = 3,
|
||||
AUDIO_ACCESSORY = 4,
|
||||
DEBUG_ACCESSORY = 5,
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
|
||||
// two cases:
|
||||
// 1). this is a frozen version file - do not edit this in any case.
|
||||
// 2). this is a 'current' file. If you make a backwards compatible change to
|
||||
// the interface (from the latest frozen version), the build system will
|
||||
// prompt you to update this file with `m <name>-update-api`.
|
||||
//
|
||||
// You must not make a backward incompatible change to any AIDL file built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.usb;
|
||||
@VintfStability
|
||||
enum PortPowerRole {
|
||||
NONE = 0,
|
||||
SOURCE = 1,
|
||||
SINK = 2,
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
|
||||
// two cases:
|
||||
// 1). this is a frozen version file - do not edit this in any case.
|
||||
// 2). this is a 'current' file. If you make a backwards compatible change to
|
||||
// the interface (from the latest frozen version), the build system will
|
||||
// prompt you to update this file with `m <name>-update-api`.
|
||||
//
|
||||
// You must not make a backward incompatible change to any AIDL file built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.usb;
|
||||
@VintfStability
|
||||
union PortRole {
|
||||
android.hardware.usb.PortPowerRole powerRole = android.hardware.usb.PortPowerRole.NONE;
|
||||
android.hardware.usb.PortDataRole dataRole;
|
||||
android.hardware.usb.PortMode mode;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
|
||||
// two cases:
|
||||
// 1). this is a frozen version file - do not edit this in any case.
|
||||
// 2). this is a 'current' file. If you make a backwards compatible change to
|
||||
// the interface (from the latest frozen version), the build system will
|
||||
// prompt you to update this file with `m <name>-update-api`.
|
||||
//
|
||||
// You must not make a backward incompatible change to any AIDL file built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.usb;
|
||||
@VintfStability
|
||||
parcelable PortStatus {
|
||||
String portName;
|
||||
android.hardware.usb.PortDataRole currentDataRole = android.hardware.usb.PortDataRole.NONE;
|
||||
android.hardware.usb.PortPowerRole currentPowerRole = android.hardware.usb.PortPowerRole.NONE;
|
||||
android.hardware.usb.PortMode currentMode = android.hardware.usb.PortMode.NONE;
|
||||
boolean canChangeMode;
|
||||
boolean canChangeDataRole;
|
||||
boolean canChangePowerRole;
|
||||
android.hardware.usb.PortMode[] supportedModes;
|
||||
android.hardware.usb.ContaminantProtectionMode[] supportedContaminantProtectionModes;
|
||||
boolean supportsEnableContaminantPresenceProtection;
|
||||
android.hardware.usb.ContaminantProtectionStatus contaminantProtectionStatus = android.hardware.usb.ContaminantProtectionStatus.NONE;
|
||||
boolean supportsEnableContaminantPresenceDetection;
|
||||
android.hardware.usb.ContaminantDetectionStatus contaminantDetectionStatus = android.hardware.usb.ContaminantDetectionStatus.NOT_SUPPORTED;
|
||||
boolean usbDataEnabled;
|
||||
boolean powerTransferLimited;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
|
||||
// two cases:
|
||||
// 1). this is a frozen version file - do not edit this in any case.
|
||||
// 2). this is a 'current' file. If you make a backwards compatible change to
|
||||
// the interface (from the latest frozen version), the build system will
|
||||
// prompt you to update this file with `m <name>-update-api`.
|
||||
//
|
||||
// You must not make a backward incompatible change to any AIDL file built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.usb;
|
||||
@Backing(type="int") @VintfStability
|
||||
enum Status {
|
||||
SUCCESS = 0,
|
||||
ERROR = 1,
|
||||
INVALID_ARGUMENT = 2,
|
||||
UNRECOGNIZED_ROLE = 3,
|
||||
NOT_SUPPORTED = 4,
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 android.hardware.usb;
|
||||
|
||||
@VintfStability
|
||||
enum ContaminantDetectionStatus {
|
||||
/**
|
||||
* Contaminant presence detection is not supported.
|
||||
*/
|
||||
NOT_SUPPORTED = 0,
|
||||
/**
|
||||
* Contaminant presence detection is supported but disabled.
|
||||
*/
|
||||
DISABLED = 1,
|
||||
/**
|
||||
* Contaminant presence detection is enabled and contaminant not detected.
|
||||
*/
|
||||
NOT_DETECTED = 2,
|
||||
/**
|
||||
* Contaminant presence detection is enabled and contaminant detected.
|
||||
*/
|
||||
DETECTED = 3,
|
||||
}
|
||||
43
usb/aidl/android/hardware/usb/ContaminantProtectionMode.aidl
Normal file
43
usb/aidl/android/hardware/usb/ContaminantProtectionMode.aidl
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 android.hardware.usb;
|
||||
|
||||
@VintfStability
|
||||
enum ContaminantProtectionMode {
|
||||
/**
|
||||
* No action performed upon detection of contaminant presence.
|
||||
*/
|
||||
NONE = 0,
|
||||
/**
|
||||
* Upon detection of contaminant presence, Port is forced to sink only
|
||||
* mode where a port shall only detect chargers until contaminant presence
|
||||
* is no longer detected.
|
||||
*/
|
||||
FORCE_SINK = 1,
|
||||
/**
|
||||
* Upon detection of contaminant presence, Port is forced to source only
|
||||
* mode where a port shall only detect usb accessories such as headsets
|
||||
* until contaminant presence is no longer detected.
|
||||
*/
|
||||
FORCE_SOURCE = 2,
|
||||
/**
|
||||
* Upon detection of contaminant presence, port is disabled until contaminant
|
||||
* presence is no longer detected. In the disabled state port will
|
||||
* not respond to connection of chargers or usb accessories.
|
||||
*/
|
||||
FORCE_DISABLE = 3,
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 android.hardware.usb;
|
||||
|
||||
import android.hardware.usb.ContaminantProtectionMode;
|
||||
|
||||
@VintfStability
|
||||
enum ContaminantProtectionStatus {
|
||||
/**
|
||||
* No action performed upon detection of contaminant presence.
|
||||
*/
|
||||
NONE = 0,
|
||||
/**
|
||||
* Upon detection of contaminant presence, Port is forced to sink only
|
||||
* mode where a port shall only detect chargers until contaminant presence
|
||||
* is no longer detected.
|
||||
*/
|
||||
FORCE_SINK = 1,
|
||||
/**
|
||||
* Upon detection of contaminant presence, Port is forced to source only
|
||||
* mode where a port shall only detect usb accessories such as headsets
|
||||
* until contaminant presence is no longer detected.
|
||||
*/
|
||||
FORCE_SOURCE = 2,
|
||||
/**
|
||||
* Upon detection of contaminant presence, port is disabled until contaminant
|
||||
* presence is no longer detected. In the disabled state port will
|
||||
* not respond to connection of chargers or usb accessories.
|
||||
*/
|
||||
FORCE_DISABLE = 3,
|
||||
/**
|
||||
* Client disabled cotaminant protection by calling
|
||||
* enableContaminantPresencePortProtection set to false. Low level drivers should
|
||||
* not autmomously take any corrective action when contaminant presence is detected.
|
||||
*/
|
||||
DISABLED = 4,
|
||||
}
|
||||
98
usb/aidl/android/hardware/usb/IUsb.aidl
Normal file
98
usb/aidl/android/hardware/usb/IUsb.aidl
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 android.hardware.usb;
|
||||
|
||||
import android.hardware.usb.IUsbCallback;
|
||||
import android.hardware.usb.PortRole;
|
||||
|
||||
@VintfStability
|
||||
oneway interface IUsb {
|
||||
/**
|
||||
* When supportsEnableContaminantPresenceDetection is true,
|
||||
* enableContaminantPresenceDetection enables/disables contaminant
|
||||
* presence detection algorithm. Calling enableContaminantPresenceDetection
|
||||
* when supportsEnableContaminantPresenceDetection is false does
|
||||
* not have any effect.
|
||||
* Change in contantaminant presence status should be notified to the
|
||||
* client via notifyPortStatusChange through PortStatus.
|
||||
*
|
||||
* @param portName name of the port.
|
||||
* @param enable true Enable contaminant presence detection algorithm.
|
||||
* false Disable contaminant presence detection algorithm.
|
||||
* @param transactionId ID to be used when invoking the callback.
|
||||
*/
|
||||
void enableContaminantPresenceDetection(in String portName, in boolean enable, long transactionId);
|
||||
|
||||
/**
|
||||
* This function is used to enable/disable USB data controller.
|
||||
*
|
||||
* @param portName Name of the port.
|
||||
* @param enable true Enable USB data signaling.
|
||||
* false Disable USB data signaling.
|
||||
* @param transactionId ID to be used when invoking the callback.
|
||||
*
|
||||
*/
|
||||
void enableUsbData(in String portName, boolean enable, long transactionId);
|
||||
|
||||
/**
|
||||
* This functions is used to request the hal for the current status
|
||||
* status of the Type-C ports. The result of the query would be sent
|
||||
* through the IUsbCallback object's notifyRoleSwitchStatus
|
||||
* to the caller. This api would would let the caller know of the number
|
||||
* of type-c ports that are present and their connection status through the
|
||||
* PortStatus type.
|
||||
* @param transactionId ID to be used when invoking the callback.
|
||||
*/
|
||||
void queryPortStatus(long transactionId);
|
||||
|
||||
/**
|
||||
* This function is used to register a callback function which is
|
||||
* called by the HAL to inform the client of port status updates and
|
||||
* result of the requested operation. Please refer IUsbCallback for
|
||||
* complete description of when each of the IUsbCallback's interface
|
||||
* methods is expected to be called.
|
||||
*
|
||||
* @param callback IUsbCallback object used to convey status to the
|
||||
* userspace.
|
||||
*/
|
||||
void setCallback(in IUsbCallback callback);
|
||||
|
||||
/**
|
||||
* This function is used to change the port role of a specific port.
|
||||
* For example, when DR_SWAP or PR_SWAP is supported.
|
||||
* The status of the role switch will be informed through IUsbCallback
|
||||
* object's notifyPortStatusChange method.
|
||||
*
|
||||
* @param portName name of the port for which the role has to be changed
|
||||
* @param role the new port role.
|
||||
* @param transactionId ID to be used when invoking the callback.
|
||||
*/
|
||||
void switchRole(in String portName, in PortRole role, long transactionId);
|
||||
|
||||
/**
|
||||
* This function is used to limit power transfer in and out of the port.
|
||||
* When limited, the port does not charge from the partner port.
|
||||
* Also, the port limits sourcing power to the partner port when the USB
|
||||
* specification allows it to do so.
|
||||
*
|
||||
* @param portName name of the port for which power transfer is being limited.
|
||||
* @param limit true limit power transfer.
|
||||
* false relax limiting power transfer.
|
||||
* @param transactionId ID to be used when invoking the callback.
|
||||
*/
|
||||
void limitPowerTransfer(in String portName, boolean limit, long transactionId);
|
||||
}
|
||||
98
usb/aidl/android/hardware/usb/IUsbCallback.aidl
Normal file
98
usb/aidl/android/hardware/usb/IUsbCallback.aidl
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 android.hardware.usb;
|
||||
|
||||
import android.hardware.usb.PortRole;
|
||||
import android.hardware.usb.PortStatus;
|
||||
import android.hardware.usb.Status;
|
||||
|
||||
/**
|
||||
* Callback object used for all the IUsb async methods which expects a result.
|
||||
* Caller is expected to register the callback object using setCallback method
|
||||
* to receive updates on the PortStatus.
|
||||
*/
|
||||
@VintfStability
|
||||
oneway interface IUsbCallback {
|
||||
/**
|
||||
* Used to convey the current port status to the caller.
|
||||
* Must be called either when PortState changes due to the port partner or
|
||||
* when caller requested for the PortStatus update through queryPortStatus.
|
||||
*
|
||||
* @param currentPortStatus describes the status of all the USB ports in the
|
||||
* device.
|
||||
* @param retval SUCCESS when the required information was enquired form
|
||||
* kernel and the PortStatus object was built.
|
||||
* ERROR otherwise.
|
||||
*/
|
||||
void notifyPortStatusChange(in PortStatus[] currentPortStatus, in Status retval);
|
||||
|
||||
/**
|
||||
* Used to notify the result of the switchRole call to the caller.
|
||||
*
|
||||
* @param portName name of the port for which the roleswap is requested.
|
||||
* @param newRole the new role requested by the caller.
|
||||
* @param retval SUCCESS if the role switch succeeded. FAILURE otherwise.
|
||||
* @param transactionId transactionId sent during switchRole request.
|
||||
*/
|
||||
void notifyRoleSwitchStatus(in String portName, in PortRole newRole, in Status retval,
|
||||
long transactionId);
|
||||
|
||||
/**
|
||||
* Used to notify the result of notifyEnableUsbDataStatus call to the caller.
|
||||
*
|
||||
* @param portName name of the port for which the enableUsbData is requested.
|
||||
* @param enable true when usb data is enabled.
|
||||
* false when usb data is disabled.
|
||||
* @param retval SUCCESS if current request succeeded. FAILURE otherwise.
|
||||
* @param transactionId transactionId sent during enableUsbData request.
|
||||
*/
|
||||
void notifyEnableUsbDataStatus(in String portName, boolean enable, in Status retval,
|
||||
long transactionId);
|
||||
|
||||
/**
|
||||
* Used to notify the result of enableContaminantPresenceDetection.
|
||||
*
|
||||
* @param portName name of the port for which contaminant detection is enabled/disabled.
|
||||
* @param enable true when contaminant detection is enabled.
|
||||
* false when disabled.
|
||||
* @param retval SUCCESS if the request for enabling/disabling contamiant detection succeeds.
|
||||
* FAILURE otherwise.
|
||||
* @param transactionId transactionId sent during queryPortStatus request
|
||||
*/
|
||||
void notifyContaminantEnabledStatus(in String portName, boolean enable, in Status retval,
|
||||
long transactionId);
|
||||
|
||||
/**
|
||||
* Used to notify the request to query port status.
|
||||
*
|
||||
* @param portName name of the port for which port status is queried.
|
||||
* @param retval SUCCESS if the port query succeeded. FAILURE otherwise.
|
||||
* @param transactionId transactionId sent during queryPortStatus request
|
||||
*/
|
||||
void notifyQueryPortStatus(in String portName, in Status retval, long transactionId);
|
||||
|
||||
/**
|
||||
* Used to notify the result of requesting limitPowerTransfer.
|
||||
*
|
||||
* @param portName name of the port for which power transfer is being limited.
|
||||
* @param limit true limit power transfer.
|
||||
* false relax limiting power transfer.
|
||||
* @param retval SUCCESS if the request to enable/disable limitPowerTransfer succeeds.
|
||||
* FAILURE otherwise.
|
||||
* @param transactionId ID sent during limitPowerTransfer request.
|
||||
*/
|
||||
void notifyLimitPowerTransferStatus(in String portName, boolean limit, in Status retval, long transactionId);
|
||||
}
|
||||
35
usb/aidl/android/hardware/usb/PortDataRole.aidl
Normal file
35
usb/aidl/android/hardware/usb/PortDataRole.aidl
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 android.hardware.usb;
|
||||
|
||||
@VintfStability
|
||||
enum PortDataRole {
|
||||
/**
|
||||
* Indicates that the port does not have a data role.
|
||||
* In case of DRP, the current data role of the port is only resolved
|
||||
* when the type-c handshake happens.
|
||||
*/
|
||||
NONE = 0,
|
||||
/**
|
||||
* Indicates that the port is acting as a host for data.
|
||||
*/
|
||||
HOST = 1,
|
||||
/**
|
||||
* Indicated that the port is acting as a device for data.
|
||||
*/
|
||||
DEVICE = 2,
|
||||
}
|
||||
49
usb/aidl/android/hardware/usb/PortMode.aidl
Normal file
49
usb/aidl/android/hardware/usb/PortMode.aidl
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 android.hardware.usb;
|
||||
|
||||
import android.hardware.usb.PortMode;
|
||||
|
||||
@VintfStability
|
||||
enum PortMode {
|
||||
/**
|
||||
* Indicates that the port does not have a mode.
|
||||
* In case of DRP, the current mode of the port is only resolved
|
||||
* when the type-c handshake happens.
|
||||
*/
|
||||
NONE = 0,
|
||||
/**
|
||||
* Indicates that port can only act as device for data and sink for power.
|
||||
*/
|
||||
UFP = 1,
|
||||
/**
|
||||
* Indicates the port can only act as host for data and source for power.
|
||||
*/
|
||||
DFP = 2,
|
||||
/**
|
||||
* Indicates can either act as UFP or DFP at a given point of time.
|
||||
*/
|
||||
DRP = 3,
|
||||
/*
|
||||
* Indicates that the port supports Audio Accessory mode.
|
||||
*/
|
||||
AUDIO_ACCESSORY = 4,
|
||||
/*
|
||||
* Indicates that the port supports Debug Accessory mode.
|
||||
*/
|
||||
DEBUG_ACCESSORY = 5,
|
||||
}
|
||||
35
usb/aidl/android/hardware/usb/PortPowerRole.aidl
Normal file
35
usb/aidl/android/hardware/usb/PortPowerRole.aidl
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 android.hardware.usb;
|
||||
|
||||
@VintfStability
|
||||
enum PortPowerRole {
|
||||
/**
|
||||
* Indicates that the port does not have a power role.
|
||||
* In case of DRP, the current power role of the port is only resolved
|
||||
* when the type-c handshake happens.
|
||||
*/
|
||||
NONE = 0,
|
||||
/**
|
||||
* Indicates that the port is supplying power to the other port.
|
||||
*/
|
||||
SOURCE = 1,
|
||||
/**
|
||||
* Indicates that the port is sinking power from the other port.
|
||||
*/
|
||||
SINK = 2,
|
||||
}
|
||||
31
usb/aidl/android/hardware/usb/PortRole.aidl
Normal file
31
usb/aidl/android/hardware/usb/PortRole.aidl
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 android.hardware.usb;
|
||||
|
||||
import android.hardware.usb.PortDataRole;
|
||||
import android.hardware.usb.PortMode;
|
||||
import android.hardware.usb.PortPowerRole;
|
||||
|
||||
/**
|
||||
* Used as a container to send port role information.
|
||||
*/
|
||||
@VintfStability
|
||||
union PortRole {
|
||||
PortPowerRole powerRole = PortPowerRole.NONE;
|
||||
PortDataRole dataRole;
|
||||
PortMode mode;
|
||||
}
|
||||
111
usb/aidl/android/hardware/usb/PortStatus.aidl
Normal file
111
usb/aidl/android/hardware/usb/PortStatus.aidl
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 android.hardware.usb;
|
||||
|
||||
import android.hardware.usb.ContaminantDetectionStatus;
|
||||
import android.hardware.usb.ContaminantProtectionMode;
|
||||
import android.hardware.usb.ContaminantProtectionStatus;
|
||||
import android.hardware.usb.PortDataRole;
|
||||
import android.hardware.usb.PortMode;
|
||||
import android.hardware.usb.PortPowerRole;
|
||||
|
||||
@VintfStability
|
||||
parcelable PortStatus {
|
||||
/**
|
||||
* Name of the port.
|
||||
* Used as the port's id by the caller.
|
||||
*/
|
||||
String portName;
|
||||
/**
|
||||
* Data role of the port.
|
||||
*/
|
||||
PortDataRole currentDataRole = PortDataRole.NONE;
|
||||
/**
|
||||
* Power Role of thte port.
|
||||
*/
|
||||
PortPowerRole currentPowerRole = PortPowerRole.NONE;
|
||||
/**
|
||||
* Mode in which the port is connected.
|
||||
* Can be UFP or DFP or AUDIO_ACCESSORY or
|
||||
* DEBUG_ACCESSORY.
|
||||
*/
|
||||
PortMode currentMode = PortMode.NONE;
|
||||
/**
|
||||
* True indicates that the port's mode can
|
||||
* be changed. False otherwise.
|
||||
*/
|
||||
boolean canChangeMode;
|
||||
/**
|
||||
* True indicates that the port's data role
|
||||
* can be changed. False otherwise.
|
||||
* For example, true if Type-C PD PD_SWAP
|
||||
* is supported.
|
||||
*/
|
||||
boolean canChangeDataRole;
|
||||
/**
|
||||
* True indicates that the port's power role
|
||||
* can be changed. False otherwise.
|
||||
* For example, true if Type-C PD PR_SWAP
|
||||
* is supported.
|
||||
*/
|
||||
boolean canChangePowerRole;
|
||||
/**
|
||||
* Identifies the type of the local port.
|
||||
*
|
||||
* UFP - Indicates that port can only act as device for
|
||||
* data and sink for power.
|
||||
* DFP - Indicates the port can only act as host for data
|
||||
* and source for power.
|
||||
* DRP - Indicates can either act as UFP or DFP at a
|
||||
* given point of time.
|
||||
* AUDIO_ACCESSORY - Indicates that the port supports
|
||||
* Audio Accessory mode.
|
||||
* DEBUG_ACCESSORY - Indicates that the port supports
|
||||
* Debug Accessory mode.
|
||||
*/
|
||||
PortMode[] supportedModes;
|
||||
/**
|
||||
* Contaminant presence protection modes supported by the port.
|
||||
*/
|
||||
ContaminantProtectionMode[] supportedContaminantProtectionModes;
|
||||
/**
|
||||
* Client can enable/disable contaminant presence protection through
|
||||
* enableContaminantPresenceProtection when true.
|
||||
*/
|
||||
boolean supportsEnableContaminantPresenceProtection;
|
||||
/**
|
||||
* Contaminant presence protection modes currently active for the port.
|
||||
*/
|
||||
ContaminantProtectionStatus contaminantProtectionStatus = ContaminantProtectionStatus.NONE;
|
||||
/**
|
||||
* Client can enable/disable contaminant presence detection through
|
||||
* enableContaminantPresenceDetection when true.
|
||||
*/
|
||||
boolean supportsEnableContaminantPresenceDetection;
|
||||
/**
|
||||
* Current status of contaminant detection algorithm.
|
||||
*/
|
||||
ContaminantDetectionStatus contaminantDetectionStatus = ContaminantDetectionStatus.NOT_SUPPORTED;
|
||||
/**
|
||||
* UsbData status of the port.
|
||||
*/
|
||||
boolean usbDataEnabled;
|
||||
/**
|
||||
* Denoted whether power transfer is limited in the port.
|
||||
*/
|
||||
boolean powerTransferLimited;
|
||||
}
|
||||
39
usb/aidl/android/hardware/usb/Status.aidl
Normal file
39
usb/aidl/android/hardware/usb/Status.aidl
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 android.hardware.usb;
|
||||
|
||||
@VintfStability
|
||||
@Backing(type="int")
|
||||
enum Status {
|
||||
SUCCESS = 0,
|
||||
/**
|
||||
* error value when the HAL operation fails for reasons not listed here.
|
||||
*/
|
||||
ERROR = 1,
|
||||
/**
|
||||
* error value returned when input argument is invalid.
|
||||
*/
|
||||
INVALID_ARGUMENT = 2,
|
||||
/**
|
||||
* error value returned when role string is unrecognized.
|
||||
*/
|
||||
UNRECOGNIZED_ROLE = 3,
|
||||
/**
|
||||
* Error value returned when the operation is not supported.
|
||||
*/
|
||||
NOT_SUPPORTED = 4,
|
||||
}
|
||||
11
usb/aidl/conversion.log
Normal file
11
usb/aidl/conversion.log
Normal file
@@ -0,0 +1,11 @@
|
||||
Notes relating to hidl2aidl conversion of android.hardware.usb@1.3 to android.hardware.usb (if any) follow:
|
||||
Unhandled comments from android.hardware.usb@1.1::types follow. Consider using hidl-lint to locate these and fixup as many as possible.
|
||||
// NOTE: suffix '_1_1' is for legacy ABI compatibility. It cannot be
|
||||
// changed to 'PortMode' which the convention dictates.
|
||||
// NOTE: suffix '_1_1' is for legacy ABI compatibility. It cannot be
|
||||
// changed to 'PortStatus' which the convention dictates.
|
||||
|
||||
An unknown named type was found in translation: android.hardware.usb@1.0::PortStatus
|
||||
An unknown named type was found in translation: android.hardware.usb@1.0::PortStatus
|
||||
An unknown named type was found in translation: android.hardware.usb@1.0::PortStatus
|
||||
END OF LOG
|
||||
35
usb/aidl/default/Android.bp
Normal file
35
usb/aidl/default/Android.bp
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// Copyright (C) 2021 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.
|
||||
//
|
||||
|
||||
cc_binary {
|
||||
name: "android.hardware.usb-service.example",
|
||||
relative_install_path: "hw",
|
||||
init_rc: ["android.hardware.usb-service.example.rc"],
|
||||
vintf_fragments: ["android.hardware.usb-service.example.xml"],
|
||||
vendor: true,
|
||||
srcs: [
|
||||
"service.cpp",
|
||||
"Usb.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"android.hardware.usb-V1-ndk",
|
||||
"libbase",
|
||||
"libbinder_ndk",
|
||||
"libcutils",
|
||||
"liblog",
|
||||
"libutils",
|
||||
],
|
||||
}
|
||||
711
usb/aidl/default/Usb.cpp
Normal file
711
usb/aidl/default/Usb.cpp
Normal file
@@ -0,0 +1,711 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "android.hardware.usb.aidl-service"
|
||||
|
||||
#include <aidl/android/hardware/usb/PortRole.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <android-base/strings.h>
|
||||
#include <assert.h>
|
||||
#include <dirent.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <chrono>
|
||||
#include <regex>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <cutils/uevent.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/StrongPointer.h>
|
||||
|
||||
#include "Usb.h"
|
||||
|
||||
using android::base::GetProperty;
|
||||
using android::base::Trim;
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace usb {
|
||||
|
||||
constexpr char kTypecPath[] = "/sys/class/typec/";
|
||||
constexpr char kDataRoleNode[] = "/data_role";
|
||||
constexpr char kPowerRoleNode[] = "/power_role";
|
||||
|
||||
// Set by the signal handler to destroy the thread
|
||||
volatile bool destroyThread;
|
||||
|
||||
void queryVersionHelper(android::hardware::usb::Usb *usb,
|
||||
std::vector<PortStatus> *currentPortStatus);
|
||||
|
||||
ScopedAStatus Usb::enableUsbData(const string& in_portName, bool in_enable, int64_t in_transactionId) {
|
||||
std::vector<PortStatus> currentPortStatus;
|
||||
|
||||
pthread_mutex_lock(&mLock);
|
||||
if (mCallback != NULL) {
|
||||
ScopedAStatus ret = mCallback->notifyEnableUsbDataStatus(
|
||||
in_portName, true, in_enable ? Status::SUCCESS : Status::ERROR, in_transactionId);
|
||||
if (!ret.isOk())
|
||||
ALOGE("notifyEnableUsbDataStatus error %s", ret.getDescription().c_str());
|
||||
} else {
|
||||
ALOGE("Not notifying the userspace. Callback is not set");
|
||||
}
|
||||
pthread_mutex_unlock(&mLock);
|
||||
queryVersionHelper(this, ¤tPortStatus);
|
||||
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
Status queryMoistureDetectionStatus(std::vector<PortStatus> *currentPortStatus) {
|
||||
string enabled, status, path, DetectedPath;
|
||||
|
||||
for (int i = 0; i < currentPortStatus->size(); i++) {
|
||||
(*currentPortStatus)[i].supportedContaminantProtectionModes
|
||||
.push_back(ContaminantProtectionMode::NONE);
|
||||
(*currentPortStatus)[i].contaminantProtectionStatus
|
||||
= ContaminantProtectionStatus::NONE;
|
||||
(*currentPortStatus)[i].contaminantDetectionStatus
|
||||
= ContaminantDetectionStatus::NOT_SUPPORTED;
|
||||
(*currentPortStatus)[i].supportsEnableContaminantPresenceDetection = false;
|
||||
(*currentPortStatus)[i].supportsEnableContaminantPresenceProtection = false;
|
||||
}
|
||||
|
||||
return Status::SUCCESS;
|
||||
}
|
||||
|
||||
string appendRoleNodeHelper(const string &portName, PortRole::Tag tag) {
|
||||
string node(kTypecPath + portName);
|
||||
|
||||
switch (tag) {
|
||||
case PortRole::dataRole:
|
||||
return node + kDataRoleNode;
|
||||
case PortRole::powerRole:
|
||||
return node + kPowerRoleNode;
|
||||
case PortRole::mode:
|
||||
return node + "/port_type";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
string convertRoletoString(PortRole role) {
|
||||
if (role.getTag() == PortRole::powerRole) {
|
||||
if (role.get<PortRole::powerRole>() == PortPowerRole::SOURCE)
|
||||
return "source";
|
||||
else if (role.get<PortRole::powerRole>() == PortPowerRole::SINK)
|
||||
return "sink";
|
||||
} else if (role.getTag() == PortRole::dataRole) {
|
||||
if (role.get<PortRole::dataRole>() == PortDataRole::HOST)
|
||||
return "host";
|
||||
if (role.get<PortRole::dataRole>() == PortDataRole::DEVICE)
|
||||
return "device";
|
||||
} else if (role.getTag() == PortRole::mode) {
|
||||
if (role.get<PortRole::mode>() == PortMode::UFP)
|
||||
return "sink";
|
||||
if (role.get<PortRole::mode>() == PortMode::DFP)
|
||||
return "source";
|
||||
}
|
||||
return "none";
|
||||
}
|
||||
|
||||
void extractRole(string *roleName) {
|
||||
std::size_t first, last;
|
||||
|
||||
first = roleName->find("[");
|
||||
last = roleName->find("]");
|
||||
|
||||
if (first != string::npos && last != string::npos) {
|
||||
*roleName = roleName->substr(first + 1, last - first - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void switchToDrp(const string &portName) {
|
||||
string filename = appendRoleNodeHelper(string(portName.c_str()), PortRole::mode);
|
||||
FILE *fp;
|
||||
|
||||
if (filename != "") {
|
||||
fp = fopen(filename.c_str(), "w");
|
||||
if (fp != NULL) {
|
||||
int ret = fputs("dual", fp);
|
||||
fclose(fp);
|
||||
if (ret == EOF)
|
||||
ALOGE("Fatal: Error while switching back to drp");
|
||||
} else {
|
||||
ALOGE("Fatal: Cannot open file to switch back to drp");
|
||||
}
|
||||
} else {
|
||||
ALOGE("Fatal: invalid node type");
|
||||
}
|
||||
}
|
||||
|
||||
bool switchMode(const string &portName, const PortRole &in_role, struct Usb *usb) {
|
||||
string filename = appendRoleNodeHelper(string(portName.c_str()), in_role.getTag());
|
||||
string written;
|
||||
FILE *fp;
|
||||
bool roleSwitch = false;
|
||||
|
||||
if (filename == "") {
|
||||
ALOGE("Fatal: invalid node type");
|
||||
return false;
|
||||
}
|
||||
|
||||
fp = fopen(filename.c_str(), "w");
|
||||
if (fp != NULL) {
|
||||
// Hold the lock here to prevent loosing connected signals
|
||||
// as once the file is written the partner added signal
|
||||
// can arrive anytime.
|
||||
pthread_mutex_lock(&usb->mPartnerLock);
|
||||
usb->mPartnerUp = false;
|
||||
int ret = fputs(convertRoletoString(in_role).c_str(), fp);
|
||||
fclose(fp);
|
||||
|
||||
if (ret != EOF) {
|
||||
struct timespec to;
|
||||
struct timespec now;
|
||||
|
||||
wait_again:
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
to.tv_sec = now.tv_sec + PORT_TYPE_TIMEOUT;
|
||||
to.tv_nsec = now.tv_nsec;
|
||||
|
||||
int err = pthread_cond_timedwait(&usb->mPartnerCV, &usb->mPartnerLock, &to);
|
||||
// There are no uevent signals which implies role swap timed out.
|
||||
if (err == ETIMEDOUT) {
|
||||
ALOGI("uevents wait timedout");
|
||||
// Validity check.
|
||||
} else if (!usb->mPartnerUp) {
|
||||
goto wait_again;
|
||||
// Role switch succeeded since usb->mPartnerUp is true.
|
||||
} else {
|
||||
roleSwitch = true;
|
||||
}
|
||||
} else {
|
||||
ALOGI("Role switch failed while wrting to file");
|
||||
}
|
||||
pthread_mutex_unlock(&usb->mPartnerLock);
|
||||
}
|
||||
|
||||
if (!roleSwitch)
|
||||
switchToDrp(string(portName.c_str()));
|
||||
|
||||
return roleSwitch;
|
||||
}
|
||||
|
||||
Usb::Usb()
|
||||
: mLock(PTHREAD_MUTEX_INITIALIZER),
|
||||
mRoleSwitchLock(PTHREAD_MUTEX_INITIALIZER),
|
||||
mPartnerLock(PTHREAD_MUTEX_INITIALIZER),
|
||||
mPartnerUp(false)
|
||||
{
|
||||
pthread_condattr_t attr;
|
||||
if (pthread_condattr_init(&attr)) {
|
||||
ALOGE("pthread_condattr_init failed: %s", strerror(errno));
|
||||
abort();
|
||||
}
|
||||
if (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)) {
|
||||
ALOGE("pthread_condattr_setclock failed: %s", strerror(errno));
|
||||
abort();
|
||||
}
|
||||
if (pthread_cond_init(&mPartnerCV, &attr)) {
|
||||
ALOGE("pthread_cond_init failed: %s", strerror(errno));
|
||||
abort();
|
||||
}
|
||||
if (pthread_condattr_destroy(&attr)) {
|
||||
ALOGE("pthread_condattr_destroy failed: %s", strerror(errno));
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
ScopedAStatus Usb::switchRole(const string& in_portName,
|
||||
const PortRole& in_role, int64_t in_transactionId) {
|
||||
string filename = appendRoleNodeHelper(string(in_portName.c_str()), in_role.getTag());
|
||||
string written;
|
||||
FILE *fp;
|
||||
bool roleSwitch = false;
|
||||
|
||||
if (filename == "") {
|
||||
ALOGE("Fatal: invalid node type");
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&mRoleSwitchLock);
|
||||
|
||||
ALOGI("filename write: %s role:%s", filename.c_str(), convertRoletoString(in_role).c_str());
|
||||
|
||||
if (in_role.getTag() == PortRole::mode) {
|
||||
roleSwitch = switchMode(in_portName, in_role, this);
|
||||
} else {
|
||||
fp = fopen(filename.c_str(), "w");
|
||||
if (fp != NULL) {
|
||||
int ret = fputs(convertRoletoString(in_role).c_str(), fp);
|
||||
fclose(fp);
|
||||
if ((ret != EOF) && ReadFileToString(filename, &written)) {
|
||||
written = Trim(written);
|
||||
extractRole(&written);
|
||||
ALOGI("written: %s", written.c_str());
|
||||
if (written == convertRoletoString(in_role)) {
|
||||
roleSwitch = true;
|
||||
} else {
|
||||
ALOGE("Role switch failed");
|
||||
}
|
||||
} else {
|
||||
ALOGE("failed to update the new role");
|
||||
}
|
||||
} else {
|
||||
ALOGE("fopen failed");
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&mLock);
|
||||
if (mCallback != NULL) {
|
||||
ScopedAStatus ret = mCallback->notifyRoleSwitchStatus(
|
||||
in_portName, in_role, roleSwitch ? Status::SUCCESS : Status::ERROR, in_transactionId);
|
||||
if (!ret.isOk())
|
||||
ALOGE("RoleSwitchStatus error %s", ret.getDescription().c_str());
|
||||
} else {
|
||||
ALOGE("Not notifying the userspace. Callback is not set");
|
||||
}
|
||||
pthread_mutex_unlock(&mLock);
|
||||
pthread_mutex_unlock(&mRoleSwitchLock);
|
||||
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ScopedAStatus Usb::limitPowerTransfer(const string& in_portName, bool /*in_limit*/,
|
||||
int64_t in_transactionId) {
|
||||
std::vector<PortStatus> currentPortStatus;
|
||||
|
||||
pthread_mutex_lock(&mLock);
|
||||
if (mCallback != NULL && in_transactionId >= 0) {
|
||||
ScopedAStatus ret = mCallback->notifyLimitPowerTransferStatus(
|
||||
in_portName, false, Status::NOT_SUPPORTED, in_transactionId);
|
||||
if (!ret.isOk())
|
||||
ALOGE("limitPowerTransfer error %s", ret.getDescription().c_str());
|
||||
} else {
|
||||
ALOGE("Not notifying the userspace. Callback is not set");
|
||||
}
|
||||
pthread_mutex_unlock(&mLock);
|
||||
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
Status getAccessoryConnected(const string &portName, string *accessory) {
|
||||
string filename = kTypecPath + portName + "-partner/accessory_mode";
|
||||
|
||||
if (!ReadFileToString(filename, accessory)) {
|
||||
ALOGE("getAccessoryConnected: Failed to open filesystem node: %s", filename.c_str());
|
||||
return Status::ERROR;
|
||||
}
|
||||
*accessory = Trim(*accessory);
|
||||
|
||||
return Status::SUCCESS;
|
||||
}
|
||||
|
||||
Status getCurrentRoleHelper(const string &portName, bool connected, PortRole *currentRole) {
|
||||
string filename;
|
||||
string roleName;
|
||||
string accessory;
|
||||
|
||||
// Mode
|
||||
|
||||
if (currentRole->getTag() == PortRole::powerRole) {
|
||||
filename = kTypecPath + portName + kPowerRoleNode;
|
||||
currentRole->set<PortRole::powerRole>(PortPowerRole::NONE);
|
||||
} else if (currentRole->getTag() == PortRole::dataRole) {
|
||||
filename = kTypecPath + portName + kDataRoleNode;
|
||||
currentRole->set<PortRole::dataRole>(PortDataRole::NONE);
|
||||
} else if (currentRole->getTag() == PortRole::mode) {
|
||||
filename = kTypecPath + portName + kDataRoleNode;
|
||||
currentRole->set<PortRole::mode>(PortMode::NONE);
|
||||
} else {
|
||||
return Status::ERROR;
|
||||
}
|
||||
|
||||
if (!connected)
|
||||
return Status::SUCCESS;
|
||||
|
||||
if (currentRole->getTag() == PortRole::mode) {
|
||||
if (getAccessoryConnected(portName, &accessory) != Status::SUCCESS) {
|
||||
return Status::ERROR;
|
||||
}
|
||||
if (accessory == "analog_audio") {
|
||||
currentRole->set<PortRole::mode>(PortMode::AUDIO_ACCESSORY);
|
||||
return Status::SUCCESS;
|
||||
} else if (accessory == "debug") {
|
||||
currentRole->set<PortRole::mode>(PortMode::DEBUG_ACCESSORY);
|
||||
return Status::SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ReadFileToString(filename, &roleName)) {
|
||||
ALOGE("getCurrentRole: Failed to open filesystem node: %s", filename.c_str());
|
||||
return Status::ERROR;
|
||||
}
|
||||
|
||||
roleName = Trim(roleName);
|
||||
extractRole(&roleName);
|
||||
|
||||
if (roleName == "source") {
|
||||
currentRole->set<PortRole::powerRole>(PortPowerRole::SOURCE);
|
||||
} else if (roleName == "sink") {
|
||||
currentRole->set<PortRole::powerRole>(PortPowerRole::SINK);
|
||||
} else if (roleName == "host") {
|
||||
if (currentRole->getTag() == PortRole::dataRole)
|
||||
currentRole->set<PortRole::dataRole>(PortDataRole::HOST);
|
||||
else
|
||||
currentRole->set<PortRole::mode>(PortMode::DFP);
|
||||
} else if (roleName == "device") {
|
||||
if (currentRole->getTag() == PortRole::dataRole)
|
||||
currentRole->set<PortRole::dataRole>(PortDataRole::DEVICE);
|
||||
else
|
||||
currentRole->set<PortRole::mode>(PortMode::UFP);
|
||||
} else if (roleName != "none") {
|
||||
/* case for none has already been addressed.
|
||||
* so we check if the role isn't none.
|
||||
*/
|
||||
return Status::UNRECOGNIZED_ROLE;
|
||||
}
|
||||
|
||||
return Status::SUCCESS;
|
||||
}
|
||||
|
||||
Status getTypeCPortNamesHelper(std::unordered_map<string, bool> *names) {
|
||||
DIR *dp;
|
||||
|
||||
dp = opendir(kTypecPath);
|
||||
if (dp != NULL) {
|
||||
struct dirent *ep;
|
||||
|
||||
while ((ep = readdir(dp))) {
|
||||
if (ep->d_type == DT_LNK) {
|
||||
if (string::npos == string(ep->d_name).find("-partner")) {
|
||||
std::unordered_map<string, bool>::const_iterator portName =
|
||||
names->find(ep->d_name);
|
||||
if (portName == names->end()) {
|
||||
names->insert({ep->d_name, false});
|
||||
}
|
||||
} else {
|
||||
(*names)[std::strtok(ep->d_name, "-")] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dp);
|
||||
return Status::SUCCESS;
|
||||
}
|
||||
|
||||
ALOGE("Failed to open /sys/class/typec");
|
||||
return Status::ERROR;
|
||||
}
|
||||
|
||||
bool canSwitchRoleHelper(const string &portName) {
|
||||
string filename = kTypecPath + portName + "-partner/supports_usb_power_delivery";
|
||||
string supportsPD;
|
||||
|
||||
if (ReadFileToString(filename, &supportsPD)) {
|
||||
supportsPD = Trim(supportsPD);
|
||||
if (supportsPD == "yes") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Status getPortStatusHelper(std::vector<PortStatus> *currentPortStatus) {
|
||||
std::unordered_map<string, bool> names;
|
||||
Status result = getTypeCPortNamesHelper(&names);
|
||||
int i = -1;
|
||||
|
||||
if (result == Status::SUCCESS) {
|
||||
currentPortStatus->resize(names.size());
|
||||
for (std::pair<string, bool> port : names) {
|
||||
i++;
|
||||
ALOGI("%s", port.first.c_str());
|
||||
(*currentPortStatus)[i].portName = port.first;
|
||||
|
||||
PortRole currentRole;
|
||||
currentRole.set<PortRole::powerRole>(PortPowerRole::NONE);
|
||||
if (getCurrentRoleHelper(port.first, port.second, ¤tRole) == Status::SUCCESS){
|
||||
(*currentPortStatus)[i].currentPowerRole = currentRole.get<PortRole::powerRole>();
|
||||
} else {
|
||||
ALOGE("Error while retrieving portNames");
|
||||
goto done;
|
||||
}
|
||||
|
||||
currentRole.set<PortRole::dataRole>(PortDataRole::NONE);
|
||||
if (getCurrentRoleHelper(port.first, port.second, ¤tRole) == Status::SUCCESS) {
|
||||
(*currentPortStatus)[i].currentDataRole = currentRole.get<PortRole::dataRole>();
|
||||
} else {
|
||||
ALOGE("Error while retrieving current port role");
|
||||
goto done;
|
||||
}
|
||||
|
||||
currentRole.set<PortRole::mode>(PortMode::NONE);
|
||||
if (getCurrentRoleHelper(port.first, port.second, ¤tRole) == Status::SUCCESS) {
|
||||
(*currentPortStatus)[i].currentMode = currentRole.get<PortRole::mode>();
|
||||
} else {
|
||||
ALOGE("Error while retrieving current data role");
|
||||
goto done;
|
||||
}
|
||||
|
||||
(*currentPortStatus)[i].canChangeMode = true;
|
||||
(*currentPortStatus)[i].canChangeDataRole =
|
||||
port.second ? canSwitchRoleHelper(port.first) : false;
|
||||
(*currentPortStatus)[i].canChangePowerRole =
|
||||
port.second ? canSwitchRoleHelper(port.first) : false;
|
||||
|
||||
(*currentPortStatus)[i].supportedModes.push_back(PortMode::DRP);
|
||||
(*currentPortStatus)[i].usbDataEnabled = true;
|
||||
|
||||
ALOGI("%d:%s connected:%d canChangeMode:%d canChagedata:%d canChangePower:%d "
|
||||
"usbDataEnabled:%d",
|
||||
i, port.first.c_str(), port.second,
|
||||
(*currentPortStatus)[i].canChangeMode,
|
||||
(*currentPortStatus)[i].canChangeDataRole,
|
||||
(*currentPortStatus)[i].canChangePowerRole, 0);
|
||||
}
|
||||
|
||||
return Status::SUCCESS;
|
||||
}
|
||||
done:
|
||||
return Status::ERROR;
|
||||
}
|
||||
|
||||
void queryVersionHelper(android::hardware::usb::Usb *usb,
|
||||
std::vector<PortStatus> *currentPortStatus) {
|
||||
Status status;
|
||||
pthread_mutex_lock(&usb->mLock);
|
||||
status = getPortStatusHelper(currentPortStatus);
|
||||
queryMoistureDetectionStatus(currentPortStatus);
|
||||
if (usb->mCallback != NULL) {
|
||||
ScopedAStatus ret = usb->mCallback->notifyPortStatusChange(*currentPortStatus,
|
||||
status);
|
||||
if (!ret.isOk())
|
||||
ALOGE("queryPortStatus error %s", ret.getDescription().c_str());
|
||||
} else {
|
||||
ALOGI("Notifying userspace skipped. Callback is NULL");
|
||||
}
|
||||
pthread_mutex_unlock(&usb->mLock);
|
||||
}
|
||||
|
||||
ScopedAStatus Usb::queryPortStatus(int64_t in_transactionId) {
|
||||
std::vector<PortStatus> currentPortStatus;
|
||||
|
||||
queryVersionHelper(this, ¤tPortStatus);
|
||||
pthread_mutex_lock(&mLock);
|
||||
if (mCallback != NULL) {
|
||||
ScopedAStatus ret = mCallback->notifyQueryPortStatus(
|
||||
"all", Status::SUCCESS, in_transactionId);
|
||||
if (!ret.isOk())
|
||||
ALOGE("notifyQueryPortStatus error %s", ret.getDescription().c_str());
|
||||
} else {
|
||||
ALOGE("Not notifying the userspace. Callback is not set");
|
||||
}
|
||||
pthread_mutex_unlock(&mLock);
|
||||
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ScopedAStatus Usb::enableContaminantPresenceDetection(const string& in_portName,
|
||||
bool /*in_enable*/, int64_t in_transactionId) {
|
||||
std::vector<PortStatus> currentPortStatus;
|
||||
|
||||
pthread_mutex_lock(&mLock);
|
||||
if (mCallback != NULL) {
|
||||
ScopedAStatus ret = mCallback->notifyContaminantEnabledStatus(
|
||||
in_portName, false, Status::ERROR, in_transactionId);
|
||||
if (!ret.isOk())
|
||||
ALOGE("enableContaminantPresenceDetection error %s", ret.getDescription().c_str());
|
||||
} else {
|
||||
ALOGE("Not notifying the userspace. Callback is not set");
|
||||
}
|
||||
pthread_mutex_unlock(&mLock);
|
||||
|
||||
queryVersionHelper(this, ¤tPortStatus);
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
|
||||
struct data {
|
||||
int uevent_fd;
|
||||
::aidl::android::hardware::usb::Usb *usb;
|
||||
};
|
||||
|
||||
static void uevent_event(uint32_t /*epevents*/, struct data *payload) {
|
||||
char msg[UEVENT_MSG_LEN + 2];
|
||||
char *cp;
|
||||
int n;
|
||||
|
||||
n = uevent_kernel_multicast_recv(payload->uevent_fd, msg, UEVENT_MSG_LEN);
|
||||
if (n <= 0)
|
||||
return;
|
||||
if (n >= UEVENT_MSG_LEN) /* overflow -- discard */
|
||||
return;
|
||||
|
||||
msg[n] = '\0';
|
||||
msg[n + 1] = '\0';
|
||||
cp = msg;
|
||||
|
||||
while (*cp) {
|
||||
if (std::regex_match(cp, std::regex("(add)(.*)(-partner)"))) {
|
||||
ALOGI("partner added");
|
||||
pthread_mutex_lock(&payload->usb->mPartnerLock);
|
||||
payload->usb->mPartnerUp = true;
|
||||
pthread_cond_signal(&payload->usb->mPartnerCV);
|
||||
pthread_mutex_unlock(&payload->usb->mPartnerLock);
|
||||
} else if (!strncmp(cp, "DEVTYPE=typec_", strlen("DEVTYPE=typec_"))) {
|
||||
std::vector<PortStatus> currentPortStatus;
|
||||
queryVersionHelper(payload->usb, ¤tPortStatus);
|
||||
|
||||
// Role switch is not in progress and port is in disconnected state
|
||||
if (!pthread_mutex_trylock(&payload->usb->mRoleSwitchLock)) {
|
||||
for (unsigned long i = 0; i < currentPortStatus.size(); i++) {
|
||||
DIR *dp =
|
||||
opendir(string(kTypecPath +
|
||||
string(currentPortStatus[i].portName.c_str()) +
|
||||
"-partner").c_str());
|
||||
if (dp == NULL) {
|
||||
switchToDrp(currentPortStatus[i].portName);
|
||||
} else {
|
||||
closedir(dp);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&payload->usb->mRoleSwitchLock);
|
||||
}
|
||||
break;
|
||||
} /* advance to after the next \0 */
|
||||
while (*cp++) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void *work(void *param) {
|
||||
int epoll_fd, uevent_fd;
|
||||
struct epoll_event ev;
|
||||
int nevents = 0;
|
||||
struct data payload;
|
||||
|
||||
uevent_fd = uevent_open_socket(UEVENT_MAX_EVENTS * UEVENT_MSG_LEN, true);
|
||||
|
||||
if (uevent_fd < 0) {
|
||||
ALOGE("uevent_init: uevent_open_socket failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
payload.uevent_fd = uevent_fd;
|
||||
payload.usb = (::aidl::android::hardware::usb::Usb *)param;
|
||||
|
||||
fcntl(uevent_fd, F_SETFL, O_NONBLOCK);
|
||||
|
||||
ev.events = EPOLLIN;
|
||||
ev.data.ptr = (void *)uevent_event;
|
||||
|
||||
epoll_fd = epoll_create(UEVENT_MAX_EVENTS);
|
||||
if (epoll_fd == -1) {
|
||||
ALOGE("epoll_create failed; errno=%d", errno);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, uevent_fd, &ev) == -1) {
|
||||
ALOGE("epoll_ctl failed; errno=%d", errno);
|
||||
goto error;
|
||||
}
|
||||
|
||||
while (!destroyThread) {
|
||||
struct epoll_event events[UEVENT_MAX_EVENTS];
|
||||
|
||||
nevents = epoll_wait(epoll_fd, events, UEVENT_MAX_EVENTS, -1);
|
||||
if (nevents == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
ALOGE("usb epoll_wait failed; errno=%d", errno);
|
||||
break;
|
||||
}
|
||||
|
||||
for (int n = 0; n < nevents; ++n) {
|
||||
if (events[n].data.ptr)
|
||||
(*(void (*)(int, struct data *payload))events[n].data.ptr)(events[n].events,
|
||||
&payload);
|
||||
}
|
||||
}
|
||||
|
||||
ALOGI("exiting worker thread");
|
||||
error:
|
||||
close(uevent_fd);
|
||||
|
||||
if (epoll_fd >= 0)
|
||||
close(epoll_fd);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void sighandler(int sig) {
|
||||
if (sig == SIGUSR1) {
|
||||
destroyThread = true;
|
||||
ALOGI("destroy set");
|
||||
return;
|
||||
}
|
||||
signal(SIGUSR1, sighandler);
|
||||
}
|
||||
|
||||
ScopedAStatus Usb::setCallback(
|
||||
const shared_ptr<IUsbCallback>& in_callback) {
|
||||
|
||||
pthread_mutex_lock(&mLock);
|
||||
if ((mCallback == NULL && in_callback == NULL) ||
|
||||
(mCallback != NULL && in_callback != NULL)) {
|
||||
mCallback = in_callback;
|
||||
pthread_mutex_unlock(&mLock);
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
mCallback = in_callback;
|
||||
ALOGI("registering callback");
|
||||
|
||||
if (mCallback == NULL) {
|
||||
if (!pthread_kill(mPoll, SIGUSR1)) {
|
||||
pthread_join(mPoll, NULL);
|
||||
ALOGI("pthread destroyed");
|
||||
}
|
||||
pthread_mutex_unlock(&mLock);
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
destroyThread = false;
|
||||
signal(SIGUSR1, sighandler);
|
||||
|
||||
/*
|
||||
* Create a background thread if the old callback value is NULL
|
||||
* and being updated with a new value.
|
||||
*/
|
||||
if (pthread_create(&mPoll, NULL, work, this)) {
|
||||
ALOGE("pthread creation failed %d", errno);
|
||||
mCallback = NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&mLock);
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
} // namespace usb
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // aidl
|
||||
78
usb/aidl/default/Usb.h
Normal file
78
usb/aidl/default/Usb.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <aidl/android/hardware/usb/BnUsb.h>
|
||||
#include <aidl/android/hardware/usb/BnUsbCallback.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#define UEVENT_MSG_LEN 2048
|
||||
#define UEVENT_MAX_EVENTS 64
|
||||
// The type-c stack waits for 4.5 - 5.5 secs before declaring a port non-pd.
|
||||
// The -partner directory would not be created until this is done.
|
||||
// Having a margin of ~3 secs for the directory and other related bookeeping
|
||||
// structures created and uvent fired.
|
||||
#define PORT_TYPE_TIMEOUT 8
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace usb {
|
||||
|
||||
using ::aidl::android::hardware::usb::IUsbCallback;
|
||||
using ::aidl::android::hardware::usb::PortRole;
|
||||
using ::android::base::ReadFileToString;
|
||||
using ::android::base::WriteStringToFile;
|
||||
using ::android::sp;
|
||||
using ::ndk::ScopedAStatus;
|
||||
using ::std::shared_ptr;
|
||||
using ::std::string;
|
||||
|
||||
struct Usb : public BnUsb {
|
||||
Usb();
|
||||
|
||||
ScopedAStatus enableContaminantPresenceDetection(const std::string& in_portName,
|
||||
bool in_enable, int64_t in_transactionId) override;
|
||||
ScopedAStatus queryPortStatus(int64_t in_transactionId) override;
|
||||
ScopedAStatus setCallback(const shared_ptr<IUsbCallback>& in_callback) override;
|
||||
ScopedAStatus switchRole(const string& in_portName, const PortRole& in_role,
|
||||
int64_t in_transactionId) override;
|
||||
ScopedAStatus enableUsbData(const string& in_portName, bool in_enable,
|
||||
int64_t in_transactionId) override;
|
||||
ScopedAStatus limitPowerTransfer(const std::string& in_portName, bool in_limit,
|
||||
int64_t in_transactionId)override;
|
||||
|
||||
shared_ptr<IUsbCallback> mCallback;
|
||||
// Protects mCallback variable
|
||||
pthread_mutex_t mLock;
|
||||
// Protects roleSwitch operation
|
||||
pthread_mutex_t mRoleSwitchLock;
|
||||
// Threads waiting for the partner to come back wait here
|
||||
pthread_cond_t mPartnerCV;
|
||||
// lock protecting mPartnerCV
|
||||
pthread_mutex_t mPartnerLock;
|
||||
// Variable to signal partner coming back online after type switch
|
||||
bool mPartnerUp;
|
||||
private:
|
||||
pthread_t mPoll;
|
||||
};
|
||||
|
||||
} // namespace usb
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // aidl
|
||||
4
usb/aidl/default/android.hardware.usb-service.example.rc
Normal file
4
usb/aidl/default/android.hardware.usb-service.example.rc
Normal file
@@ -0,0 +1,4 @@
|
||||
service vendor.usb_default /vendor/bin/hw/android.hardware.usb-service.example
|
||||
class hal
|
||||
user system
|
||||
group system
|
||||
10
usb/aidl/default/android.hardware.usb-service.example.xml
Normal file
10
usb/aidl/default/android.hardware.usb-service.example.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<manifest version="1.0" type="device">
|
||||
<hal format="aidl">
|
||||
<name>android.hardware.usb</name>
|
||||
<version>1</version>
|
||||
<interface>
|
||||
<name>IUsb</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
</manifest>
|
||||
35
usb/aidl/default/service.cpp
Normal file
35
usb/aidl/default/service.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.
|
||||
*/
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_process.h>
|
||||
|
||||
#include "Usb.h"
|
||||
|
||||
using ::aidl::android::hardware::usb::Usb;
|
||||
|
||||
int main() {
|
||||
ABinderProcess_setThreadPoolMaxThreadCount(0);
|
||||
std::shared_ptr<Usb> usb = ndk::SharedRefBase::make<Usb>();
|
||||
|
||||
const std::string instance = std::string() + Usb::descriptor + "/default";
|
||||
binder_status_t status = AServiceManager_addService(usb->asBinder().get(), instance.c_str());
|
||||
CHECK(status == STATUS_OK);
|
||||
|
||||
ABinderProcess_joinThreadPool();
|
||||
return -1; // Should never be reached
|
||||
}
|
||||
43
usb/aidl/vts/Android.bp
Normal file
43
usb/aidl/vts/Android.bp
Normal file
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// Copyright (C) 2021 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 {
|
||||
// See: http://go/android-license-faq
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "hardware_interfaces_license"
|
||||
// to get the below license kinds:
|
||||
// SPDX-license-identifier-Apache-2.0
|
||||
default_applicable_licenses: ["hardware_interfaces_license"],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "VtsAidlUsbTargetTest",
|
||||
defaults: [
|
||||
"VtsHalTargetTestDefaults",
|
||||
"use_libaidlvintf_gtest_helper_static",
|
||||
],
|
||||
srcs: ["VtsAidlUsbTargetTest.cpp"],
|
||||
shared_libs: [
|
||||
"libbinder_ndk",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.usb-V1-ndk",
|
||||
],
|
||||
test_suites: [
|
||||
"general-tests",
|
||||
"vts",
|
||||
],
|
||||
}
|
||||
473
usb/aidl/vts/VtsAidlUsbTargetTest.cpp
Normal file
473
usb/aidl/vts/VtsAidlUsbTargetTest.cpp
Normal file
@@ -0,0 +1,473 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Probject
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "UsbAidlTest"
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include <aidl/android/hardware/usb/IUsb.h>
|
||||
#include <aidl/android/hardware/usb/IUsbCallback.h>
|
||||
#include <aidl/android/hardware/usb/BnUsbCallback.h>
|
||||
#include <aidl/android/hardware/usb/PortDataRole.h>
|
||||
#include <aidl/android/hardware/usb/PortMode.h>
|
||||
#include <aidl/android/hardware/usb/PortPowerRole.h>
|
||||
#include <aidl/android/hardware/usb/PortRole.h>
|
||||
#include <aidl/android/hardware/usb/PortStatus.h>
|
||||
#include <aidl/android/hardware/usb/Status.h>
|
||||
#include <aidl/Vintf.h>
|
||||
#include <aidl/Gtest.h>
|
||||
|
||||
#include <android/binder_auto_utils.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_process.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <log/log.h>
|
||||
#include <stdlib.h>
|
||||
#include <chrono>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
|
||||
#define TIMEOUT_PERIOD 10
|
||||
|
||||
using ::aidl::android::hardware::usb::BnUsbCallback;
|
||||
using ::aidl::android::hardware::usb::IUsb;
|
||||
using ::aidl::android::hardware::usb::IUsbCallback;
|
||||
using ::aidl::android::hardware::usb::PortDataRole;
|
||||
using ::aidl::android::hardware::usb::PortMode;
|
||||
using ::aidl::android::hardware::usb::PortPowerRole;
|
||||
using ::aidl::android::hardware::usb::PortRole;
|
||||
using ::aidl::android::hardware::usb::PortStatus;
|
||||
using ::aidl::android::hardware::usb::Status;
|
||||
|
||||
using ::ndk::ScopedAStatus;
|
||||
using ::ndk::SpAIBinder;
|
||||
using std::vector;
|
||||
using std::shared_ptr;
|
||||
using std::string;
|
||||
|
||||
// The main test class for the USB aidl hal
|
||||
class UsbAidlTest : public testing::TestWithParam<std::string> {
|
||||
public:
|
||||
// Callback class for the USB aidl hal.
|
||||
// Usb Hal will call this object upon role switch or port query.
|
||||
class UsbCallback : public BnUsbCallback {
|
||||
UsbAidlTest& parent_;
|
||||
int cookie;
|
||||
|
||||
public:
|
||||
UsbCallback(UsbAidlTest& parent, int cookie)
|
||||
: parent_(parent), cookie(cookie){};
|
||||
|
||||
virtual ~UsbCallback() = default;
|
||||
|
||||
// Callback method for the port status.
|
||||
ScopedAStatus notifyPortStatusChange(const vector<PortStatus>& currentPortStatus,
|
||||
Status retval) override {
|
||||
if (retval == Status::SUCCESS && currentPortStatus.size() > 0) {
|
||||
parent_.usb_last_port_status.portName =
|
||||
currentPortStatus[0].portName.c_str();
|
||||
parent_.usb_last_port_status.currentDataRole =
|
||||
currentPortStatus[0].currentDataRole;
|
||||
parent_.usb_last_port_status.currentPowerRole =
|
||||
currentPortStatus[0].currentPowerRole;
|
||||
parent_.usb_last_port_status.currentMode =
|
||||
currentPortStatus[0].currentMode;
|
||||
}
|
||||
parent_.usb_last_cookie = cookie;
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
// Callback method for the status of role switch operation.
|
||||
ScopedAStatus notifyRoleSwitchStatus(const string& /*portName*/, const PortRole& newRole,
|
||||
Status retval, int64_t transactionId) override {
|
||||
parent_.usb_last_status = retval;
|
||||
parent_.usb_last_cookie = cookie;
|
||||
parent_.usb_last_port_role = newRole;
|
||||
parent_.usb_role_switch_done = true;
|
||||
parent_.last_transactionId = transactionId;
|
||||
parent_.notify();
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
// Callback method for the status of enableUsbData operation
|
||||
ScopedAStatus notifyEnableUsbDataStatus(const string& /*portName*/, bool /*enable*/,
|
||||
Status /*retval*/, int64_t transactionId) override {
|
||||
parent_.last_transactionId = transactionId;
|
||||
parent_.usb_last_cookie = cookie;
|
||||
parent_.enable_usb_data_done = true;
|
||||
parent_.notify();
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
// Callback method for the status of enableContaminantPresenceDetection
|
||||
ScopedAStatus notifyContaminantEnabledStatus(const string& /*portName*/, bool /*enable*/,
|
||||
Status /*retval*/, int64_t transactionId) override {
|
||||
parent_.last_transactionId = transactionId;
|
||||
parent_.usb_last_cookie = cookie;
|
||||
parent_.enable_contaminant_done = true;
|
||||
parent_.notify();
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
// Callback method for the status of queryPortStatus operation
|
||||
ScopedAStatus notifyQueryPortStatus(const string& /*portName*/, Status /*retval*/,
|
||||
int64_t transactionId) override {
|
||||
parent_.last_transactionId = transactionId;
|
||||
parent_.notify();
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
// Callback method for the status of limitPowerTransfer operation
|
||||
ScopedAStatus notifyLimitPowerTransferStatus(const string& /*portName*/, bool /*limit*/,
|
||||
Status /*retval*/, int64_t transactionId) override {
|
||||
parent_.last_transactionId = transactionId;
|
||||
parent_.usb_last_cookie = cookie;
|
||||
parent_.limit_power_transfer_done = true;
|
||||
parent_.notify();
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
};
|
||||
|
||||
virtual void SetUp() override {
|
||||
ALOGI("Setup");
|
||||
usb = IUsb::fromBinder(
|
||||
SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
|
||||
ASSERT_NE(usb, nullptr);
|
||||
|
||||
usb_cb_2 = ::ndk::SharedRefBase::make<UsbCallback>(*this, 2);
|
||||
ASSERT_NE(usb_cb_2, nullptr);
|
||||
const auto& ret = usb->setCallback(usb_cb_2);
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
}
|
||||
|
||||
virtual void TearDown() override { ALOGI("Teardown"); }
|
||||
|
||||
// Used as a mechanism to inform the test about data/event callback.
|
||||
inline void notify() {
|
||||
std::unique_lock<std::mutex> lock(usb_mtx);
|
||||
usb_count++;
|
||||
usb_cv.notify_one();
|
||||
}
|
||||
|
||||
// Test code calls this function to wait for data/event callback.
|
||||
inline std::cv_status wait() {
|
||||
std::unique_lock<std::mutex> lock(usb_mtx);
|
||||
|
||||
std::cv_status status = std::cv_status::no_timeout;
|
||||
auto now = std::chrono::system_clock::now();
|
||||
while (usb_count == 0) {
|
||||
status =
|
||||
usb_cv.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
|
||||
if (status == std::cv_status::timeout) {
|
||||
ALOGI("timeout");
|
||||
return status;
|
||||
}
|
||||
}
|
||||
usb_count--;
|
||||
return status;
|
||||
}
|
||||
|
||||
// USB aidl hal Proxy
|
||||
shared_ptr<IUsb> usb;
|
||||
|
||||
// Callback objects for usb aidl
|
||||
// Methods of these objects are called to notify port status updates.
|
||||
shared_ptr<IUsbCallback> usb_cb_1, usb_cb_2;
|
||||
|
||||
// The last conveyed status of the USB ports.
|
||||
// Stores information of currentt_data_role, power_role for all the USB ports
|
||||
PortStatus usb_last_port_status;
|
||||
|
||||
// Status of the last role switch operation.
|
||||
Status usb_last_status;
|
||||
|
||||
// Port role information of the last role switch operation.
|
||||
PortRole usb_last_port_role;
|
||||
|
||||
// Flag to indicate the invocation of role switch callback.
|
||||
bool usb_role_switch_done;
|
||||
|
||||
// Flag to indicate the invocation of notifyContaminantEnabledStatus callback.
|
||||
bool enable_contaminant_done;
|
||||
|
||||
// Flag to indicate the invocation of notifyEnableUsbDataStatus callback.
|
||||
bool enable_usb_data_done;
|
||||
|
||||
// Flag to indicate the invocation of notifyLimitPowerTransferStatus callback.
|
||||
bool limit_power_transfer_done;
|
||||
|
||||
// Stores the cookie of the last invoked usb callback object.
|
||||
int usb_last_cookie;
|
||||
|
||||
// Last transaction ID that was recorded.
|
||||
int64_t last_transactionId;
|
||||
// synchronization primitives to coordinate between main test thread
|
||||
// and the callback thread.
|
||||
std::mutex usb_mtx;
|
||||
std::condition_variable usb_cv;
|
||||
int usb_count = 0;
|
||||
};
|
||||
|
||||
/*
|
||||
* Test to see if setCallback succeeds.
|
||||
* Callback object is created and registered.
|
||||
*/
|
||||
TEST_P(UsbAidlTest, setCallback) {
|
||||
ALOGI("UsbAidlTest setCallback start");
|
||||
usb_cb_1 = ::ndk::SharedRefBase::make<UsbCallback>(*this, 1);
|
||||
ASSERT_NE(usb_cb_1, nullptr);
|
||||
const auto& ret = usb->setCallback(usb_cb_1);
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
ALOGI("UsbAidlTest setCallback end");
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to see if querying type-c
|
||||
* port status succeeds.
|
||||
* The callback parameters are checked to see if the transaction id
|
||||
* matches.
|
||||
*/
|
||||
TEST_P(UsbAidlTest, queryPortStatus) {
|
||||
ALOGI("UsbAidlTest queryPortStatus start");
|
||||
int64_t transactionId = rand() % 10000;
|
||||
const auto& ret = usb->queryPortStatus(transactionId);
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
EXPECT_EQ(std::cv_status::no_timeout, wait());
|
||||
EXPECT_EQ(2, usb_last_cookie);
|
||||
EXPECT_EQ(transactionId, last_transactionId);
|
||||
ALOGI("UsbAidlTest queryPortStatus end: %s", usb_last_port_status.portName.c_str());
|
||||
}
|
||||
|
||||
/*
|
||||
* Trying to switch a non-existent port should fail.
|
||||
* This test case tried to switch the port with empty
|
||||
* name which is expected to fail.
|
||||
* The callback parameters are checked to see if the transaction id
|
||||
* matches.
|
||||
*/
|
||||
TEST_P(UsbAidlTest, switchEmptyPort) {
|
||||
ALOGI("UsbAidlTest switchEmptyPort start");
|
||||
PortRole role;
|
||||
role.set<PortRole::powerRole>(PortPowerRole::SOURCE);
|
||||
int64_t transactionId = rand() % 10000;
|
||||
const auto& ret = usb->switchRole("", role, transactionId);
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
EXPECT_EQ(std::cv_status::no_timeout, wait());
|
||||
EXPECT_EQ(Status::ERROR, usb_last_status);
|
||||
EXPECT_EQ(transactionId, last_transactionId);
|
||||
EXPECT_EQ(2, usb_last_cookie);
|
||||
ALOGI("UsbAidlTest switchEmptyPort end");
|
||||
}
|
||||
|
||||
/*
|
||||
* Test switching the power role of usb port.
|
||||
* Test case queries the usb ports present in device.
|
||||
* If there is at least one usb port, a power role switch
|
||||
* to SOURCE is attempted for the port.
|
||||
* The callback parameters are checked to see if the transaction id
|
||||
* matches.
|
||||
*/
|
||||
TEST_P(UsbAidlTest, switchPowerRole) {
|
||||
ALOGI("UsbAidlTest switchPowerRole start");
|
||||
PortRole role;
|
||||
role.set<PortRole::powerRole>(PortPowerRole::SOURCE);
|
||||
int64_t transactionId = rand() % 10000;
|
||||
const auto& ret = usb->queryPortStatus(transactionId);
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
EXPECT_EQ(std::cv_status::no_timeout, wait());
|
||||
EXPECT_EQ(2, usb_last_cookie);
|
||||
EXPECT_EQ(transactionId, last_transactionId);
|
||||
|
||||
if (!usb_last_port_status.portName.empty()) {
|
||||
string portBeingSwitched = usb_last_port_status.portName;
|
||||
ALOGI("switchPower role portname:%s", portBeingSwitched.c_str());
|
||||
usb_role_switch_done = false;
|
||||
transactionId = rand() % 10000;
|
||||
const auto& ret = usb->switchRole(portBeingSwitched, role, transactionId);
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
|
||||
std::cv_status waitStatus = wait();
|
||||
while (waitStatus == std::cv_status::no_timeout &&
|
||||
usb_role_switch_done == false)
|
||||
waitStatus = wait();
|
||||
|
||||
EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
|
||||
EXPECT_EQ(2, usb_last_cookie);
|
||||
EXPECT_EQ(transactionId, last_transactionId);
|
||||
}
|
||||
ALOGI("UsbAidlTest switchPowerRole end");
|
||||
}
|
||||
|
||||
/*
|
||||
* Test switching the data role of usb port.
|
||||
* Test case queries the usb ports present in device.
|
||||
* If there is at least one usb port, a data role switch
|
||||
* to device is attempted for the port.
|
||||
* The callback parameters are checked to see if transaction id
|
||||
* matches.
|
||||
*/
|
||||
TEST_P(UsbAidlTest, switchDataRole) {
|
||||
ALOGI("UsbAidlTest switchDataRole start");
|
||||
PortRole role;
|
||||
role.set<PortRole::dataRole>(PortDataRole::DEVICE);
|
||||
int64_t transactionId = rand() % 10000;
|
||||
const auto& ret = usb->queryPortStatus(transactionId);
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
EXPECT_EQ(std::cv_status::no_timeout, wait());
|
||||
EXPECT_EQ(2, usb_last_cookie);
|
||||
EXPECT_EQ(transactionId, last_transactionId);
|
||||
|
||||
if (!usb_last_port_status.portName.empty()) {
|
||||
string portBeingSwitched = usb_last_port_status.portName;
|
||||
ALOGI("portname:%s", portBeingSwitched.c_str());
|
||||
usb_role_switch_done = false;
|
||||
transactionId = rand() % 10000;
|
||||
const auto& ret = usb->switchRole(portBeingSwitched, role, transactionId);
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
|
||||
std::cv_status waitStatus = wait();
|
||||
while (waitStatus == std::cv_status::no_timeout &&
|
||||
usb_role_switch_done == false)
|
||||
waitStatus = wait();
|
||||
|
||||
EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
|
||||
EXPECT_EQ(2, usb_last_cookie);
|
||||
EXPECT_EQ(transactionId, last_transactionId);
|
||||
}
|
||||
ALOGI("UsbAidlTest switchDataRole end");
|
||||
}
|
||||
|
||||
/*
|
||||
* Test enabling contaminant presence detection of the port.
|
||||
* Test case queries the usb ports present in device.
|
||||
* If there is at least one usb port, enabling contaminant detection
|
||||
* is attempted for the port.
|
||||
* The callback parameters are checked to see if transaction id
|
||||
* matches.
|
||||
*/
|
||||
TEST_P(UsbAidlTest, enableContaminantPresenceDetection) {
|
||||
ALOGI("UsbAidlTest enableContaminantPresenceDetection start");
|
||||
int64_t transactionId = rand() % 10000;
|
||||
const auto& ret = usb->queryPortStatus(transactionId);
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
EXPECT_EQ(std::cv_status::no_timeout, wait());
|
||||
EXPECT_EQ(2, usb_last_cookie);
|
||||
EXPECT_EQ(transactionId, last_transactionId);
|
||||
|
||||
if (!usb_last_port_status.portName.empty()) {
|
||||
ALOGI("portname:%s", usb_last_port_status.portName.c_str());
|
||||
enable_contaminant_done = false;
|
||||
transactionId = rand() % 10000;
|
||||
const auto& ret = usb->enableContaminantPresenceDetection(usb_last_port_status.portName,
|
||||
true, transactionId);
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
|
||||
std::cv_status waitStatus = wait();
|
||||
while (waitStatus == std::cv_status::no_timeout &&
|
||||
enable_contaminant_done == false)
|
||||
waitStatus = wait();
|
||||
|
||||
EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
|
||||
EXPECT_EQ(2, usb_last_cookie);
|
||||
EXPECT_EQ(transactionId, last_transactionId);
|
||||
}
|
||||
ALOGI("UsbAidlTest enableContaminantPresenceDetection end");
|
||||
}
|
||||
|
||||
/*
|
||||
* Test enabling Usb data of the port.
|
||||
* Test case queries the usb ports present in device.
|
||||
* If there is at least one usb port, enabling Usb data is attempted
|
||||
* for the port.
|
||||
* The callback parameters are checked to see if transaction id
|
||||
* matches.
|
||||
*/
|
||||
TEST_P(UsbAidlTest, enableUsbData) {
|
||||
ALOGI("UsbAidlTest enableUsbData start");
|
||||
int64_t transactionId = rand() % 10000;
|
||||
const auto& ret = usb->queryPortStatus(transactionId);
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
EXPECT_EQ(std::cv_status::no_timeout, wait());
|
||||
EXPECT_EQ(2, usb_last_cookie);
|
||||
EXPECT_EQ(transactionId, last_transactionId);
|
||||
|
||||
if (!usb_last_port_status.portName.empty()) {
|
||||
ALOGI("portname:%s", usb_last_port_status.portName.c_str());
|
||||
enable_usb_data_done = false;
|
||||
transactionId = rand() % 10000;
|
||||
const auto& ret = usb->enableUsbData(usb_last_port_status.portName, true, transactionId);
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
|
||||
std::cv_status waitStatus = wait();
|
||||
while (waitStatus == std::cv_status::no_timeout &&
|
||||
enable_usb_data_done == false)
|
||||
waitStatus = wait();
|
||||
|
||||
EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
|
||||
EXPECT_EQ(2, usb_last_cookie);
|
||||
EXPECT_EQ(transactionId, last_transactionId);
|
||||
}
|
||||
ALOGI("UsbAidlTest enableUsbData end");
|
||||
}
|
||||
|
||||
/*
|
||||
* Test enabling Usb data of the port.
|
||||
* Test case queries the usb ports present in device.
|
||||
* If there is at least one usb port, relaxing limit power transfer
|
||||
* is attempted for the port.
|
||||
* The callback parameters are checked to see if transaction id
|
||||
* matches.
|
||||
*/
|
||||
TEST_P(UsbAidlTest, limitPowerTransfer) {
|
||||
ALOGI("UsbAidlTest limitPowerTransfer start");
|
||||
int64_t transactionId = rand() % 10000;
|
||||
const auto& ret = usb->queryPortStatus(transactionId);
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
EXPECT_EQ(std::cv_status::no_timeout, wait());
|
||||
EXPECT_EQ(2, usb_last_cookie);
|
||||
EXPECT_EQ(transactionId, last_transactionId);
|
||||
|
||||
if (!usb_last_port_status.portName.empty()) {
|
||||
ALOGI("portname:%s", usb_last_port_status.portName.c_str());
|
||||
limit_power_transfer_done = false;
|
||||
transactionId = rand() % 10000;
|
||||
const auto& ret = usb->limitPowerTransfer(usb_last_port_status.portName, false, transactionId);
|
||||
ASSERT_TRUE(ret.isOk());
|
||||
|
||||
std::cv_status waitStatus = wait();
|
||||
while (waitStatus == std::cv_status::no_timeout &&
|
||||
limit_power_transfer_done == false)
|
||||
waitStatus = wait();
|
||||
|
||||
EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
|
||||
EXPECT_EQ(2, usb_last_cookie);
|
||||
EXPECT_EQ(transactionId, last_transactionId);
|
||||
}
|
||||
ALOGI("UsbAidlTest limitPowerTransfer end");
|
||||
}
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UsbAidlTest);
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
PerInstance, UsbAidlTest,
|
||||
testing::ValuesIn(::android::getAidlHalInstanceNames(IUsb::descriptor)),
|
||||
::android::PrintInstanceNameToString);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
ABinderProcess_setThreadPoolMaxThreadCount(1);
|
||||
ABinderProcess_startThreadPool();
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
Reference in New Issue
Block a user