From 3f4462dd776fc72b5595c52d41ab5e7032b405f9 Mon Sep 17 00:00:00 2001 From: Konsta Date: Wed, 20 Sep 2023 15:25:28 +0300 Subject: [PATCH] usb: add gadget hal * Copy from hardware/interfaces/usb/gadget/1.2/default with udc path changed and service renamed for Raspberry Pi. --- device.mk | 3 +- ramdisk/init.rpi4.usb.rc | 125 ++++---- ramdisk/ueventd.rpi4.rc | 3 + sepolicy/file_contexts | 3 + usb/Android.bp | 29 ++ usb/UsbGadget.cpp | 287 ++++++++++++++++++ usb/UsbGadget.h | 109 +++++++ ...oid.hardware.usb.gadget@1.2-service.rpi.rc | 7 + ...id.hardware.usb.gadget@1.2-service.rpi.xml | 11 + usb/service.cpp | 53 ++++ 10 files changed, 566 insertions(+), 64 deletions(-) create mode 100644 usb/Android.bp create mode 100644 usb/UsbGadget.cpp create mode 100644 usb/UsbGadget.h create mode 100644 usb/android.hardware.usb.gadget@1.2-service.rpi.rc create mode 100644 usb/android.hardware.usb.gadget@1.2-service.rpi.xml create mode 100644 usb/service.cpp diff --git a/device.mk b/device.mk index 0d4c948..0a632cd 100644 --- a/device.mk +++ b/device.mk @@ -245,7 +245,8 @@ PRODUCT_PACKAGES += \ # USB PRODUCT_PACKAGES += \ - android.hardware.usb-service.example + android.hardware.usb-service.example \ + android.hardware.usb.gadget@1.2-service.rpi PRODUCT_COPY_FILES += \ frameworks/native/data/etc/android.hardware.usb.accessory.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.usb.accessory.xml \ diff --git a/ramdisk/init.rpi4.usb.rc b/ramdisk/init.rpi4.usb.rc index 04c38f7..a4e62e0 100644 --- a/ramdisk/init.rpi4.usb.rc +++ b/ramdisk/init.rpi4.usb.rc @@ -1,8 +1,8 @@ on boot mount configfs none /config - mkdir /config/usb_gadget/g1 0770 shell shell - mkdir /config/usb_gadget/g1/strings/0x409 0770 shell shell - write /config/usb_gadget/g1/bcdDevice 0x0223 + mkdir /config/usb_gadget/g1 0770 + mkdir /config/usb_gadget/g1/strings/0x409 0770 + write /config/usb_gadget/g1/bcdDevice 0x0440 write /config/usb_gadget/g1/bcdUSB 0x0200 write /config/usb_gadget/g1/idVendor 0x18d1 write /config/usb_gadget/g1/strings/0x409/serialnumber ${ro.serialno} @@ -15,8 +15,8 @@ on boot mkdir /config/usb_gadget/g1/functions/audio_source.gs3 mkdir /config/usb_gadget/g1/functions/rndis.gs4 mkdir /config/usb_gadget/g1/functions/midi.gs5 - mkdir /config/usb_gadget/g1/configs/b.1 0770 shell shell - mkdir /config/usb_gadget/g1/configs/b.1/strings/0x409 0770 shell shell + mkdir /config/usb_gadget/g1/configs/b.1 0770 + mkdir /config/usb_gadget/g1/configs/b.1/strings/0x409 0770 write /config/usb_gadget/g1/configs/b.1/MaxPower 500 write /config/usb_gadget/g1/os_desc/b_vendor_code 0x1 write /config/usb_gadget/g1/os_desc/qw_sign "MSFT100" @@ -25,66 +25,65 @@ on boot mkdir /dev/usb-ffs/mtp 0770 mtp mtp mkdir /dev/usb-ffs/ptp 0770 mtp mtp setprop sys.usb.mtp.device_type 3 + setprop sys.usb.mtp.batchcancel true + setprop vendor.usb.rndis.config rndis.gs4 symlink /config/usb_gadget/g1/configs/b.1 /config/usb_gadget/g1/os_desc/b.1 + chown system system /config/usb_gadget/ + chown system system /config/usb_gadget/g1 + chown system system /config/usb_gadget/g1/UDC + chown system system /config/usb_gadget/g1/bDeviceClass + chown system system /config/usb_gadget/g1/bDeviceProtocol + chown system system /config/usb_gadget/g1/bDeviceSubClass + chown system system /config/usb_gadget/g1/bMaxPacketSize0 + chown system system /config/usb_gadget/g1/bcdDevice + chown system system /config/usb_gadget/g1/bcdUSB + chown system system /config/usb_gadget/g1/configs + chown system system /config/usb_gadget/g1/configs/b.1 + chown system system /config/usb_gadget/g1/configs/b.1/MaxPower + chown system system /config/usb_gadget/g1/configs/b.1/bmAttributes + chown system system /config/usb_gadget/g1/configs/b.1/strings + chown system system /config/usb_gadget/g1/functions + chown system system /config/usb_gadget/g1/functions/accessory.gs2 + chown system system /config/usb_gadget/g1/functions/audio_source.gs3 + chown system system /config/usb_gadget/g1/functions/ffs.adb + chown system system /config/usb_gadget/g1/functions/ffs.mtp + chown system system /config/usb_gadget/g1/functions/ffs.ptp + chown system system /config/usb_gadget/g1/functions/midi.gs5 + chown system system /config/usb_gadget/g1/functions/midi.gs5/buflen + chown system system /config/usb_gadget/g1/functions/midi.gs5/id + chown system system /config/usb_gadget/g1/functions/midi.gs5/in_ports + chown system system /config/usb_gadget/g1/functions/midi.gs5/index + chown system system /config/usb_gadget/g1/functions/midi.gs5/out_ports + chown system system /config/usb_gadget/g1/functions/midi.gs5/qlen + chown system system /config/usb_gadget/g1/functions/rndis.gs4 + chown system system /config/usb_gadget/g1/functions/rndis.gs4/class + chown system system /config/usb_gadget/g1/functions/rndis.gs4/dev_addr + chown system system /config/usb_gadget/g1/functions/rndis.gs4/host_addr + chown system system /config/usb_gadget/g1/functions/rndis.gs4/ifname + chown system system /config/usb_gadget/g1/functions/rndis.gs4/os_desc + chown system system /config/usb_gadget/g1/functions/rndis.gs4/os_desc/interface.rndis + chown system system /config/usb_gadget/g1/functions/rndis.gs4/os_desc/interface.rndis/compatible_id + chown system system /config/usb_gadget/g1/functions/rndis.gs4/os_desc/interface.rndis/sub_compatible_id + chown system system /config/usb_gadget/g1/functions/rndis.gs4/protocol + chown system system /config/usb_gadget/g1/functions/rndis.gs4/qmult + chown system system /config/usb_gadget/g1/functions/rndis.gs4/subclass + chown system system /config/usb_gadget/g1/idProduct + chown system system /config/usb_gadget/g1/idVendor + chown system system /config/usb_gadget/g1/max_speed + chown system system /config/usb_gadget/g1/os_desc + chown system system /config/usb_gadget/g1/os_desc/b.1 + chown system system /config/usb_gadget/g1/os_desc/b_vendor_code + chown system system /config/usb_gadget/g1/os_desc/qw_sign + chown system system /config/usb_gadget/g1/os_desc/use + chown system system /config/usb_gadget/g1/strings + chown system system /config/usb_gadget/g1/strings/0x409 + chown system system /config/usb_gadget/g1/strings/0x409/manufacturer + chown system system /config/usb_gadget/g1/strings/0x409/product + chown system system /config/usb_gadget/g1/strings/0x409/serialnumber + on property:sys.usb.controller=* - mount functionfs adb /dev/usb-ffs/adb uid=2000,gid=2000 + mount functionfs adb /dev/usb-ffs/adb rmode=0770,fmode=0660,uid=2000,gid=2000,no_disconnect=1 mount functionfs mtp /dev/usb-ffs/mtp rmode=0770,fmode=0660,uid=1024,gid=1024,no_disconnect=1 mount functionfs ptp /dev/usb-ffs/ptp rmode=0770,fmode=0660,uid=1024,gid=1024,no_disconnect=1 - setprop sys.usb.configfs 1 - -on property:sys.usb.config=none && property:sys.usb.configfs=1 - write /config/usb_gadget/g1/os_desc/use 0 - -on property:sys.usb.config=mtp && property:sys.usb.configfs=1 - write /config/usb_gadget/g1/idProduct 0x4ee1 - write /config/usb_gadget/g1/os_desc/use 1 - symlink /config/usb_gadget/g1/functions/ffs.mtp /config/usb_gadget/g1/configs/b.1/f1 - -on property:sys.usb.ffs.ready=1 && property:sys.usb.config=mtp,adb && property:sys.usb.configfs=1 - write /config/usb_gadget/g1/idProduct 0x4ee2 - write /config/usb_gadget/g1/os_desc/use 1 - symlink /config/usb_gadget/g1/functions/ffs.mtp /config/usb_gadget/g1/configs/b.1/f1 - -on property:sys.usb.config=rndis && property:sys.usb.configfs=1 - write /config/usb_gadget/g1/idProduct 0x4ee3 - -on property:sys.usb.ffs.ready=1 && property:sys.usb.config=rndis,adb && property:sys.usb.configfs=1 - write /config/usb_gadget/g1/idProduct 0x4ee4 - -on property:sys.usb.config=ptp && property:sys.usb.configfs=1 - write /config/usb_gadget/g1/idProduct 0x4ee5 - write /config/usb_gadget/g1/os_desc/use 1 - symlink /config/usb_gadget/g1/functions/ffs.ptp /config/usb_gadget/g1/configs/b.1/f1 - -on property:sys.usb.ffs.ready=1 && property:sys.usb.config=ptp,adb && property:sys.usb.configfs=1 - write /config/usb_gadget/g1/idProduct 0x4ee6 - write /config/usb_gadget/g1/os_desc/use 1 - symlink /config/usb_gadget/g1/functions/ffs.ptp /config/usb_gadget/g1/configs/b.1/f1 - -on property:sys.usb.ffs.ready=1 && property:sys.usb.config=adb && property:sys.usb.configfs=1 - write /config/usb_gadget/g1/idProduct 0x4ee7 - -on property:sys.usb.config=midi && property:sys.usb.configfs=1 - write /config/usb_gadget/g1/idProduct 0x4ee8 - -on property:sys.usb.ffs.ready=1 && property:sys.usb.config=midi,adb && property:sys.usb.configfs=1 - write /config/usb_gadget/g1/idProduct 0x4ee9 - -on property:sys.usb.config=accessory && property:sys.usb.configfs=1 - write /config/usb_gadget/g1/idProduct 0x2d00 - -on property:sys.usb.ffs.ready=1 && property:sys.usb.config=accessory,adb && property:sys.usb.configfs=1 - write /config/usb_gadget/g1/idProduct 0x2d01 - -on property:sys.usb.config=audio_source && property:sys.usb.configfs=1 - write /config/usb_gadget/g1/idProduct 0x2d02 - -on property:sys.usb.ffs.ready=1 && property:sys.usb.config=audio_source,adb && property:sys.usb.configfs=1 - write /config/usb_gadget/g1/idProduct 0x2d03 - -on property:sys.usb.config=accessory,audio_source && property:sys.usb.configfs=1 - write /config/usb_gadget/g1/idProduct 0x2d04 - -on property:sys.usb.ffs.ready=1 && property:sys.usb.config=accessory,audio_source,adb && property:sys.usb.configfs=1 - write /config/usb_gadget/g1/idProduct 0x2d05 + setprop sys.usb.configfs 2 diff --git a/ramdisk/ueventd.rpi4.rc b/ramdisk/ueventd.rpi4.rc index bcdd85f..27e1d93 100644 --- a/ramdisk/ueventd.rpi4.rc +++ b/ramdisk/ueventd.rpi4.rc @@ -16,6 +16,9 @@ # ION /dev/ion 0664 system system +# USB +/sys/class/udc/fe980000.usb current_speed 0664 system system + # V4L2 /dev/media0 0660 media media /dev/media1 0660 media media diff --git a/sepolicy/file_contexts b/sepolicy/file_contexts index 3e0824e..b25462a 100644 --- a/sepolicy/file_contexts +++ b/sepolicy/file_contexts @@ -47,5 +47,8 @@ # Suspend /vendor/bin/suspend_blocker_rpi u:object_r:suspend_blocker_exec:s0 +# USB +/vendor/bin/hw/android\.hardware\.usb\.gadget@1\.2-service\.rpi u:object_r:hal_usb_gadget_default_exec:s0 + # V4L2 /vendor/bin/hw/android\.hardware\.media\.c2@1\.0-service-v4l2(.*)? u:object_r:mediacodec_exec:s0 diff --git a/usb/Android.bp b/usb/Android.bp new file mode 100644 index 0000000..6df6893 --- /dev/null +++ b/usb/Android.bp @@ -0,0 +1,29 @@ +// Copyright (C) 2020 The Android Open Source Project +// Copyright (C) 2023 KonstaKANG +// +// SPDX-License-Identifier: Apache-2.0 + +cc_binary { + name: "android.hardware.usb.gadget@1.2-service.rpi", + defaults: ["hidl_defaults"], + relative_install_path: "hw", + init_rc: ["android.hardware.usb.gadget@1.2-service.rpi.rc"], + vintf_fragments: ["android.hardware.usb.gadget@1.2-service.rpi.xml"], + vendor: true, + srcs: [ + "service.cpp", + "UsbGadget.cpp", + ], + shared_libs: [ + "android.hardware.usb.gadget@1.0", + "android.hardware.usb.gadget@1.1", + "android.hardware.usb.gadget@1.2", + "libbase", + "libcutils", + "libhardware", + "libhidlbase", + "liblog", + "libutils", + ], + static_libs: ["libusbconfigfs-2"], +} diff --git a/usb/UsbGadget.cpp b/usb/UsbGadget.cpp new file mode 100644 index 0000000..acd29d3 --- /dev/null +++ b/usb/UsbGadget.cpp @@ -0,0 +1,287 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * Copyright (C) 2023 KonstaKANG + * + * 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.gadget@1.2-service.rpi" + +#include "UsbGadget.h" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace usb { +namespace gadget { +namespace V1_2 { +namespace implementation { + +UsbGadget::UsbGadget() { + if (access(OS_DESC_PATH, R_OK) != 0) { + ALOGE("configfs setup not done yet"); + abort(); + } +} + +void currentFunctionsAppliedCallback(bool functionsApplied, void* payload) { + UsbGadget* gadget = (UsbGadget*)payload; + gadget->mCurrentUsbFunctionsApplied = functionsApplied; +} + +Return UsbGadget::getCurrentUsbFunctions(const sp& callback) { + Return ret = callback->getCurrentUsbFunctionsCb( + mCurrentUsbFunctions, mCurrentUsbFunctionsApplied ? Status::FUNCTIONS_APPLIED + : Status::FUNCTIONS_NOT_APPLIED); + if (!ret.isOk()) ALOGE("Call to getCurrentUsbFunctionsCb failed %s", ret.description().c_str()); + + return Void(); +} + +Return UsbGadget::getUsbSpeed(const sp& callback) { + std::string current_speed; + if (ReadFileToString(SPEED_PATH, ¤t_speed)) { + current_speed = Trim(current_speed); + ALOGI("current USB speed is %s", current_speed.c_str()); + if (current_speed == "low-speed") + mUsbSpeed = UsbSpeed::LOWSPEED; + else if (current_speed == "full-speed") + mUsbSpeed = UsbSpeed::FULLSPEED; + else if (current_speed == "high-speed") + mUsbSpeed = UsbSpeed::HIGHSPEED; + else if (current_speed == "super-speed") + mUsbSpeed = UsbSpeed::SUPERSPEED; + else if (current_speed == "super-speed-plus") + mUsbSpeed = UsbSpeed::SUPERSPEED_10Gb; + else if (current_speed == "UNKNOWN") + mUsbSpeed = UsbSpeed::UNKNOWN; + else { + /** + * This part is used for USB4 or reserved speed. + * + * If reserved speed is detected, it needs to convert to other speeds. + * For example: + * If the bandwidth of new speed is 7G, adding new if + * statement and set mUsbSpeed to SUPERSPEED. + * If the bandwidth of new speed is 80G, adding new if + * statement and set mUsbSpeed to USB4_GEN3_40Gb. + */ + mUsbSpeed = UsbSpeed::RESERVED_SPEED; + } + } else { + ALOGE("Fail to read current speed"); + mUsbSpeed = UsbSpeed::UNKNOWN; + } + + if (callback) { + Return ret = callback->getUsbSpeedCb(mUsbSpeed); + + if (!ret.isOk()) ALOGE("Call to getUsbSpeedCb failed %s", ret.description().c_str()); + } + + return Void(); +} + +V1_0::Status UsbGadget::tearDownGadget() { + if (resetGadget() != V1_0::Status::SUCCESS) return V1_0::Status::ERROR; + + if (monitorFfs.isMonitorRunning()) { + monitorFfs.reset(); + } else { + ALOGI("mMonitor not running"); + } + return V1_0::Status::SUCCESS; +} + +Return UsbGadget::reset() { + if (!WriteStringToFile("none", PULLUP_PATH)) { + ALOGI("Gadget cannot be pulled down"); + return Status::ERROR; + } + + usleep(kDisconnectWaitUs); + + if (!WriteStringToFile(kGadgetName, PULLUP_PATH)) { + ALOGI("Gadget cannot be pulled up"); + return Status::ERROR; + } + + return Status::SUCCESS; +} + +static V1_0::Status validateAndSetVidPid(uint64_t functions) { + V1_0::Status ret = V1_0::Status::SUCCESS; + + switch (functions) { + case static_cast(V1_2::GadgetFunction::MTP): + ret = setVidPid("0x18d1", "0x4ee1"); + break; + case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::MTP: + ret = setVidPid("0x18d1", "0x4ee2"); + break; + case static_cast(V1_2::GadgetFunction::RNDIS): + ret = setVidPid("0x18d1", "0x4ee3"); + break; + case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::RNDIS: + ret = setVidPid("0x18d1", "0x4ee4"); + break; + case static_cast(V1_2::GadgetFunction::PTP): + ret = setVidPid("0x18d1", "0x4ee5"); + break; + case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::PTP: + ret = setVidPid("0x18d1", "0x4ee6"); + break; + case static_cast(V1_2::GadgetFunction::ADB): + ret = setVidPid("0x18d1", "0x4ee7"); + break; + case static_cast(V1_2::GadgetFunction::MIDI): + ret = setVidPid("0x18d1", "0x4ee8"); + break; + case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::MIDI: + ret = setVidPid("0x18d1", "0x4ee9"); + break; + case static_cast(V1_2::GadgetFunction::NCM): + ret = setVidPid("0x18d1", "0x4eeb"); + break; + case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::NCM: + ret = setVidPid("0x18d1", "0x4eec"); + break; + case static_cast(V1_2::GadgetFunction::ACCESSORY): + ret = setVidPid("0x18d1", "0x2d00"); + break; + case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::ACCESSORY: + ret = setVidPid("0x18d1", "0x2d01"); + break; + case static_cast(V1_2::GadgetFunction::AUDIO_SOURCE): + ret = setVidPid("0x18d1", "0x2d02"); + break; + case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::AUDIO_SOURCE: + ret = setVidPid("0x18d1", "0x2d03"); + break; + case V1_2::GadgetFunction::ACCESSORY | V1_2::GadgetFunction::AUDIO_SOURCE: + ret = setVidPid("0x18d1", "0x2d04"); + break; + case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::ACCESSORY | + V1_2::GadgetFunction::AUDIO_SOURCE: + ret = setVidPid("0x18d1", "0x2d05"); + break; + default: + ALOGE("Combination not supported"); + ret = V1_0::Status::CONFIGURATION_NOT_SUPPORTED; + } + return ret; +} + +V1_0::Status UsbGadget::setupFunctions(uint64_t functions, + const sp& callback, + uint64_t timeout) { + bool ffsEnabled = false; + int i = 0; + + if (addGenericAndroidFunctions(&monitorFfs, functions, &ffsEnabled, &i) != + V1_0::Status::SUCCESS) + return V1_0::Status::ERROR; + + if ((functions & V1_2::GadgetFunction::ADB) != 0) { + ffsEnabled = true; + if (addAdb(&monitorFfs, &i) != V1_0::Status::SUCCESS) return V1_0::Status::ERROR; + } + + // Pull up the gadget right away when there are no ffs functions. + if (!ffsEnabled) { + if (!WriteStringToFile(kGadgetName, PULLUP_PATH)) return V1_0::Status::ERROR; + mCurrentUsbFunctionsApplied = true; + if (callback) callback->setCurrentUsbFunctionsCb(functions, V1_0::Status::SUCCESS); + return V1_0::Status::SUCCESS; + } + + monitorFfs.registerFunctionsAppliedCallback(¤tFunctionsAppliedCallback, this); + // Monitors the ffs paths to pull up the gadget when descriptors are written. + // Also takes of the pulling up the gadget again if the userspace process + // dies and restarts. + monitorFfs.startMonitor(); + + if (kDebug) ALOGI("Mainthread in Cv"); + + if (callback) { + bool pullup = monitorFfs.waitForPullUp(timeout); + Return ret = callback->setCurrentUsbFunctionsCb( + functions, pullup ? V1_0::Status::SUCCESS : V1_0::Status::ERROR); + if (!ret.isOk()) ALOGE("setCurrentUsbFunctionsCb error %s", ret.description().c_str()); + } + + return V1_0::Status::SUCCESS; +} + +Return UsbGadget::setCurrentUsbFunctions(uint64_t functions, + const sp& callback, + uint64_t timeout) { + std::unique_lock lk(mLockSetCurrentFunction); + + mCurrentUsbFunctions = functions; + mCurrentUsbFunctionsApplied = false; + + // Unlink the gadget and stop the monitor if running. + V1_0::Status status = tearDownGadget(); + if (status != V1_0::Status::SUCCESS) { + goto error; + } + + ALOGI("Returned from tearDown gadget"); + + // Leave the gadget pulled down to give time for the host to sense disconnect. + usleep(kDisconnectWaitUs); + + if (functions == static_cast(V1_2::GadgetFunction::NONE)) { + if (callback == NULL) return Void(); + Return ret = callback->setCurrentUsbFunctionsCb(functions, V1_0::Status::SUCCESS); + if (!ret.isOk()) + ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.description().c_str()); + return Void(); + } + + status = validateAndSetVidPid(functions); + + if (status != V1_0::Status::SUCCESS) { + goto error; + } + + status = setupFunctions(functions, callback, timeout); + if (status != V1_0::Status::SUCCESS) { + goto error; + } + + ALOGI("Usb Gadget setcurrent functions called successfully"); + return Void(); + +error: + ALOGI("Usb Gadget setcurrent functions failed"); + if (callback == NULL) return Void(); + Return ret = callback->setCurrentUsbFunctionsCb(functions, status); + if (!ret.isOk()) + ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.description().c_str()); + return Void(); +} +} // namespace implementation +} // namespace V1_2 +} // namespace gadget +} // namespace usb +} // namespace hardware +} // namespace android diff --git a/usb/UsbGadget.h b/usb/UsbGadget.h new file mode 100644 index 0000000..83fb696 --- /dev/null +++ b/usb/UsbGadget.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * Copyright (C) 2023 KonstaKANG + * + * 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. + */ + +#ifndef ANDROID_HARDWARE_USB_GADGET_V1_2_USBGADGET_H +#define ANDROID_HARDWARE_USB_GADGET_V1_2_USBGADGET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace usb { +namespace gadget { +namespace V1_2 { +namespace implementation { + +using ::android::sp; +using ::android::base::GetProperty; +using ::android::base::ReadFileToString; +using ::android::base::SetProperty; +using ::android::base::Trim; +using ::android::base::unique_fd; +using ::android::base::WriteStringToFile; +using ::android::hardware::hidl_array; +using ::android::hardware::hidl_memory; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::usb::gadget::addAdb; +using ::android::hardware::usb::gadget::addEpollFd; +using ::android::hardware::usb::gadget::getVendorFunctions; +using ::android::hardware::usb::gadget::kDebug; +using ::android::hardware::usb::gadget::kDisconnectWaitUs; +using ::android::hardware::usb::gadget::linkFunction; +using ::android::hardware::usb::gadget::MonitorFfs; +using ::android::hardware::usb::gadget::resetGadget; +using ::android::hardware::usb::gadget::setVidPid; +using ::android::hardware::usb::gadget::unlinkFunctions; +using ::std::string; + +constexpr char kGadgetName[] = "fe980000.usb"; +static MonitorFfs monitorFfs(kGadgetName); + +#define UDC_PATH "/sys/class/udc/fe980000.usb/" +#define SPEED_PATH UDC_PATH "current_speed" + +struct UsbGadget : public IUsbGadget { + UsbGadget(); + + // Makes sure that only one request is processed at a time. + std::mutex mLockSetCurrentFunction; + uint64_t mCurrentUsbFunctions; + bool mCurrentUsbFunctionsApplied; + UsbSpeed mUsbSpeed; + + Return setCurrentUsbFunctions(uint64_t functions, + const sp& callback, + uint64_t timeout) override; + + Return getCurrentUsbFunctions(const sp& callback) override; + + Return reset() override; + + Return getUsbSpeed(const sp& callback) override; + + private: + V1_0::Status tearDownGadget(); + V1_0::Status setupFunctions(uint64_t functions, const sp& callback, + uint64_t timeout); +}; + +} // namespace implementation +} // namespace V1_2 +} // namespace gadget +} // namespace usb +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_USB_V1_2_USBGADGET_H diff --git a/usb/android.hardware.usb.gadget@1.2-service.rpi.rc b/usb/android.hardware.usb.gadget@1.2-service.rpi.rc new file mode 100644 index 0000000..ee149c2 --- /dev/null +++ b/usb/android.hardware.usb.gadget@1.2-service.rpi.rc @@ -0,0 +1,7 @@ +service vendor.usb-gadget-hal-1-2 /vendor/bin/hw/android.hardware.usb.gadget@1.2-service.rpi + interface android.hardware.usb.gadget@1.0::IUsbGadget default + interface android.hardware.usb.gadget@1.1::IUsbGadget default + interface android.hardware.usb.gadget@1.2::IUsbGadget default + class hal + user system + group system shell mtp diff --git a/usb/android.hardware.usb.gadget@1.2-service.rpi.xml b/usb/android.hardware.usb.gadget@1.2-service.rpi.xml new file mode 100644 index 0000000..8557f6f --- /dev/null +++ b/usb/android.hardware.usb.gadget@1.2-service.rpi.xml @@ -0,0 +1,11 @@ + + + android.hardware.usb.gadget + hwbinder + 1.2 + + IUsbGadget + default + + + diff --git a/usb/service.cpp b/usb/service.cpp new file mode 100644 index 0000000..aa7d5e9 --- /dev/null +++ b/usb/service.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * Copyright (C) 2023 KonstaKANG + * + * 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.gadget@1.2-service.rpi" + +#include +#include "UsbGadget.h" + +using android::sp; + +// libhwbinder: +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; + +// Generated HIDL files +using android::hardware::usb::gadget::V1_2::IUsbGadget; +using android::hardware::usb::gadget::V1_2::implementation::UsbGadget; + +using android::OK; +using android::status_t; + +int main() { + configureRpcThreadpool(1, true /*callerWillJoin*/); + + android::sp service = new UsbGadget(); + + status_t status = service->registerAsService(); + + if (status != OK) { + ALOGE("Cannot register USB Gadget HAL service"); + return 1; + } + + ALOGI("USB Gadget HAL Ready."); + joinRpcThreadpool(); + // Under noraml cases, execution will not reach this line. + ALOGI("USB Gadget HAL failed to join thread pool."); + return 1; +}