diff options
author | yhirano@chromium.org <yhirano@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-09 09:10:59 +0000 |
---|---|---|
committer | yhirano@chromium.org <yhirano@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-09 09:10:59 +0000 |
commit | fa97e2ebf432aff3eaa0cb6612ee3e49f040b3f7 (patch) | |
tree | 0239dd74cabe859e27b27f7871f2532a9a69788d /media | |
parent | 1e6f9e28f1a353a64a8f15d9ba983dc2a2b97b56 (diff) | |
download | chromium_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.java | 41 |
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; } /** |