libusbhost: factor out frameworks descriptors -> byte[] code.

Sony needed to increase the limit for a UVC device with > 4KiB
descriptors, but there wasn't one clean place to do that. Tidy up, and
also go straight to *16KiB* which was the largest buffer any copy of
this code was using to date.

Test: treehugger
Change-Id: Ide41a217dcf4291a7d38836264f59e06967d9d91
diff --git a/libusbhost/Android.bp b/libusbhost/Android.bp
index 3883317..9ae73d0 100644
--- a/libusbhost/Android.bp
+++ b/libusbhost/Android.bp
@@ -30,11 +30,9 @@
     export_include_dirs: ["include"],
     target: {
         android: {
-            cflags: [
-                "-g",
-                "-DUSE_LIBLOG",
-            ],
+            header_libs: ["jni_headers"],
             shared_libs: ["liblog"],
+            srcs: ["usbhost_jni.cpp"],
         },
         darwin: {
             enabled: false,
diff --git a/libusbhost/include/usbhost/usbhost.h b/libusbhost/include/usbhost/usbhost.h
index 7e62542..01cd68b 100644
--- a/libusbhost/include/usbhost/usbhost.h
+++ b/libusbhost/include/usbhost/usbhost.h
@@ -21,6 +21,7 @@
 extern "C" {
 #endif
 
+#include <stddef.h>
 #include <stdint.h>
 
 #include <linux/version.h>
diff --git a/libusbhost/include/usbhost/usbhost_jni.h b/libusbhost/include/usbhost/usbhost_jni.h
new file mode 100644
index 0000000..4885d45
--- /dev/null
+++ b/libusbhost/include/usbhost/usbhost_jni.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <jni.h>
+
+/**
+ * Reads USB descriptors from `fd`.
+ *
+ * Returns a byte[] on success,
+ * or returns NULL and logs an appropriate error on failure.
+ */
+jbyteArray usb_jni_read_descriptors(JNIEnv* env, int fd);
diff --git a/libusbhost/usbhost.c b/libusbhost/usbhost.c
index 3bed0e3..d8f15cd 100644
--- a/libusbhost/usbhost.c
+++ b/libusbhost/usbhost.c
@@ -18,20 +18,9 @@
 #define _GNU_SOURCE
 #endif
 
-// #define DEBUG 1
-#if DEBUG
+#include <usbhost/usbhost.h>
 
-#ifdef USE_LIBLOG
-#define LOG_TAG "usbhost"
-#include "log/log.h"
-#define D ALOGD
-#else
-#define D printf
-#endif
-
-#else
-#define D(...)
-#endif
+#include "usbhost_private.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -48,12 +37,19 @@
 #include <errno.h>
 #include <ctype.h>
 #include <poll.h>
-#include <pthread.h>
 
 #include <linux/usbdevice_fs.h>
-#include <asm/byteorder.h>
 
-#include "usbhost/usbhost.h"
+// #define DEBUG 1
+#if defined(DEBUG)
+#if defined(__BIONIC__)
+#define D ALOGD
+#else
+#define D printf
+#endif
+#else
+#define D(...)
+#endif
 
 #define DEV_DIR             "/dev"
 #define DEV_BUS_DIR         DEV_DIR "/bus"
@@ -76,8 +72,6 @@
     int                         wddbus;
 };
 
-#define MAX_DESCRIPTORS_LENGTH 4096
-
 struct usb_device {
     char dev_name[64];
     unsigned char desc[MAX_DESCRIPTORS_LENGTH];
diff --git a/libusbhost/usbhost_jni.cpp b/libusbhost/usbhost_jni.cpp
new file mode 100644
index 0000000..0da83dc
--- /dev/null
+++ b/libusbhost/usbhost_jni.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <usbhost/usbhost_jni.h>
+
+#include "usbhost_private.h"
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+jbyteArray usb_jni_read_descriptors(JNIEnv* env, int fd) {
+    if (TEMP_FAILURE_RETRY(lseek(fd, 0, SEEK_SET)) == -1) {
+        ALOGE("usb_jni_read_descriptors(%d): lseek() failed: %s", fd, strerror(errno));
+        return NULL;
+    }
+
+    jbyte buf[MAX_DESCRIPTORS_LENGTH];
+    ssize_t n = TEMP_FAILURE_RETRY(read(fd, buf, sizeof(buf)));
+    if (n == -1) {
+        ALOGE("usb_jni_read_descriptors: read failed: %s", strerror(errno));
+        return NULL;
+    }
+
+    jbyteArray result = env->NewByteArray(n);
+    if (result) env->SetByteArrayRegion(result, 0, n, buf);
+    return result;
+}
diff --git a/libusbhost/usbhost_private.h b/libusbhost/usbhost_private.h
new file mode 100644
index 0000000..72d7938
--- /dev/null
+++ b/libusbhost/usbhost_private.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#define LOG_TAG "usbhost"
+#include <log/log.h>
+
+// Somewhat arbitrary: Sony has reported needing more than 4KiB (but less
+// than 8KiB), and some frameworks code had 16KiB without any explanation,
+// so we went with the largest of those.
+#define MAX_DESCRIPTORS_LENGTH (16 * 1024)