summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authoryhirano@chromium.org <yhirano@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-09 09:10:59 +0000
committeryhirano@chromium.org <yhirano@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-09 09:10:59 +0000
commitfa97e2ebf432aff3eaa0cb6612ee3e49f040b3f7 (patch)
tree0239dd74cabe859e27b27f7871f2532a9a69788d /media
parent1e6f9e28f1a353a64a8f15d9ba983dc2a2b97b56 (diff)
downloadchromium_src-fa97e2ebf432aff3eaa0cb6612ee3e49f040b3f7.zip
chromium_src-fa97e2ebf432aff3eaa0cb6612ee3e49f040b3f7.tar.gz
chromium_src-fa97e2ebf432aff3eaa0cb6612ee3e49f040b3f7.tar.bz2
[WebMIDI] Using UsbRequest.queue leads a crash on Android.
Calling UsbRequest.queue when UsbDeviceConnection.requestWait is called in another thread leads a crash on Android. This CL fixes it with UsbEndpoint.bulkTransfer. This is a workaround. I believe UsbRequest.queue should be thread safe. BUG=303596 Review URL: https://codereview.chromium.org/253293002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269191 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java41
1 files changed, 35 insertions, 6 deletions
diff --git a/media/base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java b/media/base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java
index a6cb24b..6a38747 100644
--- a/media/base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java
+++ b/media/base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java
@@ -53,6 +53,11 @@ class UsbMidiDeviceAndroid {
private boolean mIsClosed;
/**
+ * True if there is a thread processing input data.
+ */
+ private boolean mHasInputThread;
+
+ /**
* The identifier of this device.
*/
private long mNativePointer;
@@ -73,6 +78,7 @@ class UsbMidiDeviceAndroid {
mRequestMap = new HashMap<UsbEndpoint, UsbRequest>();
mHandler = new Handler();
mIsClosed = false;
+ mHasInputThread = false;
mNativePointer = 0;
for (int i = 0; i < device.getInterfaceCount(); ++i) {
@@ -124,6 +130,7 @@ class UsbMidiDeviceAndroid {
if (bufferForEndpoints.isEmpty()) {
return;
}
+ mHasInputThread = true;
// bufferForEndpoints must not be accessed hereafter on this thread.
new Thread() {
public void run() {
@@ -188,13 +195,35 @@ class UsbMidiDeviceAndroid {
if (endpoint == null) {
return;
}
- UsbRequest request = mRequestMap.get(endpoint);
- if (request == null) {
- request = new UsbRequest();
- request.initialize(mConnection, endpoint);
- mRequestMap.put(endpoint, request);
+ if (shouldUseBulkTransfer()) {
+ // We use bulkTransfer instead of UsbRequest.queue because queueing
+ // a UsbRequest is currently not thread safe.
+ // Note that this is not exactly correct because we don't care
+ // about the transfer attribute (bmAttribute) of the endpoint.
+ // See also:
+ // http://stackoverflow.com/questions/9644415/
+ // https://code.google.com/p/android/issues/detail?id=59467
+ //
+ // TODO(yhirano): Delete this block once the problem is fixed.
+ final int TIMEOUT = 100;
+ mConnection.bulkTransfer(endpoint, bs, 0, bs.length, TIMEOUT);
+ } else {
+ UsbRequest request = mRequestMap.get(endpoint);
+ if (request == null) {
+ request = new UsbRequest();
+ request.initialize(mConnection, endpoint);
+ mRequestMap.put(endpoint, request);
+ }
+ request.queue(ByteBuffer.wrap(bs), bs.length);
}
- request.queue(ByteBuffer.wrap(bs), bs.length);
+ }
+
+ /**
+ * Returns true if |bulkTransfer| should be used in |send|.
+ * See comments in |send|.
+ */
+ private boolean shouldUseBulkTransfer() {
+ return mHasInputThread;
}
/**