diff options
author | Mike Lockwood <lockwood@google.com> | 2015-06-08 13:52:02 -0700 |
---|---|---|
committer | Mike Lockwood <lockwood@google.com> | 2015-06-08 16:48:19 -0700 |
commit | 6d5a0f916499a69f28b860fd66d09b5025c30450 (patch) | |
tree | 7ea1e6899c8a12e19d180b3d4cf49d30532409bc /services/core/jni | |
parent | 5e4c382d15968c757fb9c5783cbd420156ea8ad2 (diff) | |
download | frameworks_base-6d5a0f916499a69f28b860fd66d09b5025c30450.zip frameworks_base-6d5a0f916499a69f28b860fd66d09b5025c30450.tar.gz frameworks_base-6d5a0f916499a69f28b860fd66d09b5025c30450.tar.bz2 |
UsbMidiDevice: Only keep ALSA devices open when device is in use
This should fix contention problems for apps using USB APIs to implement MIDI support
Bug: 20949468
Bug: 21630625
Change-Id: I32b44330ca0310a4693fd56a4b01ad399f82c1c9
Diffstat (limited to 'services/core/jni')
-rw-r--r-- | services/core/jni/com_android_server_UsbMidiDevice.cpp | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/services/core/jni/com_android_server_UsbMidiDevice.cpp b/services/core/jni/com_android_server_UsbMidiDevice.cpp index cb70144..06b9bc3 100644 --- a/services/core/jni/com_android_server_UsbMidiDevice.cpp +++ b/services/core/jni/com_android_server_UsbMidiDevice.cpp @@ -36,6 +36,7 @@ namespace android { static jclass sFileDescriptorClass; +static jfieldID sPipeFDField; static jint android_server_UsbMidiDevice_get_subdevice_count(JNIEnv *env, jobject /* thiz */, @@ -66,14 +67,15 @@ android_server_UsbMidiDevice_get_subdevice_count(JNIEnv *env, jobject /* thiz */ } static jobjectArray -android_server_UsbMidiDevice_open(JNIEnv *env, jobject /* thiz */, jint card, jint device, +android_server_UsbMidiDevice_open(JNIEnv *env, jobject thiz, jint card, jint device, jint subdevice_count) { char path[100]; snprintf(path, sizeof(path), "/dev/snd/midiC%dD%d", card, device); - jobjectArray fds = env->NewObjectArray(subdevice_count, sFileDescriptorClass, NULL); + // allocate one extra file descriptor for close pipe + jobjectArray fds = env->NewObjectArray(subdevice_count + 1, sFileDescriptorClass, NULL); if (!fds) { return NULL; } @@ -91,12 +93,27 @@ android_server_UsbMidiDevice_open(JNIEnv *env, jobject /* thiz */, jint card, ji env->DeleteLocalRef(fileDescriptor); } + // create a pipe to use for unblocking our input thread + int pipeFD[2]; + pipe(pipeFD); + jobject fileDescriptor = jniCreateFileDescriptor(env, pipeFD[0]); + env->SetObjectArrayElement(fds, subdevice_count, fileDescriptor); + env->DeleteLocalRef(fileDescriptor); + // store our end of the pipe in mPipeFD + env->SetIntField(thiz, sPipeFDField, pipeFD[1]); + return fds; } static void -android_server_UsbMidiDevice_close(JNIEnv *env, jobject /* thiz */, jobjectArray fds) +android_server_UsbMidiDevice_close(JNIEnv *env, jobject thiz, jobjectArray fds) { + // write to mPipeFD to unblock input thread + jint pipeFD = env->GetIntField(thiz, sPipeFDField); + write(pipeFD, &pipeFD, sizeof(pipeFD)); + close(pipeFD); + env->SetIntField(thiz, sPipeFDField, -1); + int count = env->GetArrayLength(fds); for (int i = 0; i < count; i++) { jobject fd = env->GetObjectArrayElement(fds, i); @@ -117,13 +134,18 @@ int register_android_server_UsbMidiDevice(JNIEnv *env) ALOGE("Can't find java/io/FileDescriptor"); return -1; } - sFileDescriptorClass = (jclass)env->NewGlobalRef(clazz);; + sFileDescriptorClass = (jclass)env->NewGlobalRef(clazz); clazz = env->FindClass("com/android/server/usb/UsbMidiDevice"); if (clazz == NULL) { ALOGE("Can't find com/android/server/usb/UsbMidiDevice"); return -1; } + sPipeFDField = env->GetFieldID(clazz, "mPipeFD", "I"); + if (sPipeFDField == NULL) { + ALOGE("Can't find UsbMidiDevice.mPipeFD"); + return -1; + } return jniRegisterNativeMethods(env, "com/android/server/usb/UsbMidiDevice", method_table, NELEM(method_table)); |