//------------------------------------------------- void ofThread::run(){ #ifdef TARGET_ANDROID JNIEnv * env; jint attachResult = ofGetJavaVMPtr()->AttachCurrentThread(&env,NULL); if(attachResult!=0){ ofLogWarning() << "couldn't attach new thread to java vm"; } #endif // user function // should loop endlessly. try{ threadedFunction(); }catch(const Poco::Exception& exc){ ofLogFatalError("ofThreadErrorLogger::exception") << exc.displayText(); }catch(const std::exception& exc){ ofLogFatalError("ofThreadErrorLogger::exception") << exc.what(); }catch(...){ ofLogFatalError("ofThreadErrorLogger::exception") << "Unknown exception."; } _threadRunning = false; #if !defined(TARGET_WIN32) // FIXME: this won't be needed once we update POCO https://github.com/pocoproject/poco/issues/79 if(!threadBeingWaitedFor){ //if threadedFunction() ended and the thread is not being waited for, detach it before exiting. pthread_detach(pthread_self()); } #endif #ifdef TARGET_ANDROID attachResult = ofGetJavaVMPtr()->DetachCurrentThread(); #endif }
ofxAndroidMobileVision::ofxAndroidMobileVision() :threaded(true){ if(!ofGetJavaVMPtr()){ ofLogNotice("ofxAndroidMobileVision") << "couldn't find java virtual machine"; return; } JNIEnv *env; if (ofGetJavaVMPtr()->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { ofLogNotice("ofxAndroidMobileVision") << "failed to get environment using GetEnv()"; return; } jclass localClass = env->FindClass("cc/ofxandroidmobilevisionlib/ofxAndroidMobileVisionLib"); javaClass = (jclass) env->NewGlobalRef(localClass); if(!javaClass){ ofLogError("ofxAndroidMobileVision") << "constructor: couldn't get java class for MobileVision"; return; } jmethodID constructor = env->GetMethodID(javaClass,"<init>","()V"); if(!constructor){ ofLogError("ofxAndroidMobileVision") << "constructor: couldn't get java constructor for MobileVision"; return; } javaMobileVision = env->NewObject(javaClass,constructor); if(!javaMobileVision){ ofLogError("ofxAndroidMobileVision") << "constructor: couldn't create java MobileVision"; return; } javaMobileVision = (jobject)env->NewGlobalRef(javaMobileVision); }
//------------------------------------------------- void ofThread::run(){ #ifdef TARGET_ANDROID JNIEnv * env; jint attachResult = ofGetJavaVMPtr()->AttachCurrentThread(&env,nullptr); if(attachResult!=0){ ofLogWarning() << "couldn't attach new thread to java vm"; } #endif // user function // should loop endlessly. try{ threadedFunction(); }catch(const std::exception& exc){ ofLogFatalError("ofThreadErrorLogger::exception") << exc.what(); }catch(...){ ofLogFatalError("ofThreadErrorLogger::exception") << "Unknown exception."; } thread.detach(); #ifdef TARGET_ANDROID attachResult = ofGetJavaVMPtr()->DetachCurrentThread(); #endif std::unique_lock<std::mutex> lck(mutex); threadRunning = false; threadDone = true; condition.notify_all(); }
void ofxAndroidSoundStream::close(){ pause(); // JNI: Try to find and call OFAndroidSoundStream.getInstance().stop() if(!ofGetJavaVMPtr()){ ofLogError("ofxAndroidSoundStream") << "close(): couldn't find java virtual machine"; return; } JNIEnv *env = ofGetJNIEnv(); if (!env) { ofLogError("ofxAndroidSoundStream") << "close(): couldn't get environment using GetEnv()"; return; } jclass javaClass = env->FindClass("cc/openframeworks/OFAndroidSoundStream"); if(javaClass==0){ ofLogError("ofxAndroidSoundStream") << "close(): couldn't find OFAndroidSoundStream java class"; return; } jmethodID soundStreamSingleton = env->GetStaticMethodID(javaClass,"getInstance","()Lcc/openframeworks/OFAndroidSoundStream;"); if(!soundStreamSingleton){ ofLogError("ofxAndroidSoundStream") << "close(): couldn't find OFAndroidSoundStream singleton method"; return; } jobject javaObject = env->CallStaticObjectMethod(javaClass,soundStreamSingleton); jmethodID javaStop = env->GetMethodID(javaClass,"stop","()V"); // call stop() if(javaObject && javaStop) env->CallVoidMethod(javaObject,javaStop); else ofLogError("ofxAndroidSoundStream") << "close(): couldn't get OFAndroidSoundStream instance or stop method"; }
JNIEnv * ofGetJNIEnv(){ JNIEnv *env; JavaVM * vm = ofGetJavaVMPtr(); if(!vm){ ofLogError("ofAppAndroidWindow") << "couldn't get java virtual machine"; return NULL; } if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { ofLogError("ofAppAndroidWindow") << "couldn't get environment using GetEnv()"; return NULL; } return env; }
JNIEnv * ofGetJNIEnv(){ JNIEnv *env; JavaVM * vm = ofGetJavaVMPtr(); if(!vm){ ofLog(OF_LOG_ERROR,"couldn't get java vm"); return NULL; } if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { ofLog(OF_LOG_ERROR,"Failed to get the environment using GetEnv()"); return NULL; } return env; }
//------------------------------------------------- void ofThread::run() { #ifdef TARGET_ANDROID JNIEnv * env; jint attachResult = ofGetJavaVMPtr()->AttachCurrentThread(&env,NULL); if(attachResult!=0) { ofLogWarning() << "couldn't attach new thread to java vm"; } #endif // user function // should loop endlessly. threadedFunction(); _threadRunning = false; #if !defined(TARGET_WIN32) && !defined(TARGET_ANDROID) // FIXME: this won't be needed once we update POCO https://github.com/pocoproject/poco/issues/79 if(!threadBeingWaitedFor) { //if threadedFunction() ended and the thread is not being waited for, detach it before exiting. pthread_detach(pthread_self()); } #endif #ifdef TARGET_ANDROID attachResult = ofGetJavaVMPtr()->DetachCurrentThread(); #endif }
void ofxAccelerometerHandler::setup(){ if(!ofGetJavaVMPtr()){ ofLog(OF_LOG_ERROR,"ofxAccelerometerHandler: Cannot find java virtual machine"); return; } JNIEnv *env; if (ofGetJavaVMPtr()->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { ofLog(OF_LOG_ERROR,"Failed to get the environment using GetEnv()"); return; } jclass javaClass = env->FindClass("cc/openframeworks/OFAndroid"); if(javaClass==0){ ofLog(OF_LOG_ERROR,"cannot find OFAndroid java class"); return; } jmethodID setupAccelerometer = env->GetStaticMethodID(javaClass,"setupAccelerometer","()V"); if(!setupAccelerometer){ ofLog(OF_LOG_ERROR,"cannot find OFAndroid.setupAccelerometer method"); return; } env->CallStaticVoidMethod(javaClass,setupAccelerometer); }
void ofxCompassHandler::setup(){ if(!ofGetJavaVMPtr()){ ofLogError("ofxAndroidCompass") << "setup(): couldn't find java virtual machine"; return; } JNIEnv *env; if (ofGetJavaVMPtr()->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { ofLogError("ofxAndroidCompass") << "setup(): failed to get environment using GetEnv()"; return; } jclass javaClass = env->FindClass("cc/openframeworks/OFAndroid"); if(javaClass==0){ ofLogError("ofxAndroidCompass") << "setup(): couldn't find OFAndroid java class"; return; } jmethodID setupCompass = env->GetStaticMethodID(javaClass,"setupCompass","()V"); if(!setupCompass){ ofLogError("ofxAndroidCompass") << "setup(): couldn't find OFAndroid.setupCompass method"; return; } env->CallStaticVoidMethod(javaClass,setupCompass); }
bool ofxAndroidSoundStream::setup(int outChannels, int _inChannels, int _sampleRate, int bufferSize, int nBuffers){ if(instance!=NULL && instance!=this){ ofLogError("ofxAndroidSoundStream") << "setup(): multiple instances detected, only one instance allowed"; return false; } // Find the minimum input buffer size allowed by the Android device int input_buffer_size = _inChannels*getMinInBufferSize(_sampleRate,_inChannels) * 2; // setup size of input circular-buffer input_buffer.setup(input_buffer_size,0); // deallocate and reallocate if setup() is called more than once if(in_float_buffer != NULL){ delete[] in_float_buffer; } in_float_buffer = new float[bufferSize*_inChannels]; inBufferSize = bufferSize; inChannels = _inChannels; sampleRate = _sampleRate; tickCount = 0; requestedBufferSize = bufferSize; totalOutRequestedBufferSize = bufferSize*outChannels; totalInRequestedBufferSize = bufferSize*inChannels; // JNI: Try to find and call OFAndroidSoundStream.getInstance().setup(outChannels,inChannels,sampleRate,bufferSize,nBuffers) if(!ofGetJavaVMPtr()){ ofLogError("ofxAndroidSoundStream") << "setup(): couldn't find java virtual machine"; return false; } JNIEnv *env = ofGetJNIEnv(); if (!env) { ofLogError("ofxAndroidSoundStream") << "setup(): couldn't get environment using GetEnv()"; return false; } jclass javaClass = env->FindClass("cc/openframeworks/OFAndroidSoundStream"); if(javaClass==0){ ofLogError("ofxAndroidSoundStream") << "setup(): couldn't find OFAndroidSoundStream java class"; return false; } jmethodID soundStreamSingleton = env->GetStaticMethodID(javaClass,"getInstance","()Lcc/openframeworks/OFAndroidSoundStream;"); if(!soundStreamSingleton){ ofLogError("ofxAndroidSoundStream") << "setup(): couldn't find OFAndroidSoundStream singleton method"; return false; } jobject javaObject = env->CallStaticObjectMethod(javaClass,soundStreamSingleton); jmethodID javaSetup = env->GetMethodID(javaClass,"setup","(IIIII)V"); // call setup() if(javaObject && javaSetup) env->CallVoidMethod(javaObject,javaSetup,outChannels,inChannels,sampleRate,bufferSize,nBuffers); else ofLogError("ofxAndroidSoundStream") << "setup(): couldn't get OFAndroidSoundStream instance or setup method"; // Store instance pointer to ofxAndroidSoundStream (singleton pattern) instance = this; return true; }