#include #include #include #include #include "TerminalDevice.h" #include "PhoneDevice.h" #include "PhoneDevice2.h" #include #include #include #include #include #ifdef USING_BREAK_PAD #include "client/linux/handler/exception_handler.h" #include "client/linux/handler/minidump_descriptor.h" #endif #include #include #include "Camera.h" #include "Camera2Reader.h" #ifdef USING_BREAK_PAD bool DumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* context, bool succeeded) { LOGE("Dump path: %s\n", descriptor.path()); return succeeded; } #endif static jmethodID mRegisterTimerMid = 0; static jmethodID mRegisterHeartbeatMid = 0; static jmethodID mUnregisterTimerMid = 0; static jmethodID mUpdateTimeMid = 0; static jmethodID mRequestWakelockMid = 0; static jmethodID mReleaseWakelockMid = 0; static jmethodID mGetSystemInfoMid = 0; static jmethodID mRebootMid = 0; static jmethodID mEnableGpsMid = 0; static jmethodID mRequestPositionMid = 0; static jmethodID mWriteLogMid = 0; jint JNI_OnLoad(JavaVM* vm, void* reserved) { JNIEnv* env = NULL; jint result = -1; #if defined(JNI_VERSION_1_6) if (result==-1 && vm->GetEnv((void**)&env, JNI_VERSION_1_6) == JNI_OK) { result = JNI_VERSION_1_6; } #endif #if defined(JNI_VERSION_1_4) if (result==-1 && vm->GetEnv((void**)&env, JNI_VERSION_1_4) == JNI_OK) { result = JNI_VERSION_1_4; } #endif #if defined(JNI_VERSION_1_2) if (result==-1 && vm->GetEnv((void**)&env, JNI_VERSION_1_2) == JNI_OK) { result = JNI_VERSION_1_2; } #endif if(result == -1 || env == NULL) { return JNI_FALSE; } #ifdef USING_BREAK_PAD google_breakpad::MinidumpDescriptor descriptor("/sdcard/Android/data/com.xypower.mpapp/files/logs/"); google_breakpad::ExceptionHandler eh(descriptor, NULL, DumpCallback, NULL, true, -1); #endif const char* className = "com/xypower/mpapp/MicroPhotoService"; jclass clazz = (env)->FindClass(className); // if((env)->RegisterNatives(clazz, gMethods, 1)< 0) { // return -1; // } env->DeleteLocalRef(clazz); return result; } bool GetJniEnv(JavaVM *vm, JNIEnv **env, bool& didAttachThread) { didAttachThread = false; *env = nullptr; // Check if the current thread is attached to the VM auto get_env_result = vm->GetEnv((void**)env, JNI_VERSION_1_6); if (get_env_result == JNI_EDETACHED) { get_env_result = vm->AttachCurrentThread(env, NULL); if (get_env_result == JNI_OK) { didAttachThread = true; } else { // Failed to attach thread. Throw an exception if you want to. } } else if (get_env_result == JNI_EVERSION) { // Unsupported JNI version. Throw an exception if you want to. } return get_env_result == JNI_OK; } extern "C" JNIEXPORT jstring JNICALL Java_com_xypower_mpapp_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); } extern "C" JNIEXPORT jboolean JNICALL Java_com_xypower_mpapp_MainActivity_takePhoto( JNIEnv* env, jobject pThis, jint channel, jint preset, jstring path, jstring fileName) { // ANativeWindow *imgReaderAnw = ANativeWindow_fromSurface(env, surface); /* CCamera camera; camera.initCamera(imgReaderAnw); if (camera.isCameraReady()) { camera.takePicture(); } camera.closeCamera(); */ if (channel < 1 || channel > 0xFF) { return JNI_FALSE; } unsigned char id = (unsigned char)channel - 1; Camera2Reader *camera = new Camera2Reader(id); const char *pathStr = env->GetStringUTFChars(path, 0); const char *fileNameStr = env->GetStringUTFChars(fileName, 0); camera->Open(pathStr, fileNameStr); env->ReleaseStringUTFChars(fileName, fileNameStr); env->ReleaseStringUTFChars(path, pathStr); camera->start(); return JNI_TRUE; } extern "C" JNIEXPORT jlong JNICALL Java_com_xypower_mpapp_MicroPhotoService_init( JNIEnv* env, jobject pThis, jstring appPath, jstring ip, jint port, jstring cmdid, jint protocol, jint networkProtocol) { /* google_breakpad::MinidumpDescriptor descriptor("."); google_breakpad::ExceptionHandler eh(descriptor, NULL, NULL, NULL, true, -1); */ char model[PROP_VALUE_MAX] = { 0 }; __system_property_get("ro.product.model", model); jclass classService = env->GetObjectClass(pThis); jfieldID fieldId = env->GetFieldID(classService, "mModelName", "Ljava/lang/String;"); env->DeleteLocalRef(classService); jstring modelName = env->NewStringUTF(model); env->SetObjectField(pThis, fieldId, modelName); bool udpOrTcp = (networkProtocol != 0); // 0: tcp const char *appPathStr = env->GetStringUTFChars(appPath, 0); const char *ipStr = env->GetStringUTFChars(ip, 0); const char *cmdidStr = env->GetStringUTFChars(cmdid, 0); JavaVM* vm = NULL; jint ret = env->GetJavaVM(&vm); // const string& appPath, const string& termId, const string& server, unsigned short port, const string& bindIp // CTerminal* pTerminal = reinterpret_cast(handler); // CTerminalDevice* device = new CTerminalDevice(vm, pThis); // CPhoneDevice2* device = new CPhoneDevice2(vm, pThis); CTerminal* pTerminal = NewTerminal(protocol); CPhoneDevice* device = new CPhoneDevice(vm, pThis, appPathStr); device->SetListener(pTerminal); pTerminal->InitServerInfo(appPathStr, cmdidStr, ipStr, port, udpOrTcp); // pTerminal->SetPacketSize(1 * 1024); // 1K bool res = pTerminal->Startup(device); env->ReleaseStringUTFChars(appPath, appPathStr); env->ReleaseStringUTFChars(ip, ipStr); env->ReleaseStringUTFChars(cmdid, cmdidStr); if (!res) { delete pTerminal; pTerminal = NULL; } return reinterpret_cast(pTerminal); } extern "C" JNIEXPORT jboolean JNICALL Java_com_xypower_mpapp_MicroPhotoService_notifyToTakePhoto( JNIEnv* env, jobject pThis, jlong handler, jint channel, jint preset, jlong scheduleTime, jboolean sendToCma) { if (channel < 1 || channel > 0xFF) { return JNI_FALSE; } CTerminal* pTerminal = reinterpret_cast(handler); if (pTerminal == NULL) { return JNI_FALSE; } pTerminal->RequestCapture((unsigned int)channel, (unsigned int)preset, 0, (unsigned long)scheduleTime); return JNI_TRUE; } extern "C" JNIEXPORT jboolean JNICALL Java_com_xypower_mpapp_MicroPhotoService_sendHeartbeat( JNIEnv* env, jobject pThis, jlong handler) { CTerminal* pTerminal = reinterpret_cast(handler); if (pTerminal == NULL) { return JNI_FALSE; } pTerminal->SendHeartbeat(); return JNI_TRUE; } extern "C" JNIEXPORT jboolean JNICALL Java_com_xypower_mpapp_MicroPhotoService_fireTimeout( JNIEnv* env, jobject pThis, jlong handler, jlong uid, jlong times) { CTerminal* pTerminal = reinterpret_cast(handler); IDevice* dev = pTerminal->GetDevice(); if (dev == NULL) { return JNI_FALSE; } CPhoneDevice* phoneDevice = (CPhoneDevice *)dev; return phoneDevice->FireTimer((IDevice::timer_uid_t)uid, static_cast(times)) ? JNI_TRUE : JNI_FALSE; } extern "C" JNIEXPORT void JNICALL Java_com_xypower_mpapp_MicroPhotoService_updatePosition( JNIEnv* env, jobject pThis, jlong handler, jdouble lon, jdouble lat, jlong ts) { CTerminal* pTerminal = reinterpret_cast(handler); IDevice* dev = pTerminal->GetDevice(); if (dev == NULL) { return; } CPhoneDevice* phoneDevice = (CPhoneDevice *)dev; phoneDevice->UpdatePosition(lon, lat, ts); } extern "C" JNIEXPORT jboolean JNICALL Java_com_xypower_mpapp_MicroPhotoService_uninit( JNIEnv* env, jobject pThis, jlong handler) { CTerminal* pTerminal = reinterpret_cast(handler); if (pTerminal == NULL) { return JNI_FALSE; } IDevice* dev = pTerminal->GetDevice(); if (dev != NULL) { ((CPhoneDevice *)dev)->CloseCamera(); } pTerminal->SignalExit(); pTerminal->Shutdown(); delete pTerminal; return JNI_TRUE; } extern "C" JNIEXPORT jlong JNICALL Java_com_xypower_mpapp_MicroPhotoService_getHeartbeatDuration( JNIEnv* env, jobject pThis, jlong handler) { CTerminal* pTerminal = reinterpret_cast(handler); if (pTerminal == NULL) { return DEFAULT_HEARTBEAT_DURATION; } return pTerminal->GetHeartbeatDuration(); } extern "C" JNIEXPORT jlongArray JNICALL Java_com_xypower_mpapp_MicroPhotoService_getPhotoTimeData( JNIEnv* env, jobject pThis, jlong handler) { CTerminal* pTerminal = reinterpret_cast(handler); if (pTerminal == NULL) { return NULL; } map> photoTime; if (!pTerminal->GetPhotoTime(photoTime) || photoTime.empty()) { return NULL; } size_t numberOfData = photoTime.size() * photoTime.begin()->second.size(); if (numberOfData == 0) { return NULL; } vector dataArray; dataArray.reserve(numberOfData); unsigned long val = 0; jint channel = 0; for (map>::const_iterator it = photoTime.cbegin(); it != photoTime.cend(); ++it) { if (it->second.empty()) { continue; } channel = (jint)((unsigned short)it->first); // dataArray.push_back(channel); // val = (jint)it->second.size(); // dataArray.push_back(val); for (vector::const_iterator it2 = it->second.cbegin(); it2 != it->second.cend(); ++it2) { // time val = ((unsigned long)((*it2) & 0xFFFFFF00)) << 24; // channel val |= ((unsigned long)channel) << 16; // preset val |= ((unsigned long)((*it2) & 0xFF)) << 8; dataArray.push_back((jlong)val); } } std::sort(dataArray.begin(), dataArray.end()); jlongArray data = env->NewLongArray(dataArray.size()); if (data == NULL) { return NULL; } env->SetLongArrayRegion(data, 0, dataArray.size(), &dataArray[0]); return data; } /* extern "C" JNIEXPORT jlongArray JNICALL Java_com_xypower_mpapp_MicroPhotoService_getNextScheduleItem( JNIEnv* env, jobject pThis, jlong handler) { CTerminal* pTerminal = reinterpret_cast(handler); if (pTerminal == NULL) { return NULL; } map> photoTime; if (!pTerminal->GetPhotoTime(photoTime) || photoTime.empty()) { return NULL; } size_t numberOfData = photoTime.size() * photoTime.begin()->second.size(); if (numberOfData == 0) { return NULL; } vector dataArray; dataArray.reserve(numberOfData); unsigned long val = 0; jint channel = 0; for (map>::const_iterator it = photoTime.cbegin(); it != photoTime.cend(); ++it) { if (it->second.empty()) { continue; } channel = (jint)((unsigned short)it->first); // dataArray.push_back(channel); // val = (jint)it->second.size(); // dataArray.push_back(val); for (vector::const_iterator it2 = it->second.cbegin(); it2 != it->second.cend(); ++it2) { // time val = ((unsigned long)((*it2) & 0xFFFFFF00)) << 24; // channel val |= ((unsigned long)channel) << 16; // preset val |= ((unsigned long)((*it2) & 0xFF)) << 8; dataArray.push_back((jlong)val); } } std::sort(dataArray.begin(), dataArray.end()); jlongArray data = env->NewLongArray(dataArray.size()); if (data == NULL) { return NULL; } env->SetLongArrayRegion(data, 0, dataArray.size(), &dataArray[0]); return data; } */