From 2a3476786b612882df3b1ff5edcbb5656dfb67e6 Mon Sep 17 00:00:00 2001 From: Matthew Date: Sun, 17 Sep 2023 15:23:18 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AE=9A=E6=97=B6=E6=8B=8D?= =?UTF-8?q?=E7=85=A7bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 4 +- app/src/main/AndroidManifest.xml | 4 +- app/src/main/cpp/Camera.cpp | 5 +- app/src/main/cpp/MicroPhoto.cpp | 26 +-- app/src/main/cpp/PhoneDevice.cpp | 151 ++++++++------ app/src/main/cpp/PhoneDevice.h | 9 +- app/src/main/cpp/PhoneDevice2.cpp | 129 +++++++----- app/src/main/cpp/PhoneDevice2.h | 5 - app/src/main/cpp/TerminalDevice.cpp | 17 +- app/src/main/cpp/camera2/Camera2Helper.h | 18 ++ app/src/main/cpp/camera2/ndkcamera.cpp | 140 ++++++++++++- app/src/main/cpp/camera2/ndkcamera.h | 25 +++ .../microphoto/FloatingWindow.java | 9 +- .../xinyingpower/microphoto/MainActivity.java | 44 ++--- .../microphoto/MicroPhotoService.java | 187 +++++++++--------- .../microphoto/ScreenActionReceiver.java | 3 - 16 files changed, 503 insertions(+), 273 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index b9d79815..c0bc9584 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,8 +2,8 @@ plugins { id 'com.android.application' } -def AppVersionName = "1.0.4" -def AppVersionCode = ((1 * 100 + 1) * 100 + 0) * 10 + 4 +def AppVersionName = "1.0.5" +def AppVersionCode = ((1 * 100 + 1) * 100 + 0) * 10 + 5 android { namespace 'com.xinyingpower.microphoto' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e201e81f..eb66fe2b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -32,8 +32,8 @@ - + + - -#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) -#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) -#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) +#include CCamera::CCamera() { diff --git a/app/src/main/cpp/MicroPhoto.cpp b/app/src/main/cpp/MicroPhoto.cpp index 962dd2e6..b11e375e 100644 --- a/app/src/main/cpp/MicroPhoto.cpp +++ b/app/src/main/cpp/MicroPhoto.cpp @@ -16,18 +16,17 @@ #include "Camera.h" #include "Camera2Reader.h" - - -bool GetJniEnv(JavaVM *vm, JNIEnv **env) +bool GetJniEnv(JavaVM *vm, JNIEnv **env, bool& didAttachThread) { - bool did_attach_thread = false; + 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) { - if (vm->AttachCurrentThread(env, NULL) == JNI_OK) { - did_attach_thread = true; + 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. } @@ -36,10 +35,9 @@ bool GetJniEnv(JavaVM *vm, JNIEnv **env) // Unsupported JNI version. Throw an exception if you want to. } - return did_attach_thread; + return get_env_result == JNI_OK; } - // #include "client/linux/handler/exception_handler.h" // #include "client/linux/handler/minidump_descriptor.h" @@ -92,7 +90,7 @@ Java_com_xinyingpower_microphoto_MainActivity_takePhoto( extern "C" JNIEXPORT jlong JNICALL Java_com_xinyingpower_microphoto_MicroPhotoService_init( JNIEnv* env, - jobject pThis, jstring appPath, jstring ip, jint port, jstring cmdid) { + jobject pThis, jstring appPath, jstring ip, jint port, jstring cmdid, jint protocol) { /* google_breakpad::MinidumpDescriptor descriptor("."); @@ -125,6 +123,12 @@ Java_com_xinyingpower_microphoto_MicroPhotoService_init( env->ReleaseStringUTFChars(ip, ipStr); env->ReleaseStringUTFChars(cmdid, cmdidStr); + if (!res) + { + delete pTerminal; + pTerminal = NULL; + } + return reinterpret_cast(pTerminal); } @@ -170,7 +174,7 @@ Java_com_xinyingpower_microphoto_MicroPhotoService_sendHeartbeat( extern "C" JNIEXPORT jboolean JNICALL Java_com_xinyingpower_microphoto_MicroPhotoService_fireTimeout( JNIEnv* env, - jobject pThis, jlong handler, jlong uid) { + jobject pThis, jlong handler, jlong uid, jlong times) { CTerminal* pTerminal = reinterpret_cast(handler); IDevice* dev = pTerminal->GetDevice(); @@ -180,7 +184,7 @@ Java_com_xinyingpower_microphoto_MicroPhotoService_fireTimeout( } CPhoneDevice* phoneDevice = (CPhoneDevice *)dev; - return phoneDevice->FireTimer((IDevice::timer_uid_t)uid) ? JNI_TRUE : JNI_FALSE; + return phoneDevice->FireTimer((IDevice::timer_uid_t)uid, static_cast(times)) ? JNI_TRUE : JNI_FALSE; } extern "C" JNIEXPORT jboolean JNICALL diff --git a/app/src/main/cpp/PhoneDevice.cpp b/app/src/main/cpp/PhoneDevice.cpp index 9d2acf2a..872bc59a 100644 --- a/app/src/main/cpp/PhoneDevice.cpp +++ b/app/src/main/cpp/PhoneDevice.cpp @@ -17,7 +17,7 @@ */ #define LOG_TAG "CameraTestHelpers" - +#include #include "PhoneDevice.h" #include @@ -33,15 +33,8 @@ #include #include -#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) -#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) -#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) -#define ASSERT(cond, fmt, ...) \ - if (!(cond)) { \ - __android_log_assert(#cond, LOG_TAG, fmt, ##__VA_ARGS__); \ - } -extern bool GetJniEnv(JavaVM *vm, JNIEnv **env); +extern bool GetJniEnv(JavaVM *vm, JNIEnv **env, bool& didAttachThread); #define WAKELOCK_NAME "NDK_WK_" // This value is 2 ^ 18 - 1, and is used to clamp the RGB values before their @@ -166,14 +159,20 @@ CPhoneDevice::CPhoneDevice(JavaVM* vm, jobject service) m_listener = NULL; mHeartbeatStartTime = 0; mHeartbeatDuration = 0; + m_javaService = NULL; m_vm = vm; JNIEnv* env = NULL; - bool attached = GetJniEnv(m_vm, &env); + bool didAttachThread = false; + bool res = GetJniEnv(m_vm, &env, didAttachThread); + if (!res) + { + ALOGE("Failed to get JNI Env"); + } m_javaService = env->NewGlobalRef(service); jclass classService = env->GetObjectClass(m_javaService); - mRegisterTimerMid = env->GetMethodID(classService, "registerTimer", "(JI)Z"); + mRegisterTimerMid = env->GetMethodID(classService, "registerTimer", "(JIJ)Z"); mRegisterHeartbeatMid = env->GetMethodID(classService, "registerHeartbeatTimer", "(I)V"); mUnregisterTimerMid = env->GetMethodID(classService, "unregisterTimer", "(J)Z"); mUpdateTimeMid = env->GetMethodID(classService, "updateTime", "(J)Z"); @@ -183,7 +182,7 @@ CPhoneDevice::CPhoneDevice(JavaVM* vm, jobject service) env->DeleteLocalRef(classService); - if (attached) + if (didAttachThread) { vm->DetachCurrentThread(); } @@ -195,9 +194,14 @@ CPhoneDevice::CPhoneDevice(JavaVM* vm, jobject service) CPhoneDevice::~CPhoneDevice() { JNIEnv* env = NULL; - bool attached = GetJniEnv(m_vm, &env); + bool didAttachThread = false; + bool res = GetJniEnv(m_vm, &env, didAttachThread); + if (!res) + { + ALOGE("Failed to get JNI Env"); + } env->DeleteGlobalRef(m_javaService); - if (attached) + if (didAttachThread) { m_vm->DetachCurrentThread(); } @@ -213,11 +217,16 @@ bool CPhoneDevice::UpdateTime(time_t ts) { JNIEnv* env = NULL; jboolean ret = JNI_FALSE; - bool attached = GetJniEnv(m_vm, &env); - if (attached) + bool didAttachThread = false; + bool res = GetJniEnv(m_vm, &env, didAttachThread); + if (!res) + { + ALOGE("Failed to get JNI Env"); + } + jlong timeInMillis = ((jlong)ts) * 1000; + ret = env->CallBooleanMethod(m_javaService, mUpdateTimeMid, timeInMillis); + if (didAttachThread) { - jlong timeInMillis = ((jlong)ts) * 1000; - ret = env->CallBooleanMethod(m_javaService, mUpdateTimeMid, timeInMillis); m_vm->DetachCurrentThread(); } @@ -266,18 +275,23 @@ bool CPhoneDevice::Reboot() return false; } -IDevice::timer_uid_t CPhoneDevice::RegisterTimer(unsigned int timerType, unsigned int timeout) +IDevice::timer_uid_t CPhoneDevice::RegisterTimer(unsigned int timerType, unsigned int timeout, unsigned long times/* = 0*/) { IDevice::timer_uid_t uid = m_timerUidFeed.fetch_add(1); ALOGI("NDK RegTimer: uid=%lld Type=%u timeout=%u", uid, timerType, timeout); JNIEnv* env = NULL; - jboolean ret = JNI_FALSE; - bool attached = GetJniEnv(m_vm, &env); - if (attached) + bool didAttachThread = false; + bool res = GetJniEnv(m_vm, &env, didAttachThread); + if (!res) + { + ALOGE("Failed to get JNI Env"); + return 0; + } + jboolean ret = env->CallBooleanMethod(m_javaService, mRegisterTimerMid, (jlong)uid, (jint)timeout, (jlong)times); + if (didAttachThread) { - ret = env->CallBooleanMethod(m_javaService, mRegisterTimerMid, (jlong)uid, (jint)timeout); m_vm->DetachCurrentThread(); } @@ -292,12 +306,18 @@ IDevice::timer_uid_t CPhoneDevice::RegisterTimer(unsigned int timerType, unsigne bool CPhoneDevice::UnregisterTimer(IDevice::timer_uid_t uid) { - JNIEnv* env = NULL; jboolean ret = JNI_FALSE; - bool attached = GetJniEnv(m_vm, &env); - if (attached) + JNIEnv* env = NULL; + bool didAttachThread = false; + bool res = GetJniEnv(m_vm, &env, didAttachThread); + if (!res) + { + ALOGE("Failed to get JNI Env"); + return false; + } + ret = env->CallBooleanMethod(m_javaService, mUnregisterTimerMid, (jlong)uid); + if (didAttachThread) { - ret = env->CallBooleanMethod(m_javaService, mUnregisterTimerMid, (jlong)uid); m_vm->DetachCurrentThread(); } @@ -315,49 +335,61 @@ unsigned long CPhoneDevice::RequestWakelock(unsigned long timeout) std::string name = WAKELOCK_NAME; name += to_string(wakelockId); - JNIEnv* env = NULL; + ALOGI("RequestWakelock=%lld",wakelockId); + jboolean ret = JNI_FALSE; - bool attached = GetJniEnv(m_vm, &env); - if (attached) + JNIEnv* env = NULL; + bool didAttachThread = false; + bool res = GetJniEnv(m_vm, &env, didAttachThread); + if (!res) { - jstring jname = env->NewStringUTF(name.c_str()); - jlong jtimeout = (jlong)timeout; + ALOGE("Failed to get JNI Env"); + return 0; + } + jstring jname = env->NewStringUTF(name.c_str()); + jlong jtimeout = (jlong)timeout; - env->CallVoidMethod(m_javaService, mRequestWakelockMid, jname, jtimeout); - // env->ReleaseStringUTFChars(jname, name.c_str()); - env->DeleteLocalRef(jname); + env->CallVoidMethod(m_javaService, mRequestWakelockMid, jname, jtimeout); + // env->ReleaseStringUTFChars(jname, name.c_str()); + env->DeleteLocalRef(jname); + if (didAttachThread) + { m_vm->DetachCurrentThread(); } - // return (ret == JNI_TRUE); - return wakelockId; } bool CPhoneDevice::ReleaseWakelock(unsigned long wakelock) { + ALOGI("ReleaseWakelock=%lld", wakelock); std::string name = WAKELOCK_NAME; name += to_string(wakelock); - JNIEnv* env = NULL; jboolean ret = JNI_FALSE; - bool attached = GetJniEnv(m_vm, &env); - if (attached) + JNIEnv* env = NULL; + bool didAttachThread = false; + bool res = GetJniEnv(m_vm, &env, didAttachThread); + if (!res) { - jstring jname = env->NewStringUTF(name.c_str()); - - env->CallVoidMethod(m_javaService, mReleaseWakelockMid, jname); - env->DeleteLocalRef(jname); - // env->ReleaseStringUTFChars(jname, name.c_str()); + ALOGE("Failed to get JNI Env"); + return false; + } + jstring jname = env->NewStringUTF(name.c_str()); + env->CallVoidMethod(m_javaService, mReleaseWakelockMid, jname); + env->DeleteLocalRef(jname); + // env->ReleaseStringUTFChars(jname, name.c_str()); + if (didAttachThread) + { m_vm->DetachCurrentThread(); } return true; } -bool CPhoneDevice::FireTimer(timer_uid_t uid) +bool CPhoneDevice::FireTimer(timer_uid_t uid, unsigned long times) { std::map::iterator it = mTimers.find(uid); if (it == mTimers.end()) @@ -366,21 +398,21 @@ bool CPhoneDevice::FireTimer(timer_uid_t uid) } unsigned long timerType = it->second & 0xFFFFFFFF; - unsigned long times = (it->second & 0xFFFFFFFF00000000) >> 32; - times++; + unsigned long ntimes = (it->second & 0xFFFFFFFF00000000) >> 32; + ntimes++; if (timerType != 100) { int aa = 0; } - it->second = timerType | (times << 32); + it->second = timerType | (ntimes << 32); if (m_listener == NULL) { return false; } - m_listener->OnTimeout(uid, timerType, times); + m_listener->OnTimeout(uid, timerType, ntimes); return true; } @@ -392,10 +424,16 @@ IDevice::timer_uid_t CPhoneDevice::RegisterHeartbeat(unsigned int timerType, uns IDevice::timer_uid_t uid = m_timerUidFeed.fetch_add(1); - JNIEnv* env = NULL; jboolean ret = JNI_FALSE; - bool attached = GetJniEnv(m_vm, &env); - if (attached) + JNIEnv* env = NULL; + bool didAttachThread = false; + bool res = GetJniEnv(m_vm, &env, didAttachThread); + if (!res) + { + ALOGE("Failed to get JNI Env"); + return 0; + } + if (didAttachThread) { env->CallVoidMethod(m_javaService, mRegisterHeartbeatMid, (jint)timeout); m_vm->DetachCurrentThread(); @@ -412,7 +450,7 @@ bool CPhoneDevice::TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector< mCamera = NULL; } - LOGI("TAKE_PHOTO: CH=%u PR=%u\n", (unsigned int)photoInfo.channel, (unsigned int)photoInfo.preset); + ALOGI("TAKE_PHOTO: CH=%u PR=%u\n", (unsigned int)photoInfo.channel, (unsigned int)photoInfo.preset); mPhotoInfo = photoInfo; mPath = path; mOsds = osds; @@ -467,7 +505,6 @@ bool CPhoneDevice::OnImageReady(const cv::Mat& mat) const compression_params.push_back(cv::IMWRITE_JPEG_QUALITY); compression_params.push_back(mPhotoInfo.quality); - ALOGI("Will write photo: %s", mPath.c_str()); if (!std::filesystem::exists(std::filesystem::path(mPath))) { bool res = cv::imwrite(mPath.c_str(), mat, compression_params); @@ -475,6 +512,10 @@ bool CPhoneDevice::OnImageReady(const cv::Mat& mat) const { ALOGE("Failed to write photo: %s", mPath.c_str()); } + else + { + ALOGI("Succeeded to write photo: %s", mPath.c_str()); + } TakePhotoCb(res, mPhotoInfo, mPath, time(NULL)); return res; } diff --git a/app/src/main/cpp/PhoneDevice.h b/app/src/main/cpp/PhoneDevice.h index ab7ba5a8..dc86e510 100644 --- a/app/src/main/cpp/PhoneDevice.h +++ b/app/src/main/cpp/PhoneDevice.h @@ -18,11 +18,6 @@ #include #include #include -#include -// #define LOG_TAG "native-camera2-jni" -#define PD_LOG_TAG "PhoneDev" -#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,PD_LOG_TAG,__VA_ARGS__) -#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,PD_LOG_TAG,__VA_ARGS__) #include #include @@ -43,12 +38,12 @@ public: virtual timer_uid_t RegisterHeartbeat(unsigned int timerType, unsigned int timeout); virtual bool TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector& osds, const string& path); virtual bool CloseCamera(); - virtual timer_uid_t RegisterTimer(unsigned int timerType, unsigned int timeout); + virtual timer_uid_t RegisterTimer(unsigned int timerType, unsigned int timeout, unsigned long times = 0); virtual bool UnregisterTimer(timer_uid_t uid); virtual unsigned long RequestWakelock(unsigned long timeout); virtual bool ReleaseWakelock(unsigned long wakelock); - virtual bool FireTimer(timer_uid_t uid); + virtual bool FireTimer(timer_uid_t uid, unsigned long times); bool GetNextScheduleItem(uint32_t tsBasedZero, uint32_t scheduleTime, vector& items); diff --git a/app/src/main/cpp/PhoneDevice2.cpp b/app/src/main/cpp/PhoneDevice2.cpp index 1da7ee22..2cd12887 100644 --- a/app/src/main/cpp/PhoneDevice2.cpp +++ b/app/src/main/cpp/PhoneDevice2.cpp @@ -32,15 +32,9 @@ #include -#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) -#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) -#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) -#define ASSERT(cond, fmt, ...) \ - if (!(cond)) { \ - __android_log_assert(#cond, LOG_TAG, fmt, ##__VA_ARGS__); \ - } +#include -extern bool GetJniEnv(JavaVM *vm, JNIEnv **env); +extern bool GetJniEnv(JavaVM *vm, JNIEnv **env, bool& didAttachThread); // This value is 2 ^ 18 - 1, and is used to clamp the RGB values before their @@ -79,7 +73,12 @@ CPhoneDevice2::CPhoneDevice2(JavaVM* vm, jobject service) { m_vm = vm; JNIEnv* env = NULL; - bool attached = GetJniEnv(m_vm, &env); + bool attached = false; + bool res = GetJniEnv(m_vm, &env, attached); + if (!res) + { + ALOGE("Failed to get JNI Env"); + } m_javaService = env->NewGlobalRef(service); jclass classService = env->GetObjectClass(m_javaService); @@ -102,7 +101,12 @@ CPhoneDevice2::CPhoneDevice2(JavaVM* vm, jobject service) CPhoneDevice2::~CPhoneDevice2() { JNIEnv* env = NULL; - bool attached = GetJniEnv(m_vm, &env); + bool attached = false; + bool res = GetJniEnv(m_vm, &env, attached); + if (!res) + { + ALOGE("Failed to get JNI Env"); + } env->DeleteGlobalRef(m_javaService); if (attached) { @@ -120,11 +124,17 @@ bool CPhoneDevice2::UpdateTime(time_t ts) { JNIEnv* env = NULL; jboolean ret = JNI_FALSE; - bool attached = GetJniEnv(m_vm, &env); + bool attached = false; + bool res = GetJniEnv(m_vm, &env, attached); + if (!res) + { + ALOGE("Failed to get JNI Env"); + return false; + } + jlong timeInMillis = ((jlong)ts) * 1000; + ret = env->CallBooleanMethod(m_javaService, mUpdateTimeMid, timeInMillis); if (attached) { - jlong timeInMillis = ((jlong)ts) * 1000; - ret = env->CallBooleanMethod(m_javaService, mUpdateTimeMid, timeInMillis); m_vm->DetachCurrentThread(); } @@ -144,10 +154,17 @@ IDevice::timer_uid_t CPhoneDevice2::RegisterTimer(unsigned int timerType, unsign JNIEnv* env = NULL; jboolean ret = JNI_FALSE; - bool attached = GetJniEnv(m_vm, &env); + bool attached = false; + bool res = GetJniEnv(m_vm, &env, attached); + if (!res) + { + ALOGE("Failed to get JNI Env"); + return 0; + } + ret = env->CallBooleanMethod(m_javaService, mRegisterTimerMid, (jlong)uid, (jint)timeout); + if (attached) { - ret = env->CallBooleanMethod(m_javaService, mRegisterTimerMid, (jlong)uid, (jint)timeout); m_vm->DetachCurrentThread(); } @@ -164,10 +181,16 @@ bool CPhoneDevice2::UnregisterTimer(IDevice::timer_uid_t uid) { JNIEnv* env = NULL; jboolean ret = JNI_FALSE; - bool attached = GetJniEnv(m_vm, &env); + bool attached = false; + bool res = GetJniEnv(m_vm, &env, attached); + if (!res) + { + ALOGE("Failed to get JNI Env"); + return false; + } + ret = env->CallBooleanMethod(m_javaService, mUnregisterTimerMid, (jlong)uid); if (attached) { - ret = env->CallBooleanMethod(m_javaService, mUnregisterTimerMid, (jlong)uid); m_vm->DetachCurrentThread(); } @@ -213,10 +236,16 @@ IDevice::timer_uid_t CPhoneDevice2::RegisterHeartbeat(unsigned int timerType, un JNIEnv* env = NULL; jboolean ret = JNI_FALSE; - bool attached = GetJniEnv(m_vm, &env); + bool attached = false; + bool res = GetJniEnv(m_vm, &env, attached); + if (!res) + { + ALOGE("Failed to get JNI Env"); + return 0; + } + env->CallVoidMethod(m_javaService, mRegisterHeartbeatMid, (jint)timeout); if (attached) { - env->CallVoidMethod(m_javaService, mRegisterHeartbeatMid, (jint)timeout); m_vm->DetachCurrentThread(); } @@ -225,15 +254,15 @@ IDevice::timer_uid_t CPhoneDevice2::RegisterHeartbeat(unsigned int timerType, un bool CPhoneDevice2::TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector& osds, const string& path) { - LOGI("TAKE_PHOTO: CH=%u PR=%u\n", (unsigned int)photoInfo.channel, (unsigned int)photoInfo.preset); + ALOGI("TAKE_PHOTO: CH=%u PR=%u\n", (unsigned int)photoInfo.channel, (unsigned int)photoInfo.preset); mPhotoInfo = photoInfo; mPath = path; mDisplayDimension = DisplayDimension(photoInfo.width, photoInfo.height); - LOGE("Image Buffer Size: %d", photoInfo.width * photoInfo.height * 4); + ALOGE("Image Buffer Size: %d", photoInfo.width * photoInfo.height * 4); imageBuffer_ = (uint8_t*)malloc(photoInfo.width * photoInfo.height * 4); - ASSERT(imageBuffer_ != nullptr, "Failed to allocate imageBuffer_"); + AASSERT(imageBuffer_ != nullptr, "Failed to allocate imageBuffer_"); int cameraId = (int)photoInfo.channel - 1; @@ -246,33 +275,33 @@ bool CPhoneDevice2::TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector camera_status = ACameraManager_getCameraIdList(cameraManager, &cameraIdList); if (camera_status != ACAMERA_OK) { - LOGI("Failed to get camera id list (reason: %d)\n", camera_status); + ALOGI("Failed to get camera id list (reason: %d)\n", camera_status); TakePhotoCb(false, photoInfo, path, 0); return false; } if (cameraIdList->numCameras < 1 ) { - LOGI("No camera device detected.\n"); + ALOGI("No camera device detected.\n"); TakePhotoCb(false, photoInfo, path, 0); return false; } if (cameraIdList->numCameras <= cameraId ) { - LOGI("No required camera device %d detected.\n", cameraId); + ALOGI("No required camera device %d detected.\n", cameraId); TakePhotoCb(false, photoInfo, path, 0); return false; } selectedCameraId = cameraIdList->cameraIds[cameraId]; - LOGI("Trying to open Camera2 (id: %s, num of camera : %d)\n", selectedCameraId, + ALOGI("Trying to open Camera2 (id: %s, num of camera : %d)\n", selectedCameraId, cameraIdList->numCameras); camera_status = ACameraManager_getCameraCharacteristics(cameraManager, selectedCameraId, &cameraMetadata); if (camera_status != ACAMERA_OK) { - LOGI("Failed to get camera meta data of ID:%s\n", selectedCameraId); + ALOGI("Failed to get camera meta data of ID:%s\n", selectedCameraId); } ACameraMetadata_const_entry face, orientation; @@ -286,7 +315,7 @@ bool CPhoneDevice2::TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector camera_status = ACameraMetadata_getConstEntry(cameraMetadata, ACAMERA_SENSOR_ORIENTATION, &orientation); - LOGI("====Current SENSOR_ORIENTATION: %8d", orientation.data.i32[0]); + ALOGI("====Current SENSOR_ORIENTATION: %8d", orientation.data.i32[0]); uint32_t cameraOrientation_ = orientation.data.i32[0]; if (cameraOrientation_ == 90 || cameraOrientation_ == 270) { @@ -303,14 +332,14 @@ bool CPhoneDevice2::TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector &deviceStateCallbacks, &cameraDevice); if (camera_status != ACAMERA_OK) { - LOGI("Failed to open camera device (id: %s)\n", selectedCameraId); + ALOGI("Failed to open camera device (id: %s)\n", selectedCameraId); } camera_status = ACameraDevice_createCaptureRequest(cameraDevice, TEMPLATE_STILL_CAPTURE/*TEMPLATE_PREVIEW*/, &captureRequest); if (camera_status != ACAMERA_OK) { - LOGI("Failed to create preview capture request (id: %s)\n", selectedCameraId); + ALOGI("Failed to create preview capture request (id: %s)\n", selectedCameraId); } ACaptureSessionOutputContainer_create(&captureSessionOutputContainer); @@ -328,7 +357,7 @@ bool CPhoneDevice2::TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector status = AImageReader_new(resCap.width, resCap.height, resCap.format, 5, &mAImageReader); if (status != AMEDIA_OK) { - LOGI("AImageReader_new error\n"); + ALOGI("AImageReader_new error\n"); TakePhotoCb(false, photoInfo, path, 0); return false; } @@ -343,12 +372,12 @@ bool CPhoneDevice2::TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector status = AImageReader_getWindow(mAImageReader, &theNativeWindow); if (status != AMEDIA_OK) { - LOGI("AImageReader_getWindow error\n"); + ALOGI("AImageReader_getWindow error\n"); TakePhotoCb(false, photoInfo, path, 0); return false; } - LOGI("Surface is prepared in %p.\n", theNativeWindow); + ALOGI("Surface is prepared in %p.\n", theNativeWindow); // theNativeWindow ACameraOutputTarget_create(theNativeWindow, &cameraOutputTarget); @@ -362,7 +391,7 @@ bool CPhoneDevice2::TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector // ACameraCaptureSession_setRepeatingRequest(captureSession, NULL, 1, &captureRequest, NULL); ACameraCaptureSession_capture(captureSession, NULL, 1, &captureRequest, NULL); - LOGI("Surface is prepared in here.\n"); + ALOGI("Surface is prepared in here.\n"); return true; } @@ -388,10 +417,10 @@ void CPhoneDevice2::ImageCallback(AImageReader *reader) { int32_t srcFormat = -1; AImage_getFormat(image, &srcFormat); - ASSERT(AIMAGE_FORMAT_YUV_420_888 == srcFormat, "Failed to get format"); + AASSERT(AIMAGE_FORMAT_YUV_420_888 == srcFormat, "Failed to get format"); int32_t srcPlanes = 0; AImage_getNumberOfPlanes(image, &srcPlanes); - ASSERT(srcPlanes == 3, "Is not 3 planes"); + AASSERT(srcPlanes == 3, "Is not 3 planes"); AImageCropRect srcRect; AImage_getCropRect(image, &srcRect); @@ -474,10 +503,10 @@ bool CPhoneDevice2::WriteFile(AImage *image, const string& path) int planeCount = 0; media_status_t status = AImage_getNumberOfPlanes(image, &planeCount); - LOGI("Info: getNumberOfPlanes() planeCount = %d", planeCount); + ALOGI("Info: getNumberOfPlanes() planeCount = %d", planeCount); if (!(status == AMEDIA_OK && planeCount == 1)) { - LOGE("Error: getNumberOfPlanes() planeCount = %d", planeCount); + ALOGE("Error: getNumberOfPlanes() planeCount = %d", planeCount); return false; } @@ -492,7 +521,7 @@ bool CPhoneDevice2::WriteFile(AImage *image, const string& path) fwrite(data, 1, len, file); fclose(file); - LOGI("Capture: %s", path.c_str()); + ALOGI("Capture: %s", path.c_str()); res = true; @@ -545,7 +574,7 @@ bool CPhoneDevice2::MatchCaptureSizeRequest(ACameraManager *cameraManager, const if (format == AIMAGE_FORMAT_YUV_420_888 || format == AIMAGE_FORMAT_JPEG) { DisplayDimension res(entry.data.i32[i + 1], entry.data.i32[i + 2]); - LOGI("Camera Resolution: %d x %d fmt=%d", res.width(), res.height(), format); + ALOGI("Camera Resolution: %d x %d fmt=%d", res.width(), res.height(), format); if (!disp.IsSameRatio(res)) continue; if (format == AIMAGE_FORMAT_YUV_420_888 && res > disp) { foundIt = true; @@ -562,7 +591,7 @@ bool CPhoneDevice2::MatchCaptureSizeRequest(ACameraManager *cameraManager, const resCap->width = foundRes.org_width(); resCap->height = foundRes.org_height(); } else { - LOGI("Did not find any compatible camera resolution, taking 640x480"); + ALOGI("Did not find any compatible camera resolution, taking 640x480"); resCap->width = disp.org_width(); resCap->height = disp.org_height(); // *resCap = *resView; @@ -583,16 +612,16 @@ bool CPhoneDevice2::MatchCaptureSizeRequest(ACameraManager *cameraManager, const * it will be deleted via {@link AImage_delete} */ bool CPhoneDevice2::DisplayImage(ANativeWindow_Buffer *buf, AImage *image) { - ASSERT(buf->format == WINDOW_FORMAT_RGBX_8888 || + AASSERT(buf->format == WINDOW_FORMAT_RGBX_8888 || buf->format == WINDOW_FORMAT_RGBA_8888, "Not supported buffer format"); int32_t srcFormat = -1; AImage_getFormat(image, &srcFormat); - ASSERT(AIMAGE_FORMAT_YUV_420_888 == srcFormat, "Failed to get format"); + AASSERT(AIMAGE_FORMAT_YUV_420_888 == srcFormat, "Failed to get format"); int32_t srcPlanes = 0; AImage_getNumberOfPlanes(image, &srcPlanes); - ASSERT(srcPlanes == 3, "Is not 3 planes"); + AASSERT(srcPlanes == 3, "Is not 3 planes"); switch (presentRotation_) { case 0: @@ -608,7 +637,7 @@ bool CPhoneDevice2::DisplayImage(ANativeWindow_Buffer *buf, AImage *image) { PresentImage270(buf, image); break; default: - ASSERT(0, "NOT recognized display rotation: %d", presentRotation_); + AASSERT(0, "NOT recognized display rotation: %d", presentRotation_); } AImage_delete(image); @@ -857,27 +886,27 @@ bool CPhoneDevice2::SendBroadcastMessage(String16 action, int value) void CPhoneDevice2::camera_device_on_disconnected(void *context, ACameraDevice *device) { - LOGI("Camera(id: %s) is diconnected.\n", ACameraDevice_getId(device)); + ALOGI("Camera(id: %s) is diconnected.\n", ACameraDevice_getId(device)); CPhoneDevice2* pThis = (CPhoneDevice2*)context; // delete pThis; } void CPhoneDevice2::camera_device_on_error(void *context, ACameraDevice *device, int error) { - LOGI("Error(code: %d) on Camera(id: %s).\n", error, ACameraDevice_getId(device)); + ALOGI("Error(code: %d) on Camera(id: %s).\n", error, ACameraDevice_getId(device)); } void CPhoneDevice2::capture_session_on_ready(void *context, ACameraCaptureSession *session) { - LOGI("Session is ready. %p\n", session); + ALOGI("Session is ready. %p\n", session); } void CPhoneDevice2::capture_session_on_active(void *context, ACameraCaptureSession *session) { - LOGI("Session is activated. %p\n", session); + ALOGI("Session is activated. %p\n", session); } void CPhoneDevice2::capture_session_on_closed(void *context, ACameraCaptureSession *session) { - LOGI("Session is closed. %p\n", session); + ALOGI("Session is closed. %p\n", session); } \ No newline at end of file diff --git a/app/src/main/cpp/PhoneDevice2.h b/app/src/main/cpp/PhoneDevice2.h index 871a7625..dc9cfe43 100644 --- a/app/src/main/cpp/PhoneDevice2.h +++ b/app/src/main/cpp/PhoneDevice2.h @@ -17,11 +17,6 @@ #include #include #include -#include -// #define LOG_TAG "native-camera2-jni" -#define PD_LOG_TAG "PhoneDev" -#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,PD_LOG_TAG,__VA_ARGS__) -#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,PD_LOG_TAG,__VA_ARGS__) #include #include diff --git a/app/src/main/cpp/TerminalDevice.cpp b/app/src/main/cpp/TerminalDevice.cpp index 19d91fb2..922aa670 100644 --- a/app/src/main/cpp/TerminalDevice.cpp +++ b/app/src/main/cpp/TerminalDevice.cpp @@ -1,16 +1,22 @@ #include "TerminalDevice.h" #include #include "Camera.h" +#include typedef jbyteArray (*TakePhotoFunc)(int, int, int, int); -extern bool GetJniEnv(JavaVM *vm, JNIEnv **env); +extern bool GetJniEnv(JavaVM *vm, JNIEnv **env, bool& didAttachThread); CTerminalDevice::CTerminalDevice(JavaVM* vm, jobject service) { m_vm = vm; JNIEnv* env = NULL; - bool attached = GetJniEnv(m_vm, &env); + bool attached = false; + bool res = GetJniEnv(m_vm, &env, attached); + if (!res) + { + ALOGE("Failed to get JNI Env"); + } m_javaService = env->NewGlobalRef(service); if (attached) { @@ -21,7 +27,12 @@ CTerminalDevice::CTerminalDevice(JavaVM* vm, jobject service) CTerminalDevice::~CTerminalDevice() { JNIEnv* env = NULL; - bool attached = GetJniEnv(m_vm, &env); + bool attached = false; + bool res = GetJniEnv(m_vm, &env, attached); + if (!res) + { + ALOGE("Failed to get JNI Env"); + } env->DeleteGlobalRef(m_javaService); if (attached) { diff --git a/app/src/main/cpp/camera2/Camera2Helper.h b/app/src/main/cpp/camera2/Camera2Helper.h index b3263fdc..d75746eb 100644 --- a/app/src/main/cpp/camera2/Camera2Helper.h +++ b/app/src/main/cpp/camera2/Camera2Helper.h @@ -17,6 +17,24 @@ #ifndef __CAMERA2_HELPER_H__ #define __CAMERA2_HELPER_H__ + +template +class RangeValue { +public: + T min_, max_; + /** + * return absolute value from relative value + * value: in percent (50 for 50%) + */ + T value(int percent) { + return static_cast(min_ + (max_ - min_) * percent / 100); + } + RangeValue() { min_ = max_ = static_cast(0); } + + bool Supported(void) const { return (min_ != max_); } +}; + + struct ImageFormat { int32_t width; int32_t height; diff --git a/app/src/main/cpp/camera2/ndkcamera.cpp b/app/src/main/cpp/camera2/ndkcamera.cpp index e61bcb23..197225e8 100644 --- a/app/src/main/cpp/camera2/ndkcamera.cpp +++ b/app/src/main/cpp/camera2/ndkcamera.cpp @@ -20,6 +20,7 @@ #include #include "mat.h" #include "Camera2Helper.h" +#include static void onDisconnected(void* context, ACameraDevice* device) { @@ -70,7 +71,7 @@ void onCaptureSequenceAborted(void* context, ACameraCaptureSession* session, int void onCaptureCompleted(void* context, ACameraCaptureSession* session, ACaptureRequest* request, const ACameraMetadata* result) { - __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onCaptureCompleted %p %p %p", session, request, result); + ((NdkCamera*)context)->onCaptureCompleted(session, request, result); } NdkCamera::NdkCamera(int32_t width, int32_t height) @@ -82,6 +83,10 @@ NdkCamera::NdkCamera(int32_t width, int32_t height) mWidth = width; mHeight = height; + hdrSupported = false; + nightModeSupported = false; + nightPortraitModeSupported = false; + camera_manager = 0; camera_device = 0; image_reader = 0; @@ -202,6 +207,64 @@ int NdkCamera::open(const char* cameraId) } + { + ACameraMetadata_const_entry val = { 0 }; + camera_status_t status = ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_SENSOR_INFO_EXPOSURE_TIME_RANGE, &val); + if (status == ACAMERA_OK) { + exposureRange.min_ = val.data.i64[0]; + if (exposureRange.min_ < kMinExposureTime) { + exposureRange.min_ = kMinExposureTime; + } + exposureRange.max_ = val.data.i64[1]; + if (exposureRange.max_ > kMaxExposureTime) { + exposureRange.max_ = kMaxExposureTime; + } + // exposureTime = exposureRange.value(2); + } else { + ALOGW("Unsupported ACAMERA_SENSOR_INFO_EXPOSURE_TIME_RANGE"); + exposureRange.min_ = exposureRange.max_ = 0l; + // exposureTime_ = 0l; + } + } + + { + ACameraMetadata_const_entry val = { 0 }; + camera_status_t status = ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_SENSOR_INFO_SENSITIVITY_RANGE, &val); + + if (status == ACAMERA_OK) { + sensitivityRange.min_ = val.data.i32[0]; + sensitivityRange.max_ = val.data.i32[1]; + + // sensitivity = sensitivityRange.value(2); + } else { + ALOGW("failed for ACAMERA_SENSOR_INFO_SENSITIVITY_RANGE"); + sensitivityRange.min_ = sensitivityRange.max_ = 0; + // sensitivity_ = 0; + } + + } + + { + ACameraMetadata_const_entry e = { 0 }; + ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_CONTROL_AVAILABLE_SCENE_MODES, &e); + + for (int i = 0; i < e.count; i ++) { + if (ACAMERA_CONTROL_SCENE_MODE_HDR == e.data.u8[i]) + { + hdrSupported = true; + break; + } + else if (ACAMERA_CONTROL_SCENE_MODE_NIGHT == e.data.u8[i]) + { + nightModeSupported = true; + } + else if (ACAMERA_CONTROL_SCENE_MODE_NIGHT_PORTRAIT == e.data.u8[i]) + { + nightPortraitModeSupported = true; + } + } + + } ACameraMetadata_free(camera_metadata); @@ -216,6 +279,11 @@ int NdkCamera::open(const char* cameraId) return 1; } + if (camera_id == "1") + { + camera_facing = 1; + } + mCameraId = camera_id; camera_status_t res = ACAMERA_OK; @@ -257,6 +325,49 @@ int NdkCamera::open(const char* cameraId) { res = ACameraDevice_createCaptureRequest(camera_device, TEMPLATE_STILL_CAPTURE, &capture_request); + int32_t fpsRange[2] = {10,15}; + res = ACaptureRequest_setEntry_i32(capture_request, ACAMERA_CONTROL_AE_TARGET_FPS_RANGE,2,fpsRange); + + bool usingAE = true; + + if (usingAE) { + uint8_t aeModeOff = ACAMERA_CONTROL_AE_MODE_ON; + ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AE_MODE, 1, &aeModeOff); + // ACaptureRequest_setEntry_i32(capture_request, ACAMERA_SENSOR_SENSITIVITY, 1, &sensitivity_); + + + uint8_t aeLockOff = ACAMERA_CONTROL_AE_LOCK_OFF; + ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AE_LOCK, 1, &aeLockOff); + } else { + uint8_t aeModeOff = ACAMERA_CONTROL_AE_MODE_OFF; + res = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AE_MODE, 1, &aeModeOff); + + uint8_t hdrMode = ACAMERA_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10; // ACAMERA_CONTROL_SCENE_MODE_HDR + res = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_SCENE_MODE_HDR, 1, &hdrMode); + + int32_t sensitivity = sensitivityRange.value(2); + res = ACaptureRequest_setEntry_i32(capture_request,ACAMERA_SENSOR_SENSITIVITY, 1, &sensitivity); + int64_t exposureTime = exposureRange.value(5); + res = ACaptureRequest_setEntry_i64(capture_request, ACAMERA_SENSOR_EXPOSURE_TIME, 1, &exposureTime); + } + + if (hdrSupported) { + uint8_t hdrMode = ACAMERA_CONTROL_SCENE_MODE_HDR; // ACAMERA_CONTROL_SCENE_MODE_HDR + // res = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_SCENE_MODE_HDR, 1, &hdrMode); + res = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_SCENE_MODE, 1, &hdrMode); + + } + + if (nightModeSupported) { + uint8_t modeEnabled = 1; // ACAMERA_CONTROL_SCENE_MODE_HDR + res = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_SCENE_MODE_NIGHT, 1, &modeEnabled); + } + if (nightPortraitModeSupported) { + uint8_t modeEnabled = 1; // ACAMERA_CONTROL_SCENE_MODE_HDR + res = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_SCENE_MODE_NIGHT_PORTRAIT, 1, &modeEnabled); + } + + res = ACameraOutputTarget_create(image_reader_surface, &image_reader_target); res = ACaptureRequest_addTarget(capture_request, image_reader_target); } @@ -281,7 +392,7 @@ int NdkCamera::open(const char* cameraId) camera_capture_session_capture_callbacks.context = this; camera_capture_session_capture_callbacks.onCaptureStarted = 0; camera_capture_session_capture_callbacks.onCaptureProgressed = 0; - camera_capture_session_capture_callbacks.onCaptureCompleted = onCaptureCompleted; + camera_capture_session_capture_callbacks.onCaptureCompleted = ::onCaptureCompleted; camera_capture_session_capture_callbacks.onCaptureFailed = onCaptureFailed; camera_capture_session_capture_callbacks.onCaptureSequenceCompleted = onCaptureSequenceCompleted; camera_capture_session_capture_callbacks.onCaptureSequenceAborted = onCaptureSequenceAborted; @@ -442,8 +553,6 @@ void NdkCamera::onImageAvailable(AImageReader* reader) } AImage_delete(image); - - ACameraCaptureSession_stopRepeating(capture_session); } void NdkCamera::on_error(const std::string& msg) const @@ -515,3 +624,26 @@ void NdkCamera::on_image(const unsigned char* nv21, int nv21_width, int nv21_hei on_image(rgb); } + +void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureRequest* request, const ACameraMetadata* result) +{ +// CALL_REQUEST(setEntry_i64(requests_[PREVIEW_REQUEST_IDX].request_, + // ACAMERA_SENSOR_EXPOSURE_TIME, 1, &exposureTime_)); + + // ACameraMetadata_getConstEntry(result, ) + + ACameraMetadata_const_entry val = { 0 }; + camera_status_t status = ACameraMetadata_getConstEntry(result, ACAMERA_SENSOR_EXPOSURE_TIME, &val); + int64_t exTime = val.data.i64[0]; + + + + val = { 0 }; + status = ACameraMetadata_getConstEntry(result, ACAMERA_CONTROL_AE_MODE, &val); + uint8_t aeMode = val.data.u8[0]; + // ACaptureRequest_setEntry_i32(capture_request, ACAMERA_SENSOR_SENSITIVITY, 1, &sensitivity_); + + ALOGD("onCaptureCompleted EXPOSURE_TIME=%lld, camera id=%s, AE=%s", val.data.i64[0], mCameraId.c_str(), ((aeMode == 1) ? 'ON' : 'OFF')); + + // __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onCaptureCompleted %p %p %p", session, request, result); +} \ No newline at end of file diff --git a/app/src/main/cpp/camera2/ndkcamera.h b/app/src/main/cpp/camera2/ndkcamera.h index 277a8155..318c7545 100644 --- a/app/src/main/cpp/camera2/ndkcamera.h +++ b/app/src/main/cpp/camera2/ndkcamera.h @@ -21,10 +21,23 @@ #include #include +#include "Camera2Helper.h" + +/** + * Range of Camera Exposure Time: + * Camera's capability range have a very long range which may be disturbing + * on camera. For this sample purpose, clamp to a range showing visible + * video on preview: 100000ns ~ 250000000ns + */ +static const uint64_t kMinExposureTime = static_cast(1000000); +static const uint64_t kMaxExposureTime = static_cast(250000000); + class NdkCamera { public: + + NdkCamera(int32_t width, int32_t height); virtual ~NdkCamera(); @@ -38,6 +51,9 @@ public: virtual void on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const; + void onCaptureCompleted(ACameraCaptureSession* session, ACaptureRequest* request, const ACameraMetadata* result); + + public: int camera_facing; int camera_orientation; @@ -46,6 +62,15 @@ public: int32_t mHeight; std::string mCameraId; + bool hdrSupported; + bool nightModeSupported; + bool nightPortraitModeSupported; + // int64_t exposureTime_; + RangeValue exposureRange; + // int32_t sensitivity_; + RangeValue sensitivityRange; + + private: ACameraManager* camera_manager; ACameraDevice* camera_device; diff --git a/app/src/main/java/com/xinyingpower/microphoto/FloatingWindow.java b/app/src/main/java/com/xinyingpower/microphoto/FloatingWindow.java index 85762f3c..bee385ea 100644 --- a/app/src/main/java/com/xinyingpower/microphoto/FloatingWindow.java +++ b/app/src/main/java/com/xinyingpower/microphoto/FloatingWindow.java @@ -50,9 +50,14 @@ public class FloatingWindow extends Service { @Override public void onDestroy() { - if (mView != null) { - mWindowManager.removeView(mView); + try { + if (mView != null) { + mWindowManager.removeView(mView); + } + } catch (Exception ex) { + ex.printStackTrace(); } + super.onDestroy(); } diff --git a/app/src/main/java/com/xinyingpower/microphoto/MainActivity.java b/app/src/main/java/com/xinyingpower/microphoto/MainActivity.java index d88e7f1e..d926222c 100644 --- a/app/src/main/java/com/xinyingpower/microphoto/MainActivity.java +++ b/app/src/main/java/com/xinyingpower/microphoto/MainActivity.java @@ -5,6 +5,7 @@ import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; +import android.graphics.Path; import android.graphics.SurfaceTexture; import android.hardware.Camera; import android.os.Build; @@ -19,6 +20,7 @@ import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; +import android.text.TextUtils; import android.util.Log; import android.view.Display; import android.view.View; @@ -46,8 +48,6 @@ import org.json.JSONException; import org.json.JSONObject; public class MainActivity extends AppCompatActivity { - - public static final String TAG = "MainActivity"; private static int MY_PERMISSIONS_REQUEST_FOREGROUND_SERVICE = 100; @@ -55,22 +55,18 @@ public class MainActivity extends AppCompatActivity { static { System.loadLibrary("microphoto"); } - private ActivityMainBinding binding; private int defaultDataSubId; - @Override protected void onDestroy() { super.onDestroy(); } - protected class AppConfig { public String cmdid; public String server; public int port; public int protocol; } - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -84,7 +80,6 @@ public class MainActivity extends AppCompatActivity { int width = defaultDisplay.getWidth(); int height = defaultDisplay.getHeight(); - Log.d(TAG, "Screen Size: " + width + " x " + height); String cmdid = "0123456789ABCDEFG"; @@ -96,7 +91,6 @@ public class MainActivity extends AppCompatActivity { binding.cmdid.setText(appConfig.cmdid); binding.server.setText(appConfig.server); binding.port.setText(Integer.toString(appConfig.port)); - this.binding.startServBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { @@ -154,36 +148,28 @@ public class MainActivity extends AppCompatActivity { binding.stopServBtn.setEnabled(true); } }); - this.binding.takePhotoBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - MicroPhotoService.takePhoto(MainActivity.this, 1, 255, true); -// setDefaultDataSubId(1); + MicroPhotoService.takePhoto(MainActivity.this.getApplicationContext(), 1, 255, true); } }); - this.binding.takePhotoBtn2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { MicroPhotoService.takePhoto(MainActivity.this, 2, 255, true); -// setDefaultDataSubId(2); } }); - this.binding.takePhotoBtn3.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { MicroPhotoService.takePhoto(MainActivity.this, 3, 255, true); -// setDefaultDataSubId(2); } }); - this.binding.takePhotoBtn4.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { MicroPhotoService.takePhoto(MainActivity.this, 4, 255, true); -// setDefaultDataSubId(2); } }); @@ -225,14 +211,20 @@ public class MainActivity extends AppCompatActivity { } }); - Handler handler = new Handler(); - Runnable runnable = new Runnable() { - @Override - public void run() { - // binding.startServBtn.performClick(); - } - }; - handler.postDelayed(runnable, 1000); + + if (!TextUtils.isEmpty(appConfig.cmdid) && !TextUtils.isEmpty(appConfig.server) && appConfig.port != 0) { + Handler handler = new Handler(); + Runnable runnable = new Runnable() { + @Override + public void run() { + if (binding.startServBtn.isEnabled()) { + binding.startServBtn.performClick(); + } + } + }; + handler.postDelayed(runnable, 5000); + } + } private void setDefaultDataSubId(int subId) { @@ -256,7 +248,7 @@ public class MainActivity extends AppCompatActivity { InputStreamReader inputStreamReader = null; try { - inputStreamReader = new InputStreamReader(new FileInputStream(new File(appPath + "App.json")), "UTF-8"); + inputStreamReader = new InputStreamReader(new FileInputStream(new File(appPath + "data/App.json")), "UTF-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String line; StringBuilder stringBuilder = new StringBuilder(); diff --git a/app/src/main/java/com/xinyingpower/microphoto/MicroPhotoService.java b/app/src/main/java/com/xinyingpower/microphoto/MicroPhotoService.java index bf6c4867..628e21c0 100644 --- a/app/src/main/java/com/xinyingpower/microphoto/MicroPhotoService.java +++ b/app/src/main/java/com/xinyingpower/microphoto/MicroPhotoService.java @@ -1,6 +1,5 @@ package com.xinyingpower.microphoto; -import android.Manifest; import android.app.AlarmManager; import android.app.Notification; import android.app.NotificationChannel; @@ -11,25 +10,14 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.os.Environment; import android.os.IBinder; import android.os.PowerManager; import android.os.SystemClock; -import androidx.core.app.ActivityCompat; import androidx.core.app.NotificationCompat; -import android.telephony.CellLocation; -import android.telephony.PhoneStateListener; -import android.telephony.ServiceState; -import android.telephony.SignalStrength; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; -import android.telephony.cdma.CdmaCellLocation; -import android.telephony.gsm.GsmCellLocation; import android.text.TextUtils; import android.text.format.DateFormat; import android.util.Log; @@ -43,7 +31,6 @@ import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -54,63 +41,45 @@ public class MicroPhotoService extends Service { static { System.loadLibrary("microphoto"); } - - private static String ALARM_EVENT = "com.xinyingpower.mp.MicroPhotoService.AlarmReceiver"; - + private static final String ALARM_EVENT = "com.xinyingpower.mp.MicroPhotoService.AlarmReceiver"; public static final int NOTIFICATION_ID_FOREGROUND_SERVICE = 8466503; - - public static final String ACTION_START = "ACT_START"; public static final String ACTION_STOP = "ACT_STOP"; - public static final String ACTION_MAIN = "ACT_MAIN"; - - private static String ACTION_HEARTBEAT = "ACT_HB"; - private static String ACTION_TAKE_PHOTO = "ACT_TP"; - private static String ACTION_TAKE_PHOTO_MANUALLY = "ACT_TP_M"; - - private static String ACTION_TIMEOUT = "ACT_TIMEOUT"; - - private static String EXTRA_PARAM_CHANNEL = "Channel"; - private static String EXTRA_PARAM_PRESET = "Preset"; - private static String EXTRA_PARAM_PHOTO_OR_VIDEO = "PhotoOrVideo"; - private static String EXTRA_PARAM_SCHEDULES = "Schedules"; - private static String EXTRA_PARAM_SCHEDULE = "Schedule_"; - - private static String EXTRA_PARAM_TIME = "Time"; + private static final String ACTION_HEARTBEAT = "ACT_HB"; + private static final String ACTION_TAKE_PHOTO = "ACT_TP"; + private static final String ACTION_TAKE_PHOTO_MANUALLY = "ACT_TP_M"; + private static final String ACTION_TIMEOUT = "ACT_TIMEOUT"; + private static final String EXTRA_PARAM_CHANNEL = "Channel"; + private static final String EXTRA_PARAM_PRESET = "Preset"; + private static final String EXTRA_PARAM_PHOTO_OR_VIDEO = "PhotoOrVideo"; + private static final String EXTRA_PARAM_SCHEDULES = "Schedules"; + private static final String EXTRA_PARAM_SCHEDULE = "Schedule_"; + private static final String EXTRA_PARAM_TIME = "Time"; // private static String EXTRA_PARAM_FILENAME = "FileName"; - - private static String EXTRA_PARAM_TIMER_UID = "TimerUid"; + private static final String EXTRA_PARAM_TIMER_UID = "TimerUid"; // private static String EXTRA_PARAM_TIMER_TYPE = "TimerType"; - private static String EXTRA_PARAM_TIMEOUT = "Timeout"; - - private final static String FOREGROUND_CHANNEL_ID = "foreground_channel_id"; - - + private static final String EXTRA_PARAM_TIMEOUT = "Timeout"; + private static final String EXTRA_PARAM_TIMES = "Times"; + private static final String EXTRA_PARAM_ELASPED_TIMES = "ElapsedTimes"; + private static final String FOREGROUND_CHANNEL_ID = "foreground_channel_id"; public static class STATE_SERVICE { public static final int CONNECTED = 10; public static final int NOT_CONNECTED = 0; } - private NotificationManager mNotificationManager; - - private Map mWakeLocks = new HashMap<>(); - + private final Map mWakeLocks = new HashMap<>(); private int mHeartbeatDuration = 0; // 5m: 5 * 60 * 1000 private long mNextHeartbeatTime = 0; - - private Map mTimers = new HashMap<>(); + private final Map mTimers = new HashMap<>(); private static int stateService = STATE_SERVICE.NOT_CONNECTED; - public MicroPhotoService() { } - @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } - @Override public void onCreate() { super.onCreate(); @@ -121,6 +90,8 @@ public class MicroPhotoService extends Service { DeviceUtil.getPhoneState(this.getApplicationContext()); alarmReceiver = new AlarmReceiver(this); + screenactionreceiver = new ScreenActionReceiver(); + // 注册广播接受者 IntentFilter intentFilter = new IntentFilter(ACTION_HEARTBEAT); intentFilter.addAction(ACTION_TAKE_PHOTO); @@ -136,19 +107,20 @@ public class MicroPhotoService extends Service { break; } + /* if (aci.getShowIntent().isBroadcast()) { // alarmManager.cancel(aci.getShowIntent()); } + */ } // alarmManager.cancel(); - boolean res = false; + // boolean res = false; // Environment.getExternalStoragePublicDirectory(String) // registerHeartbeatTimer(getHeartbeatDuration()); } - @Override public void onDestroy() { @@ -158,6 +130,7 @@ public class MicroPhotoService extends Service { mHandler = 0; unregisterReceiver(alarmReceiver); + unregisterReceiver(screenactionreceiver); for(Map.Entry entry : mWakeLocks.entrySet()) { entry.getValue().release(); @@ -166,22 +139,18 @@ public class MicroPhotoService extends Service { super.onDestroy(); } - public static class AlarmReceiver extends BroadcastReceiver { - private MicroPhotoService mService; - public AlarmReceiver() { mService = null; } public AlarmReceiver(MicroPhotoService service) { mService = service; } - public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (TextUtils.equals(ACTION_HEARTBEAT, action)) { - Log.i(TAG, "receiver ACTION=" + action); + Log.i(TAG, "HB Timer Fired ACTION=" + action); mService.sendHeartbeat(mService.mHandler); mService.registerHeartbeatTimer(); } else if (TextUtils.equals(ACTION_TAKE_PHOTO, action)) { @@ -194,6 +163,7 @@ public class MicroPhotoService extends Service { int channel = (int) ((val & 0xFF0000L) >> 16); int preset = (int) ((val & 0xFF00L) >> 8); + Log.i(TAG, "PhotoTimer Fired: CH=" + channel + " PR=" + preset); mService.notifyToTakePhoto(mService.mHandler, channel, preset, ts, mService.buildPhotoDir(mService.getApplicationContext(), channel), mService.buildPhotoFileName(channel, preset, ts), true); } } @@ -215,24 +185,34 @@ public class MicroPhotoService extends Service { boolean photoOrVideo = intent.getBooleanExtra(EXTRA_PARAM_PHOTO_OR_VIDEO, true); long ts = System.currentTimeMillis() / 1000; - Log.i(TAG, "Take Photo CH=" + channel + " PR=" + preset); + Log.i(TAG, "Take Photo CH=" + channel + " PR=" + preset + " Mannually"); mService.notifyToTakePhoto(mService.mHandler, channel, preset, ts, mService.buildPhotoDir(mService.getApplicationContext(), channel), mService.buildPhotoFileName(channel, preset, ts), photoOrVideo); } else if (TextUtils.equals(ACTION_TIMEOUT, action)) { long uid = intent.getLongExtra(EXTRA_PARAM_TIMER_UID, 0); - Log.i(TAG, "Timeout:" + uid); - mService.fireTimeout(mService.mHandler, uid); + long expectedTimes = intent.getLongExtra(EXTRA_PARAM_TIMES, 0); + long elapsedTimes = intent.getLongExtra(EXTRA_PARAM_ELASPED_TIMES, 0); + elapsedTimes++; + + Log.i(TAG, "Timeout uid=" + uid + " expectedTimes=" + expectedTimes + " Times=" + elapsedTimes); + mService.fireTimeout(mService.mHandler, uid, elapsedTimes); + + intent.putExtra(EXTRA_PARAM_ELASPED_TIMES, elapsedTimes); - int timeout = intent.getIntExtra(EXTRA_PARAM_TIMEOUT, 0); Long uidObj = Long.valueOf(uid); - PendingIntent pendingIntent = mService.mTimers.get(uidObj); + if ((expectedTimes == 0) || (elapsedTimes < expectedTimes)) { + int timeout = intent.getIntExtra(EXTRA_PARAM_TIMEOUT, 0); + + PendingIntent pendingIntent = mService.mTimers.get(uidObj); - if (pendingIntent != null) { - mService.registerTimer(pendingIntent, uid, timeout); + if (pendingIntent != null) { + mService.registerTimer(pendingIntent, uid, timeout); + } + } else { + mService.mTimers.remove(uidObj); } } } } - private void registerHeartbeatTimer(int duration) { int orgHeartbeatDuration = mHeartbeatDuration; mHeartbeatDuration = duration; @@ -241,7 +221,6 @@ public class MicroPhotoService extends Service { } } - private void registerHeartbeatTimer() { // 创建延迟意图 @@ -256,7 +235,7 @@ public class MicroPhotoService extends Service { // alarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + timeout, pendingIntent); } - private void registerPhotoTimer(int channel, int preset, long ts, long timeout, List schedules) { + private static void registerPhotoTimer(Context context, int channel, int preset, long ts, long timeout, List schedules) { // 创建延迟意图 Intent alarmIntent = new Intent(); @@ -265,33 +244,39 @@ public class MicroPhotoService extends Service { alarmIntent.putExtra(EXTRA_PARAM_SCHEDULES, cnt); String channelStr = ""; for (int idx = 0; idx < cnt; idx++) { + long val = schedules.get(idx).longValue(); alarmIntent.putExtra(EXTRA_PARAM_SCHEDULE + idx, schedules.get(idx).longValue()); - channelStr += schedules.get(idx).toString() + " "; + channelStr += "CH=" + ((val & 0XFF0000) >> 16) + "-PR=" + ((val & 0XFF00) >> 8) + " "; } alarmIntent.putExtra(EXTRA_PARAM_TIME, ts); - PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT); - AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); + AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE); long currentTimeMillis = System.currentTimeMillis(); Date date = new Date(currentTimeMillis + timeout); String dateStr = (String) DateFormat.format("MM-dd kk:mm:ss", date); - Log.d(TAG, "Register Photo Timer: " + dateStr + " currentTimeMillis=" + currentTimeMillis + " timeout=" + timeout + " Channels=" + channelStr); + Log.d(TAG, "PhotoTimer Reg: " + dateStr + " currentTimeMillis=" + currentTimeMillis + " timeout=" + timeout + " Channels=" + channelStr); alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + timeout, pendingIntent); } + private void registerPhotoTimer(int channel, int preset, long ts, long timeout, List schedules) { - // private HashMap mTimers = new HashMap(); + registerPhotoTimer(this.getApplicationContext(), channel, preset, ts, timeout, schedules); + } - public boolean registerTimer(long uid, int timeout) { + // private HashMap mTimers = new HashMap(); + public boolean registerTimer(long uid, int timeout, long times) { // 创建延迟意图 Intent alarmIntent = new Intent(); alarmIntent.setAction(ACTION_TIMEOUT); alarmIntent.putExtra(EXTRA_PARAM_TIMER_UID, uid); alarmIntent.putExtra(EXTRA_PARAM_TIMEOUT, timeout); + alarmIntent.putExtra(EXTRA_PARAM_TIMES, times); + alarmIntent.putExtra(EXTRA_PARAM_ELASPED_TIMES, 0L); PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT); @@ -311,7 +296,6 @@ public class MicroPhotoService extends Service { Log.e(TAG, "wjz debug setDefaultDataSubId: error is " + e.getMessage()); } } - private int getDefaultDataSubId() { SubscriptionManager subscriptionManager = (SubscriptionManager) getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); try { @@ -322,7 +306,6 @@ public class MicroPhotoService extends Service { } return 0; } - public boolean registerTimer(PendingIntent pendingIntent, long uid, int timeout) { AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); @@ -332,7 +315,6 @@ public class MicroPhotoService extends Service { Log.i(TAG, "RegTimer:" + uid + " timeout=" + timeout); return true; } - public boolean unregisterTimer(long uid) { Long uidObj = Long.valueOf(uid); @@ -348,7 +330,6 @@ public class MicroPhotoService extends Service { return true; } - private boolean registerCaptureSchedule(long startTime, long baseTime) { long[] photoTimeData = getPhotoTimeData(mHandler); @@ -386,7 +367,7 @@ public class MicroPhotoService extends Service { schedules.add(Long.valueOf(val)); - Log.i(TAG, "Reg Photo Timer: CH=" + channel + " PR=" + preset); + Log.i(TAG, "PhotoTimer Reg: CH=" + channel + " PR=" + preset); } else if (ts > currentTs) { break; } else { @@ -394,7 +375,7 @@ public class MicroPhotoService extends Service { channel = (short) ((val & 0xFF0000L) >> 16); preset = (short) ((val & 0xFF00L) >> 8); - Log.i(TAG, "Reg Photo Timer: CH=" + channel + " PR=" + preset); + Log.i(TAG, "PhotoTimer Reg: CH=" + channel + " PR=" + preset); schedules.add(Long.valueOf(val)); } } @@ -417,11 +398,14 @@ public class MicroPhotoService extends Service { public static void takePhoto(Context context, int channel, int preset, boolean photoOrVideo) { - Intent intent = new Intent(ACTION_TAKE_PHOTO_MANUALLY); - intent.putExtra(EXTRA_PARAM_CHANNEL, channel); - intent.putExtra(EXTRA_PARAM_PRESET, preset); - intent.putExtra(EXTRA_PARAM_PHOTO_OR_VIDEO, photoOrVideo); - context.sendBroadcast(intent); + List schedules = new ArrayList<>(); + long ts = System.currentTimeMillis() / 1000; + long val = (ts << 24); + val |= ((long)channel << 16); + val |= ((long)preset << 8); + schedules.add(Long.valueOf(val)); + + registerPhotoTimer(context, channel, preset, System.currentTimeMillis() / 1000, 0, schedules); } @Override @@ -441,29 +425,34 @@ public class MicroPhotoService extends Service { connect(); + registerReceiver(screenactionreceiver, screenactionreceiver.getFilter()); + + // File path = getApplicationContext().getFilesDir(); String appPath = buildAppDir(this.getApplicationContext()); String ip = intent.getStringExtra("server"); int port = intent.getIntExtra("port", 0); String cmdid = intent.getStringExtra("cmdid"); + int protocol = intent.getIntExtra("protocol", 0); - Log.i(TAG, "AppPath=" + appPath + " Server=" + ip + ":" + port + " cmdid=" + cmdid); - mHandler = init(appPath, ip, port, cmdid); + Log.i(TAG, "AppPath=" + appPath + " Server=" + ip + ":" + port + " cmdid=" + cmdid + " protocol" + protocol); + mHandler = init(appPath, ip, port, cmdid, protocol); // Start the locker receiver - registerReceiver(screenactionreceiver, screenactionreceiver.getFilter()); + if (mHandler !=0) { + Date date = new Date(); + long nowTs = date.getTime() / 1000; + date.setHours(0); + date.setMinutes(0); + date.setSeconds(0); + long startTime = date.getTime() / 1000; + long baseTime = nowTs - startTime; - Date date = new Date(); - long nowTs = date.getTime() / 1000; - date.setHours(0); - date.setMinutes(0); - date.setSeconds(0); - long startTime = date.getTime() / 1000; - long baseTime = nowTs - startTime; + registerCaptureSchedule(startTime, baseTime); - registerCaptureSchedule(startTime, baseTime); + } // registerPhotoTimer(); break; @@ -483,7 +472,7 @@ public class MicroPhotoService extends Service { public void requestWakelock(String name, long timeout) { PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); - PowerManager.WakeLock wl = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, name); + PowerManager.WakeLock wl = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, name); PowerManager.WakeLock wl2 = null; synchronized (mWakeLocks) { wl2 = mWakeLocks.replace(name, wl); @@ -578,7 +567,7 @@ public class MicroPhotoService extends Service { .setContentIntent(pendingIntent); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { - notificationBuilder.setVisibility(Notification.VISIBILITY_PUBLIC); + notificationBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC); } return notificationBuilder.build(); @@ -655,16 +644,16 @@ CellSignalStrengthGsm cellSignalStrengthGsm = cellInfoGsm.getCellSignalStrength( cellSignalStrengthGsm.getDbm(); */ - protected native long init(String appPath, String ip, int port, String cmdid); + protected native long init(String appPath, String ip, int port, String cmdid, int protocol); protected native long getHeartbeatDuration(long handler); protected native long[] getPhotoTimeData(long handler); // protected native long[] getNextScheduleItem(long handler); protected native boolean notifyToTakePhoto(long handler, int channel, int preset, long scheduleTime, String path, String fileName, boolean sendToCma); protected native boolean sendHeartbeat(long handler); - protected native boolean fireTimeout(long handler, long uid); + protected native boolean fireTimeout(long handler, long uid, long times); protected native boolean uninit(long handler); protected long mHandler = 0; private AlarmReceiver alarmReceiver = null; - final ScreenActionReceiver screenactionreceiver = new ScreenActionReceiver(); + private ScreenActionReceiver screenactionreceiver = null; } \ No newline at end of file diff --git a/app/src/main/java/com/xinyingpower/microphoto/ScreenActionReceiver.java b/app/src/main/java/com/xinyingpower/microphoto/ScreenActionReceiver.java index b9a278da..7575058c 100644 --- a/app/src/main/java/com/xinyingpower/microphoto/ScreenActionReceiver.java +++ b/app/src/main/java/com/xinyingpower/microphoto/ScreenActionReceiver.java @@ -15,7 +15,6 @@ public class ScreenActionReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - //LOG StringBuilder sb = new StringBuilder(); sb.append("Action: " + intent.getAction() + "\n"); @@ -34,8 +33,6 @@ public class ScreenActionReceiver extends BroadcastReceiver { //Run the locker context.startService(new Intent(context, FloatingWindow.class)); - - } else if(Intent.ACTION_SCREEN_OFF.equals(action))