From 78c948b95f4ae8b04a6816d51675f84ae45e1ad5 Mon Sep 17 00:00:00 2001 From: Matthew Date: Sat, 1 Jun 2024 21:35:18 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E8=87=AA=E6=A3=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/cpp/PhoneDevice.cpp | 174 +++++++++++++++++++++---- app/src/main/cpp/PhoneDevice.h | 4 + app/src/main/cpp/camera2/ndkcamera.cpp | 68 +++++++++- app/src/main/cpp/camera2/ndkcamera.h | 2 + 4 files changed, 219 insertions(+), 29 deletions(-) diff --git a/app/src/main/cpp/PhoneDevice.cpp b/app/src/main/cpp/PhoneDevice.cpp index f54d47d8..09a98c7a 100644 --- a/app/src/main/cpp/PhoneDevice.cpp +++ b/app/src/main/cpp/PhoneDevice.cpp @@ -1,7 +1,6 @@ -#include "TerminalDevice.h" - -#include #include "PhoneDevice.h" +#include +#include #include #include #include @@ -289,6 +288,119 @@ bool CPhoneDevice::BindNetwork(int sock) return true; } +bool CPhoneDevice::SelfTest(std::string& result) +{ + result.clear(); + + unsigned int numberOfChannels = 0; + + result += "自检。Version:" + GetVersion() + "\r\n"; + + Json::Value appConfig = Json::objectValue; + std::vector content; + std::string filePath = m_appPath + (APP_DATA_DIR DIR_SEP_STR APP_FILE_NAME_APP_CONF); + if (!readFile(filePath, content)) + { + result += "读取系统配置文件App.json失败\r\n"; + } + else + { + Json::CharReaderBuilder builder; + std::unique_ptr reader(builder.newCharReader()); + + const char* doc = (const char*)&(content[0]); + if (reader->parse(doc, doc + content.size(), &appConfig, NULL)) + { + unsigned int val = 0; + if (GetJSONUInt32Value(appConfig, "channels", val) && (val > 0 && val <= 255)) + { + numberOfChannels = val; + result += "通道数:" + std::to_string(numberOfChannels) + "\r\n"; + } + else + { + result += "通道数未定义或者无效\r\n"; + } + } + else + { + result += "解析系统配置文件App.json失败\r\n"; + } + } + + for (unsigned int channel = 1; channel <= numberOfChannels; channel++) + { + std::string path = m_appPath + (APP_PATH_CHANNELS DIR_SEP_STR); + + unsigned char cameraId = 0; + Json::Value channelCfg = Json::objectValue; + content.clear(); + filePath = m_appPath + (APP_DATA_DIR DIR_SEP_STR APP_FILE_NAME_APP_CONF); + if (!readFile(filePath, content)) + { + result += "读取通道" + std::to_string(channel) + "配置文件失败\r\n"; + } + else + { + Json::CharReaderBuilder builder; + std::unique_ptr reader(builder.newCharReader()); + + const char* doc = (const char*)&(content[0]); + if (reader->parse(doc, doc + content.size(), &channelCfg, NULL)) + { + unsigned char val = 0; + if (GetJSONUInt8Value(channelCfg, "cameraId", cameraId)) + { + result += "通道" + std::to_string(channel) + " Camera ID为 " + std::to_string(cameraId) + "\r\n"; + } + else + { + cameraId = channel - 1; + result += "通道" + std::to_string(channel) + "未定义Camera ID, 使用默认值 " + std::to_string(cameraId) + "\r\n"; + } + } + else + { + result += "解析通道" + std::to_string(channel) + "配置文件App.json失败\r\n"; + } + } + + int32_t width = 0; + int32_t height = 0; + NdkCamera::CAMERA_PARAMS params = { 0 }; + NdkCamera camera(width, height, params); + int res = camera.selfTest(std::to_string(cameraId), width, height); + if (res == 0) + { + result += "通道" + std::to_string(channel) + "正常:最大分辨率:" + std::to_string(width) + "x" + std::to_string(height) + "\r\n"; + } + else + { + result += "通道" + std::to_string(channel) + " 异常 err=" + std::to_string(res) + "\r\n"; + } + } + + int bv = QueryBatteryVoltage(DEFAULT_BATTERY_QUERY_RETRIES); + if (bv > 0) + { + bv -= bv % 100; + result += "电池电压:" + std::to_string((float)bv / 1000) + "\r\n"; + } + + fs::space_info si = fs::space("/data"); + double fr = ((double)si.available * 100.0f) / ((double)si.capacity); + result += "存储剩余:"; + result += std::to_string((int)fr); + result += "%\r\n"; + + long fm = android_os_Process_getFreeMemory(); + long tm = android_os_Process_getTotalMemory(); + double fmp = ((double)fm * 100.0f) / ((double)tm); + result += std::string("可用内存:") + std::to_string((int)fmp) + std::string("%\r\n"); + + return true; +} + bool CPhoneDevice::UpdateTime(time_t ts) { JNIEnv* env = NULL; @@ -329,6 +441,22 @@ bool CPhoneDevice::UpdateSchedules() return (ret == JNI_TRUE); } +int CPhoneDevice::QueryBatteryVoltage(int retries) +{ + int val = -1; // // BatVol + for (int idx = 0; idx < retries; idx++) + { + val = GpioControl::getBatteryBusVoltage(); // // BatVol + if (val >= 0) + { + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + + return val; +} + bool CPhoneDevice::QuerySystemProperties(std::map& properties) { char value[PROP_VALUE_MAX] = { 0 }; @@ -368,11 +496,7 @@ bool CPhoneDevice::QuerySystemProperties(std::map& pro else if (it->first == (PROP_VERSION_ABBR)) { // FOR OSD - string version = std::to_string(mVersionCode / 100000); - version += "."; - version += std::to_string((mVersionCode % 100000) / 1000); - version += "."; - version += std::to_string(mVersionCode % 1000); + string version = GetVersion(); #if 0 version += " " + FormatLocalTime(mBuildTime); #endif @@ -481,17 +605,7 @@ bool CPhoneDevice::QuerySystemProperties(std::map& pro } else if (it->first == (PROP_BATTERY_BUS_VOL) || it->first == (PROP_BATTERY_VOLTAGE)) { - int val = -1; // // BatVol - for (int idx = 0; idx < DEFAULT_BATTERY_QUERY_RETRIES; idx++) - { - val = GpioControl::getBatteryBusVoltage(); // // BatVol - if (val >= 0) - { - break; - } - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - + int val = QueryBatteryVoltage(DEFAULT_BATTERY_QUERY_RETRIES); // // BatVol if (val > 0) { bv = val; @@ -529,15 +643,7 @@ bool CPhoneDevice::QuerySystemProperties(std::map& pro { if (bv == -1) { - for (int idx = 0; idx < DEFAULT_BATTERY_QUERY_RETRIES; idx++) - { - bv = GpioControl::getBatteryBusVoltage(); // // BatVol - if (bv >= 0) - { - break; - } - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } + bv = QueryBatteryVoltage(DEFAULT_BATTERY_QUERY_RETRIES); } if (bv > 0) @@ -1498,6 +1604,18 @@ std::string CPhoneDevice::GetFileName() const return mPath; } +std::string CPhoneDevice::GetVersion() const +{ + // FOR OSD + string version = std::to_string(mVersionCode / 100000); + version += "."; + version += std::to_string((mVersionCode % 100000) / 1000); + version += "."; + version += std::to_string(mVersionCode % 1000); + + return version; +} + void CPhoneDevice::UpdatePosition(double lon, double lat, double radius, time_t ts) { if (m_listener != NULL) diff --git a/app/src/main/cpp/PhoneDevice.h b/app/src/main/cpp/PhoneDevice.h index 49515801..95200681 100644 --- a/app/src/main/cpp/PhoneDevice.h +++ b/app/src/main/cpp/PhoneDevice.h @@ -181,6 +181,7 @@ public: virtual void SetListener(IListener* listener); virtual void SetRecognizationCfg(const CFG_RECOGNIZATION* pRecognizationCfg); virtual bool BindNetwork(int sock); + virtual bool SelfTest(std::string& result); virtual bool UpdateTime(time_t ts); virtual bool UpdateSchedules(); virtual bool QuerySystemProperties(map& properties); @@ -211,6 +212,7 @@ public: protected: std::string GetFileName() const; + std::string GetVersion() const; bool SendBroadcastMessage(std::string action, int value); // bool MatchCaptureSizeRequest(ACameraManager *cameraManager, const char *selectedCameraId, unsigned int width, unsigned int height, uint32_t cameraOrientation_, @@ -256,6 +258,8 @@ protected: void static handleTimer(union sigval v); void handleTimerImpl(TIMER_CONTEXT* context); + int QueryBatteryVoltage(int retries); + protected: std::mutex m_devLocker; diff --git a/app/src/main/cpp/camera2/ndkcamera.cpp b/app/src/main/cpp/camera2/ndkcamera.cpp index 37e28ba1..7c764284 100644 --- a/app/src/main/cpp/camera2/ndkcamera.cpp +++ b/app/src/main/cpp/camera2/ndkcamera.cpp @@ -154,6 +154,73 @@ NdkCamera::~NdkCamera() close(); } +int NdkCamera::selfTest(const std::string& cameraId, int& maxResolutionX, int& maxResolutionY) +{ + camera_manager.Create(); + // ACameraManager_registerAvailabilityCallback(camera_manager, &camera_manager_cb); + + // find camera + bool foundIt = false; + // DisplayDimension disp(mWidth, mHeight); + // DisplayDimension foundRes = disp; + camera_status_t status = ACAMERA_OK; + + ACameraIdList* cameraIdList = NULL; + status = ACameraManager_getCameraIdList(camera_manager, &cameraIdList); + if (status != ACAMERA_OK) + { + return 1; + } + + for (int i = 0; i < cameraIdList->numCameras; ++i) + { + const char *id = cameraIdList->cameraIds[i]; + if (cameraId.compare(id) == 0) { + foundIt = true; + break; + } + } + ACameraManager_deleteCameraIdList(cameraIdList); + if (!foundIt) + { + return 2; + } + + ACameraMetadata * camera_metadata = 0; + status = ACameraManager_getCameraCharacteristics(camera_manager, cameraId.c_str(), &camera_metadata); + if (status != ACAMERA_OK) + { + return 3; + } + + { + ACameraMetadata_const_entry e = {0}; + camera_status_t status = ACameraMetadata_getConstEntry(camera_metadata,ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &e); + // format of the data: format, width, height, input?, type int32 + + maxResolutionX = 0; + maxResolutionY = 0; + + for (int i = 0; i < e.count; i += 4) + { + int32_t input = e.data.i32[i + 3]; + int32_t format = e.data.i32[i + 0]; + if (input) continue; + + // if (format == AIMAGE_FORMAT_YUV_420_888 || format == AIMAGE_FORMAT_JPEG) + { + if (e.data.i32[i + 1] * e.data.i32[i + 2] > (maxResolutionX * maxResolutionY)) + { + maxResolutionX = e.data.i32[i + 1]; + maxResolutionY = e.data.i32[i + 2]; + } + } + } + } + + return 0; +} + int NdkCamera::open(const std::string& cameraId) { XYLOG(XYLOG_SEVERITY_DEBUG, "DBG::try open %s", cameraId.c_str()); @@ -539,7 +606,6 @@ int NdkCamera::open(const std::string& cameraId) { // std::this_thread::sleep_for(std::chrono::milliseconds(128)); - { if (m_params.sceneMode != 0) { diff --git a/app/src/main/cpp/camera2/ndkcamera.h b/app/src/main/cpp/camera2/ndkcamera.h index d4c0e3ce..4f06f7d5 100644 --- a/app/src/main/cpp/camera2/ndkcamera.h +++ b/app/src/main/cpp/camera2/ndkcamera.h @@ -105,6 +105,8 @@ public: int open(const std::string& cameraId); void close(); + int selfTest(const std::string& cameraId, int& maxResolutionX, int& maxResolutionY); + void onAvailabilityCallback(const char* cameraId); void onUnavailabilityCallback(const char* cameraId); void onImageAvailable(AImageReader* reader);