diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-09-07 23:03:14 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-09-07 23:03:14 +0000 |
commit | 073b5a9af392ba1687e364dd85c32c6a01036438 (patch) | |
tree | 07be8e38a6457b70cf6b4e5dd6a8683a80a50400 | |
parent | b347307855de228d7929018f4c72e6024096309f (diff) | |
parent | 969c01c3f2fe7ded6976ecaf94f09640d93cf977 (diff) | |
download | zuma-073b5a9af392ba1687e364dd85c32c6a01036438.tar.gz |
Snap for 10776546 from 969c01c3f2fe7ded6976ecaf94f09640d93cf977 to udc-qpr1-release
Change-Id: Ic797d41bc019e530f4b76f66cbea62afd5bc4eaa
-rw-r--r-- | conf/init.zuma.usb.rc | 159 | ||||
-rw-r--r-- | default-permissions.xml | 5 | ||||
-rw-r--r-- | device.mk | 3 | ||||
-rw-r--r-- | overlay/frameworks/base/core/res/res/values/config.xml | 13 | ||||
-rw-r--r-- | usb/gadget/UsbGadget.cpp | 27 | ||||
-rw-r--r-- | usb/usb/Usb.cpp | 195 | ||||
-rw-r--r-- | usb/usb/Usb.h | 16 |
7 files changed, 393 insertions, 25 deletions
diff --git a/conf/init.zuma.usb.rc b/conf/init.zuma.usb.rc index 136382f..8ff9743 100644 --- a/conf/init.zuma.usb.rc +++ b/conf/init.zuma.usb.rc @@ -71,6 +71,72 @@ on early-boot # acm function for uwb mkdir /config/usb_gadget/g1/functions/acm.uwb0 + # uvc function + mkdir /config/usb_gadget/g1/functions/uvc.0 + write /config/usb_gadget/g1/functions/uvc.0/function_name "Android Webcam" + write /config/usb_gadget/g1/functions/uvc.0/streaming_maxpacket 3072 + # write /config/usb_gadget/g1/functions/uvc.0/streaming_maxburst 5 + # write /config/usb_gadget/g1/functions/uvc.0/streaming_interval 2 + # setup control params + mkdir /config/usb_gadget/g1/functions/uvc.0/control/header/h + symlink /config/usb_gadget/g1/functions/uvc.0/control/header/h /config/usb_gadget/g1/functions/uvc.0/control/class/fs/h + symlink /config/usb_gadget/g1/functions/uvc.0/control/header/h /config/usb_gadget/g1/functions/uvc.0/control/class/ss/h + # advertise mjpeg streams + mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m + # advertise 720p resolution for webcam encoded as mjpeg + mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p + write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/wHeight 720 + write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/wWidth 1280 + write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/dwMaxVideoFrameBufferSize 1843200 + write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/dwDefaultFrameInterval 333333 + write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/dwFrameInterval "166666 +333333 +416666 +666666" + # advertise 1080p resolution for webcam encoded as mjpeg + mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p + write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/wHeight 1080 + write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/wWidth 1920 + write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/dwMaxVideoFrameBufferSize 4147200 + write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/dwDefaultFrameInterval 333333 + write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/dwFrameInterval "166666 +333333 +416666 +666666" + # TODO: Add uncompressed streams + # setup streaming params + mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/header/h + symlink /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m /config/usb_gadget/g1/functions/uvc.0/streaming/header/h/m + symlink /config/usb_gadget/g1/functions/uvc.0/streaming/header/h /config/usb_gadget/g1/functions/uvc.0/streaming/class/fs/h + symlink /config/usb_gadget/g1/functions/uvc.0/streaming/header/h /config/usb_gadget/g1/functions/uvc.0/streaming/class/hs/h + symlink /config/usb_gadget/g1/functions/uvc.0/streaming/header/h /config/usb_gadget/g1/functions/uvc.0/streaming/class/ss/h + # remove write permissions for 'others' + chmod 664 /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/dwFrameInterval + chmod 664 /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/dwDefaultFrameInterval + chmod 664 /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/dwMaxVideoFrameBufferSize + chmod 664 /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/dwMaxBitRate + chmod 664 /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/dwMinBitRate + chmod 664 /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/wHeight + chmod 664 /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/wWidth + chmod 664 /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/bmCapabilities + chmod 664 /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/dwFrameInterval + chmod 664 /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/dwDefaultFrameInterval + chmod 664 /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/dwMaxVideoFrameBufferSize + chmod 664 /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/dwMaxBitRate + chmod 664 /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/dwMinBitRate + chmod 664 /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/wHeight + chmod 664 /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/wWidth + chmod 664 /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/bmCapabilities + chmod 664 /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/bmaControls + chmod 664 /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/bDefaultFrameIndex + chmod 664 /config/usb_gadget/g1/functions/uvc.0/control/terminal/output/default/bSourceID + chmod 664 /config/usb_gadget/g1/functions/uvc.0/control/header/h/dwClockFrequency + chmod 664 /config/usb_gadget/g1/functions/uvc.0/control/header/h/bcdUVC + chmod 664 /config/usb_gadget/g1/functions/uvc.0/function_name + chmod 664 /config/usb_gadget/g1/functions/uvc.0/streaming_maxburst + chmod 664 /config/usb_gadget/g1/functions/uvc.0/streaming_maxpacket + chmod 664 /config/usb_gadget/g1/functions/uvc.0/streaming_interval + # chown file/folder permission chown system system /config/usb_gadget/ chown system system /config/usb_gadget/g1 @@ -135,6 +201,99 @@ on early-boot 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/functions/uvc.0/ + chown system system /config/usb_gadget/g1/functions/uvc.0/control + chown system system /config/usb_gadget/g1/functions/uvc.0/control/bInterfaceNumber + chown system system /config/usb_gadget/g1/functions/uvc.0/control/class + chown system system /config/usb_gadget/g1/functions/uvc.0/control/class/fs + chown system system /config/usb_gadget/g1/functions/uvc.0/control/class/fs/h + chown system system /config/usb_gadget/g1/functions/uvc.0/control/class/ss + chown system system /config/usb_gadget/g1/functions/uvc.0/control/class/ss/h + chown system system /config/usb_gadget/g1/functions/uvc.0/control/header + chown system system /config/usb_gadget/g1/functions/uvc.0/control/header/h + chown system system /config/usb_gadget/g1/functions/uvc.0/control/header/h/bcdUVC + chown system system /config/usb_gadget/g1/functions/uvc.0/control/header/h/dwClockFrequency + chown system system /config/usb_gadget/g1/functions/uvc.0/control/processing + chown system system /config/usb_gadget/g1/functions/uvc.0/control/processing/default + chown system system /config/usb_gadget/g1/functions/uvc.0/control/processing/default/bmControls + chown system system /config/usb_gadget/g1/functions/uvc.0/control/processing/default/bSourceID + chown system system /config/usb_gadget/g1/functions/uvc.0/control/processing/default/bUnitID + chown system system /config/usb_gadget/g1/functions/uvc.0/control/processing/default/iProcessing + chown system system /config/usb_gadget/g1/functions/uvc.0/control/processing/default/wMaxMultiplier + chown system system /config/usb_gadget/g1/functions/uvc.0/control/terminal + chown system system /config/usb_gadget/g1/functions/uvc.0/control/terminal/camera + chown system system /config/usb_gadget/g1/functions/uvc.0/control/terminal/camera/default + chown system system /config/usb_gadget/g1/functions/uvc.0/control/terminal/camera/default/bAssocTerminal + chown system system /config/usb_gadget/g1/functions/uvc.0/control/terminal/camera/default/bmControls + chown system system /config/usb_gadget/g1/functions/uvc.0/control/terminal/camera/default/bTerminalID + chown system system /config/usb_gadget/g1/functions/uvc.0/control/terminal/camera/default/iTerminal + chown system system /config/usb_gadget/g1/functions/uvc.0/control/terminal/camera/default/wObjectiveFocalLengthMax + chown system system /config/usb_gadget/g1/functions/uvc.0/control/terminal/camera/default/wObjectiveFocalLengthMin + chown system system /config/usb_gadget/g1/functions/uvc.0/control/terminal/camera/default/wOcularFocalLength + chown system system /config/usb_gadget/g1/functions/uvc.0/control/terminal/camera/default/wTerminalType + chown system system /config/usb_gadget/g1/functions/uvc.0/control/terminal/output + chown system system /config/usb_gadget/g1/functions/uvc.0/control/terminal/output/default + chown system system /config/usb_gadget/g1/functions/uvc.0/control/terminal/output/default/bAssocTerminal + chown system system /config/usb_gadget/g1/functions/uvc.0/control/terminal/output/default/bSourceID + chown system system /config/usb_gadget/g1/functions/uvc.0/control/terminal/output/default/bTerminalID + chown system system /config/usb_gadget/g1/functions/uvc.0/control/terminal/output/default/iTerminal + chown system system /config/usb_gadget/g1/functions/uvc.0/control/terminal/output/default/wTerminalType + chown system system /config/usb_gadget/g1/functions/uvc.0/function_name + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming_interval + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming_maxburst + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming_maxpacket + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/bInterfaceNumber + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/class + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/class/fs + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/class/fs/h + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/class/hs + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/class/hs/h + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/class/ss + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/class/ss/h + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/color_matching + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/color_matching/default + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/color_matching/default/bColorPrimaries + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/color_matching/default/bMatrixCoefficients + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/color_matching/default/bTransferCharacteristics + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/header + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/header/h + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/header/h/bmInfo + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/header/h/bStillCaptureMethod + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/header/h/bTerminalLink + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/header/h/bTriggerSupport + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/header/h/bTriggerUsage + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/header/h/m + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/bFrameIndex + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/bmCapabilities + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/dwDefaultFrameInterval + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/dwFrameInterval + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/dwMaxBitRate + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/dwMaxVideoFrameBufferSize + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/dwMinBitRate + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/wHeight + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/wWidth + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/bFrameIndex + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/bmCapabilities + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/dwDefaultFrameInterval + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/dwFrameInterval + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/dwMaxBitRate + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/dwMaxVideoFrameBufferSize + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/dwMinBitRate + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/wHeight + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/wWidth + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/bAspectRatioX + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/bAspectRatioY + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/bDefaultFrameIndex + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/bFormatIndex + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/bmaControls + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/bmFlags + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/bmInterlaceFlags + chown system system /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed 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 diff --git a/default-permissions.xml b/default-permissions.xml index 0918a74..1731dae 100644 --- a/default-permissions.xml +++ b/default-permissions.xml @@ -51,6 +51,11 @@ <permission name="android.permission.BLUETOOTH_CONNECT" fixed="false"/> </exception> + <exception package="com.google.android.apps.camera.services"> + <!-- Camera --> + <permission name="android.permission.CAMERA" fixed="false"/> + </exception> + <exception package="com.google.android.apps.cbrsnetworkmonitor"> <!-- Location access to create CBRS geofences--> <permission name="android.permission.ACCESS_FINE_LOCATION" fixed="true"/> @@ -692,9 +692,6 @@ PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.surface_flinger.use_color_management=tr PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.surface_flinger.protected_contents=true PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.surface_flinger.display_update_imminent_timeout_ms=50 -# Enhance VRR detection -PRODUCT_DEFAULT_PROPERTY_OVERRIDES += debug.sf.enable_small_dirty_detection=true - # force to blend in P3 mode PRODUCT_PROPERTY_OVERRIDES += \ persist.sys.sf.native_mode=2 \ diff --git a/overlay/frameworks/base/core/res/res/values/config.xml b/overlay/frameworks/base/core/res/res/values/config.xml index 4ade200..73ba083 100644 --- a/overlay/frameworks/base/core/res/res/values/config.xml +++ b/overlay/frameworks/base/core/res/res/values/config.xml @@ -287,17 +287,4 @@ <!-- Enable variable refresh rate when typing. --> <bool name="config_variableRefreshRateTypingSupported">true</bool> - - <!-- The list of packages to automatically opt in of fresh rate suppressing by small area - detection. Format of this array should be packageName:threshold and threshold value should - be between 0 to 1--> - <string-array name="config_smallAreaDetectionAllowlist" translatable="false"> - <!-- Add packages:threshold here --> - <item>com.google.android.youtube:0.07</item> - <item>com.spotify.music:0.05</item> - <item>com.reddit.frontpage:0.07</item> - <item>com.zhiliaoapp.musically:0.07</item> - <item>com.bilibili.app.in:0.07</item> - <item>com.twitter.android:0.07</item> - </string-array> </resources> diff --git a/usb/gadget/UsbGadget.cpp b/usb/gadget/UsbGadget.cpp index 70bd801..c96c6c4 100644 --- a/usb/gadget/UsbGadget.cpp +++ b/usb/gadget/UsbGadget.cpp @@ -26,6 +26,8 @@ #include <sys/types.h> #include <unistd.h> +#include <android-base/properties.h> + #include <aidl/android/frameworks/stats/IStats.h> namespace aidl { @@ -34,6 +36,9 @@ namespace hardware { namespace usb { namespace gadget { +using ::android::base::GetBoolProperty; +using ::android::hardware::google::pixel::usb::kUvcEnabled; + string enabledPath; constexpr char kHsi2cPath[] = "/sys/devices/platform/10cb0000.hsi2c"; constexpr char kI2CPath[] = "/sys/devices/platform/10cb0000.hsi2c/i2c-"; @@ -302,6 +307,28 @@ static Status validateAndSetVidPid(uint64_t functions) { ret = Status(setVidPid("0x18d1", "0x4eec")); } break; + case GadgetFunction::UVC: + if (!(vendorFunctions == "user" || vendorFunctions == "")) { + ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str()); + ret = Status::CONFIGURATION_NOT_SUPPORTED; + } else if (!GetBoolProperty(kUvcEnabled, false)) { + ALOGE("UVC function not enabled by config"); + ret = Status::CONFIGURATION_NOT_SUPPORTED; + } else { + ret = Status(setVidPid("0x18d1", "0x4eed")); + } + break; + case GadgetFunction::ADB | GadgetFunction::UVC: + if (!(vendorFunctions == "user" || vendorFunctions == "")) { + ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str()); + ret = Status::CONFIGURATION_NOT_SUPPORTED; + } else if (!GetBoolProperty(kUvcEnabled, false)) { + ALOGE("UVC function not enabled by config"); + ret = Status::CONFIGURATION_NOT_SUPPORTED; + } else { + ret = Status(setVidPid("0x18d1", "0x4eee")); + } + break; default: ALOGE("Combination not supported"); ret = Status::CONFIGURATION_NOT_SUPPORTED; diff --git a/usb/usb/Usb.cpp b/usb/usb/Usb.cpp index 7407077..5594bff 100644 --- a/usb/usb/Usb.cpp +++ b/usb/usb/Usb.cpp @@ -35,6 +35,7 @@ #include <cutils/uevent.h> #include <sys/epoll.h> #include <sys/eventfd.h> +#include <sys/timerfd.h> #include <utils/Errors.h> #include <utils/StrongPointer.h> @@ -47,6 +48,7 @@ using aidl::android::frameworks::stats::IStats; using android::base::GetProperty; using android::base::Join; +using android::base::ParseUint; using android::base::Tokenize; using android::base::Trim; using android::hardware::google::pixel::getStatsService; @@ -91,6 +93,8 @@ constexpr char kIrqHpdCounPath[] = "-0025/irq_hpd_count"; constexpr int kSamplingIntervalSec = 5; void queryVersionHelper(android::hardware::usb::Usb *usb, std::vector<PortStatus> *currentPortStatus); +AltModeData::DisplayPortAltModeData constructAltModeData(string hpd, string pin_assignment, + string link_status, string vdo); ScopedAStatus Usb::enableUsbData(const string& in_portName, bool in_enable, int64_t in_transactionId) { @@ -482,6 +486,11 @@ Usb::Usb() ALOGE("mDisplayPortEventPipe eventfd failed: %s", strerror(errno)); abort(); } + mDisplayPortDebounceTimer = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); + if (mDisplayPortDebounceTimer == -1) { + ALOGE("mDisplayPortDebounceTimer timerfd failed: %s", strerror(errno)); + abort(); + } } ScopedAStatus Usb::switchRole(const string& in_portName, const PortRole& in_role, @@ -821,6 +830,118 @@ done: return Status::ERROR; } +/* DisplayPort Helper Functions Start */ + +DisplayPortAltModePinAssignment parsePinAssignmentHelper(string pinAssignments) { + size_t pos = pinAssignments.find("["); + if (pos != string::npos) { + pinAssignments = pinAssignments.substr(pos+1, 1); + if (pinAssignments == "C") { + return DisplayPortAltModePinAssignment::C; + } else if (pinAssignments == "D") { + return DisplayPortAltModePinAssignment::D; + } else if (pinAssignments == "E") { + return DisplayPortAltModePinAssignment::E; + } + } + return DisplayPortAltModePinAssignment::NONE; +} + +LinkTrainingStatus parseLinkTrainingStatusHelper(string linkTrainingStatus) { + linkTrainingStatus = Trim(linkTrainingStatus); + if (linkTrainingStatus == LINK_TRAINING_STATUS_SUCCESS) { + return LinkTrainingStatus::SUCCESS; + } else if (linkTrainingStatus == LINK_TRAINING_STATUS_FAILURE || \ + linkTrainingStatus == LINK_TRAINING_STATUS_FAILURE_SINK) { + return LinkTrainingStatus::FAILURE; + } + return LinkTrainingStatus::UNKNOWN; +} + +bool isDisplayPortPlugHelper(string vdoString) { + unsigned long vdo; + unsigned long receptacleFlag = 1 << DISPLAYPORT_CAPABILITIES_RECEPTACLE_BIT; + + vdoString = Trim(vdoString); + if (ParseUint(vdoString.c_str(), &vdo)) { + /* We check to see if receptacleFlag is 0, meaning that the DP interface is presented on a + * USB-C plug. + */ + return !(vdo & receptacleFlag); + } else { + ALOGE("usbdp: isDisplayPortPlugHelper: errno:%d", errno); + } + + return false; +} + +AltModeData::DisplayPortAltModeData constructAltModeData(string hpd, string pin_assignment, + string link_status, string vdo) { + AltModeData::DisplayPortAltModeData dpData; + + // vdo + if (isDisplayPortPlugHelper(vdo)) { + dpData.cableStatus = DisplayPortAltModeStatus::CAPABLE; + } else { + dpData.partnerSinkStatus = DisplayPortAltModeStatus::CAPABLE; + } + + // hpd, status + if (!strncmp(hpd.c_str(), "1", strlen("1"))) { + dpData.hpd = true; + } + + // pin + dpData.pinAssignment = parsePinAssignmentHelper(pin_assignment); + + // link training + link_status = Trim(link_status); + dpData.linkTrainingStatus = parseLinkTrainingStatusHelper(link_status); + if (dpData.linkTrainingStatus == LinkTrainingStatus::SUCCESS) { + dpData.partnerSinkStatus = dpData.partnerSinkStatus == DisplayPortAltModeStatus::CAPABLE ? \ + DisplayPortAltModeStatus::ENABLED : DisplayPortAltModeStatus::UNKNOWN; + dpData.cableStatus = dpData.cableStatus == DisplayPortAltModeStatus::CAPABLE ? \ + DisplayPortAltModeStatus::ENABLED : DisplayPortAltModeStatus::UNKNOWN; + if (dpData.partnerSinkStatus == DisplayPortAltModeStatus::ENABLED) { + dpData.cableStatus = DisplayPortAltModeStatus::ENABLED; + } + } else if (dpData.linkTrainingStatus == LinkTrainingStatus::FAILURE && + dpData.partnerSinkStatus == DisplayPortAltModeStatus::CAPABLE) { + // 2.0 cable that fails EDID reports not capable, other link training failures assume + // 3.0 cable that fails in all other cases. + dpData.cableStatus = (link_status == LINK_TRAINING_STATUS_FAILURE_SINK) ? \ + DisplayPortAltModeStatus::NOT_CAPABLE : DisplayPortAltModeStatus::CAPABLE; + } + + return dpData; +} + +/* DisplayPort Helper Functions End */ + +// Only care about first port which must support DisplayPortAltMode +Status queryDisplayPortStatus(android::hardware::usb::Usb *usb, + std::vector<PortStatus> *currentPortStatus) { + string hpd, pinAssign, linkStatus, vdo; + string path; + AltModeData::DisplayPortAltModeData dpData; + + if (usb->getDisplayPortUsbPathHelper(&path) == Status::ERROR) { + (*currentPortStatus)[0].supportedAltModes.push_back(dpData); + return Status::SUCCESS; + } + + usb->readDisplayPortAttribute("hpd", path, &hpd); + usb->readDisplayPortAttribute("pin_assignment", path, &pinAssign); + usb->readDisplayPortAttribute("vdo", path, &vdo); + usb->readDisplayPortAttribute("link_status", path, &linkStatus); + + // Set DisplayPortAltModeInfo + dpData = constructAltModeData(hpd, pinAssign, linkStatus, vdo); + (*currentPortStatus)[0].supportedAltModes.push_back(dpData); + + return Status::SUCCESS; +} + void queryVersionHelper(android::hardware::usb::Usb *usb, std::vector<PortStatus> *currentPortStatus) { Status status; @@ -839,7 +960,7 @@ void queryVersionHelper(android::hardware::usb::Usb *usb, usb->setupDisplayPortPoll(); } pthread_mutex_unlock(&usb->mDisplayPortLock); - + queryDisplayPortStatus(usb, currentPortStatus); if (usb->mCallback != NULL) { ScopedAStatus ret = usb->mCallback->notifyPortStatusChange(*currentPortStatus, status); @@ -1158,6 +1279,30 @@ Status Usb::getDisplayPortUsbPathHelper(string *path) { return result; } +Status Usb::readDisplayPortAttribute(string attribute, string usb_path, string* value) { + string attrPath; + + if (!strncmp(attribute.c_str(), "hpd", strlen("hpd")) || + !strncmp(attribute.c_str(), "pin_assignment", strlen("pin_assignment"))) { + attrPath = usb_path + attribute; + } else if (!strncmp(attribute.c_str(), "link_status", strlen("link_status"))) { + attrPath = string(kDisplayPortDrmPath) + "link_status"; + } else if (!strncmp(attribute.c_str(), "vdo", strlen("vdo"))) { + attrPath = usb_path + "/../vdo"; + } else { + goto error; + } + + // Read Attribute + if(ReadFileToString(attrPath.c_str(), value)) { + return Status::SUCCESS; + } + +error: + ALOGE("usbdp: Failed to read Type-C attribute %s", attribute.c_str()); + return Status::ERROR; +} + Status Usb::writeDisplayPortAttributeOverride(string attribute, string value) { string attrDrmPath; @@ -1255,15 +1400,28 @@ static int displayPortPollOpenFileHelper(const char *file, int flags) { return fd; } +static int armTimerFdHelper(int fd, int ms) { + struct itimerspec ts; + + ts.it_interval.tv_sec = 0; + ts.it_interval.tv_nsec = 0; + ts.it_value.tv_sec = ms / 1000; + ts.it_value.tv_nsec = (ms % 1000) * 1000000; + + return timerfd_settime(fd, 0, &ts, NULL); +} + void *displayPortPollWork(void *param) { int epoll_fd; - struct epoll_event ev_hpd, ev_pin, ev_orientation, ev_eventfd, ev_link; + struct epoll_event ev_hpd, ev_pin, ev_orientation, ev_eventfd, ev_link, ev_debounce; int nevents = 0; - int hpd_fd, pin_fd, orientation_fd, link_fd; + int hpd_fd, pin_fd, orientation_fd, link_training_status_fd; int file_flags = O_RDONLY; int epoll_flags; bool orientationSet = false; bool pinSet = false; + unsigned long res; + int ret = 0; string displayPortUsbPath, irqHpdCountPath, hpdPath, pinAssignmentPath, orientationPath; string tcpcI2cBus, linkPath; ::aidl::android::hardware::usb::Usb *usb = (::aidl::android::hardware::usb::Usb *)param; @@ -1302,8 +1460,8 @@ void *displayPortPollWork(void *param) { == -1){ goto orientation_fd_error; } - if ((link_fd = displayPortPollOpenFileHelper(linkPath.c_str(), file_flags)) == -1){ - goto link_fd_error; + if ((link_training_status_fd = displayPortPollOpenFileHelper(linkPath.c_str(), file_flags)) == -1){ + goto link_training_status_fd_error; } // Set epoll_event events and flags @@ -1313,11 +1471,13 @@ void *displayPortPollWork(void *param) { ev_orientation.events = epoll_flags; ev_eventfd.events = epoll_flags; ev_link.events = epoll_flags; + ev_debounce.events = epoll_flags; ev_hpd.data.fd = hpd_fd; ev_pin.data.fd = pin_fd; ev_orientation.data.fd = orientation_fd; ev_eventfd.data.fd = usb->mDisplayPortEventPipe; - ev_link.data.fd = link_fd; + ev_link.data.fd = link_training_status_fd; + ev_debounce.data.fd = usb->mDisplayPortDebounceTimer; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, hpd_fd, &ev_hpd) == -1) { ALOGE("usbdp: worker: epoll_ctl failed to add hpd; errno=%d", errno); @@ -1331,10 +1491,14 @@ void *displayPortPollWork(void *param) { ALOGE("usbdp: worker: epoll_ctl failed to add orientation; errno=%d", errno); goto error; } - if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, link_fd, &ev_link) == -1) { + if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, link_training_status_fd, &ev_link) == -1) { ALOGE("usbdp: worker: epoll_ctl failed to add link status; errno=%d", errno); goto error; } + if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, usb->mDisplayPortDebounceTimer, &ev_debounce) == -1) { + ALOGE("usbdp: worker: epoll_ctl failed to add debounce; errno=%d", errno); + goto error; + } if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, usb->mDisplayPortEventPipe, &ev_eventfd) == -1) { ALOGE("usbdp: worker: epoll_ctl failed to add orientation; errno=%d", errno); goto error; @@ -1367,16 +1531,28 @@ void *displayPortPollWork(void *param) { } } usb->writeDisplayPortAttribute("hpd", hpdPath); + armTimerFdHelper(usb->mDisplayPortDebounceTimer, DISPLAYPORT_STATUS_DEBOUNCE_MS); } else if (events[n].data.fd == pin_fd) { if (usb->writeDisplayPortAttribute("pin_assignment", pinAssignmentPath) == Status::SUCCESS) { pinSet = true; + armTimerFdHelper(usb->mDisplayPortDebounceTimer, DISPLAYPORT_STATUS_DEBOUNCE_MS); } } else if (events[n].data.fd == orientation_fd) { if (usb->writeDisplayPortAttribute("orientation", orientationPath) == Status::SUCCESS) { orientationSet = true; + armTimerFdHelper(usb->mDisplayPortDebounceTimer, DISPLAYPORT_STATUS_DEBOUNCE_MS); } + } else if (events[n].data.fd == link_training_status_fd) { + armTimerFdHelper(usb->mDisplayPortDebounceTimer, DISPLAYPORT_STATUS_DEBOUNCE_MS); + } else if (events[n].data.fd == usb->mDisplayPortDebounceTimer) { + std::vector<PortStatus> currentPortStatus; + ret = read(usb->mDisplayPortDebounceTimer, &res, sizeof(res)); + ALOGI("usbdp: dp debounce triggered, val:%lu ret:%d", res, ret); + if (ret < 0) + ALOGE("usbdp: debounce read errno:%d", errno); + queryVersionHelper(usb, ¤tPortStatus); } else if (events[n].data.fd == usb->mDisplayPortEventPipe) { uint64_t flag = 0; if (!read(usb->mDisplayPortEventPipe, &flag, sizeof(flag))) { @@ -1398,14 +1574,15 @@ void *displayPortPollWork(void *param) { } error: - close(link_fd); -link_fd_error: + close(link_training_status_fd); +link_training_status_fd_error: close(orientation_fd); orientation_fd_error: close(pin_fd); pin_fd_error: close(hpd_fd); hpd_fd_error: + epoll_ctl(epoll_fd, EPOLL_CTL_DEL, usb->mDisplayPortDebounceTimer, &ev_debounce); epoll_ctl(epoll_fd, EPOLL_CTL_DEL, usb->mDisplayPortEventPipe, &ev_eventfd); close(epoll_fd); epoll_fd_error: diff --git a/usb/usb/Usb.h b/usb/usb/Usb.h index 892d769..1add68f 100644 --- a/usb/usb/Usb.h +++ b/usb/usb/Usb.h @@ -29,6 +29,8 @@ // Having a margin of ~3 secs for the directory and other related bookeeping // structures created and uvent fired. #define PORT_TYPE_TIMEOUT 8 +#define DISPLAYPORT_CAPABILITIES_RECEPTACLE_BIT 6 +#define DISPLAYPORT_STATUS_DEBOUNCE_MS 2000 namespace aidl { namespace android { @@ -57,6 +59,11 @@ constexpr char kGadgetName[] = "11210000.dwc3"; #define VBUS_PATH NEW_UDC_PATH "dwc3_exynos_otg_b_sess" #define USB_DATA_PATH NEW_UDC_PATH "usb_data_enabled" +#define LINK_TRAINING_STATUS_UNKNOWN "0" +#define LINK_TRAINING_STATUS_SUCCESS "1" +#define LINK_TRAINING_STATUS_FAILURE "2" +#define LINK_TRAINING_STATUS_FAILURE_SINK "3" + #define DISPLAYPORT_SHUTDOWN_CLEAR 0 #define DISPLAYPORT_SHUTDOWN_SET 1 #define DISPLAYPORT_IRQ_HPD_COUNT_CHECK 3 @@ -81,6 +88,7 @@ struct Usb : public BnUsb { ScopedAStatus resetUsbPort(const string& in_portName, int64_t in_transactionId) override; Status getDisplayPortUsbPathHelper(string *path); + Status readDisplayPortAttribute(string attribute, string usb_path, string* value); Status writeDisplayPortAttributeOverride(string attribute, string value); Status writeDisplayPortAttribute(string attribute, string usb_path); bool determineDisplayPortRetry(string linkPath, string hpdPath); @@ -121,6 +129,14 @@ struct Usb : public BnUsb { pthread_mutex_t mDisplayPortLock; // eventfd to signal DisplayPort thread int mDisplayPortEventPipe; + + /* + * eventfd to set DisplayPort framework update debounce timer. Debounce timer is necessary for + * 1) allowing enough time for each sysfs node needed to set HPD high in the drm to populate + * 2) preventing multiple IRQs that trigger link training failures from continuously + * sending notifications to the frameworks layer. + */ + int mDisplayPortDebounceTimer; private: pthread_t mPoll; pthread_t mDisplayPortPoll; |