Merge ccfa001e0b9897000bf9f84e40cf84a6260c8604 on remote branch
Change-Id: I50e919a08cb3dfb93d68b075376ab992b2c93150
diff --git a/etc/init.qcom.usb.rc b/etc/init.qcom.usb.rc
index ce1b1c4..012c6db 100644
--- a/etc/init.qcom.usb.rc
+++ b/etc/init.qcom.usb.rc
@@ -1807,45 +1807,119 @@
on property:vendor.usb.uvc.function.init=1
write /config/usb_gadget/g1/functions/uvc.0/streaming_maxpacket 3072
- write /config/usb_gadget/g1/functions/uvc.0/streaming_maxburst 1
+ write /config/usb_gadget/g1/functions/uvc.0/streaming_maxburst 10
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
mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u
mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/360p
- write /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/360p/dwFrameInterval "666666\n1000000\n5000000\n"
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/360p/dwFrameInterval 333333\n666666\n1000000\n5000000\n
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/360p/dwDefaultFrameInterval 333333
mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/720p
write /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/720p/wWidth 1280
write /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/720p/wHeight 720
write /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/720p/dwMinBitRate 29491200
write /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/720p/dwMaxBitRate 29491200
write /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/720p/dwMaxVideoFrameBufferSize 1843200
- write /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/720p/dwDefaultFrameInterval 5000000
- write /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/720p/dwFrameInterval "5000000\n"
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/720p/dwDefaultFrameInterval 333333
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/720p/dwFrameInterval 333333\n666666\n1000000\n5000000\n
+ mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/1080p
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/1080p/wWidth 1920
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/1080p/wHeight 1080
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/1080p/dwMinBitRate 66355200
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/1080p/dwMaxBitRate 995328000
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/1080p/dwMaxVideoFrameBufferSize 4147200
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/1080p/dwDefaultFrameInterval 333333
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/1080p/dwFrameInterval 333333\n666666\n1000000\n5000000\n
+ mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u1
+ mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u1/360p
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u1/360p/dwFrameInterval 333333\n666666\n1000000\n5000000\n
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u1/360p/dwDefaultFrameInterval 333333
+ mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1
+ mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/360p
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/360p/wWidth 640
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/360p/wHeight 360
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/360p/dwMinBitRate 18432000
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/360p/dwMaxBitRate 55296000
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/360p/dwMaxVideoFrameBufferSize 460800
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/360p/dwDefaultFrameInterval 333333
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/360p/dwFrameInterval 333333\n666666\n1000000\n5000000\n
+ mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/720p
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/720p/wWidth 1280
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/720p/wHeight 720
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/720p/dwMinBitRate 29491200
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/720p/dwMaxBitRate 29491200
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/720p/dwMaxVideoFrameBufferSize 1843200
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/720p/dwDefaultFrameInterval 333333
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/720p/dwFrameInterval 333333\n666666\n1000000\n5000000\n
+ mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/1080p
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/1080p/wWidth 1920
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/1080p/wHeight 1080
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/1080p/dwMinBitRate 66355200
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/1080p/dwMaxBitRate 995328000
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/1080p/dwMaxVideoFrameBufferSize 4147200
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/1080p/dwDefaultFrameInterval 333333
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/1080p/dwFrameInterval 333333\n666666\n1000000\n5000000\n
mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m
mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/360p
- write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/360p/dwFrameInterval "666666\n1000000\n5000000\n"
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/360p/wWidth 640
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/360p/wHeight 360
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/360p/dwMinBitRate 18432000
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/360p/dwMaxBitRate 55296000
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/360p/dwMaxVideoFrameBufferSize 460800
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/360p/dwDefaultFrameInterval 333333
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/360p/dwFrameInterval 333333\n666666\n1000000\n5000000\n
mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p
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/wHeight 720
write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/dwMinBitRate 29491200
write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/dwMaxBitRate 29491200
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 5000000
- write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/720p/dwFrameInterval "5000000\n"
+ 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 333333\n666666\n1000000\n5000000\n
+ mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p
+ 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/wHeight 1080
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/dwMinBitRate 66355200
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1080p/dwMaxBitRate 995328000
+ 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 333333\n666666\n1000000\n5000000\n
+ mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1440p
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1440p/wWidth 2560
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1440p/wHeight 1440
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1440p/dwMinBitRate 117964800
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1440p/dwMaxBitRate 1769472000
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/1440p/dwMaxVideoFrameBufferSize 7372800
+ 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/1440p/dwFrameInterval 333333\n666666\n1000000\n5000000\n
+ mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/2160p
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/2160p/wWidth 3840
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/2160p/wHeight 2160
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/2160p/dwMinBitRate 265420800
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/2160p/dwMaxBitRate 3981312000
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/2160p/dwMaxVideoFrameBufferSize 16588800
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/2160p/dwDefaultFrameInterval 333333
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/2160p/dwFrameInterval 333333\n666666\n1000000\n5000000\n
write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m/bmaControls 0x04
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1/bmaControls 0x04
mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/h264/h
- mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/h264/h/960p
- write /config/usb_gadget/g1/functions/uvc.0/streaming/h264/h/960p/wWidth 1920
- write /config/usb_gadget/g1/functions/uvc.0/streaming/h264/h/960p/wHeight 960
- write /config/usb_gadget/g1/functions/uvc.0/streaming/h264/h/960p/bLevelIDC 40
- write /config/usb_gadget/g1/functions/uvc.0/streaming/h264/h/960p/dwFrameInterval "333667\n"
- mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/h264/h/1920p
- write /config/usb_gadget/g1/functions/uvc.0/streaming/h264/h/1920p/dwFrameInterval "333667\n"
+ mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/h264/h/1080p
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/h264/h/1080p/wWidth 1920
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/h264/h/1080p/wHeight 1080
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/h264/h/1080p/bLevelIDC 40
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/h264/h/1080p/dwMinBitRate 66355200
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/h264/h/1080p/dwMaxBitRate 995328000
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/h264/h/1080p/dwMaxVideoFrameBufferSize 4147200
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/h264/h/1080p/dwDefaultFrameInterval 333333
+ write /config/usb_gadget/g1/functions/uvc.0/streaming/h264/h/1080p/dwFrameInterval 333333\n666666\n1000000\n5000000\n
mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/header/h
+ mkdir /config/usb_gadget/g1/functions/uvc.0/streaming/header/h1
+ symlink /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u1 /config/usb_gadget/g1/functions/uvc.0/streaming/header/h1/u1
+ symlink /config/usb_gadget/g1/functions/uvc.0/streaming/mjpeg/m1 /config/usb_gadget/g1/functions/uvc.0/streaming/header/h1/h1
symlink /config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u /config/usb_gadget/g1/functions/uvc.0/streaming/header/h/u
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/h264/h /config/usb_gadget/g1/functions/uvc.0/streaming/header/h
- 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/h264/h /config/usb_gadget/g1/functions/uvc.0/streaming/header/h/h
+ symlink /config/usb_gadget/g1/functions/uvc.0/streaming/header/h1 /config/usb_gadget/g1/functions/uvc.0/streaming/class/fs/h1
+ symlink /config/usb_gadget/g1/functions/uvc.0/streaming/header/h1 /config/usb_gadget/g1/functions/uvc.0/streaming/class/hs/h1
symlink /config/usb_gadget/g1/functions/uvc.0/streaming/header/h /config/usb_gadget/g1/functions/uvc.0/streaming/class/ss/h
diff --git a/hal/Usb.cpp b/hal/Usb.cpp
index 06b60b1..0310d0a 100644
--- a/hal/Usb.cpp
+++ b/hal/Usb.cpp
@@ -55,11 +55,19 @@
// Set by the signal handler to destroy the thread
volatile bool destroyThread;
+volatile bool armResetRecovery = false;
+std::string audioDev = "";
+volatile int monDisconnect = 0;
+pthread_t mDisMon;
+
static void checkUsbWakeupSupport(struct Usb *usb);
static void checkUsbInHostMode(struct Usb *usb);
static void checkUsbDeviceAutoSuspend(const std::string& devicePath);
static bool checkUsbInterfaceAutoSuspend(const std::string& devicePath,
const std::string &intf);
+static bool isAudioClass(const std::string& devicePath,
+ const std::string &intf);
+static bool isRootHub(const std::string& devicePath);
static int32_t readFile(const std::string &filename, std::string *contents) {
FILE *fp;
@@ -728,14 +736,36 @@
}
}
+// USB audio device disconnect monitor
+void *disconnectMon(void *param) {
+ std::string *devicePath = (std::string *)param;
+ int timeout = 300;
+
+ while (!destroyThread && monDisconnect) {
+ if (!timeout) {
+ ALOGI("disconnectMon timed out, deauthorizing");
+ writeFile(*devicePath + "/../authorized", "0");
+ break;
+ }
+ timeout--;
+ usleep(1000);
+ }
+
+ return NULL;
+}
+
static void uevent_event(uint32_t /*epevents*/, struct data *payload) {
char msg[UEVENT_MSG_LEN + 2];
int n;
std::string gadgetName = GetProperty(USB_CONTROLLER_PROP, "");
static std::regex add_regex("add@(/devices/platform/soc/.*dwc3/xhci-hcd\\.\\d\\.auto/"
"usb\\d/\\d-\\d(?:/[\\d\\.-]+)*)");
+ static std::regex remove_regex("remove@((/devices/platform/soc/.*dwc3/xhci-hcd\\.\\d\\.auto/"
+ "usb\\d)/\\d-\\d(?:/[\\d\\.-]+)*)");
static std::regex bind_regex("bind@(/devices/platform/soc/.*dwc3/xhci-hcd\\.\\d\\.auto/"
"usb\\d/\\d-\\d(?:/[\\d\\.-]+)*)/([^/]*:[^/]*)");
+ static std::regex unbind_regex("unbind@(/devices/platform/soc/.*dwc3/xhci-hcd\\.\\d\\.auto/"
+ "usb\\d/\\d-\\d(?:/[\\d\\.-]+)*)/([^/]*:[^/]*)");
static std::regex udc_regex("(add|remove)@/devices/platform/soc/.*/" + gadgetName +
"/udc/" + gadgetName);
@@ -758,11 +788,23 @@
std::csub_match submatch = match[1];
checkUsbDeviceAutoSuspend("/sys" + submatch.str());
}
- } else if (!payload->usb->mIgnoreWakeup && std::regex_match(msg, match, bind_regex)) {
- if (match.size() == 3) {
- std::csub_match devpath = match[1];
- std::csub_match intfpath = match[2];
- checkUsbInterfaceAutoSuspend("/sys" + devpath.str(), intfpath.str());
+ } else if (std::regex_match(msg, match, bind_regex)) {
+ std::csub_match devpath = match[1];
+ std::csub_match intfpath = match[2];
+ std::string dpath;
+
+ if (!payload->usb->mIgnoreWakeup) {
+ if (match.size() == 3) {
+ checkUsbInterfaceAutoSuspend("/sys" + devpath.str(), intfpath.str());
+ }
+ }
+
+ dpath.assign("/sys" + devpath.str());
+ // Limit the audio path recovery to devices directly connected to the root hub.
+ // Save the device path to the audio device, which will trigger the recovery.
+ if (audioDev == "" && isAudioClass(dpath, intfpath.str()) && isRootHub(dpath)) {
+ audioDev.assign(dpath);
+ armResetRecovery = true;
}
} else if (std::regex_match(msg, match, udc_regex)) {
if (!strncmp(msg, "add", 3)) {
@@ -775,7 +817,6 @@
ALOGI("Binding UDC %s to ConfigFS", gadgetName.c_str());
writeFile("/config/usb_gadget/g1/UDC", gadgetName);
}
-
} else {
// When the UDC is removed, the ConfigFS gadget will no longer be
// bound. If ADBD is running it would keep opening/writing to its
@@ -785,6 +826,40 @@
// Setting this property stops ADBD from proceeding with the retry.
SetProperty(VENDOR_USB_ADB_DISABLED_PROP, "1");
}
+ } else if (std::regex_match(msg, match, unbind_regex)) {
+ std::csub_match devpath = match[1];
+ std::csub_match intfpath = match[2];
+ std::string dpath;
+
+ dpath.assign("/sys" + devpath.str());
+ // Limit the recovery to when an audio device is connected directly to
+ // the roothub. A path reference is needed so other non-audio class
+ // related devices don't trigger the disconnectMon. (unbind uevent occurs
+ // after sysfs files are cleaned, can't check bInterfaceClass)
+ if (armResetRecovery && audioDev == dpath) {
+ monDisconnect = 1;
+ armResetRecovery = false;
+ if (pthread_create(&mDisMon, NULL, disconnectMon, &audioDev)) {
+ ALOGE("pthread creation failed %d", errno);
+ }
+ }
+ } else if (std::regex_match(msg, match, remove_regex)) {
+ std::csub_match devpath = match[1];
+ std::csub_match parentpath = match[2];
+ std::string dpath;
+
+ dpath.assign("/sys" + devpath.str());
+ ALOGI("Disconnect received");
+ if (monDisconnect) {
+ monDisconnect = 0;
+ if (!pthread_kill(mDisMon, 0)) {
+ pthread_join(mDisMon, NULL);
+ }
+ writeFile("/sys" + parentpath.str() + "/authorized", "1");
+ }
+ if (audioDev == dpath)
+ audioDev = "";
+ armResetRecovery = false;
}
}
@@ -1023,6 +1098,27 @@
}
}
+static bool isRootHub(const std::string& devicePath) {
+ std::string devpath;
+ int path;
+
+ readFile(devicePath + "/../devpath", &devpath);
+ path = std::stoi(devpath, 0, 16);
+
+ return !path;
+}
+
+static bool isAudioClass(const std::string& devicePath,
+ const std::string &intf) {
+ std::string bInterfaceClass;
+ int interfaceClass, ret = -1;
+
+ readFile(devicePath + "/" + intf + "/bInterfaceClass", &bInterfaceClass);
+ interfaceClass = std::stoi(bInterfaceClass, 0, 16);
+
+ return (interfaceClass == USB_CLASS_AUDIO);
+}
+
/*
* allow specific USB device idProduct and idVendor to auto suspend
*/