diff options
author | Haamed Gheibi <haamed@google.com> | 2022-02-09 14:35:06 -0800 |
---|---|---|
committer | Haamed Gheibi <haamed@google.com> | 2022-02-09 14:41:16 -0800 |
commit | ab52181d73b04e131fd72e32d69b5123a5d6892b (patch) | |
tree | 0ac86b537180b6fb97716b3058dfae44af9eaac7 /usb | |
parent | f99b35c293439db0b7436b47b939eb8c7bf21b51 (diff) | |
parent | 4d2548cfa7b86b79a516be9b60f6b666cc9af682 (diff) |
Merge TP1A.220126.001
Change-Id: Ibf6bd2c20d9927fde8b2a05dde2b58bd8faea20f
Diffstat (limited to 'usb')
36 files changed, 2790 insertions, 0 deletions
diff --git a/usb/aidl/Android.bp b/usb/aidl/Android.bp new file mode 100644 index 0000000000..d1e9e680e9 --- /dev/null +++ b/usb/aidl/Android.bp @@ -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, + }, + }, + }, +} diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantDetectionStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantDetectionStatus.aidl new file mode 100644 index 0000000000..24c69664f7 --- /dev/null +++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantDetectionStatus.aidl @@ -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, +} diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantProtectionMode.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantProtectionMode.aidl new file mode 100644 index 0000000000..99798693ff --- /dev/null +++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantProtectionMode.aidl @@ -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, +} diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantProtectionStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantProtectionStatus.aidl new file mode 100644 index 0000000000..9642261444 --- /dev/null +++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantProtectionStatus.aidl @@ -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, +} diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl new file mode 100644 index 0000000000..4ba9ff8dff --- /dev/null +++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl @@ -0,0 +1,44 @@ +/* + * 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 enableUsbDataWhileDocked(in String portName, 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); +} diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsbCallback.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsbCallback.aidl new file mode 100644 index 0000000000..57f02c548c --- /dev/null +++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsbCallback.aidl @@ -0,0 +1,44 @@ +/* + * 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 notifyEnableUsbDataWhileDockedStatus(in String portName, 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); +} diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortDataRole.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortDataRole.aidl new file mode 100644 index 0000000000..105b316775 --- /dev/null +++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortDataRole.aidl @@ -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, +} diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortMode.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortMode.aidl new file mode 100644 index 0000000000..34e43343ad --- /dev/null +++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortMode.aidl @@ -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, +} diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortPowerRole.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortPowerRole.aidl new file mode 100644 index 0000000000..0e6f3fb426 --- /dev/null +++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortPowerRole.aidl @@ -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, +} diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortRole.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortRole.aidl new file mode 100644 index 0000000000..c66aeccde9 --- /dev/null +++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortRole.aidl @@ -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; +} diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl new file mode 100644 index 0000000000..dfd99fb249 --- /dev/null +++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl @@ -0,0 +1,53 @@ +/* + * 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; + android.hardware.usb.UsbDataStatus[] usbDataStatus; + boolean powerTransferLimited; + android.hardware.usb.PowerBrickStatus powerBrickStatus; +} diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PowerBrickStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PowerBrickStatus.aidl new file mode 100644 index 0000000000..01d2fdd9f7 --- /dev/null +++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PowerBrickStatus.aidl @@ -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 PowerBrickStatus { + UNKNOWN = 0, + CONNECTED = 1, + NOT_CONNECTED = 2, +} diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/Status.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/Status.aidl new file mode 100644 index 0000000000..f28fc2a70e --- /dev/null +++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/Status.aidl @@ -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, +} diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/UsbDataStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/UsbDataStatus.aidl new file mode 100644 index 0000000000..e2c0cfbef1 --- /dev/null +++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/UsbDataStatus.aidl @@ -0,0 +1,44 @@ +/* + * 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 UsbDataStatus { + UNKNOWN = 0, + ENABLED = 1, + DISABLED_OVERHEAT = 2, + DISABLED_CONTAMINANT = 3, + DISABLED_DOCK = 4, + DISABLED_FORCE = 5, + DISABLED_DEBUG = 6, +} diff --git a/usb/aidl/android/hardware/usb/ContaminantDetectionStatus.aidl b/usb/aidl/android/hardware/usb/ContaminantDetectionStatus.aidl new file mode 100644 index 0000000000..d9bc576f94 --- /dev/null +++ b/usb/aidl/android/hardware/usb/ContaminantDetectionStatus.aidl @@ -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, +} diff --git a/usb/aidl/android/hardware/usb/ContaminantProtectionMode.aidl b/usb/aidl/android/hardware/usb/ContaminantProtectionMode.aidl new file mode 100644 index 0000000000..47c073dcc4 --- /dev/null +++ b/usb/aidl/android/hardware/usb/ContaminantProtectionMode.aidl @@ -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, +} diff --git a/usb/aidl/android/hardware/usb/ContaminantProtectionStatus.aidl b/usb/aidl/android/hardware/usb/ContaminantProtectionStatus.aidl new file mode 100644 index 0000000000..c4fa979698 --- /dev/null +++ b/usb/aidl/android/hardware/usb/ContaminantProtectionStatus.aidl @@ -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, +} diff --git a/usb/aidl/android/hardware/usb/IUsb.aidl b/usb/aidl/android/hardware/usb/IUsb.aidl new file mode 100644 index 0000000000..d296fbb209 --- /dev/null +++ b/usb/aidl/android/hardware/usb/IUsb.aidl @@ -0,0 +1,107 @@ +/* + * 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 function is used to enable USB controller if and when the controller + * disabled due to docking event. + * + * @param portName Name of the port. + * @param transactionId ID to be used when invoking the callback. + */ + void enableUsbDataWhileDocked(in String portName, 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); +} diff --git a/usb/aidl/android/hardware/usb/IUsbCallback.aidl b/usb/aidl/android/hardware/usb/IUsbCallback.aidl new file mode 100644 index 0000000000..e33672aa2b --- /dev/null +++ b/usb/aidl/android/hardware/usb/IUsbCallback.aidl @@ -0,0 +1,108 @@ +/* + * 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 enableUsbDataWhileDocked call to the caller. + * + * @param portName name of the port for which the enableUsbDataWhileDocked is requested. + * @param retval SUCCESS if current request succeeded. FAILURE otherwise. + * @param transactionId transactionId sent during enableUsbDataWhileDocked request. + */ + void notifyEnableUsbDataWhileDockedStatus(in String portName, 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); +} diff --git a/usb/aidl/android/hardware/usb/PortDataRole.aidl b/usb/aidl/android/hardware/usb/PortDataRole.aidl new file mode 100644 index 0000000000..a69f97719e --- /dev/null +++ b/usb/aidl/android/hardware/usb/PortDataRole.aidl @@ -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, +} diff --git a/usb/aidl/android/hardware/usb/PortMode.aidl b/usb/aidl/android/hardware/usb/PortMode.aidl new file mode 100644 index 0000000000..399f0ebaeb --- /dev/null +++ b/usb/aidl/android/hardware/usb/PortMode.aidl @@ -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, +} diff --git a/usb/aidl/android/hardware/usb/PortPowerRole.aidl b/usb/aidl/android/hardware/usb/PortPowerRole.aidl new file mode 100644 index 0000000000..ae3dc47c45 --- /dev/null +++ b/usb/aidl/android/hardware/usb/PortPowerRole.aidl @@ -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, +} diff --git a/usb/aidl/android/hardware/usb/PortRole.aidl b/usb/aidl/android/hardware/usb/PortRole.aidl new file mode 100644 index 0000000000..e0429c8b74 --- /dev/null +++ b/usb/aidl/android/hardware/usb/PortRole.aidl @@ -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; +} diff --git a/usb/aidl/android/hardware/usb/PortStatus.aidl b/usb/aidl/android/hardware/usb/PortStatus.aidl new file mode 100644 index 0000000000..51bee71389 --- /dev/null +++ b/usb/aidl/android/hardware/usb/PortStatus.aidl @@ -0,0 +1,118 @@ +/* + * 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; +import android.hardware.usb.PowerBrickStatus; +import android.hardware.usb.UsbDataStatus; + +@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. + * Lists reasons for USB data being disabled. + */ + UsbDataStatus[] usbDataStatus; + /** + * Denoted whether power transfer is limited in the port. + */ + boolean powerTransferLimited; + /** + * Denotes whether Power brick is connected. + */ + PowerBrickStatus powerBrickStatus; +} diff --git a/usb/aidl/android/hardware/usb/PowerBrickStatus.aidl b/usb/aidl/android/hardware/usb/PowerBrickStatus.aidl new file mode 100644 index 0000000000..620fb25922 --- /dev/null +++ b/usb/aidl/android/hardware/usb/PowerBrickStatus.aidl @@ -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. + */ + +package android.hardware.usb; + +@VintfStability +enum PowerBrickStatus { + /** + * Status not known. + */ + UNKNOWN = 0, + /** + * Port partner is power brick. + */ + CONNECTED = 1, + /** + * Port partner is not power brick. + */ + NOT_CONNECTED = 2, +} diff --git a/usb/aidl/android/hardware/usb/Status.aidl b/usb/aidl/android/hardware/usb/Status.aidl new file mode 100644 index 0000000000..468ba4a068 --- /dev/null +++ b/usb/aidl/android/hardware/usb/Status.aidl @@ -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, +} diff --git a/usb/aidl/android/hardware/usb/UsbDataStatus.aidl b/usb/aidl/android/hardware/usb/UsbDataStatus.aidl new file mode 100644 index 0000000000..4b6a41a01e --- /dev/null +++ b/usb/aidl/android/hardware/usb/UsbDataStatus.aidl @@ -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; + +@VintfStability +enum UsbDataStatus { + /** + * USB data status not known. + */ + UNKNOWN = 0, + /** + * USB data is enabled. + */ + ENABLED = 1, + /** + * USB data is disabled as the port is hot. + */ + DISABLED_OVERHEAT = 2, + /** + * USB data is disabled as port is contaminated. + */ + DISABLED_CONTAMINANT = 3, + /** + * USB data is disabled due to dock. + */ + DISABLED_DOCK = 4, + /** + * USB data is disabled by USB Service. + */ + DISABLED_FORCE = 5, + /** + * USB data disabled for debug. + */ + DISABLED_DEBUG = 6 +} diff --git a/usb/aidl/conversion.log b/usb/aidl/conversion.log new file mode 100644 index 0000000000..c09044689f --- /dev/null +++ b/usb/aidl/conversion.log @@ -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 diff --git a/usb/aidl/default/Android.bp b/usb/aidl/default/Android.bp new file mode 100644 index 0000000000..da0cff23c3 --- /dev/null +++ b/usb/aidl/default/Android.bp @@ -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", + ], +} diff --git a/usb/aidl/default/Usb.cpp b/usb/aidl/default/Usb.cpp new file mode 100644 index 0000000000..92b09a2b44 --- /dev/null +++ b/usb/aidl/default/Usb.cpp @@ -0,0 +1,727 @@ +/* + * 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(); +} + +ScopedAStatus Usb::enableUsbDataWhileDocked(const string& in_portName, int64_t in_transactionId) { + + pthread_mutex_lock(&mLock); + if (mCallback != NULL) { + ScopedAStatus ret = mCallback->notifyEnableUsbDataWhileDockedStatus( + in_portName, Status::NOT_SUPPORTED, in_transactionId); + if (!ret.isOk()) + ALOGE("notifyEnableUsbDataWhileDockedStatus error %s", ret.getDescription().c_str()); + } else { + ALOGE("Not notifying the userspace. Callback is not set"); + } + pthread_mutex_unlock(&mLock); + + 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].usbDataStatus.push_back(UsbDataStatus::ENABLED); + + 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 diff --git a/usb/aidl/default/Usb.h b/usb/aidl/default/Usb.h new file mode 100644 index 0000000000..7e8422e39b --- /dev/null +++ b/usb/aidl/default/Usb.h @@ -0,0 +1,80 @@ +/* + * 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 enableUsbDataWhileDocked(const string& in_portName, + 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 diff --git a/usb/aidl/default/android.hardware.usb-service.example.rc b/usb/aidl/default/android.hardware.usb-service.example.rc new file mode 100644 index 0000000000..335bca744d --- /dev/null +++ b/usb/aidl/default/android.hardware.usb-service.example.rc @@ -0,0 +1,4 @@ +service vendor.usb_default /vendor/bin/hw/android.hardware.usb-service.example + class hal + user system + group system diff --git a/usb/aidl/default/android.hardware.usb-service.example.xml b/usb/aidl/default/android.hardware.usb-service.example.xml new file mode 100644 index 0000000000..6088194890 --- /dev/null +++ b/usb/aidl/default/android.hardware.usb-service.example.xml @@ -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> diff --git a/usb/aidl/default/service.cpp b/usb/aidl/default/service.cpp new file mode 100644 index 0000000000..398458aff7 --- /dev/null +++ b/usb/aidl/default/service.cpp @@ -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 +} diff --git a/usb/aidl/vts/Android.bp b/usb/aidl/vts/Android.bp new file mode 100644 index 0000000000..00a7c93ec3 --- /dev/null +++ b/usb/aidl/vts/Android.bp @@ -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", + ], +} diff --git a/usb/aidl/vts/VtsAidlUsbTargetTest.cpp b/usb/aidl/vts/VtsAidlUsbTargetTest.cpp new file mode 100644 index 0000000000..ed3bd6e7db --- /dev/null +++ b/usb/aidl/vts/VtsAidlUsbTargetTest.cpp @@ -0,0 +1,523 @@ +/* + * 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 enableUsbData operation + ScopedAStatus notifyEnableUsbDataWhileDockedStatus(const string& /*portName*/, + Status /*retval*/, + int64_t transactionId) override { + parent_.last_transactionId = transactionId; + parent_.usb_last_cookie = cookie; + parent_.enable_usb_data_while_docked_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 notifyEnableUsbDataWhileDockedStatus callback. + bool enable_usb_data_while_docked_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 while being docked. + * Test case queries the usb ports present in device. + * If there is at least one usb port, enabling Usb data while docked + * is attempted for the port. + * The callback parameters are checked to see if transaction id + * matches. + */ +TEST_P(UsbAidlTest, enableUsbDataWhileDocked) { + ALOGI("UsbAidlTest enableUsbDataWhileDocked 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_while_docked_done = false; + transactionId = rand() % 10000; + const auto& ret = usb->enableUsbDataWhileDocked(usb_last_port_status.portName, transactionId); + ASSERT_TRUE(ret.isOk()); + + std::cv_status waitStatus = wait(); + while (waitStatus == std::cv_status::no_timeout && + enable_usb_data_while_docked_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 enableUsbDataWhileDocked 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(); +} |