From fa65ebbf165c0b5480e6fd389ac91bd5e7cff0b1 Mon Sep 17 00:00:00 2001 From: zhonglufu Date: Wed, 20 Aug 2025 19:49:02 +0800 Subject: [PATCH] =?UTF-8?q?MTP=E5=9C=BA=E6=99=AFcopy=E8=BF=9B=E5=BA=A6?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhonglufu --- .../include/copy/file_copy_listener.h | 6 + .../src/copy/file_copy_listener.cpp | 33 ++++- .../src/copy/file_copy_manager.cpp | 4 + .../copy/file_copy_listener_test.cpp | 137 ++++++++++++++++++ .../copy/file_copy_manager_test.cpp | 22 ++- 5 files changed, 197 insertions(+), 5 deletions(-) diff --git a/frameworks/native/distributed_file_inner/include/copy/file_copy_listener.h b/frameworks/native/distributed_file_inner/include/copy/file_copy_listener.h index d755452b0..9322a0a81 100644 --- a/frameworks/native/distributed_file_inner/include/copy/file_copy_listener.h +++ b/frameworks/native/distributed_file_inner/include/copy/file_copy_listener.h @@ -62,6 +62,10 @@ public: return filePaths_; } int32_t GetResult() { return errorCode_; }; + void SetMtpPath() + { + isMtpPath_ = true; + } private: void CloseNotifyFd(); @@ -72,6 +76,7 @@ private: std::tuple HandleProgress(inotify_event *event); bool CheckFileValid(const std::string &filePath); int UpdateProgressSize(const std::string &filePath, std::shared_ptr receivedInfo); + void GetNotifyEvent4Mtp(); private: bool isFile_ = false; @@ -97,6 +102,7 @@ private: std::condition_variable notifyCv_; std::mutex cvLock_; std::mutex processMutex_; + bool isMtpPath_ = false; }; } // namespace DistributedFile } // namespace Storage diff --git a/frameworks/native/distributed_file_inner/src/copy/file_copy_listener.cpp b/frameworks/native/distributed_file_inner/src/copy/file_copy_listener.cpp index ce7e7b665..51d2b509b 100644 --- a/frameworks/native/distributed_file_inner/src/copy/file_copy_listener.cpp +++ b/frameworks/native/distributed_file_inner/src/copy/file_copy_listener.cpp @@ -34,6 +34,7 @@ using namespace FileManagement; static constexpr int BUF_SIZE = 1024; static constexpr std::chrono::milliseconds NOTIFY_PROGRESS_DELAY(100); static constexpr int SLEEP_TIME_US = 100000; +constexpr uint64_t DEFAULT_SPEED_SIZE = 2.8 * 1024 * 1024; FileCopyLocalListener::FileCopyLocalListener(const std::string &srcPath, bool isFile, const ProcessCallback &processCallback) : isFile_(isFile), processCallback_(processCallback) @@ -81,10 +82,30 @@ void FileCopyLocalListener::StartListener() LOGE("notifyHandler has join"); return; } - notifyHandler_ = std::thread([this] { - LOGI("StartListener."); - GetNotifyEvent(); + if (isMtpPath_) { + notifyHandler_ = std::thread([this] { + LOGI("MTP copy StartListener."); + GetNotifyEvent4Mtp(); }); + } else { + notifyHandler_ = std::thread([this] { + LOGI("StartListener."); + GetNotifyEvent(); + }); + } +} + +void FileCopyLocalListener::GetNotifyEvent4Mtp() +{ + prctl(PR_SET_NAME, "NotifyThread4Mtp"); + while (notifyRun_.load() && (processCallback_ != nullptr)) { + progressSize_ += DEFAULT_SPEED_SIZE; + if (progressSize_ >= totalSize_) { + progressSize_ = totalSize_; + } + processCallback_(progressSize_, totalSize_); + usleep(SLEEP_TIME_US); + } } void FileCopyLocalListener::StopListener() @@ -95,7 +116,11 @@ void FileCopyLocalListener::StopListener() LOGI("processCallback is nullptr"); return; } - processCallback_(progressSize_, totalSize_); + if (isMtpPath_) { + processCallback_(totalSize_, totalSize_); + } else { + processCallback_(progressSize_, totalSize_); + } CloseNotifyFdLocked(); notifyRun_.store(false); { diff --git a/frameworks/native/distributed_file_inner/src/copy/file_copy_manager.cpp b/frameworks/native/distributed_file_inner/src/copy/file_copy_manager.cpp index 3e5c7e5a6..560f95880 100644 --- a/frameworks/native/distributed_file_inner/src/copy/file_copy_manager.cpp +++ b/frameworks/native/distributed_file_inner/src/copy/file_copy_manager.cpp @@ -200,6 +200,10 @@ int32_t FileCopyManager::Copy(const std::string &srcUri, const std::string &dest } infos->localListener = FileCopyLocalListener::GetLocalListener(infos->srcPath, infos->srcUriIsFile, processCallback); + if (infos->srcPath.rfind(MTP_PATH_PREFIX, 0) != std::string::npos) { + infos->localListener->SetMtpPath(); + LOGI("Copy srcpath is mtp path"); + } auto result = ExecLocal(infos); RemoveFileInfos(infos); infos->localListener->StopListener(); diff --git a/test/unittests/distributed_file_inner/copy/file_copy_listener_test.cpp b/test/unittests/distributed_file_inner/copy/file_copy_listener_test.cpp index 11fb005e9..2d667f65f 100644 --- a/test/unittests/distributed_file_inner/copy/file_copy_listener_test.cpp +++ b/test/unittests/distributed_file_inner/copy/file_copy_listener_test.cpp @@ -40,6 +40,7 @@ const std::string SRC_FILE = TEST_DIR + "test_src.txt"; const std::string DEST_DIR = TEST_DIR + "dest/"; constexpr uint64_t TEST_FILE_SIZE = 1024; // 1KB test file constexpr mode_t TEST_DIR_MODE = 0777; +constexpr uint64_t MTP_SPEED_SIZE = 3 * 1024 * 1024; /* Test Fixture */ class FileCopyLocalListenerTest : public testing::Test { @@ -226,6 +227,142 @@ HWTEST_F(FileCopyLocalListenerTest, FileCopyLocalListener_ThreadSafety_0001, Tes GTEST_LOG_(INFO) << "FileCopyLocalListener_ThreadSafety_0001 End"; } +/** + * @tc.name: FileCopyLocalListener_StartListener_0001 + * @tc.desc: Verify StartListener behavior + * @tc.type: FUNC + * @tc.require: AR000H0E5H + */ +HWTEST_F(FileCopyLocalListenerTest, FileCopyLocalListener_StartListener_0001, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "FileCopyLocalListener_StartListener_0001 Start"; + + std::string srcPath = "/data/test.txt"; + std::string testPath = "/data/test_file_listener.txt"; + std::function callback = [](uint64_t current, uint64_t total) { + GTEST_LOG_(INFO) << "Progress: " << current << "/" << total; + }; + + std::ofstream out(testPath); + out << "init"; + out.close(); + + std::ofstream out1(srcPath); + out1 << "test"; + out1.close(); + + auto listener = FileCopyLocalListener::GetLocalListener(testPath, true, callback); + ASSERT_NE(listener, nullptr); + + listener->AddListenerFile(srcPath, testPath, IN_MODIFY | IN_CLOSE_WRITE); + listener->AddFile(testPath); + + listener->isMtpPath_ = true; + listener->StartListener(); + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + std::ofstream modify(testPath); + modify << "trigger event"; + modify.close(); + + std::this_thread::sleep_for(std::chrono::milliseconds(300)); + + listener->StopListener(); + remove(testPath.c_str()); + + GTEST_LOG_(INFO) << "FileCopyLocalListener_StartListener_0001 End"; +} + +/** + * @tc.name: FileCopyLocalListener_StartListener_0002 + * @tc.desc: Verify StartListener behavior + * @tc.type: FUNC + * @tc.require: AR000H0E5H + */ +HWTEST_F(FileCopyLocalListenerTest, FileCopyLocalListener_StartListener_0002, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "FileCopyLocalListener_StartListener_0002 Start"; + + std::string srcPath = "/data/test.txt"; + std::string testPath = "/data/test_file_listener.txt"; + std::function callback = [](uint64_t current, uint64_t total) { + GTEST_LOG_(INFO) << "Progress: " << current << "/" << total; + }; + + std::ofstream out(testPath); + out << "init"; + out.close(); + + std::ofstream out1(srcPath); + out1 << "test"; + out1.close(); + + auto listener = FileCopyLocalListener::GetLocalListener(testPath, true, callback); + ASSERT_NE(listener, nullptr); + + listener->AddListenerFile(srcPath, testPath, IN_MODIFY | IN_CLOSE_WRITE); + listener->AddFile(testPath); + + listener->isMtpPath_ = true; + listener->totalSize_ = MTP_SPEED_SIZE; + listener->StartListener(); + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + std::ofstream modify(testPath); + modify << "trigger event"; + modify.close(); + + std::this_thread::sleep_for(std::chrono::milliseconds(300)); + + listener->StopListener(); + remove(testPath.c_str()); + + GTEST_LOG_(INFO) << "FileCopyLocalListener_StartListener_0002 End"; +} + +/** + * @tc.name: FileCopyLocalListener_GetNotifyEvent4Mtp_0001 + * @tc.desc: Verify GetNotifyEvent4Mtp behavior + * @tc.type: FUNC + * @tc.require: AR000H0E5H + */ +HWTEST_F(FileCopyLocalListenerTest, FileCopyLocalListener_GetNotifyEvent4Mtp_0001, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "FileCopyLocalListener_GetNotifyEvent4Mtp_0001 Start"; + + std::string testPath = "/data/test_file_listener.txt"; + std::function callback = [](uint64_t current, uint64_t total) { + GTEST_LOG_(INFO) << "Progress: " << current << "/" << total; + }; + + auto listener = FileCopyLocalListener::GetLocalListener(testPath, true, callback); + ASSERT_NE(listener, nullptr); + + listener->notifyRun_.store(false); + listener->GetNotifyEvent4Mtp(); + + GTEST_LOG_(INFO) << "FileCopyLocalListener_GetNotifyEvent4Mtp_0001 End"; +} + +/** + * @tc.name: FileCopyLocalListener_GetNotifyEvent4Mtp_0002 + * @tc.desc: Verify GetNotifyEvent4Mtp behavior + * @tc.type: FUNC + * @tc.require: AR000H0E5H + */ +HWTEST_F(FileCopyLocalListenerTest, FileCopyLocalListener_GetNotifyEvent4Mtp_0002, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "FileCopyLocalListener_GetNotifyEvent4Mtp_0002 Start"; + + std::string testPath = "/data/test_file_listener.txt"; + auto listener = FileCopyLocalListener::GetLocalListener(testPath, true, nullptr); + ASSERT_NE(listener, nullptr); + + listener->GetNotifyEvent4Mtp(); + + GTEST_LOG_(INFO) << "FileCopyLocalListener_GetNotifyEvent4Mtp_0002 End"; +} + } // namespace Test } // namespace DistributedFile } // namespace Storage diff --git a/test/unittests/distributed_file_inner/copy/file_copy_manager_test.cpp b/test/unittests/distributed_file_inner/copy/file_copy_manager_test.cpp index 9fbf724aa..5958f77b1 100644 --- a/test/unittests/distributed_file_inner/copy/file_copy_manager_test.cpp +++ b/test/unittests/distributed_file_inner/copy/file_copy_manager_test.cpp @@ -225,6 +225,26 @@ HWTEST_F(FileCopyManagerTest, FileCopyManager_Copy_0006, TestSize.Level0) GTEST_LOG_(INFO) << "FileCopyManager_Copy_0006 End"; } +/** + * @tc.name: FileCopyManager_Copy_0007 + * @tc.desc: The execution of the Copy failed. + * @tc.type: FUNC + * @tc.require: I7TDJK + */ +HWTEST_F(FileCopyManagerTest, FileCopyManager_Copy_0007, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "FileCopyManager_Copy_0007 Start"; + string srcUri = "file://docs/storage/External/mtp/1.txt"; + string destUri = "file://docs/storage/media/100/local/files/Docs/a1.txt"; + string srcPath = "/storage/External/mtp/1.txt"; + + EXPECT_TRUE(OHOS::RemoveFile(srcPath)); + auto ret = Storage::DistributedFile::FileCopyManager::GetInstance()->Copy(srcUri, destUri, emptyCallback_); + EXPECT_EQ(ret, EINVAL); + + GTEST_LOG_(INFO) << "FileCopyManager_Copy_0007 End"; +} + /** * @tc.name: FileCopyManager_ExecLocal_0001 * @tc.desc: The execution of the execlocal failed. @@ -466,7 +486,7 @@ HWTEST_F(FileCopyManagerTest, FileCopyManager_ExecLocal_0006, TestSize.Level0) infos->destPath = destpath; infos->localListener = FileCopyLocalListener::GetLocalListener(infos->srcPath, infos->srcUriIsFile, listener_); - + // destpath is invalid auto ret = Storage::DistributedFile::FileCopyManager::GetInstance()->ExecLocal(infos); EXPECT_EQ(ret, ENOENT); -- Gitee