From c8a7bfbcc4a2cb92b38bd79a6d7a9c945660fbe1 Mon Sep 17 00:00:00 2001 From: chenchong_666 Date: Wed, 4 Jun 2025 19:38:52 +0800 Subject: [PATCH] fix:dump buffer Signed-off-by: chenchong_666 --- .../include/hardware_cursor_pointer_manager.h | 4 + .../src/hardware_cursor_pointer_manager.cpp | 32 ++- .../src/pointer_drawing_manager.cpp | 79 +++---- service/window_manager/src/screen_pointer.cpp | 202 +++++++++++++++++- .../test/screen_pointer_test.cpp | 19 +- 5 files changed, 284 insertions(+), 52 deletions(-) diff --git a/service/hardware_cursor_pointer_manager/include/hardware_cursor_pointer_manager.h b/service/hardware_cursor_pointer_manager/include/hardware_cursor_pointer_manager.h index 6989a947fb..969c070426 100644 --- a/service/hardware_cursor_pointer_manager/include/hardware_cursor_pointer_manager.h +++ b/service/hardware_cursor_pointer_manager/include/hardware_cursor_pointer_manager.h @@ -35,6 +35,7 @@ public: int32_t SetPosition(uint32_t devId, int32_t x, int32_t y, BufferHandle* buffer); int32_t EnableStats(bool enable); int32_t GetCursorStats(uint32_t &frameCount, uint32_t &vsyncCount); + std::string reserveLastThreeLen(uint64_t addr); private: sptr GetPowerInterface(); bool isEnableState_ { false }; @@ -43,6 +44,9 @@ private: uint32_t devId_ { 0 }; sptr powerInterface_ = nullptr; std::mutex mtx_; + bool isFirstSetPosition_ { true }; + std::map preBuffer_; + std::map moveCount_; #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR }; } // namespace MMI diff --git a/service/hardware_cursor_pointer_manager/src/hardware_cursor_pointer_manager.cpp b/service/hardware_cursor_pointer_manager/src/hardware_cursor_pointer_manager.cpp index fa9639e03b..9773f7fe98 100644 --- a/service/hardware_cursor_pointer_manager/src/hardware_cursor_pointer_manager.cpp +++ b/service/hardware_cursor_pointer_manager/src/hardware_cursor_pointer_manager.cpp @@ -15,6 +15,7 @@ #include "hardware_cursor_pointer_manager.h" +#include #include #include "mmi_log.h" @@ -27,13 +28,28 @@ namespace OHOS { namespace MMI { #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR +constexpr uint32_t HEX_OUTPUT_WIDTH = 16; +constexpr uint32_t ADDR_RESERVE_LEN = 3; +constexpr uint32_t MOVE_RECORD_MAX_COUNT = 100; + +std::string HardwareCursorPointerManager::reserveLastThreeLen(uint64_t addr) +{ + std::stringstream buffer; + buffer << std::hex << std::uppercase << std::setw(HEX_OUTPUT_WIDTH) << std::setfill('0') << addr; + + std::string bufferStr = buffer.str(); + std::string reserveAddr = bufferStr.substr(bufferStr.length() - ADDR_RESERVE_LEN); + + return reserveAddr; +} + void HardwareCursorPointerManager::SetTargetDevice(uint32_t devId) { if (static_cast(devId) < 0) { MMI_HILOGE("SetTargetDevice devId %{public}d is invalid", static_cast(devId)); return; } - + if (devId != devId_) { devId_ = devId; MMI_HILOGI("SetTargetDevice devId_ changed"); @@ -83,6 +99,8 @@ bool HardwareCursorPointerManager::IsSupported() int32_t HardwareCursorPointerManager::SetPosition(uint32_t devId, int32_t x, int32_t y, BufferHandle* buffer) { CHKPR(buffer, RET_ERR); + preBuffer_[devId] = nullptr; + moveCoumt[devId] = 0; auto powerInterface = GetPowerInterface(); CHKPR(powerInterface, RET_ERR); @@ -101,7 +119,17 @@ int32_t HardwareCursorPointerManager::SetPosition(uint32_t devId, int32_t x, int return RET_ERR; } } - MMI_HILOGD("SetPosition, devId:%{public}u, x:%{private}d, y:%{private}d", devId, x, y); + + if ((preBuffer_[devId] != buffer) || (moveCount_[devId] == MOVE_RECORD_MAX_COUNT)) { + MMI_HILOGI("preBuffer:%{public}lx, buffer:%{public}lx, devId:%{public}u, moveCount:%{public}u", + reserveLastThreeLen(reinterpret_cast(preBuffer_[devId])).c_str(), + reserveLastThreeLen(reinterpret_cast(buffer)).c_str(), devId, moveCount_[devId]); + preBuffer_[devId] = buffer; + moveCount_[devId] = 0; + } else { + MMI_HILOGD("devId:%{public}u, x:%{private}d, y:%{private}d", devId, x, y); + moveCount_[devId]++; + } return RET_OK; } diff --git a/service/window_manager/src/pointer_drawing_manager.cpp b/service/window_manager/src/pointer_drawing_manager.cpp index f07ff16aa3..c502e16478 100644 --- a/service/window_manager/src/pointer_drawing_manager.cpp +++ b/service/window_manager/src/pointer_drawing_manager.cpp @@ -15,6 +15,7 @@ #include "pointer_drawing_manager.h" +#include #include #include #include @@ -132,6 +133,10 @@ constexpr uint32_t CURSOR_STRIDE { 4 }; constexpr int32_t MAX_FAIL_COUNT { 1000 }; constexpr int32_t CHECK_SLEEP_TIME { 10 }; std::atomic g_isRsRestart { false }; + +// #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR +const std::string BUFFER_DUMP_PATH = "/data/service/el1/public/multimodalinput/"; +// #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR } // namespace } // namespace MMI } // namespace OHOS @@ -326,7 +331,7 @@ ICON_TYPE PointerDrawingManager::MouseIcon2IconType(MOUSE_ICON m) } bool PointerDrawingManager::SetCursorLocation(int32_t displayId, int32_t physicalX, - int32_t physicalY, ICON_TYPE iconType) + int32_t physicalY, MOUSE_ICON mouseStyle) { bool magicCursorSetBounds = false; if (UpdateSurfaceNodeBounds(physicalX, physicalY) == RET_OK) { @@ -346,7 +351,7 @@ bool PointerDrawingManager::SetCursorLocation(int32_t displayId, int32_t physica lastMouseStyle_.id != MOUSE_ICON::RUNNING) { // Change the coordinates issued by RS to asynchronous, // without blocking the issuance of HardwareCursor coordinates. - SoftwareCursorMoveAsync(physicalX, physicalY, iconType); + SoftwareCursorMoveAsync(physicalX, physicalY); } } else { surfaceNodePtr->SetBounds(physicalX, physicalY, surfaceNodePtr->GetStagingProperties().GetBounds().z_, @@ -359,8 +364,8 @@ bool PointerDrawingManager::SetCursorLocation(int32_t displayId, int32_t physica lastMouseStyle_.id != MOUSE_ICON::LOADING && lastMouseStyle_.id != MOUSE_ICON::RUNNING) { ResetMoveRetryTimer(); - if (HardwareCursorMove(physicalX, physicalY, iconType) != RET_OK) { - MoveRetryAsync(physicalX, physicalY, iconType); + if (HardwareCursorMove(physicalX, physicalY, mouseStyle) != RET_OK) { + MoveRetryAsync(physicalX, physicalY, mouseStyle); } } #else @@ -388,7 +393,7 @@ int32_t PointerDrawingManager::UpdateMouseLayer(const PointerStyle& pointerStyle MMI_HILOGE("Init layer failed"); return RET_ERR; } - if (!SetCursorLocation(displayId, physicalX, physicalY, MouseIcon2IconType(MOUSE_ICON(lastMouseStyle_.id)))) { + if (!SetCursorLocation(displayId, physicalX, physicalY, MOUSE_ICON(lastMouseStyle_.id))) { return RET_ERR; } return RET_OK; @@ -414,7 +419,7 @@ int32_t PointerDrawingManager::DrawMovePointer(int32_t displayId, int32_t physic UpdateBindDisplayId(displayId); #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR if (lastMouseStyle_ == pointerStyle && !mouseIconUpdate_ && lastDirection_ == direction) { - if (!SetCursorLocation(displayId, physicalX, physicalY, MouseIcon2IconType(MOUSE_ICON(lastMouseStyle_.id)))) { + if (!SetCursorLocation(displayId, physicalX, physicalY, MOUSE_ICON(pointerStyle.id))) { return RET_ERR; } MMI_HILOGD("The lastpointerStyle is equal with pointerStyle, id:%{public}d, size:%{public}d", @@ -493,10 +498,9 @@ void PointerDrawingManager::SetHardwareCursorPosition(int32_t displayId, int32_t } if (hardwareCursorPointerManager_->IsSupported() && lastMouseStyle_.id != MOUSE_ICON::LOADING && lastMouseStyle_.id != MOUSE_ICON::RUNNING) { - auto align = MouseIcon2IconType(MOUSE_ICON(lastMouseStyle_.id)); ResetMoveRetryTimer(); - if (HardwareCursorMove(physicalX, physicalY, align) != RET_OK) { - MoveRetryAsync(physicalX, physicalY, align); + if (HardwareCursorMove(physicalX, physicalY, MOUSE_ICON(lastMouseStyle_.id)) != RET_OK) { + MoveRetryAsync(physicalX, physicalY, MOUSE_ICON(lastMouseStyle_.id)); } } #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR @@ -1169,13 +1173,12 @@ void PointerDrawingManager::OnVsync(uint64_t timestamp) HardwareCursorDynamicRender(MOUSE_ICON(currentMouseStyle_.id)); ResetMoveRetryTimer(); - if (HardwareCursorMove(lastPhysicalX_, lastPhysicalY_, - MouseIcon2IconType(MOUSE_ICON(currentMouseStyle_.id))) != RET_OK) { - MoveRetryAsync(lastPhysicalX_, lastPhysicalY_, MouseIcon2IconType(MOUSE_ICON(currentMouseStyle_.id))); + if (HardwareCursorMove(lastPhysicalX_, lastPhysicalY_, MOUSE_ICON(currentMouseStyle_.id)) != RET_OK) { + MoveRetryAsync(lastPhysicalX_, lastPhysicalY_, MOUSE_ICON(currentMouseStyle_.id)); } PostSoftCursorTask([this]() { SoftwareCursorDynamicRender(MOUSE_ICON(currentMouseStyle_.id)); - SoftwareCursorMove(lastPhysicalX_, lastPhysicalY_, MouseIcon2IconType(MOUSE_ICON(currentMouseStyle_.id))); + SoftwareCursorMove(lastPhysicalX_, lastPhysicalY_); }); currentFrame_++; if (currentFrame_ == frameCount_) { @@ -1722,7 +1725,7 @@ int32_t PointerDrawingManager::CreatePointerWindowForScreenPointer(int32_t displ CHKPR(sp, RET_ERR); SetSurfaceNode(sp->GetSurfaceNode()); // use SurfaceNode from current display CHKPR(GetSurfaceNode(), RET_ERR); - sp->MoveSoft(physicalX, physicalY, MouseIcon2IconType(MOUSE_ICON(lastMouseStyle_.id))); + sp->MoveSoft(physicalX, physicalY); return RET_OK; } #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR @@ -2609,8 +2612,7 @@ void PointerDrawingManager::UpdatePointerVisible() MMI_HILOGE("Init Layer failed"); return; } - auto align = MouseIcon2IconType(MOUSE_ICON(lastMouseStyle_.id)); - if (!SetCursorLocation(displayId_, lastPhysicalX_, lastPhysicalY_, align)) { + if (!SetCursorLocation(displayId_, lastPhysicalX_, lastPhysicalY_, MOUSE_ICON(lastMouseStyle_.id))) { MMI_HILOGE("SetCursorLocation fail"); } } @@ -2794,7 +2796,7 @@ void PointerDrawingManager::SetPointerLocation(int32_t x, int32_t y, int32_t dis hardwareCursorPointerManager_->SetHdiServiceState(false); } if (hardwareCursorPointerManager_->IsSupported()) { - if (!SetCursorLocation(displayId_, x, y, MouseIcon2IconType(MOUSE_ICON(lastMouseStyle_.id)))) { + if (!SetCursorLocation(displayId_, x, y, MOUSE_ICON(lastMouseStyle_.id))) { MMI_HILOGE("SetCursorLocation fail"); return; } @@ -3323,8 +3325,7 @@ void PointerDrawingManager::UpdateBindDisplayId(int32_t displayId) AttachToDisplay(); // 新屏幕上软硬光标位置更新 - auto align = MouseIcon2IconType(MOUSE_ICON(lastMouseStyle_.id)); - if (!SetCursorLocation(displayId, lastPhysicalX_, lastPhysicalY_, align)) { + if (!SetCursorLocation(displayId, lastPhysicalX_, lastPhysicalY_, MOUSE_ICON(lastMouseStyle_.id))) { MMI_HILOGE("SetCursorLocation fail"); } @@ -3585,13 +3586,17 @@ std::shared_ptr PointerDrawingManager::GetScreenPointer(uint32_t return nullptr; } -int32_t PointerDrawingManager::HardwareCursorMove(int32_t x, int32_t y, ICON_TYPE align) +int32_t PointerDrawingManager::HardwareCursorMove(int32_t x, int32_t y, const MOUSE_ICON mouseStyle) { - MMI_HILOGD("HardwareCursorMove loc: (%{public}d, %{public}d), align type: %{public}d", x, y, align); + MMI_HILOGD("HardwareCursorMove loc: (%{public}d, %{public}d), mouseStyle:%{public}d", + x, y, static_cast(mouseStyle)); int32_t ret = RET_OK; auto sp = GetScreenPointer(displayId_); CHKPR(sp, RET_ERR); - if (!sp->Move(x, y, align)) { + if (!sp->AsyncDumpBufferToFile(BUFFER_DUMP_PATH, mouseStyle)) { + MMI_HILOGW("Dump buffer is failed."); + } + if (!sp->Move(x, y)) { ret = RET_ERR; MMI_HILOGE("ScreenPointer::Move failed, screenId: %{public}u", displayId_); } @@ -3602,12 +3607,12 @@ int32_t PointerDrawingManager::HardwareCursorMove(int32_t x, int32_t y, ICON_TYP } for (auto it : screenPointers) { if (it.second->IsMirror()) { - if (!it.second->Move(x, y, align)) { + if (!it.second->Move(x, y)) { ret = RET_ERR; MMI_HILOGE("ScreenPointer::Move failed, screenId: %{public}u", it.first); } } else if (static_cast(it.first) != displayId_) { - if (!it.second->Move(0, 0, align)) { + if (!it.second->Move(0, 0)) { ret = RET_ERR; MMI_HILOGE("ScreenPointer::Move failed, screenId: %{public}u", it.first); } @@ -3621,7 +3626,7 @@ int32_t PointerDrawingManager::CheckHwcReady() auto sp = GetScreenPointer(displayId_); CHKPR(sp, RET_ERR); int32_t failCount = 0; - while (sp != nullptr && !sp->Move(lastPhysicalX_, lastPhysicalY_, ICON_TYPE::ANGLE_NW)) { + while (sp != nullptr && !sp->Move(lastPhysicalX_, lastPhysicalY_)) { failCount++; if (failCount > MAX_FAIL_COUNT) { MMI_HILOGE("CheckHwcReady failed, screenId: %{public}u", displayId_); @@ -3633,38 +3638,38 @@ int32_t PointerDrawingManager::CheckHwcReady() return RET_OK; } -void PointerDrawingManager::SoftwareCursorMove(int32_t x, int32_t y, ICON_TYPE align) +void PointerDrawingManager::SoftwareCursorMove(int32_t x, int32_t y) { auto sp = GetScreenPointer(displayId_); CHKPV(sp); - sp->MoveSoft(x, y, align); + sp->MoveSoft(x, y); for (auto& msp : GetMirrorScreenPointers()) { - msp->MoveSoft(x, y, align); + msp->MoveSoft(x, y); } Rosen::RSTransaction::FlushImplicitTransaction(); } -void PointerDrawingManager::SoftwareCursorMoveAsync(int32_t x, int32_t y, ICON_TYPE align) +void PointerDrawingManager::SoftwareCursorMoveAsync(int32_t x, int32_t y) { - PostSoftCursorTask([this, x, y, align]() { - SoftwareCursorMove(x, y, align); + PostSoftCursorTask([this, x, y]() { + SoftwareCursorMove(x, y); }); } -void PointerDrawingManager::MoveRetryAsync(int32_t x, int32_t y, ICON_TYPE align) +void PointerDrawingManager::MoveRetryAsync(int32_t x, int32_t y, MOUSE_ICON mouseStyle) { - moveRetryTimerId_ = TimerMgr->AddTimer(MOVE_RETRY_TIME, MAX_MOVE_RETRY_COUNT, [this, x, y, align]() { - PostMoveRetryTask([this, x, y, align]() { + moveRetryTimerId_ = TimerMgr->AddTimer(MOVE_RETRY_TIME, MAX_MOVE_RETRY_COUNT, [this, x, y, mouseStyle]() { + PostMoveRetryTask([this, x, y, mouseStyle]() { moveRetryCount_++; - MMI_HILOGI("MoveRetryAsync start, x:%{private}d, y:%{private}d, align:%{public}d, Timer Id:%{public}d," - "move retry count:%{public}d", x, y, align, moveRetryTimerId_, moveRetryCount_); + MMI_HILOGI("MoveRetryAsync start, x:%{private}d, y:%{private}d, mouseStyle:%{public}d, Timer Id:%{public}d," + "move retry count:%{public}d", x, y, mouseStyle, moveRetryTimerId_, moveRetryCount_); if (moveRetryTimerId_ == DEFAULT_VALUE) { moveRetryCount_ = 0; MMI_HILOGI("MoveRetryAsync timer id is invalid, stop retry"); return; } - if (HardwareCursorMove(x, y, align) == RET_OK) { + if (HardwareCursorMove(x, y, mouseStyle) == RET_OK) { int32_t ret = TimerMgr->RemoveTimer(moveRetryTimerId_); MMI_HILOGI("Move retry success, cancel timer, TimerId:%{public}d, ret:%{public}d", moveRetryTimerId_, ret); diff --git a/service/window_manager/src/screen_pointer.cpp b/service/window_manager/src/screen_pointer.cpp index 2941177905..8afe7399df 100644 --- a/service/window_manager/src/screen_pointer.cpp +++ b/service/window_manager/src/screen_pointer.cpp @@ -14,6 +14,12 @@ */ #include "screen_pointer.h" +#include +#include +#include +#include +#include + #include "bytrace_adapter.h" #include "define_multimodal.h" #include "transaction/rs_transaction.h" @@ -43,6 +49,14 @@ constexpr uint32_t RENDER_STRIDE{4}; constexpr uint32_t POINTER_SIZE_DEFAULT { 1 }; constexpr uint32_t POINTER_SIZE_HPR { 2 }; +#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR +constexpr size_t BLOCK_SIZE = 1024 * 1024; // 1MB +constexpr uint32_t DUMP_FILE_MAX_NUM = 60; +constexpr uint32_t USEC_TO_MSEC_COEFF = 1000; +constexpr uint32_t DATE_MAX_LEN = 80; +uint32_t ScreenPointer::dumpTotalNum_ = 0; +std::mutex ScreenPointer::dumpMtx_; +#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR uint32_t GetScreenInfoWidth(screen_info_ptr_t si) { @@ -54,6 +68,7 @@ uint32_t GetScreenInfoWidth(screen_info_ptr_t si) } return modes[modeId]->width_; } + uint32_t GetScreenInfoHeight(screen_info_ptr_t si) { uint32_t height = 0; @@ -405,7 +420,7 @@ void ScreenPointer::CalculateHwcPositionForExtend(int32_t& x, int32_t& y) y = y * offRenderScale_; } -bool ScreenPointer::Move(int32_t x, int32_t y, ICON_TYPE align) +bool ScreenPointer::Move(int32_t x, int32_t y) { #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR CHKPF(hwcMgr_); @@ -439,7 +454,7 @@ bool ScreenPointer::Move(int32_t x, int32_t y, ICON_TYPE align) return true; } -bool ScreenPointer::MoveSoft(int32_t x, int32_t y, ICON_TYPE align) +bool ScreenPointer::MoveSoft(int32_t x, int32_t y) { CHKPF(surfaceNode_); if (IsPositionOutScreen(x, y)) { @@ -522,4 +537,187 @@ bool ScreenPointer::IsPositionOutScreen(int32_t x, int32_t y) return false; } +#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR +bool ScreenPointer::AsyncDumpBufferToFile(const std::string& dumpPath, const MOUSE_ICON mouseStyle) +{ + (void)mouseStyle; + static buffer_ptr_t preBuffer = nullptr; + auto buffer = GetCurrentBuffer(); + CHKPF(buffer); + if (preBuffer == buffer) { + MMI_HILOGD("The buffer is not changed."); + return true; + } + MMI_HILOGI("The buffer is changed."); + + size_t bufferSize = buffer->GetSize(); + if (bufferSize == 0) { + MMI_HILOGE("The buffer size is incorrect."); + return false; + } + uint8_t* srcAddr = static_cast(buffer->GetVirAddr()); + CHKPF(srcAddr); + uint8_t* destAddr = static_cast(malloc(bufferSize)); + if (destAddr == nullptr) { + MMI_HILOGE("Malloc failed."); + return false; + } + CloneBuffer(destAddr, srcAddr, bufferSize); + + const uint32_t screenId = screenId_; + std::string pid = std::to_string(GetPid()); + std::thread t([this, buffer, bufferSize, destAddr, dumpPath, screenId] () { + std::lock_guard guard(ScreenPointer::dumpMtx_); + WriteToFile(buffer, bufferSize, destAddr, dumpPath, screenId); + }); + t.detach(); + preBuffer = buffer; + return true; +} + +void ScreenPointer::CloneBuffer(uint8_t* dest, const uint8_t* src, size_t totalSize) +{ + CHKPV(dest); + CHKPV(src); + size_t numBlocks = totalSize / BLOCK_SIZE; + size_t lastBlockSize = totalSize % BLOCK_SIZE; + // Obtain the number of parallelizable threads. + size_t numThreads = std::thread::hardware_concurrency(); + numThreads = numThreads > 0 ? numThreads : 1; + size_t blocksPerThread = numBlocks / numThreads; + size_t remainingBlocks = numBlocks % numThreads; + // Lambda function to copy a block of memory + auto copyBlock = [&](uint8_t* currentDest, const uint8_t* currentSrc, size_t size) { + if (size == 0) { + MMI_HILOGE("The size is incorrect"); + return; + } + auto ret = memcpy_s(currentDest, size, currentSrc, size); + if (ret != EOK) { + MMI_HILOGE("memcpy_s ret:%{public}d", static_cast(ret)); + } + }; + + // Vector to store threads + std::vector threads; + uint8_t* currentDest = dest; + const uint8_t* currentSrc = src; + // Create threads and copy blocks of memory + for (size_t i = 0; i < numThreads; ++i) { + // If the number of threads is not enough, the preceding threads will process an additional block + size_t blocksToCopy = blocksPerThread + (i < remainingBlocks ? 1 : 0); + size_t lengthToCopy = blocksToCopy * BLOCK_SIZE; + threads.emplace_back(copyBlock, currentDest, currentSrc, lengthToCopy); + currentDest += lengthToCopy; + currentSrc += lengthToCopy; + } + if (lastBlockSize > 0) { + threads.emplace_back(copyBlock, currentDest, currentSrc, lastBlockSize); + } + // Wait for all threads to finish + for (auto& th : threads) { + if (th.joinable()) { + th.join(); + } + } +} + +bool ScreenPointer::WriteToFile(buffer_ptr_t buffer, size_t bufferSize, + uint8_t* destAddr, const std::string dumpPath, const uint32_t screenId) +{ + CHKPF(buffer); + CHKPF(destAddr); + + // When the multi-mode process starts, there is already a. raw file + if (ScreenPointer::dumpTotalNum_ == 0) { + UpdateDumpTotalNum(dumpPath); + } + + if (ScreenPointer::dumpTotalNum_ < DUMP_FILE_MAX_NUM) { + ScreenPointer::dumpTotalNum_++; + } else { + DeleteOldestFile(dumpPath); + } + + std::string filePath = CreateFilePath(buffer, dumpPath, screenId); + if (filePath.length() == 0) { + MMI_HILOGE("CreateFilePath is failed."); + return false; + } + std::ofstream rawDataFile(filePath, std::ofstream::binary); + if (!rawDataFile.good()) { + MMI_HILOGE("open failed: (%{public}d)%{public}s", errno, strerror(errno)); + return false; + } + rawDataFile.write(reinterpret_cast(destAddr), bufferSize); + if (rawDataFile.fail()) { + MMI_HILOGE("Write failed: (%{public}d)%{public}s", errno, strerror(errno)); + return false; + } + rawDataFile.flush(); + rawDataFile.close(); + free(destAddr); + MMI_HILOGD("WriteToFile is completed."); + return true; +} + +void ScreenPointer::UpdateDumpTotalNum(const std::string dumpPath) +{ + uint32_t fileCount = 0; + std::vector files; + for (const auto& file : std::filesystem::directory_iterator(dumpPath)) { + if (file.is_regular_file() && (file.path().extension() == ".raw")) { + ++fileCount; + } + } + ScreenPointer::dumpTotalNum_ = fileCount; +} + +void ScreenPointer::DeleteOldestFile(const std::string dumpPath) +{ + std::vector files; + for (const auto& file : std::filesystem::directory_iterator(dumpPath)) { + if (file.is_regular_file() && (file.path().extension() == ".raw")) { + files.push_back(file.path()); + } + } + + auto compare = [] (const std::filesystem::path&a, const std::filesystem::path& b) { + return std::filesystem::last_write_time(a) < std::filesystem::last_write_time(b); + }; + auto oldestFile = *std::min_element(files.begin(), files.end(), compare); + std::filesystem::remove(oldestFile); +} + +std::string ScreenPointer::CreateFilePath(buffer_ptr_t buffer, const std::string dumpPath, const uint32_t screenId) +{ + CHKPS(buffer); + CHKPS(hwcMgr_); + auto handle = buffer->GetBufferHandle(); + CHKPS(handle); + // Leave the last 3 digits of the address. + std::string reserveAddrHandle = hwcMgr_->reserveLastThreeLen(reinterpret_cast(handle)); + + // Get the current time point, accurate to μs. + struct timeval now; + struct tm *info; + char array[DATE_MAX_LEN]; + + gettimeofday(&now, nullptr); + time_t currentTime = now.tv_sec; + info = localtime(¤tTime); + strftime(array, DATE_MAX_LEN, "%Y-%m-%d-%H-%M-%s", info); + std::string dateString(array); + + uint32_t msec = now.tv_usec / USEC_TO_MSEC_COEFF; + uint32_t usec = now.tv_usec % USEC_TO_MSEC_COEFF; + + std::stringstream filePath; + filePath << dumpPath << "cursor_" << dateString << "_" << msec << "ms_" << usec + << "us_pid" << std::to_string(GetPid()) << "_screenId" << screenId << "_addr" << reserveAddrHandle + << buffer->GetFormat() << "_" << buffer->GetWidth() << buffer->GetHeight() <<".raw"; + + return filePath.str(); +} +#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR } // namespace OHOS::MMI \ No newline at end of file diff --git a/service/window_manager/test/screen_pointer_test.cpp b/service/window_manager/test/screen_pointer_test.cpp index 631b91e93b..18187ef063 100644 --- a/service/window_manager/test/screen_pointer_test.cpp +++ b/service/window_manager/test/screen_pointer_test.cpp @@ -104,16 +104,15 @@ HWTEST_F(ScreenPointerTest, ScreenPointerTest_MoveSoft_001, TestSize.Level1) Rosen::RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE); ASSERT_NE(screenpointer->surfaceNode_, nullptr); screenpointer->mode_ = mode_t::SCREEN_MIRROR; - ICON_TYPE align = ANGLE_W; int32_t x = 0; int32_t y = 0; - bool ret = screenpointer->MoveSoft(x, y, align); + bool ret = screenpointer->MoveSoft(x, y); EXPECT_TRUE(ret); screenpointer->mode_ = mode_t::SCREEN_MAIN; - ret = screenpointer->MoveSoft(x, y, align); + ret = screenpointer->MoveSoft(x, y); EXPECT_TRUE(ret); screenpointer->mode_ = mode_t::SCREEN_EXTEND; - ret = screenpointer->MoveSoft(x, y, align); + ret = screenpointer->MoveSoft(x, y); EXPECT_TRUE(ret); } @@ -141,8 +140,7 @@ HWTEST_F(ScreenPointerTest, ScreenPointerTest_MoveSoft_002, TestSize.Level1) int32_t x = -1; int32_t y = -1; - ICON_TYPE align = ICON_TYPE::ANGLE_N; - auto ret = screenpointer->MoveSoft(x, y, align); + auto ret = screenpointer->MoveSoft(x, y); EXPECT_TRUE(ret); } @@ -170,22 +168,21 @@ HWTEST_F(ScreenPointerTest, ScreenPointerTest_Move_001, TestSize.Level1) ASSERT_NE(screenpointer->surfaceNode_, nullptr); screenpointer->mode_ = mode_t::SCREEN_MIRROR; screenpointer->isCurrentOffScreenRendering_ = true; - ICON_TYPE align = ANGLE_W; int32_t x = 0; int32_t y = 0; - bool ret = screenpointer->Move(x, y, align); + bool ret = screenpointer->Move(x, y); EXPECT_TRUE(ret); screenpointer->mode_ = mode_t::SCREEN_MAIN; screenpointer->isCurrentOffScreenRendering_ = true; - ret = screenpointer->Move(x, y, align); + ret = screenpointer->Move(x, y); EXPECT_TRUE(ret); screenpointer->mode_ = mode_t::SCREEN_EXTEND; screenpointer->isCurrentOffScreenRendering_ = false; - ret = screenpointer->Move(x, y, align); + ret = screenpointer->Move(x, y); EXPECT_TRUE(ret); screenpointer->mode_ = mode_t::SCREEN_MIRROR; screenpointer->isCurrentOffScreenRendering_ = false; - ret = screenpointer->Move(x, y, align); + ret = screenpointer->Move(x, y); EXPECT_TRUE(ret); } -- Gitee