summaryrefslogtreecommitdiffstats
path: root/device
diff options
context:
space:
mode:
authorreillyg <reillyg@chromium.org>2016-01-06 13:25:18 -0800
committerCommit bot <commit-bot@chromium.org>2016-01-06 21:26:56 +0000
commit8a310851fb144e91d1777112930ac15c0d88577b (patch)
tree85bb9212d1b39ae365d840f76c7cb89183bb40a1 /device
parent25bb71f2b1b21837728366fbb9d073b7745ce42c (diff)
downloadchromium_src-8a310851fb144e91d1777112930ac15c0d88577b.zip
chromium_src-8a310851fb144e91d1777112930ac15c0d88577b.tar.gz
chromium_src-8a310851fb144e91d1777112930ac15c0d88577b.tar.bz2
Implement basic USB device enumeration on Android.
This patch provides a basic implementation of UsbService::GetDevices on Android that populates UsbDevice objects by collecting properties of the Java-side UsbDevice, UsbConfiguration, UsbInterface and UsbEndpoint objects over JNI. It does not support opening devices and does not generate device add or remove notifications. BUG=549257 Review URL: https://codereview.chromium.org/1514603006 Cr-Commit-Position: refs/heads/master@{#367918}
Diffstat (limited to 'device')
-rw-r--r--device/test/run_all_unittests.cc2
-rw-r--r--device/usb/BUILD.gn50
-rw-r--r--device/usb/DEPS1
-rw-r--r--device/usb/android/java/src/org/chromium/device/usb/ChromeUsbConfiguration.java68
-rw-r--r--device/usb/android/java/src/org/chromium/device/usb/ChromeUsbDevice.java84
-rw-r--r--device/usb/android/java/src/org/chromium/device/usb/ChromeUsbEndpoint.java83
-rw-r--r--device/usb/android/java/src/org/chromium/device/usb/ChromeUsbInterface.java70
-rw-r--r--device/usb/android/java/src/org/chromium/device/usb/ChromeUsbService.java45
-rw-r--r--device/usb/android/usb_jni_registrar.cc35
-rw-r--r--device/usb/android/usb_jni_registrar.h22
-rw-r--r--device/usb/mock_usb_device.h5
-rw-r--r--device/usb/usb.gyp62
-rw-r--r--device/usb/usb_configuration_android.cc49
-rw-r--r--device/usb/usb_configuration_android.h25
-rw-r--r--device/usb/usb_descriptors.h4
-rw-r--r--device/usb/usb_device.h5
-rw-r--r--device/usb/usb_device_android.cc107
-rw-r--r--device/usb/usb_device_android.h42
-rw-r--r--device/usb/usb_device_impl.cc5
-rw-r--r--device/usb/usb_device_impl.h4
-rw-r--r--device/usb/usb_endpoint_android.cc41
-rw-r--r--device/usb/usb_endpoint_android.h25
-rw-r--r--device/usb/usb_interface_android.cc51
-rw-r--r--device/usb/usb_interface_android.h25
-rw-r--r--device/usb/usb_service_android.cc35
-rw-r--r--device/usb/usb_service_android.h11
26 files changed, 933 insertions, 23 deletions
diff --git a/device/test/run_all_unittests.cc b/device/test/run_all_unittests.cc
index b70df54..76a4996 100644
--- a/device/test/run_all_unittests.cc
+++ b/device/test/run_all_unittests.cc
@@ -11,11 +11,13 @@
#if defined(OS_ANDROID)
#include "base/android/jni_android.h"
#include "device/bluetooth/android/bluetooth_jni_registrar.h"
+#include "device/usb/android/usb_jni_registrar.h"
#endif
int main(int argc, char** argv) {
#if defined(OS_ANDROID)
device::android::RegisterBluetoothJni(base::android::AttachCurrentThread());
+ device::android::RegisterUsbJni(base::android::AttachCurrentThread());
#endif
base::TestSuite test_suite(argc, argv);
diff --git a/device/usb/BUILD.gn b/device/usb/BUILD.gn
index 99e12ca..6adc36f 100644
--- a/device/usb/BUILD.gn
+++ b/device/usb/BUILD.gn
@@ -6,23 +6,39 @@ import("//build/config/features.gni")
assert(!is_ios)
+if (is_android) {
+ import("//build/config/android/rules.gni") # For generate_jni().
+}
+
source_ids = "//third_party/usb_ids/usb.ids"
generated_ids = "$target_gen_dir/usb_ids_gen.cc"
source_set("usb") {
sources = [
+ "android/usb_jni_registrar.cc",
+ "android/usb_jni_registrar.h",
+ "usb_configuration_android.cc",
+ "usb_configuration_android.h",
"usb_descriptors.cc",
"usb_descriptors.h",
"usb_device.cc",
"usb_device.h",
+ "usb_device_android.cc",
+ "usb_device_android.h",
"usb_device_filter.cc",
"usb_device_filter.h",
"usb_device_handle.cc",
"usb_device_handle.h",
+ "usb_endpoint_android.cc",
+ "usb_endpoint_android.h",
"usb_ids.cc",
"usb_ids.h",
+ "usb_interface_android.cc",
+ "usb_interface_android.h",
"usb_service.cc",
"usb_service.h",
+ "usb_service_android.cc",
+ "usb_service_android.h",
"webusb_descriptors.cc",
"webusb_descriptors.h",
generated_ids,
@@ -42,10 +58,7 @@ source_set("usb") {
}
if (is_android) {
- sources += [
- "usb_service_android.cc",
- "usb_service_android.h",
- ]
+ deps += [ ":jni_headers" ]
} else {
sources += [
"usb_context.cc",
@@ -111,3 +124,32 @@ action("usb_device_ids") {
# Only the device_usb target can depend on us.
visibility = [ ":usb" ]
}
+
+if (is_android) {
+ java_sources_needing_jni = [
+ "android/java/src/org/chromium/device/usb/ChromeUsbConfiguration.java",
+ "android/java/src/org/chromium/device/usb/ChromeUsbDevice.java",
+ "android/java/src/org/chromium/device/usb/ChromeUsbEndpoint.java",
+ "android/java/src/org/chromium/device/usb/ChromeUsbInterface.java",
+ "android/java/src/org/chromium/device/usb/ChromeUsbService.java",
+ ]
+
+ generate_jni("jni_headers") {
+ sources = java_sources_needing_jni
+ jni_package = "device"
+ }
+
+ java_cpp_enum("usb_descriptors_javagen") {
+ sources = [
+ "usb_descriptors.h",
+ ]
+ }
+
+ android_library("java") {
+ java_files = java_sources_needing_jni
+ deps = [
+ "//base:base_java",
+ ]
+ srcjar_deps = [ ":usb_descriptors_javagen" ]
+ }
+}
diff --git a/device/usb/DEPS b/device/usb/DEPS
index 25ff287..b1c259f 100644
--- a/device/usb/DEPS
+++ b/device/usb/DEPS
@@ -1,6 +1,7 @@
include_rules = [
"+chromeos",
"+dbus",
+ "+jni",
"-net",
"+net/base",
diff --git a/device/usb/android/java/src/org/chromium/device/usb/ChromeUsbConfiguration.java b/device/usb/android/java/src/org/chromium/device/usb/ChromeUsbConfiguration.java
new file mode 100644
index 0000000..90371e5
--- /dev/null
+++ b/device/usb/android/java/src/org/chromium/device/usb/ChromeUsbConfiguration.java
@@ -0,0 +1,68 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.device.usb;
+
+import android.annotation.TargetApi;
+import android.hardware.usb.UsbConfiguration;
+import android.hardware.usb.UsbInterface;
+import android.os.Build;
+
+import org.chromium.base.Log;
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.JNINamespace;
+
+/**
+ * Exposes android.hardware.usb.UsbConfiguration as necessary for C++
+ * device::UsbConfigurationAndroid.
+ *
+ * Lifetime is controlled by device::UsbConfigurationAndroid.
+ */
+@JNINamespace("device")
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+final class ChromeUsbConfiguration {
+ private static final String TAG = "Usb";
+
+ final UsbConfiguration mConfiguration;
+
+ private ChromeUsbConfiguration(UsbConfiguration configuration) {
+ mConfiguration = configuration;
+ Log.v(TAG, "ChromeUsbConfiguration created.");
+ }
+
+ @CalledByNative
+ private static ChromeUsbConfiguration create(UsbConfiguration configuration) {
+ return new ChromeUsbConfiguration(configuration);
+ }
+
+ @CalledByNative
+ private int getConfigurationValue() {
+ return mConfiguration.getId();
+ }
+
+ @CalledByNative
+ private boolean isSelfPowered() {
+ return mConfiguration.isSelfPowered();
+ }
+
+ @CalledByNative
+ private boolean isRemoteWakeup() {
+ return mConfiguration.isRemoteWakeup();
+ }
+
+ @CalledByNative
+ private int getMaxPower() {
+ return mConfiguration.getMaxPower();
+ }
+
+ @CalledByNative
+ private UsbInterface[] getInterfaces() {
+ int count = mConfiguration.getInterfaceCount();
+ UsbInterface[] interfaces = new UsbInterface[count];
+ for (int i = 0; i < count; ++i) {
+ interfaces[i] = mConfiguration.getInterface(i);
+ }
+ return interfaces;
+ }
+}
diff --git a/device/usb/android/java/src/org/chromium/device/usb/ChromeUsbDevice.java b/device/usb/android/java/src/org/chromium/device/usb/ChromeUsbDevice.java
new file mode 100644
index 0000000..92e4e14
--- /dev/null
+++ b/device/usb/android/java/src/org/chromium/device/usb/ChromeUsbDevice.java
@@ -0,0 +1,84 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.device.usb;
+
+import android.annotation.TargetApi;
+import android.hardware.usb.UsbConfiguration;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbInterface;
+import android.os.Build;
+
+import org.chromium.base.Log;
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.JNINamespace;
+
+/**
+ * Exposes android.hardware.usb.UsbDevice as necessary for C++
+ * device::UsbDeviceAndroid.
+ *
+ * Lifetime is controlled by device::UsbDeviceAndroid.
+ */
+@JNINamespace("device")
+final class ChromeUsbDevice {
+ private static final String TAG = "Usb";
+
+ final UsbDevice mDevice;
+
+ private ChromeUsbDevice(UsbDevice device) {
+ mDevice = device;
+ Log.v(TAG, "ChromeUsbDevice created.");
+ }
+
+ @CalledByNative
+ private static ChromeUsbDevice create(UsbDevice device) {
+ return new ChromeUsbDevice(device);
+ }
+
+ @CalledByNative
+ private int getVendorId() {
+ return mDevice.getVendorId();
+ }
+
+ @CalledByNative
+ private int getProductId() {
+ return mDevice.getProductId();
+ }
+
+ @CalledByNative
+ private String getManufacturerName() {
+ return mDevice.getManufacturerName();
+ }
+
+ @CalledByNative
+ private String getProductName() {
+ return mDevice.getProductName();
+ }
+
+ @CalledByNative
+ private String getSerialNumber() {
+ return mDevice.getSerialNumber();
+ }
+
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ @CalledByNative
+ private UsbConfiguration[] getConfigurations() {
+ int count = mDevice.getConfigurationCount();
+ UsbConfiguration[] configurations = new UsbConfiguration[count];
+ for (int i = 0; i < count; ++i) {
+ configurations[i] = mDevice.getConfiguration(i);
+ }
+ return configurations;
+ }
+
+ @CalledByNative
+ private UsbInterface[] getInterfaces() {
+ int count = mDevice.getInterfaceCount();
+ UsbInterface[] interfaces = new UsbInterface[count];
+ for (int i = 0; i < count; ++i) {
+ interfaces[i] = mDevice.getInterface(i);
+ }
+ return interfaces;
+ }
+}
diff --git a/device/usb/android/java/src/org/chromium/device/usb/ChromeUsbEndpoint.java b/device/usb/android/java/src/org/chromium/device/usb/ChromeUsbEndpoint.java
new file mode 100644
index 0000000..135dc51
--- /dev/null
+++ b/device/usb/android/java/src/org/chromium/device/usb/ChromeUsbEndpoint.java
@@ -0,0 +1,83 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.device.usb;
+
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbEndpoint;
+
+import org.chromium.base.Log;
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.JNINamespace;
+
+/**
+ * Exposes android.hardware.usb.UsbEndpoint as necessary for C++
+ * device::UsbEndpointAndroid.
+ *
+ * Lifetime is controlled by device::UsbEndpointAndroid.
+ */
+@JNINamespace("device")
+final class ChromeUsbEndpoint {
+ private static final String TAG = "Usb";
+
+ final UsbEndpoint mEndpoint;
+
+ private ChromeUsbEndpoint(UsbEndpoint endpoint) {
+ mEndpoint = endpoint;
+ Log.v(TAG, "ChromeUsbEndpoint created.");
+ }
+
+ @CalledByNative
+ private static ChromeUsbEndpoint create(UsbEndpoint endpoint) {
+ return new ChromeUsbEndpoint(endpoint);
+ }
+
+ @CalledByNative
+ private int getAddress() {
+ return mEndpoint.getAddress();
+ }
+
+ @CalledByNative
+ private int getDirection() {
+ switch (mEndpoint.getDirection()) {
+ case UsbConstants.USB_DIR_IN:
+ return UsbEndpointDirection.USB_DIRECTION_INBOUND;
+ case UsbConstants.USB_DIR_OUT:
+ return UsbEndpointDirection.USB_DIRECTION_OUTBOUND;
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ @CalledByNative
+ private int getMaxPacketSize() {
+ return mEndpoint.getMaxPacketSize();
+ }
+
+ @CalledByNative
+ private int getAttributes() {
+ return mEndpoint.getAttributes();
+ }
+
+ @CalledByNative
+ private int getType() {
+ switch (mEndpoint.getType()) {
+ case UsbConstants.USB_ENDPOINT_XFER_CONTROL:
+ return UsbTransferType.USB_TRANSFER_CONTROL;
+ case UsbConstants.USB_ENDPOINT_XFER_ISOC:
+ return UsbTransferType.USB_TRANSFER_ISOCHRONOUS;
+ case UsbConstants.USB_ENDPOINT_XFER_BULK:
+ return UsbTransferType.USB_TRANSFER_BULK;
+ case UsbConstants.USB_ENDPOINT_XFER_INT:
+ return UsbTransferType.USB_TRANSFER_INTERRUPT;
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ @CalledByNative
+ private int getInterval() {
+ return mEndpoint.getInterval();
+ }
+}
diff --git a/device/usb/android/java/src/org/chromium/device/usb/ChromeUsbInterface.java b/device/usb/android/java/src/org/chromium/device/usb/ChromeUsbInterface.java
new file mode 100644
index 0000000..cd4f492
--- /dev/null
+++ b/device/usb/android/java/src/org/chromium/device/usb/ChromeUsbInterface.java
@@ -0,0 +1,70 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.device.usb;
+
+import android.hardware.usb.UsbEndpoint;
+import android.hardware.usb.UsbInterface;
+
+import org.chromium.base.Log;
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.JNINamespace;
+
+/**
+ * Exposes android.hardware.usb.UsbInterface as necessary for C++
+ * device::UsbInterfaceAndroid.
+ *
+ * Lifetime is controlled by device::UsbInterfaceAndroid.
+ */
+@JNINamespace("device")
+final class ChromeUsbInterface {
+ private static final String TAG = "Usb";
+
+ final UsbInterface mInterface;
+
+ private ChromeUsbInterface(UsbInterface iface) {
+ mInterface = iface;
+ Log.v(TAG, "ChromeUsbInterface created.");
+ }
+
+ @CalledByNative
+ private static ChromeUsbInterface create(UsbInterface iface) {
+ return new ChromeUsbInterface(iface);
+ }
+
+ @CalledByNative
+ private int getInterfaceNumber() {
+ return mInterface.getId();
+ }
+
+ @CalledByNative
+ private int getAlternateSetting() {
+ return mInterface.getAlternateSetting();
+ }
+
+ @CalledByNative
+ private int getInterfaceClass() {
+ return mInterface.getInterfaceClass();
+ }
+
+ @CalledByNative
+ private int getInterfaceSubclass() {
+ return mInterface.getInterfaceSubclass();
+ }
+
+ @CalledByNative
+ private int getInterfaceProtocol() {
+ return mInterface.getInterfaceProtocol();
+ }
+
+ @CalledByNative
+ private UsbEndpoint[] getEndpoints() {
+ int count = mInterface.getEndpointCount();
+ UsbEndpoint[] endpoints = new UsbEndpoint[count];
+ for (int i = 0; i < count; ++i) {
+ endpoints[i] = mInterface.getEndpoint(i);
+ }
+ return endpoints;
+ }
+}
diff --git a/device/usb/android/java/src/org/chromium/device/usb/ChromeUsbService.java b/device/usb/android/java/src/org/chromium/device/usb/ChromeUsbService.java
new file mode 100644
index 0000000..834ddb1
--- /dev/null
+++ b/device/usb/android/java/src/org/chromium/device/usb/ChromeUsbService.java
@@ -0,0 +1,45 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.device.usb;
+
+import android.content.Context;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbManager;
+
+import org.chromium.base.Log;
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.JNINamespace;
+
+import java.util.HashMap;
+
+/**
+ * Exposes android.hardware.usb.UsbManager as necessary for C++
+ * device::UsbServiceAndroid.
+ *
+ * Lifetime is controlled by device::UsbServiceAndroid.
+ */
+@JNINamespace("device")
+final class ChromeUsbService {
+ private static final String TAG = "Usb";
+
+ Context mContext;
+
+ private ChromeUsbService(Context context) {
+ mContext = context;
+ Log.v(TAG, "ChromeUsbService created.");
+ }
+
+ @CalledByNative
+ private static ChromeUsbService create(Context context) {
+ return new ChromeUsbService(context);
+ }
+
+ @CalledByNative
+ private Object[] getDevices() {
+ UsbManager manager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
+ HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
+ return deviceList.values().toArray();
+ }
+}
diff --git a/device/usb/android/usb_jni_registrar.cc b/device/usb/android/usb_jni_registrar.cc
new file mode 100644
index 0000000..1e53c5b
--- /dev/null
+++ b/device/usb/android/usb_jni_registrar.cc
@@ -0,0 +1,35 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/usb/android/usb_jni_registrar.h"
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_registrar.h"
+#include "device/usb/usb_configuration_android.h"
+#include "device/usb/usb_device_android.h"
+#include "device/usb/usb_endpoint_android.h"
+#include "device/usb/usb_interface_android.h"
+#include "device/usb/usb_service_android.h"
+
+namespace device {
+namespace android {
+namespace {
+
+const base::android::RegistrationMethod kRegisteredMethods[] = {
+ {"UsbConfigurationAndroid", device::UsbConfigurationAndroid::RegisterJNI},
+ {"UsbDeviceAndroid", device::UsbDeviceAndroid::RegisterJNI},
+ {"UsbEndpointAndroid", device::UsbEndpointAndroid::RegisterJNI},
+ {"UsbInterfaceAndroid", device::UsbInterfaceAndroid::RegisterJNI},
+ {"UsbServiceAndroid", device::UsbServiceAndroid::RegisterJNI},
+};
+
+} // namespace
+
+bool RegisterUsbJni(JNIEnv* env) {
+ return RegisterNativeMethods(env, kRegisteredMethods,
+ arraysize(kRegisteredMethods));
+}
+
+} // namespace android
+} // namespace device
diff --git a/device/usb/android/usb_jni_registrar.h b/device/usb/android/usb_jni_registrar.h
new file mode 100644
index 0000000..a691583
--- /dev/null
+++ b/device/usb/android/usb_jni_registrar.h
@@ -0,0 +1,22 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DEVICE_USB_ANDROID_USB_JNI_REGISTRAR_H_
+#define DEVICE_USB_ANDROID_USB_JNI_REGISTRAR_H_
+
+#include <jni.h>
+
+namespace device {
+namespace android {
+
+// Registers C++ methods in device/usb classes with JNI.
+// See https://www.chromium.org/developers/design-documents/android-jni
+//
+// Must be called before classes in the USB module are used.
+bool RegisterUsbJni(JNIEnv* env);
+
+} // namespace android
+} // namespace device
+
+#endif // DEVICE_USB_ANDROID_USB_JNI_REGISTRAR_H_
diff --git a/device/usb/mock_usb_device.h b/device/usb/mock_usb_device.h
index c25a915..91bb0bb 100644
--- a/device/usb/mock_usb_device.h
+++ b/device/usb/mock_usb_device.h
@@ -5,12 +5,12 @@
#ifndef DEVICE_USB_MOCK_USB_DEVICE_H_
#define DEVICE_USB_MOCK_USB_DEVICE_H_
-#include "device/usb/usb_device.h"
-
#include <stdint.h>
#include <string>
+#include <vector>
+#include "device/usb/usb_device.h"
#include "device/usb/usb_device_handle.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -41,7 +41,6 @@ class MockUsbDevice : public UsbDevice {
const std::vector<UsbConfigDescriptor>& configurations);
MOCK_METHOD1(Open, void(const OpenCallback&));
- MOCK_METHOD1(Close, bool(scoped_refptr<UsbDeviceHandle>));
MOCK_METHOD0(GetActiveConfiguration, const device::UsbConfigDescriptor*());
private:
diff --git a/device/usb/usb.gyp b/device/usb/usb.gyp
index 453ba1a..a68b187 100644
--- a/device/usb/usb.gyp
+++ b/device/usb/usb.gyp
@@ -20,6 +20,10 @@
'../..',
],
'sources': [
+ 'android/usb_jni_registrar.cc',
+ 'android/usb_jni_registrar.h',
+ 'usb_configuration_android.cc',
+ 'usb_configuration_android.h',
'usb_context.cc',
'usb_context.h',
'usb_descriptors.cc',
@@ -28,18 +32,26 @@
'usb_device_impl.h',
'usb_device.cc',
'usb_device.h',
+ 'usb_device_android.cc',
+ 'usb_device_android.h',
'usb_device_filter.cc',
'usb_device_filter.h',
'usb_device_handle_impl.cc',
'usb_device_handle_impl.h',
'usb_device_handle.cc',
'usb_device_handle.h',
+ 'usb_endpoint_android.cc',
+ 'usb_endpoint_android.h',
'usb_error.cc',
'usb_error.h',
'usb_ids.cc',
'usb_ids.h',
+ 'usb_interface_android.cc',
+ 'usb_interface_android.h',
'usb_service.cc',
'usb_service.h',
+ 'usb_service_android.cc',
+ 'usb_service_android.h',
'usb_service_impl.cc',
'usb_service_impl.h',
'webusb_descriptors.cc',
@@ -75,13 +87,14 @@
],
}],
['OS=="android"', {
+ 'dependencies': [
+ 'device_usb_java',
+ 'device_usb_jni_headers',
+ ],
'dependencies!': [
'../../third_party/libusb/libusb.gyp:libusb',
],
- 'sources': [
- 'usb_service_android.cc',
- 'usb_service_android.h',
- ],
+ # These sources are libusb-specific.
'sources!': [
'usb_context.cc',
'usb_context.h',
@@ -122,4 +135,45 @@
],
},
],
+ 'conditions': [
+ ['OS == "android"', {
+ 'targets': [
+ {
+ 'target_name': 'device_usb_jni_headers',
+ 'type': 'none',
+ 'sources': [
+ 'android/java/src/org/chromium/device/usb/ChromeUsbConfiguration.java',
+ 'android/java/src/org/chromium/device/usb/ChromeUsbDevice.java',
+ 'android/java/src/org/chromium/device/usb/ChromeUsbEndpoint.java',
+ 'android/java/src/org/chromium/device/usb/ChromeUsbInterface.java',
+ 'android/java/src/org/chromium/device/usb/ChromeUsbService.java',
+ ],
+ 'variables': {
+ 'jni_gen_package': 'device_usb',
+ },
+ 'includes': [ '../../build/jni_generator.gypi' ],
+ },
+ {
+ 'target_name': 'device_usb_java',
+ 'type': 'none',
+ 'dependencies': [
+ 'usb_descriptors_javagen',
+ '../../base/base.gyp:base',
+ ],
+ 'variables': {
+ 'java_in_dir': '../../device/usb/android/java',
+ },
+ 'includes': [ '../../build/java.gypi' ],
+ },
+ {
+ 'target_name': 'usb_descriptors_javagen',
+ 'type': 'none',
+ 'variables': {
+ 'source_file': 'usb_descriptors.h',
+ },
+ 'includes': [ '../../build/android/java_cpp_enum.gypi' ],
+ },
+ ],
+ }],
+ ],
}
diff --git a/device/usb/usb_configuration_android.cc b/device/usb/usb_configuration_android.cc
new file mode 100644
index 0000000..4a9c712
--- /dev/null
+++ b/device/usb/usb_configuration_android.cc
@@ -0,0 +1,49 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/usb/usb_configuration_android.h"
+
+#include "device/usb/usb_interface_android.h"
+#include "jni/ChromeUsbConfiguration_jni.h"
+
+using base::android::ScopedJavaLocalRef;
+
+namespace device {
+
+// static
+bool UsbConfigurationAndroid::RegisterJNI(JNIEnv* env) {
+ return RegisterNativesImpl(env); // Generated in ChromeUsbConfiguration_jni.h
+}
+
+// static
+UsbConfigDescriptor UsbConfigurationAndroid::Convert(
+ JNIEnv* env,
+ const base::android::JavaRef<jobject>& usb_configuration) {
+ ScopedJavaLocalRef<jobject> wrapper =
+ Java_ChromeUsbConfiguration_create(env, usb_configuration.obj());
+
+ UsbConfigDescriptor config;
+ config.configuration_value =
+ Java_ChromeUsbConfiguration_getConfigurationValue(env, wrapper.obj());
+ config.self_powered =
+ Java_ChromeUsbConfiguration_isSelfPowered(env, wrapper.obj());
+ config.remote_wakeup =
+ Java_ChromeUsbConfiguration_isRemoteWakeup(env, wrapper.obj());
+ config.maximum_power =
+ Java_ChromeUsbConfiguration_getMaxPower(env, wrapper.obj());
+
+ ScopedJavaLocalRef<jobjectArray> interfaces =
+ Java_ChromeUsbConfiguration_getInterfaces(env, wrapper.obj());
+ jsize count = env->GetArrayLength(interfaces.obj());
+ config.interfaces.reserve(count);
+ for (jsize i = 0; i < count; ++i) {
+ ScopedJavaLocalRef<jobject> interface(
+ env, env->GetObjectArrayElement(interfaces.obj(), i));
+ config.interfaces.push_back(UsbInterfaceAndroid::Convert(env, interface));
+ }
+
+ return config;
+}
+
+} // namespace device
diff --git a/device/usb/usb_configuration_android.h b/device/usb/usb_configuration_android.h
new file mode 100644
index 0000000..610ac07
--- /dev/null
+++ b/device/usb/usb_configuration_android.h
@@ -0,0 +1,25 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DEVICE_USB_USB_CONFIGURATION_ANDROID_H_
+#define DEVICE_USB_USB_CONFIGURATION_ANDROID_H_
+
+#include "base/android/scoped_java_ref.h"
+#include "device/usb/usb_descriptors.h"
+
+namespace device {
+
+class UsbConfigurationAndroid {
+ public:
+ // Register C++ methods exposed to Java using JNI.
+ static bool RegisterJNI(JNIEnv* env);
+
+ static UsbConfigDescriptor Convert(
+ JNIEnv* env,
+ const base::android::JavaRef<jobject>& usb_configuration);
+};
+
+} // namespace device
+
+#endif // DEVICE_USB_USB_CONFIGURATION_ANDROID_H_
diff --git a/device/usb/usb_descriptors.h b/device/usb/usb_descriptors.h
index 93b6f62..adaa0ab 100644
--- a/device/usb/usb_descriptors.h
+++ b/device/usb/usb_descriptors.h
@@ -12,6 +12,8 @@
namespace device {
+// A Java counterpart will be generated for this enum.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.device.usb
enum UsbTransferType {
USB_TRANSFER_CONTROL = 0,
USB_TRANSFER_ISOCHRONOUS,
@@ -19,6 +21,8 @@ enum UsbTransferType {
USB_TRANSFER_INTERRUPT,
};
+// A Java counterpart will be generated for this enum.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.device.usb
enum UsbEndpointDirection {
USB_DIRECTION_INBOUND = 0,
USB_DIRECTION_OUTBOUND,
diff --git a/device/usb/usb_device.h b/device/usb/usb_device.h
index 9822a38..92d0e29 100644
--- a/device/usb/usb_device.h
+++ b/device/usb/usb_device.h
@@ -7,6 +7,7 @@
#include <stdint.h>
+#include <string>
#include <vector>
#include "base/callback.h"
@@ -59,10 +60,6 @@ class UsbDevice : public base::RefCountedThreadSafe<UsbDevice> {
// Creates a UsbDeviceHandle for further manipulation.
virtual void Open(const OpenCallback& callback) = 0;
- // Explicitly closes a device handle. This method will be automatically called
- // by the destructor of a UsbDeviceHandle as well.
- virtual bool Close(scoped_refptr<UsbDeviceHandle> handle) = 0;
-
// Gets the UsbConfigDescriptor for the active device configuration or nullptr
// if the device is unconfigured.
virtual const UsbConfigDescriptor* GetActiveConfiguration() = 0;
diff --git a/device/usb/usb_device_android.cc b/device/usb/usb_device_android.cc
new file mode 100644
index 0000000..ee9e93b
--- /dev/null
+++ b/device/usb/usb_device_android.cc
@@ -0,0 +1,107 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/usb/usb_device_android.h"
+
+#include "base/android/build_info.h"
+#include "base/android/jni_string.h"
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/thread_task_runner_handle.h"
+#include "device/usb/usb_configuration_android.h"
+#include "device/usb/usb_device_handle.h"
+#include "device/usb/usb_interface_android.h"
+#include "jni/ChromeUsbDevice_jni.h"
+
+using base::android::AttachCurrentThread;
+using base::android::ConvertJavaStringToUTF16;
+using base::android::JavaRef;
+using base::android::ScopedJavaLocalRef;
+
+namespace device {
+
+// static
+bool UsbDeviceAndroid::RegisterJNI(JNIEnv* env) {
+ return RegisterNativesImpl(env); // Generated in ChromeUsbDevice_jni.h
+}
+
+// static
+scoped_refptr<UsbDeviceAndroid> UsbDeviceAndroid::Create(
+ JNIEnv* env,
+ const JavaRef<jobject>& usb_device) {
+ ScopedJavaLocalRef<jobject> wrapper =
+ Java_ChromeUsbDevice_create(env, usb_device.obj());
+ uint16_t vendor_id = Java_ChromeUsbDevice_getVendorId(env, wrapper.obj());
+ uint16_t product_id = Java_ChromeUsbDevice_getProductId(env, wrapper.obj());
+ ScopedJavaLocalRef<jstring> manufacturer_string =
+ Java_ChromeUsbDevice_getManufacturerName(env, wrapper.obj());
+ ScopedJavaLocalRef<jstring> product_string =
+ Java_ChromeUsbDevice_getProductName(env, wrapper.obj());
+ ScopedJavaLocalRef<jstring> serial_number =
+ Java_ChromeUsbDevice_getSerialNumber(env, wrapper.obj());
+ return make_scoped_refptr(new UsbDeviceAndroid(
+ env, vendor_id, product_id,
+ ConvertJavaStringToUTF16(env, manufacturer_string),
+ ConvertJavaStringToUTF16(env, product_string),
+ ConvertJavaStringToUTF16(env, serial_number), wrapper));
+}
+
+void UsbDeviceAndroid::Open(const OpenCallback& callback) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ base::Bind(callback, nullptr));
+}
+
+const UsbConfigDescriptor* UsbDeviceAndroid::GetActiveConfiguration() {
+ return nullptr;
+}
+
+UsbDeviceAndroid::UsbDeviceAndroid(JNIEnv* env,
+ uint16_t vendor_id,
+ uint16_t product_id,
+ const base::string16& manufacturer_string,
+ const base::string16& product_string,
+ const base::string16& serial_number,
+ const JavaRef<jobject>& wrapper)
+ : UsbDevice(vendor_id,
+ product_id,
+ manufacturer_string,
+ product_string,
+ serial_number) {
+ j_object_.Reset(wrapper);
+
+ if (base::android::BuildInfo::GetInstance()->sdk_int() >= 21) {
+ ScopedJavaLocalRef<jobjectArray> configurations =
+ Java_ChromeUsbDevice_getConfigurations(env, j_object_.obj());
+ jsize count = env->GetArrayLength(configurations.obj());
+ configurations_.reserve(count);
+ for (jsize i = 0; i < count; ++i) {
+ ScopedJavaLocalRef<jobject> config(
+ env, env->GetObjectArrayElement(configurations.obj(), i));
+ configurations_.push_back(UsbConfigurationAndroid::Convert(env, config));
+ }
+ } else {
+ // Pre-lollipop only the first configuration was supported. Build a basic
+ // configuration out of the available interfaces.
+ UsbConfigDescriptor config;
+ config.configuration_value = 1; // Reasonable guess.
+ config.self_powered = false; // Arbitrary default.
+ config.remote_wakeup = false; // Arbitrary default.
+ config.maximum_power = 0; // Arbitrary default.
+
+ ScopedJavaLocalRef<jobjectArray> interfaces =
+ Java_ChromeUsbDevice_getInterfaces(env, wrapper.obj());
+ jsize count = env->GetArrayLength(interfaces.obj());
+ config.interfaces.reserve(count);
+ for (jsize i = 0; i < count; ++i) {
+ ScopedJavaLocalRef<jobject> interface(
+ env, env->GetObjectArrayElement(interfaces.obj(), i));
+ config.interfaces.push_back(UsbInterfaceAndroid::Convert(env, interface));
+ }
+ configurations_.push_back(config);
+ }
+}
+
+UsbDeviceAndroid::~UsbDeviceAndroid() {}
+
+} // namespace device
diff --git a/device/usb/usb_device_android.h b/device/usb/usb_device_android.h
new file mode 100644
index 0000000..ad468913
--- /dev/null
+++ b/device/usb/usb_device_android.h
@@ -0,0 +1,42 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DEVICE_USB_USB_DEVICE_ANDROID_H_
+#define DEVICE_USB_USB_DEVICE_ANDROID_H_
+
+#include "base/android/scoped_java_ref.h"
+#include "device/usb/usb_device.h"
+
+namespace device {
+
+class UsbDeviceAndroid : public UsbDevice {
+ public:
+ // Register C++ methods exposed to Java using JNI.
+ static bool RegisterJNI(JNIEnv* env);
+
+ static scoped_refptr<UsbDeviceAndroid> Create(
+ JNIEnv* env,
+ const base::android::JavaRef<jobject>& usb_device);
+
+ // UsbDevice:
+ void Open(const OpenCallback& callback) override;
+ const UsbConfigDescriptor* GetActiveConfiguration() override;
+
+ private:
+ UsbDeviceAndroid(JNIEnv* env,
+ uint16_t vendor_id,
+ uint16_t product_id,
+ const base::string16& manufacturer_string,
+ const base::string16& product_string,
+ const base::string16& serial_number,
+ const base::android::JavaRef<jobject>& wrapper);
+ ~UsbDeviceAndroid() override;
+
+ // Java object org.chromium.device.usb.ChromeUsbDevice.
+ base::android::ScopedJavaGlobalRef<jobject> j_object_;
+};
+
+} // namespace device
+
+#endif // DEVICE_USB_USB_DEVICE_ANDROID_H_
diff --git a/device/usb/usb_device_impl.cc b/device/usb/usb_device_impl.cc
index 874ccad..271b631 100644
--- a/device/usb/usb_device_impl.cc
+++ b/device/usb/usb_device_impl.cc
@@ -204,7 +204,7 @@ void UsbDeviceImpl::Open(const OpenCallback& callback) {
#endif // defined(OS_CHROMEOS)
}
-bool UsbDeviceImpl::Close(scoped_refptr<UsbDeviceHandle> handle) {
+void UsbDeviceImpl::Close(scoped_refptr<UsbDeviceHandle> handle) {
DCHECK(thread_checker_.CalledOnValidThread());
for (HandlesVector::iterator it = handles_.begin(); it != handles_.end();
@@ -212,10 +212,9 @@ bool UsbDeviceImpl::Close(scoped_refptr<UsbDeviceHandle> handle) {
if (it->get() == handle.get()) {
(*it)->InternalClose();
handles_.erase(it);
- return true;
+ return;
}
}
- return false;
}
const UsbConfigDescriptor* UsbDeviceImpl::GetActiveConfiguration() {
diff --git a/device/usb/usb_device_impl.h b/device/usb/usb_device_impl.h
index 337c0e8..a64e3d1 100644
--- a/device/usb/usb_device_impl.h
+++ b/device/usb/usb_device_impl.h
@@ -6,6 +6,8 @@
#define DEVICE_USB_USB_DEVICE_IMPL_H_
#include <stdint.h>
+
+#include <string>
#include <utility>
#include <vector>
@@ -45,7 +47,6 @@ class UsbDeviceImpl : public UsbDevice {
void CheckUsbAccess(const ResultCallback& callback) override;
#endif // OS_CHROMEOS
void Open(const OpenCallback& callback) override;
- bool Close(scoped_refptr<UsbDeviceHandle> handle) override;
const UsbConfigDescriptor* GetActiveConfiguration() override;
// These functions are used during enumeration only. The values must not
@@ -87,6 +88,7 @@ class UsbDeviceImpl : public UsbDevice {
void ReadAllConfigurations();
// Called by UsbDeviceHandleImpl.
+ void Close(scoped_refptr<UsbDeviceHandle> handle);
void RefreshActiveConfiguration();
private:
diff --git a/device/usb/usb_endpoint_android.cc b/device/usb/usb_endpoint_android.cc
new file mode 100644
index 0000000..3280b04
--- /dev/null
+++ b/device/usb/usb_endpoint_android.cc
@@ -0,0 +1,41 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/usb/usb_endpoint_android.h"
+
+#include "jni/ChromeUsbEndpoint_jni.h"
+
+namespace device {
+
+// static
+bool UsbEndpointAndroid::RegisterJNI(JNIEnv* env) {
+ return RegisterNativesImpl(env); // Generated in ChromeUsbEndpoint_jni.h
+}
+
+// static
+UsbEndpointDescriptor UsbEndpointAndroid::Convert(
+ JNIEnv* env,
+ const base::android::JavaRef<jobject>& usb_endpoint) {
+ base::android::ScopedJavaLocalRef<jobject> wrapper =
+ Java_ChromeUsbEndpoint_create(env, usb_endpoint.obj());
+
+ UsbEndpointDescriptor endpoint;
+ endpoint.address = Java_ChromeUsbEndpoint_getAddress(env, wrapper.obj());
+ endpoint.direction = static_cast<UsbEndpointDirection>(
+ Java_ChromeUsbEndpoint_getDirection(env, wrapper.obj()));
+ endpoint.maximum_packet_size =
+ Java_ChromeUsbEndpoint_getMaxPacketSize(env, wrapper.obj());
+ jint attributes = Java_ChromeUsbEndpoint_getAttributes(env, wrapper.obj());
+ endpoint.synchronization_type =
+ static_cast<UsbSynchronizationType>((attributes >> 2) & 3);
+ endpoint.usage_type = static_cast<UsbUsageType>((attributes >> 4) & 3);
+ endpoint.transfer_type = static_cast<UsbTransferType>(
+ Java_ChromeUsbEndpoint_getType(env, wrapper.obj()));
+ endpoint.polling_interval =
+ Java_ChromeUsbEndpoint_getInterval(env, wrapper.obj());
+
+ return endpoint;
+}
+
+} // namespace device
diff --git a/device/usb/usb_endpoint_android.h b/device/usb/usb_endpoint_android.h
new file mode 100644
index 0000000..3fc835c
--- /dev/null
+++ b/device/usb/usb_endpoint_android.h
@@ -0,0 +1,25 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DEVICE_USB_USB_ENDPOINT_ANDROID_H_
+#define DEVICE_USB_USB_ENDPOINT_ANDROID_H_
+
+#include "base/android/scoped_java_ref.h"
+#include "device/usb/usb_descriptors.h"
+
+namespace device {
+
+class UsbEndpointAndroid {
+ public:
+ // Register C++ methods exposed to Java using JNI.
+ static bool RegisterJNI(JNIEnv* env);
+
+ static UsbEndpointDescriptor Convert(
+ JNIEnv* env,
+ const base::android::JavaRef<jobject>& usb_endpoint);
+};
+
+} // namespace device
+
+#endif // DEVICE_USB_USB_ENDPOINT_ANDROID_H_
diff --git a/device/usb/usb_interface_android.cc b/device/usb/usb_interface_android.cc
new file mode 100644
index 0000000..60403ae
--- /dev/null
+++ b/device/usb/usb_interface_android.cc
@@ -0,0 +1,51 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/usb/usb_interface_android.h"
+
+#include "device/usb/usb_endpoint_android.h"
+#include "jni/ChromeUsbInterface_jni.h"
+
+using base::android::ScopedJavaLocalRef;
+
+namespace device {
+
+// static
+bool UsbInterfaceAndroid::RegisterJNI(JNIEnv* env) {
+ return RegisterNativesImpl(env); // Generated in ChromeUsbInterface_jni.h
+}
+
+// static
+UsbInterfaceDescriptor UsbInterfaceAndroid::Convert(
+ JNIEnv* env,
+ const base::android::JavaRef<jobject>& usb_interface) {
+ ScopedJavaLocalRef<jobject> wrapper =
+ Java_ChromeUsbInterface_create(env, usb_interface.obj());
+
+ UsbInterfaceDescriptor interface;
+ interface.interface_number =
+ Java_ChromeUsbInterface_getInterfaceNumber(env, wrapper.obj());
+ interface.alternate_setting =
+ Java_ChromeUsbInterface_getAlternateSetting(env, wrapper.obj());
+ interface.interface_class =
+ Java_ChromeUsbInterface_getInterfaceClass(env, wrapper.obj());
+ interface.interface_subclass =
+ Java_ChromeUsbInterface_getInterfaceSubclass(env, wrapper.obj());
+ interface.interface_protocol =
+ Java_ChromeUsbInterface_getInterfaceProtocol(env, wrapper.obj());
+
+ ScopedJavaLocalRef<jobjectArray> endpoints =
+ Java_ChromeUsbInterface_getEndpoints(env, wrapper.obj());
+ jsize count = env->GetArrayLength(endpoints.obj());
+ interface.endpoints.reserve(count);
+ for (jsize i = 0; i < count; ++i) {
+ ScopedJavaLocalRef<jobject> endpoint(
+ env, env->GetObjectArrayElement(endpoints.obj(), i));
+ interface.endpoints.push_back(UsbEndpointAndroid::Convert(env, endpoint));
+ }
+
+ return interface;
+}
+
+} // namespace device
diff --git a/device/usb/usb_interface_android.h b/device/usb/usb_interface_android.h
new file mode 100644
index 0000000..ec04b61
--- /dev/null
+++ b/device/usb/usb_interface_android.h
@@ -0,0 +1,25 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DEVICE_USB_USB_INTERFACE_ANDROID_H_
+#define DEVICE_USB_USB_INTERFACE_ANDROID_H_
+
+#include "base/android/scoped_java_ref.h"
+#include "device/usb/usb_descriptors.h"
+
+namespace device {
+
+class UsbInterfaceAndroid {
+ public:
+ // Register C++ methods exposed to Java using JNI.
+ static bool RegisterJNI(JNIEnv* env);
+
+ static UsbInterfaceDescriptor Convert(
+ JNIEnv* env,
+ const base::android::JavaRef<jobject>& usb_interface);
+};
+
+} // namespace device
+
+#endif // DEVICE_USB_USB_INTERFACE_ANDROID_H_
diff --git a/device/usb/usb_service_android.cc b/device/usb/usb_service_android.cc
index 45ce499..3bdf3bc 100644
--- a/device/usb/usb_service_android.cc
+++ b/device/usb/usb_service_android.cc
@@ -4,14 +4,30 @@
#include "device/usb/usb_service_android.h"
+#include <string>
+#include <vector>
+
+#include "base/android/context_utils.h"
#include "base/bind.h"
#include "base/location.h"
#include "base/thread_task_runner_handle.h"
-#include "device/usb/usb_device.h"
+#include "device/usb/usb_device_android.h"
+#include "jni/ChromeUsbService_jni.h"
+
+using base::android::AttachCurrentThread;
+using base::android::ScopedJavaLocalRef;
namespace device {
-UsbServiceAndroid::UsbServiceAndroid() {}
+// static
+bool UsbServiceAndroid::RegisterJNI(JNIEnv* env) {
+ return RegisterNativesImpl(env); // Generated in ChromeUsbService_jni.h
+}
+
+UsbServiceAndroid::UsbServiceAndroid() {
+ j_object_.Reset(Java_ChromeUsbService_create(
+ AttachCurrentThread(), base::android::GetApplicationContext()));
+}
UsbServiceAndroid::~UsbServiceAndroid() {}
@@ -20,9 +36,20 @@ scoped_refptr<UsbDevice> UsbServiceAndroid::GetDevice(const std::string& guid) {
}
void UsbServiceAndroid::GetDevices(const GetDevicesCallback& callback) {
- std::vector<scoped_refptr<UsbDevice>> empty;
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobjectArray> devices =
+ Java_ChromeUsbService_getDevices(env, j_object_.obj());
+ jsize length = env->GetArrayLength(devices.obj());
+
+ std::vector<scoped_refptr<UsbDevice>> results;
+ for (jsize i = 0; i < length; ++i) {
+ ScopedJavaLocalRef<jobject> raw_device(
+ env, env->GetObjectArrayElement(devices.obj(), i));
+ results.push_back(UsbDeviceAndroid::Create(env, raw_device));
+ }
+
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
- base::Bind(callback, empty));
+ base::Bind(callback, results));
}
} // namespace device
diff --git a/device/usb/usb_service_android.h b/device/usb/usb_service_android.h
index d1ffd9d..9cab438 100644
--- a/device/usb/usb_service_android.h
+++ b/device/usb/usb_service_android.h
@@ -5,6 +5,9 @@
#ifndef DEVICE_USB_USB_SERVICE_ANDROID_H_
#define DEVICE_USB_USB_SERVICE_ANDROID_H_
+#include <string>
+
+#include "base/android/scoped_java_ref.h"
#include "device/usb/usb_service.h"
namespace device {
@@ -13,11 +16,19 @@ namespace device {
// does not return any devices.
class UsbServiceAndroid : public UsbService {
public:
+ // Register C++ methods exposed to Java using JNI.
+ static bool RegisterJNI(JNIEnv* env);
+
UsbServiceAndroid();
~UsbServiceAndroid() override;
+ // UsbService:
scoped_refptr<UsbDevice> GetDevice(const std::string& guid) override;
void GetDevices(const GetDevicesCallback& callback) override;
+
+ private:
+ // Java object org.chromium.device.usb.ChromeUsbService.
+ base::android::ScopedJavaGlobalRef<jobject> j_object_;
};
} // namespace device