summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-09-07 23:03:14 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-09-07 23:03:14 +0000
commit073b5a9af392ba1687e364dd85c32c6a01036438 (patch)
tree07be8e38a6457b70cf6b4e5dd6a8683a80a50400
parentb347307855de228d7929018f4c72e6024096309f (diff)
parent969c01c3f2fe7ded6976ecaf94f09640d93cf977 (diff)
downloadzuma-073b5a9af392ba1687e364dd85c32c6a01036438.tar.gz
Snap for 10776546 from 969c01c3f2fe7ded6976ecaf94f09640d93cf977 to udc-qpr1-release
Change-Id: Ic797d41bc019e530f4b76f66cbea62afd5bc4eaa
-rw-r--r--conf/init.zuma.usb.rc159
-rw-r--r--default-permissions.xml5
-rw-r--r--device.mk3
-rw-r--r--overlay/frameworks/base/core/res/res/values/config.xml13
-rw-r--r--usb/gadget/UsbGadget.cpp27
-rw-r--r--usb/usb/Usb.cpp195
-rw-r--r--usb/usb/Usb.h16
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"/>
diff --git a/device.mk b/device.mk
index cecff17..84e7aab 100644
--- a/device.mk
+++ b/device.mk
@@ -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, &currentPortStatus);
} 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;