#include #include #include #include #include #include "PhoneDevice.h" #include #include #include #include #include "ncnn/yolov5ncnn.h" #include #ifndef USING_N938 #define NRSEC_PATH "/dev/spidev0.0" #else #define NRSEC_PATH "/dev/spidev32766.0" #endif #ifdef USING_BREAK_PAD #include "client/linux/handler/exception_handler.h" #include "client/linux/handler/minidump_descriptor.h" #endif #ifdef USING_MQTT #include #endif #ifdef USING_FFMPEG extern "C" { #include } #endif #include #include #include "Camera2Reader.h" #include "GPIOControl.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 #ifdef USING_NRSEC #include #endif #include 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; void posix_signal_handler(int sig, siginfo_t *siginfo, void *context) { (void)context; switch(sig) { case SIGSEGV: fputs("Caught SIGSEGV: Segmentation Fault\n", stderr); break; case SIGINT: fputs("Caught SIGINT: Interactive attention signal, (usually ctrl+c)\n", stderr); break; case SIGFPE: switch(siginfo->si_code) { case FPE_INTDIV: fputs("Caught SIGFPE: (integer divide by zero)\n", stderr); break; case FPE_INTOVF: fputs("Caught SIGFPE: (integer overflow)\n", stderr); break; case FPE_FLTDIV: fputs("Caught SIGFPE: (floating-point divide by zero)\n", stderr); break; case FPE_FLTOVF: fputs("Caught SIGFPE: (floating-point overflow)\n", stderr); break; case FPE_FLTUND: fputs("Caught SIGFPE: (floating-point underflow)\n", stderr); break; case FPE_FLTRES: fputs("Caught SIGFPE: (floating-point inexact result)\n", stderr); break; case FPE_FLTINV: fputs("Caught SIGFPE: (floating-point invalid operation)\n", stderr); break; case FPE_FLTSUB: fputs("Caught SIGFPE: (subscript out of range)\n", stderr); break; default: fputs("Caught SIGFPE: Arithmetic Exception\n", stderr); break; } case SIGILL: switch(siginfo->si_code) { case ILL_ILLOPC: fputs("Caught SIGILL: (illegal opcode)\n", stderr); break; case ILL_ILLOPN: fputs("Caught SIGILL: (illegal operand)\n", stderr); break; case ILL_ILLADR: fputs("Caught SIGILL: (illegal addressing mode)\n", stderr); break; case ILL_ILLTRP: fputs("Caught SIGILL: (illegal trap)\n", stderr); break; case ILL_PRVOPC: fputs("Caught SIGILL: (privileged opcode)\n", stderr); break; case ILL_PRVREG: fputs("Caught SIGILL: (privileged register)\n", stderr); break; case ILL_COPROC: fputs("Caught SIGILL: (coprocessor error)\n", stderr); break; case ILL_BADSTK: fputs("Caught SIGILL: (internal stack error)\n", stderr); break; default: fputs("Caught SIGILL: Illegal Instruction\n", stderr); break; } break; case SIGTERM: fputs("Caught SIGTERM: a termination request was sent to the program\n", stderr); break; case SIGABRT: fputs("Caught SIGABRT: usually caused by an abort() or assert()\n", stderr); break; default: break; } _Exit(1); } class Runner { public: static void RequestCapture(CTerminal* pTerminal, unsigned int channel, unsigned int preset, unsigned int type, uint64_t scheduleTime); }; void Runner::RequestCapture(CTerminal* pTerminal, unsigned int channel, unsigned int preset, unsigned int type, uint64_t scheduleTime) { pTerminal->RequestCapture(channel, preset, type, scheduleTime); } #include #include #if 0 void sighandler(int sig) { __android_log_print(ANDROID_LOG_ERROR, "NativeCrash", "Caught signal %d", sig); exit(1); } #endif jint JNI_OnLoad(JavaVM* vm, void* reserved) { JNIEnv* env = NULL; jint result = -1; // 在 JNI_OnLoad 或其他初始化函数中注册 #if 0 signal(SIGSEGV, sighandler); #endif #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 #if 0 { struct sigaction sig_action = {}; sig_action.sa_sigaction = posix_signal_handler; sigemptyset(&sig_action.sa_mask); #ifdef __APPLE__ /* for some reason we backtrace() doesn't work on osx when we use an alternate stack */ sig_action.sa_flags = SA_SIGINFO; #else sig_action.sa_flags = SA_SIGINFO | SA_ONSTACK; #endif if (sigaction(SIGSEGV, &sig_action, NULL) != 0) { // err(1, "sigaction"); int aa = 0; } } const char* className = "com/xypower/mpapp/MicroPhotoService"; jclass clazz = (env)->FindClass(className); // if((env)->RegisterNatives(clazz, gMethods, 1)< 0) { // return -1; // } env->DeleteLocalRef(clazz); #endif curl_global_init(CURL_GLOBAL_ALL); #ifdef USING_MQTT mosquitto_lib_init(); #endif #ifdef USING_FFMPEG // av_register_all(); avformat_network_init(); #endif return result; } JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved) { #ifdef USING_MQTT mosquitto_lib_cleanup(); #endif curl_global_cleanup(); #ifdef USING_FFMPEG // av_register_all(); avformat_network_deinit(); #endif } 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 jboolean JNICALL Java_com_xypower_mpapp_MainActivity_takePhoto( JNIEnv* env, jobject pThis, jint channel, jint preset, jstring path, jstring fileName) { if (channel < 1 || channel > 0xFF) { return JNI_FALSE; } unsigned char id = (unsigned char)channel - 1; Camera2Reader *camera = new Camera2Reader(id); std::string pathStr = jstring2string(env, path); std::string fileNameStr = jstring2string(env, fileName); camera->Open(pathStr.c_str(), fileNameStr.c_str()); 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, jint encryptData, jlong netHandle, jint signalLevel, jint versionCode, jlong buildTime, jstring simcard, jstring tfCardPath, jstring nativeLibraryDir) { /* 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 std::string appPathStr = jstring2string(env, appPath); std::string ipStr = jstring2string(env, ip); std::string cmdidStr = jstring2string(env, cmdid); std::string simcardStr = jstring2string(env, simcard); std::string tfCardPathStr = jstring2string(env, tfCardPath); std::string nativeLibraryDirStr = jstring2string(env, nativeLibraryDir); 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, (uint64_t)netHandle, versionCode, nativeLibraryDirStr); device->SetListener(pTerminal); device->UpdateSignalLevel(signalLevel); device->SetBuildTime(buildTime / 1000); device->UpdateSimcard(simcardStr); device->UpdateTfCardPath(tfCardPathStr); pTerminal->InitServerInfo(appPathStr, cmdidStr, ipStr, port, udpOrTcp, encryptData); // pTerminal->SetPacketSize(1 * 1024); // 1K #if defined(USING_NRSEC) && !defined(USING_NRSEC_VPN) pTerminal->InitEncryptionInfo(simcardStr, "/dev/spidev0.0", ""); #endif #ifdef _DEBUG ALOGD("Call Startup"); #endif bool res = pTerminal->Startup(device); #ifdef _DEBUG ALOGD("Finish Startup"); #endif 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, jstring url, jint mediaType) { if (channel < 0 || channel > 0xFFFF) { return JNI_FALSE; } CTerminal* pTerminal = reinterpret_cast(handler); if (pTerminal == NULL) { return JNI_FALSE; } uint8_t type = (uint8_t)mediaType; // std::thread th(&Runner::RequestCapture, pTerminal, (unsigned int)channel, (unsigned int)preset, type, (uint64_t)scheduleTime, 0, true); // th.detach(); if (channel < 0x100) { if (mediaType == XY_MEDIA_TYPE_PHOTO || mediaType == XY_MEDIA_TYPE_VIDEO) { pTerminal->RequestCapture((uint32_t)channel, (unsigned int)preset, type, (uint64_t)scheduleTime, 0, true); } else if (mediaType == XY_MEDIA_TYPE_STREAM) { // virtual bool StartStream(unsigned char channel, unsigned char preset, const std::string& url, uint32_t* photoId = NULL); // virtual bool StopStream(unsigned char channel, unsigned char preset, uint32_t photoId); uint32_t photoId = 0; std::string urlStr = jstring2string(env, url); pTerminal->StartStream(channel, preset, urlStr, &photoId); } else if (mediaType == XY_MEDIA_TYPE_STREAM_OFF) { pTerminal->StopStream(channel, preset, 0); } } else { uint32_t packetType = channel; packetType &= 0xFF; pTerminal->RequestSampling(packetType, (uint64_t)scheduleTime, 0); } return JNI_TRUE; } extern "C" JNIEXPORT jlong JNICALL Java_com_xypower_mpapp_MicroPhotoService_takePhoto( JNIEnv* env, jclass cls, jint channel, jint preset, jboolean photoOrVideo, jstring configFilePath, jstring path) { if (channel < 1 || channel > 0xFF) { return 0; } JavaVM* vm = NULL; jint ret = env->GetJavaVM(&vm); std::string configFilePathStr = jstring2string(env, configFilePath); CFG_CHANNEL cfg; cfg.camera_id = channel - 1; cfg.quality = DEFAULT_JPEG_QUALITY; cfg.requestTemplate = 2; IDevice::PHOTO_INFO photoInfo(channel, preset); CTerminal::LoadChannelConfig(channel, configFilePathStr, cfg); CTerminal::ConvertChannelConfigToPhotoInfo(cfg, photoOrVideo != JNI_FALSE, photoInfo); CPhoneDevice* device = new CPhoneDevice(vm, NULL, "", NETID_UNSET, 0, std::string("")); // device->SetListener(pTerminal); if (photoInfo.usbCamera) { GpioControl::setOtgState(true); } GpioControl::setCam3V3Enable(true); std::vector osds; osds.resize(4); osds[1].alignment = IDevice::OSD_ALIGNMENT_TOP_RIGHT; osds[2].alignment = IDevice::OSD_ALIGNMENT_BOTTOM_RIGHT; osds[3].alignment = IDevice::OSD_ALIGNMENT_BOTTOM_LEFT; osds[0].text = cfg.osd.leftTop; osds[1].text = cfg.osd.rightTop; osds[2].text = cfg.osd.rightBottom; osds[3].text = cfg.osd.leftBottom; std::string pathStr = jstring2string(env, path); device->TakePhoto(photoInfo, osds, pathStr); // device->TurnOffCameraPower(NULL); // if (photoInfo.usbCamera) //{ // device->TurnOffOtg(NULL); //} return reinterpret_cast(device); } extern "C" JNIEXPORT void JNICALL Java_com_xypower_mpapp_MicroPhotoService_releaseDeviceHandle( JNIEnv* env, jclass cls, jlong deviceHandle) { if (deviceHandle != 0) { CPhoneDevice* pDevice = reinterpret_cast(deviceHandle); delete pDevice; } } extern "C" JNIEXPORT jboolean JNICALL Java_com_xypower_mpapp_MicroPhotoService_sendHeartbeat( JNIEnv* env, jobject pThis, jlong handler, jint signalLevel) { CTerminal* pTerminal = reinterpret_cast(handler); if (pTerminal == NULL) { return JNI_FALSE; } CPhoneDevice* device = (CPhoneDevice*)pTerminal->GetDevice(); if (device != NULL) { device->UpdateSignalLevel(signalLevel); } pTerminal->SendHeartbeat(); return JNI_TRUE; } extern "C" JNIEXPORT void JNICALL Java_com_xypower_mpapp_MicroPhotoService_updatePosition( JNIEnv* env, jobject pThis, jlong handler, jdouble lon, jdouble lat, jdouble radius, jlong ts) { if (handler == 0) { return; } CTerminal* pTerminal = reinterpret_cast(handler); IDevice* dev = pTerminal->GetDevice(); if (dev == NULL) { return; } CPhoneDevice* phoneDevice = (CPhoneDevice *)dev; phoneDevice->UpdatePosition(lon, lat, radius, 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; } XYLOG(XYLOG_SEVERITY_WARNING, "Will uninit service"); IDevice* dev = pTerminal->GetDevice(); if (dev != NULL) { ((CPhoneDevice *)dev)->CloseCamera(); } pTerminal->SignalExit(); pTerminal->Shutdown(); dev = pTerminal->GetDevice(); if (dev != NULL) { delete dev; } 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_getPhotoTimeData2( 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); uint64_t 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 = ((uint64_t)((*it2) & 0xFFFFFF00)) << 24; // channel val |= ((uint64_t)channel) << 16; // preset val |= ((uint64_t)((*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_getPhotoTimeData( JNIEnv* env, jobject pThis, jlong handler, jlong startTime) { CTerminal* pTerminal = reinterpret_cast(handler); if (pTerminal == NULL) { return NULL; } unsigned int scheduleTime = 0; time_t zeroPointTime = 0; std::vector > channelsAndPresets; if (!pTerminal->GetAndRefreshLatestScheduleTime(startTime, zeroPointTime, scheduleTime, channelsAndPresets)) { return NULL; } if (channelsAndPresets.empty()) { return NULL; } vector dataArray; dataArray.reserve(channelsAndPresets.size() + 3); dataArray.push_back((jlong)zeroPointTime); dataArray.push_back((jlong)scheduleTime); dataArray.push_back((jlong)channelsAndPresets.size()); uint64_t val = 0; for (std::vector >::const_iterator it = channelsAndPresets.cbegin(); it != channelsAndPresets.cend(); ++it) { val = (((uint64_t)scheduleTime) << 28); // channel val |= (((uint64_t)(it->first)) << 12); // preset val |= (((uint64_t)(it->second)) << 4); dataArray.push_back((jlong)val); } jlongArray data = env->NewLongArray(dataArray.size()); if (data == NULL) { return NULL; } env->SetLongArrayRegion(data, 0, dataArray.size(), &dataArray[0]); return data; } extern "C" JNIEXPORT jintArray JNICALL Java_com_xypower_mpapp_MicroPhotoService_recoganizePicture( JNIEnv* env, jclass cls, jstring paramPath, jstring binPath, jstring blobName8, jstring blobName16, jstring blobName32, jstring picPath) { std::string paramPathStr = jstring2string(env, paramPath); const char* pBinPathStr = env->GetStringUTFChars(binPath, 0); std::string binPathStr = MakeString(pBinPathStr); env->ReleaseStringUTFChars(binPath, pBinPathStr); const char* pBlobName8Str = env->GetStringUTFChars(blobName8, 0); std::string blobName8Str = MakeString(pBlobName8Str); env->ReleaseStringUTFChars(blobName8, pBlobName8Str); const char* pBlobName16Str = env->GetStringUTFChars(blobName16, 0); std::string blobName16Str = MakeString(pBlobName16Str); env->ReleaseStringUTFChars(blobName16, pBlobName16Str); const char* pBlobName32Str = env->GetStringUTFChars(blobName32, 0); std::string blobName32Str = MakeString(pBlobName32Str); env->ReleaseStringUTFChars(blobName32, pBlobName32Str); const char* pPicPathStr = env->GetStringUTFChars(picPath, 0); std::string picPathStr = MakeString(pPicPathStr); env->ReleaseStringUTFChars(picPath, pPicPathStr); cv::Mat mat = cv::imread(picPathStr); if (mat.empty()) { return NULL; } std::vector dataArray; ncnn_init(); ncnn::Net net; bool res = YoloV5Ncnn_Init(net, paramPathStr, binPathStr); if (res) { std::vector objs; res = YoloV5NcnnDetect(net, mat, true, blobName8Str, blobName16Str, blobName32Str, objs); if (res && !objs.empty()) { for (std::vector::const_iterator it = objs.cbegin(); it != objs.cend(); ++it) { // float x; // float y; // float w; // float h; // int label; // float prob; dataArray.push_back(it->x); dataArray.push_back(it->y); dataArray.push_back(it->w); dataArray.push_back(it->h); dataArray.push_back(it->label); dataArray.push_back((int)(it->prob * 100.0f)); } } } // ncnn_uninit(); if (dataArray.empty()) { return NULL; } jintArray data = env->NewIntArray(dataArray.size()); if (data == NULL) { return NULL; } env->SetIntArrayRegion(data, 0, dataArray.size(), &dataArray[0]); return data; } extern "C" JNIEXPORT void JNICALL Java_com_xypower_mpapp_MicroPhotoService_captureFinished( JNIEnv* env, jobject pThis, jlong handler, jboolean photoOrVideo, jboolean result, jobject bitmap, jlong photoId) { CTerminal* pTerminal = reinterpret_cast(handler); if (pTerminal == NULL) { return; } IDevice* dev = pTerminal->GetDevice(); if (dev != NULL) { if (result == JNI_FALSE || bitmap == NULL) { cv::Mat mat; ((CPhoneDevice *)dev)->OnCaptureReady(photoOrVideo != JNI_FALSE, result != JNI_FALSE, mat, (uint64_t)photoId); return; } AndroidBitmapInfo info = { 0 }; int res = AndroidBitmap_getInfo(env, bitmap, &info); if (res < 0 || info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) { } bool hardwareBitmap = (info.flags & ANDROID_BITMAP_FLAGS_IS_HARDWARE) != 0; void* pixels = NULL; AHardwareBuffer* hardwareBuffer = NULL; if (hardwareBitmap) { #if 0 res = AndroidBitmap_getHardwareBuffer(env, bitmap, &hardwareBuffer); int32_t fence = -1; res = AHardwareBuffer_lock(hardwareBuffer, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, fence, NULL, &pixels); cv::Mat mat(info.height, info.width, CV_8UC4, pixels); AHardwareBuffer_unlock(hardwareBuffer, &fence); cv::cvtColor(mat, mat, cv::COLOR_RGB2BGR); ((CPhoneDevice *)dev)->OnCaptureReady(photoOrVideo != JNI_FALSE, result != JNI_FALSE, mat, (uint64_t)photoId); #endif // 0 } else { res = AndroidBitmap_lockPixels(env, bitmap, &pixels); cv::Mat tmp(info.height, info.width, CV_8UC4, pixels); cv::Mat raw(info.height, info.width, CV_8UC4); // tmp.copyTo(mat); cv::cvtColor(tmp, raw, cv::COLOR_RGBA2BGR); cv::Mat mat; cv::fastNlMeansDenoisingColored(raw, mat, 13, 13, 7, 21); AndroidBitmap_unlockPixels(env, bitmap); ((CPhoneDevice *)dev)->OnCaptureReady(photoOrVideo != JNI_FALSE, result != JNI_FALSE, mat, (uint64_t)photoId); } } } extern "C" JNIEXPORT void JNICALL Java_com_xypower_mpapp_MicroPhotoService_burstCaptureFinished( JNIEnv* env, jobject pThis, jlong handler, jboolean result, jint numberOfCaptures, jstring pathsJoinedByTab, jboolean frontCamera, jint rotation, jlong photoId) { CTerminal* pTerminal = reinterpret_cast(handler); if (pTerminal == NULL) { return; } /// HDRPlus #ifdef USING_HDRPLUS #endif IDevice* dev = pTerminal->GetDevice(); if (dev != NULL) { if (result == JNI_FALSE) { cv::Mat mat; ((CPhoneDevice *)dev)->OnCaptureReady(true, false, mat, (uint64_t)photoId); return; } #if 0 const char* pathsStr = env->GetStringUTFChars(pathsJoinedByTab, 0); ((CPhoneDevice *)dev)->ProcessRawCapture(result != JNI_FALSE, numberOfCaptures, MakeString(pathsStr), frontCamera != JNI_FALSE, rotation, photoId); env->ReleaseStringUTFChars(pathsJoinedByTab, pathsStr); #endif } } extern "C" JNIEXPORT void JNICALL Java_com_xypower_mpapp_MicroPhotoService_recordingFinished( JNIEnv* env, jobject pThis, jlong handler, jboolean photoOrVideo, jboolean result, jstring path, jlong videoId) { CTerminal* pTerminal = reinterpret_cast(handler); if (pTerminal == NULL) { return; } IDevice* dev = pTerminal->GetDevice(); if (dev != NULL) { const char *pathStr = NULL; if (path != NULL) { pathStr = env->GetStringUTFChars(path, 0); } // camera->Open(pathStr, fileNameStr); uint64_t photoId = videoId; ((CPhoneDevice *)dev)->OnVideoReady(photoOrVideo != JNI_FALSE, result != JNI_FALSE, pathStr, photoId); if (path != NULL) { env->ReleaseStringUTFChars(path, pathStr); } } } extern "C" JNIEXPORT jboolean JNICALL Java_com_xypower_mpapp_MicroPhotoService_reloadConfigs( JNIEnv* env, jobject pThis, jlong handler) { CTerminal* pTerminal = reinterpret_cast(handler); if (pTerminal == NULL) { return JNI_FALSE; } bool res = pTerminal->LoadAppConfigs(); return res ? JNI_TRUE : JNI_FALSE; } extern "C" JNIEXPORT jboolean JNICALL Java_com_xypower_mpapp_MicroPhotoService_sendExternalPhoto( JNIEnv* env, jclass cls, jlong handler, jstring path, jlong photoInfo) { CTerminal* pTerminal = reinterpret_cast(handler); if (pTerminal == NULL) { return JNI_FALSE; } if (env->GetStringUTFLength(path) <=0) { return JNI_FALSE; } IDevice::PHOTO_INFO* pPhotoInfo = photoInfo == 0 ? NULL : reinterpret_cast(photoInfo); const char *pathStr = NULL; if (path != NULL) { pathStr = env->GetStringUTFChars(path, 0); } bool res = pTerminal->SendExternalPhoto(pathStr); if (pathStr != NULL) { env->ReleaseStringUTFChars(path, pathStr); } if (pPhotoInfo != NULL) { delete pPhotoInfo; } return res ? JNI_TRUE : JNI_FALSE; } extern "C" JNIEXPORT void JNICALL Java_com_xypower_mpapp_MicroPhotoService_infoLog( JNIEnv* env, jclass cls, jstring msg) { if (env->GetStringUTFLength(msg) <=0) { return; } std::string str = jstring2string(env, msg); XYLOG(XYLOG_SEVERITY_INFO, str.c_str()); } extern "C" JNIEXPORT jboolean JNICALL Java_com_xypower_mpapp_MicroPhotoService_usingEthernet( JNIEnv* env, jclass cls) { #ifdef USING_ETHERNET return JNI_TRUE; #else return JNI_FALSE; #endif } extern "C" JNIEXPORT void JNICALL Java_com_xypower_mpapp_MicroPhotoService_setOtgState( JNIEnv* env, jclass cls, jboolean enabled) { GpioControl::setOtgState(enabled != JNI_FALSE); } extern "C" JNIEXPORT void JNICALL Java_com_xypower_mpapp_MicroPhotoService_setCam3V3Enable( JNIEnv* env, jclass cls, jboolean enabled) { GpioControl::setCam3V3Enable(enabled != JNI_FALSE); } extern "C" JNIEXPORT jstring JNICALL Java_com_xypower_mpapp_MicroPhotoService_getSerialNumber( JNIEnv* env, jclass cls) { char value[PROP_VALUE_MAX] = { 0 }; __system_property_get("ro.serialno", value); return env->NewStringUTF(value); } extern "C" JNIEXPORT jboolean JNICALL Java_com_xypower_mpapp_MicroPhotoService_importPublicKeyFile( JNIEnv* env, jclass cls, jint index, jstring outputPath, jstring md5) { #ifdef USING_NRSEC if (env->GetStringUTFLength(outputPath) <=0) { return JNI_FALSE; } const char *outputPathStr = env->GetStringUTFChars(outputPath, 0); std::vector data; bool res = readFile(outputPathStr, data); env->ReleaseStringUTFChars(outputPath, outputPathStr); if (!res || data.empty()) { return JNI_FALSE; } const char *md5Str = env->GetStringUTFChars(md5, 0); GpioControl::setCam3V3Enable(true); GpioControl::setSpiPower(true); NrsecPort nrsec; const char *path = NRSEC_PATH; res = nrsec.Open(path); if (res) { res = nrsec.SM2ImportPublicKey(index, &data[0]) == 0; nrsec.Close(); } GpioControl::setSpiPower(false); GpioControl::setCam3V3Enable(false); env->ReleaseStringUTFChars(md5, md5Str); return res ? JNI_TRUE : JNI_FALSE; #else return JNI_FALSE; #endif } extern "C" JNIEXPORT jboolean JNICALL Java_com_xypower_mpapp_MicroPhotoService_importPublicKey( JNIEnv* env, jclass cls, jint index, jbyteArray cert) { #ifdef USING_NRSEC int byteCertLen = env->GetArrayLength(cert); if (byteCertLen <= 0) { return JNI_FALSE; } GpioControl::setCam3V3Enable(true); GpioControl::setSpiPower(true); NrsecPort nrsec; const char *path = NRSEC_PATH; bool res = nrsec.Open(path); if (res) { jbyte* byteCert = env->GetByteArrayElements(cert, 0); res = nrsec.SM2ImportPublicKey(index, (const uint8_t*)byteCert) == 0; nrsec.Close(); env->ReleaseByteArrayElements(cert, byteCert, JNI_ABORT); } GpioControl::setSpiPower(false); GpioControl::setCam3V3Enable(false); return res ? JNI_TRUE : JNI_FALSE; #else return JNI_FALSE; #endif } extern "C" JNIEXPORT jboolean JNICALL Java_com_xypower_mpapp_MicroPhotoService_importPrivateKey( JNIEnv* env, jclass cls, jint index, jbyteArray cert) { #ifdef USING_NRSEC int byteCertLen = env->GetArrayLength(cert); if (byteCertLen <= 0) { return JNI_FALSE; } GpioControl::setCam3V3Enable(true); GpioControl::setSpiPower(true); NrsecPort nrsec; const char *path = NRSEC_PATH; bool res = nrsec.Open(path); if (res) { jbyte* byteCert = env->GetByteArrayElements(cert, 0); res = nrsec.SM2ImportPrivateKey(index, (const uint8_t*)byteCert) == 0; nrsec.Close(); env->ReleaseByteArrayElements(cert, byteCert, JNI_ABORT); } GpioControl::setSpiPower(false); GpioControl::setCam3V3Enable(false); return res ? JNI_TRUE : JNI_FALSE; #else return JNI_FALSE; #endif } extern "C" JNIEXPORT jint JNICALL Java_com_xypower_mpapp_MicroPhotoService_getGpioInt( JNIEnv* env, jclass cls, jint cmd) { return GpioControl::getInt(cmd); } extern "C" JNIEXPORT jboolean JNICALL Java_com_xypower_mpapp_MicroPhotoService_genKeys( JNIEnv* env, jclass cls, jint index) { #ifdef USING_NRSEC GpioControl::setCam3V3Enable(true); GpioControl::setSpiPower(true); const char *path = NRSEC_PATH; NrsecPort nrsec; bool res = nrsec.Open(path); if (res) { res = nrsec.SM2keypair(index) == 0; nrsec.Close(); } GpioControl::setSpiPower(false); GpioControl::setCam3V3Enable(false); return res ? JNI_TRUE : JNI_FALSE; #else return JNI_FALSE; #endif } extern "C" JNIEXPORT jstring JNICALL Java_com_xypower_mpapp_MicroPhotoService_querySecVersion( JNIEnv* env, jclass cls) { std::string version; #ifdef USING_NRSEC GpioControl::setCam3V3Enable(true); GpioControl::setSpiPower(true); const char *path = NRSEC_PATH; NrsecPort nrsec; bool res = nrsec.Open(path); if (res) { version = nrsec.Version(); nrsec.Close(); } GpioControl::setSpiPower(false); GpioControl::setCam3V3Enable(false); #endif return env->NewStringUTF(version.c_str()); } extern "C" JNIEXPORT jboolean JNICALL Java_com_xypower_mpapp_MicroPhotoService_genCertRequest( JNIEnv* env, jclass cls, jint index, jint type, jstring subject, jstring outputPath) { #ifdef USING_NRSEC if (env->GetStringUTFLength(subject) <=0 || env->GetStringUTFLength(outputPath) <=0) { return JNI_FALSE; } const char *path = NRSEC_PATH; GpioControl::setCam3V3Enable(true); GpioControl::setSpiPower(true); uint8_t output[1024] = { 0 }; uint16_t len = 0; NrsecPort nrsec; bool res = nrsec.Open(path); if (res) { const char* subjectStr = env->GetStringUTFChars(subject, 0); res = nrsec.SM2cert(type, index, MakeString(subjectStr), output, &len) == 0; nrsec.Close(); env->ReleaseStringUTFChars(subject, subjectStr); } GpioControl::setSpiPower(false); GpioControl::setCam3V3Enable(false); if (res) { const char* outputPathStr = env->GetStringUTFChars(outputPath, 0); res = writeFile(outputPathStr, output, len); env->ReleaseStringUTFChars(outputPath, outputPathStr); } return res ? JNI_TRUE : JNI_FALSE; #else return JNI_FALSE; #endif } extern "C" JNIEXPORT jboolean JNICALL Java_com_xypower_mpapp_MicroPhotoService_importPrivateKeyFile( JNIEnv* env, jclass cls, jint index, jstring keyFilePath, jstring md5) { #ifdef USING_NRSEC if (env->GetStringUTFLength(keyFilePath) <= 0) { return JNI_FALSE; } bool res = false; std::vector data; const char *keyFilePathStr = env->GetStringUTFChars(keyFilePath, 0); res = readFile(keyFilePathStr, data); env->ReleaseStringUTFChars(keyFilePath, keyFilePathStr); if (!res || data.empty()) { return JNI_FALSE; } const char *path = NRSEC_PATH; GpioControl::setCam3V3Enable(true); GpioControl::setSpiPower(true); NrsecPort nrsec; res = nrsec.Open(path); if (res) { res = nrsec.SM2ImportPrivateKey(index, &data[0]) == 0; nrsec.Close(); } GpioControl::setSpiPower(false); GpioControl::setCam3V3Enable(false); // const char *md5Str = env->GetStringUTFChars(md5, 0); // env->ReleaseStringUTFChars(md5, md5Str); return res ? JNI_TRUE : JNI_FALSE; #else return JNI_FALSE; #endif } extern "C" JNIEXPORT jboolean JNICALL Java_com_xypower_mpapp_MicroPhotoService_exportPublicKeyFile( JNIEnv* env, jclass cls, jint index, jstring outputPath) { #ifdef USING_NRSEC if (env->GetStringUTFLength(outputPath) <= 0) { return JNI_FALSE; } const char *path = NRSEC_PATH; uint8_t len = 0; std::vector data(64, 0); GpioControl::setCam3V3Enable(true); GpioControl::setSpiPower(true); NrsecPort nrsec; bool res = nrsec.Open(path); if (res) { res = nrsec.SM2ExportPublicKey(index, &data[0], &len) == 0; nrsec.Close(); } GpioControl::setSpiPower(false); GpioControl::setCam3V3Enable(false); if (res) { const char* outputPathStr = env->GetStringUTFChars(outputPath, 0); res = writeFile(outputPathStr, &data[0], len); env->ReleaseStringUTFChars(outputPath, outputPathStr); } return res ? JNI_TRUE : JNI_FALSE; #else return JNI_FALSE; #endif } extern "C" JNIEXPORT jboolean JNICALL Java_com_xypower_mpapp_MicroPhotoService_exportPrivateFile( JNIEnv* env, jclass cls, jint index, jstring outputPath) { #ifdef USING_NRSEC if (env->GetStringUTFLength(outputPath) <= 0) { return JNI_FALSE; } const char *path = NRSEC_PATH; GpioControl::setCam3V3Enable(true); GpioControl::setSpiPower(true); NrsecPort nrsec; if (!nrsec.Open(path)) { return JNI_FALSE; } bool res = false; std::vector data(64, 0); uint8_t len = 0; res = nrsec.SM2ExportPrivateKey(index, &data[0], &len) == 0; nrsec.Close(); GpioControl::setSpiPower(false); GpioControl::setCam3V3Enable(false); if (res) { const char *outputPathStr = env->GetStringUTFChars(outputPath, 0); res = writeFile(outputPathStr, &data[0], len); env->ReleaseStringUTFChars(outputPath, outputPathStr); } return res ? JNI_TRUE : JNI_FALSE; #else return JNI_FALSE; #endif } extern "C" JNIEXPORT jboolean JNICALL Java_com_xypower_mpapp_MicroPhotoService_updateEhernet( JNIEnv* env, jobject pThis, jlong handle, jlong networkHandle, jboolean available) { CTerminal* pTerminal = reinterpret_cast(handle); if (pTerminal == NULL) { return JNI_FALSE; } CPhoneDevice* device = (CPhoneDevice*)pTerminal->GetDevice(); if (device != NULL) { bool changed = false; device->UpdateNetwork(static_cast(networkHandle), available != JNI_FALSE, false, changed); if (changed) { XYLOG(XYLOG_SEVERITY_DEBUG, "Ethernet Changed and Check socket connection"); pTerminal->ResetNetwork(); } else { XYLOG(XYLOG_SEVERITY_DEBUG, "Ethernet Changing Not Cause Socket Disconnection"); } } return JNI_TRUE; } extern "C" JNIEXPORT jboolean JNICALL Java_com_xypower_mpapp_MicroPhotoService_updateActiveNetwork( JNIEnv* env, jobject pThis, jlong handle, jlong networkHandle, jboolean available) { CTerminal* pTerminal = reinterpret_cast(handle); if (pTerminal == NULL) { return JNI_FALSE; } CPhoneDevice* device = (CPhoneDevice*)pTerminal->GetDevice(); if (device != NULL) { bool changed = false; device->UpdateNetwork(static_cast(networkHandle), available != JNI_FALSE, true, changed); } return JNI_TRUE; } extern "C" JNIEXPORT jlong JNICALL Java_com_xypower_mpapp_MicroPhotoService_requestPowerControl( JNIEnv* env, jclass cls, jint type) { if (type == 1) // Net { NetCameraPowerCtrl* powerControl = new NetCameraPowerCtrl(2); return reinterpret_cast(powerControl); } return 0L; } extern "C" JNIEXPORT jboolean JNICALL Java_com_xypower_mpapp_MicroPhotoService_releasePowerControl( JNIEnv* env, jclass cls, jlong powerControlHandle) { PowerControl* powerControl = reinterpret_cast(powerControlHandle); delete powerControl; return JNI_TRUE; } extern "C" JNIEXPORT jint JNICALL Java_com_xypower_mpapp_MicroPhotoService_getCustomAppId(JNIEnv *env, jobject thiz) { #ifdef USING_N938 return 2; #elif defined(USING_PTZ) return 1; #else return 0; #endif } extern "C" JNIEXPORT void JNICALL Java_com_xypower_mpapp_MicroPhotoService_sendCameraCtrl( JNIEnv* env, jobject pThis, jlong handle, jint channel, jint preset, jint cmd) { CTerminal* pTerminal = reinterpret_cast(handle); if (pTerminal == NULL) { return; } pTerminal->SendCameraCtrl(channel, preset, cmd); }