libusb を使用してUSBデバイスに接続するアプリケーションがあります。アプリケーションは今までうまく機能していました。Android 5.0 (Lollipop) では、SELinuxが USB デバイスをブロックしました。私はなんとか回避策を実行し、SELinux は USB をブロックしなくなりましたが、しばらくするとデバイスと電話の間のデータ転送がフリーズします (10 秒、30 秒、1 分など)。
NDK r10d を使用しています。
LogCat :
I/USBHelp(21136): entering iniUSB
I/USBHelp(21136): successfully initialized libusb
D/OpenGLRenderer(21136): Render dirty regions requested: true
D/Atlas(21136): Validating map...
I/Adreno-EGL(21136): <qeglDrvAPI_eglInitialize:410>: QUALCOMM Build: 10/24/14, 167c270, I68fa98814b
I/OpenGLRenderer(21136): Initialized EGL, version 1.4
D/OpenGLRenderer(21136): Enabling debug mode 0
JNI DETECTED ERROR IN APPLICATION: thread Thread[15,tid=21176,Native,Thread*=0xac85d800,peer=0x12c00200,"Thread-1044"] using JNIEnv* from thread Thread[16,tid=21177,Runnable,Thread*=0xac85dc00,peer=0x12c00260,"Thread-1045"]
in call to CallVoidMethod
from int nok.pack.Device.SendData(byte[], int)
"Thread-1044" prio=1 tid=15 Runnable
| group="main" sCount=0 dsCount=0 obj=0x12c00200 self=0xac85d800
| sysTid=21176 nice=0 cgrp=apps sched=0/0 handle=0xa3e2b700
| state=R schedstat=( 190490211 139839161 1498 ) utm=17 stm=2 core=0 HZ=100
| stack=0xa1189000-0xa118b000 stackSize=1036KB
| held mutexes= "mutator lock"(shared held)
#00 pc 00004c58 /system/lib/libbacktrace_libc++.so (UnwindCurrent::Unwind(unsigned int, ucontext*)+23)
#01 pc 000034c1 /system/lib/libbacktrace_libc++.so (Backtrace::Unwind(unsigned int, ucontext*)+8)
#02 pc 002526ad /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, char const*, art::mirror::ArtMethod*)+84)
#03 pc 0023618b /system/lib/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const+162)
#04 pc 000b1215 /system/lib/libart.so (art::JniAbort(char const*, char const*)+620)
#05 pc 000b1945 /system/lib/libart.so (art::JniAbortF(char const*, char const*, ...)+68)
#06 pc 000b4b35 /system/lib/libart.so (art::ScopedCheck::ScopedCheck(_JNIEnv*, int, char const*)+1172)
#07 pc 000bcf05 /system/lib/libart.so (art::CheckJNI::CallVoidMethod(_JNIEnv*, _jobject*, _jmethodID*, ...)+48)
#08 pc 0000fee8 /data/app/nok.pack.sample-1/lib/arm/libusbnok.so (cb_in+88)
#09 pc 000074b4 /data/app/nok.pack.sample-1/lib/arm/libusbnok.so (usbi_handle_transfer_completion+276)
#10 pc 0000ef20 /data/app/nok.pack.sample-1/lib/arm/libusbnok.so (???)
#11 pc 0000f888 /data/app/nok.pack.sample-1/lib/arm/libusbnok.so (???)
#12 pc 0000fa34 /data/app/nok.pack.sample-1/lib/arm/libusbnok.so (???)
#13 pc 0000800c /data/app/nok.pack.sample-1/lib/arm/libusbnok.so (???)
#14 pc 00008234 /data/app/nok.pack.sample-1/lib/arm/libusbnok.so (libusb_handle_events_timeout_completed+172)
#15 pc 000083a4 /data/app/nok.pack.sample-1/lib/arm/libusbnok.so (libusb_handle_events_completed+52)
#16 pc 00009258 /data/app/nok.pack.sample-1/lib/arm/libusbnok.so (???)
#17 pc 00009408 /data/app/nok.pack.sample-1/lib/arm/libusbnok.so (libusb_bulk_transfer+76)
#18 pc 00010304 /data/app/nok.pack.sample-1/lib/arm/libusbnok.so (Java_nok_pack_Device_SendData+120)
#19 pc 00001613 /data/dalvik-cache/arm/data@app@nok.pack.sample-1@base.apk@classes.dex (Java_nok_pack_Device_SendData___3BI+106)
at nok.pack.Device.SendData(Native method)
at nok.pack.Device.access$3(Device.java:30)
at nok.pack.Device$1.run(Device.java:96)
- locked <0x066c1f6a> (a nok.pack.Device$1)
at java.lang.Thread.run(Thread.java:818)
W/art(21136): Thread suspension timed out: 16
コード:
#define TIMEOUT_VIN -1
#define TIMEOUT_COUT -1
#define ENDPOINT_BULK_IN 0x61
#define ENDPOINT_BULK_OUT 0x12
#define USB_CHUNC_SIZE 512
libusb_context * ctx = NULL;
libusb_device_handle *dev_handle = NULL;
JNIEnv * callback_env;
jobject callback_obj;
jmethodID mid;
jclass cls;
struct libusb_transfer *transfer_in;
int do_exit = 1;
int grab_en = 1;
jint length;
void cb_in()
{
(*callback_env)->CallVoidMethod(callback_env, callback_obj, mid, 0);
do_exit = 1;
}
jint
Java_nok_pack_Device_DataRequest(JNIEnv * env, jobject this,
jbyteArray buffer_1, jbyteArray buffer_2, jint length_loc)
{
unsigned char* bufferPtr_1 = (unsigned char* )((*env)->GetByteArrayElements(env, buffer_1, NULL));
unsigned char* bufferPtr_2 = (unsigned char* )((*env)->GetByteArrayElements(env, buffer_2, NULL));
unsigned char* tmp;
length = length_loc;
transfer_in = libusb_alloc_transfer(0);
callback_env = env;
callback_obj = this;
cls = (*callback_env)->GetObjectClass(callback_env, callback_obj);
mid = (*callback_env)->GetMethodID(callback_env, cls, "RecCallback", "(I)V");
grab_en = 1;
do_exit = 0;
while(grab_en)
{
libusb_fill_bulk_transfer( transfer_in, dev_handle, ENDPOINT_BULK_IN,
bufferPtr_1, length, // Note: in_buffer is where input data written.
cb_in, NULL, // no user data
TIMEOUT_VIN); // wait untill data available
libusb_submit_transfer(transfer_in);
while ( !do_exit )
{
libusb_handle_events_completed(ctx, NULL);
}
tmp = bufferPtr_1;
bufferPtr_1 = bufferPtr_2;
bufferPtr_2 = tmp;
do_exit = 0;
}
if(NULL != dev_handle) libusb_close(dev_handle);
if(NULL != ctx) libusb_exit(ctx);
(*env)->ReleaseByteArrayElements(env,buffer_1, bufferPtr_1, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env,buffer_2, bufferPtr_2, JNI_ABORT);
}
jint
Java_nok_pack_Device_SendData(JNIEnv * env, jobject this,
jbyteArray cnfg, jint length)
{
int actual_length = 0;
jbyte* cnfgPtr = (*env)->GetByteArrayElements(env, cnfg, NULL);
int ret = libusb_bulk_transfer(dev_handle, ENDPOINT_BULK_OUT, cnfgPtr, length, &actual_length, TIMEOUT_COUT);
(*env)->ReleaseByteArrayElements(env,cnfg,cnfgPtr,JNI_ABORT);
return actual_length;
}