• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <string>
17 #include <dlfcn.h>
18 #include <thread>
19 #include <cstdint>
20 #define MLOG_TAG "MediaMtpServiceManager"
21 
22 #include "media_mtp_service_manager.h"
23 #include "media_log.h"
24 
25 namespace OHOS {
26 namespace Media {
27 namespace {
28 constexpr int64_t WAIT_TIMEOUT = 60000; // 60s
29 const std::string PLUGIN_SO_PATH = "libmedia_mtp.z.so";
30 const std::string STOP_MTP_SERVICE = "StopMtpService";
31 const std::string START_MTP_SERVICE = "StartMtpService";
32 }
33 
StopMtpService()34 void MediaMtpServiceManager::StopMtpService()
35 {
36     MEDIA_INFO_LOG("mtp MediaMtpServiceManager StopMtpService");
37     CHECK_AND_RETURN_LOG(handler_, "Dynamic library libmedia_mtp.z.so not loaded");
38 
39     using StopMtpServiceFunc = void(*)();
40     StopMtpServiceFunc stopMtpService = (StopMtpServiceFunc)dlsym(handler_, STOP_MTP_SERVICE.c_str());
41     if (stopMtpService == nullptr) {
42         MEDIA_ERR_LOG("Not find stopMtpService func.");
43         CloseLibrary();
44         return;
45     }
46 
47     stopMtpService();
48     isNeedClose_.store(true);
49     NotifyRefreshStopWaitTime();
50 }
51 
StartMtpService(const MtpMode mode)52 void MediaMtpServiceManager::StartMtpService(const MtpMode mode)
53 {
54     MEDIA_INFO_LOG("mtp MediaMtpServiceManager StartMtpService");
55     if (handler_ == nullptr) {
56         handler_ = dlopen(PLUGIN_SO_PATH.c_str(), RTLD_NOW);
57         CHECK_AND_RETURN_LOG(handler_, "Not find libmedia_mtp.z.so");
58     }
59 
60     using StartMtpServiceFunc = void(*)(uint32_t mtpMode);
61     StartMtpServiceFunc startMtpServiceFunc = (StartMtpServiceFunc) dlsym(handler_, START_MTP_SERVICE.c_str());
62     if (startMtpServiceFunc == nullptr) {
63         MEDIA_ERR_LOG("mtp dlsym failed: %{public}s", dlerror());
64         CloseLibrary();
65         return;
66     }
67     startMtpServiceFunc(static_cast<uint32_t>(mode));
68     isNeedClose_.store(false);
69     isTimerRefresh_.store(true);
70     cv_.notify_all();
71 }
72 
NotifyRefreshStopWaitTime()73 void MediaMtpServiceManager::NotifyRefreshStopWaitTime()
74 {
75     MEDIA_INFO_LOG("mtp NotifyRefreshStopWaitTime");
76     isTimerRefresh_.store(true);
77     if (isThreadRunning_.load()) {
78         cv_.notify_all();
79     } else {
80         isThreadRunning_.store(true);
81         std::thread([&] { CloseDlopenByStop(); }).detach();
82     }
83 }
84 
CloseDlopenByStop()85 void MediaMtpServiceManager::CloseDlopenByStop()
86 {
87     while (isThreadRunning_.load()) {
88         {
89             std::unique_lock<std::mutex> lock(mutex_);
90             isTimerRefresh_.store(false);
91             cv_.wait_for(lock, std::chrono::milliseconds(WAIT_TIMEOUT), [] {
92                 return isTimerRefresh_.load() || !isThreadRunning_.load();
93             });
94             CHECK_AND_CONTINUE(!isTimerRefresh_.load());
95         }
96         if (!isThreadRunning_.load()) {
97             CloseLibrary();
98             return;
99         }
100         MEDIA_INFO_LOG("mtp CloseDlopenByStop dlclose start isNeedClose_: %{public}d", isNeedClose_.load());
101         if (isNeedClose_.load()) {
102             CloseLibrary();
103         }
104     }
105 }
106 
CloseLibrary()107 void MediaMtpServiceManager::CloseLibrary()
108 {
109     isThreadRunning_.store(false);
110     isNeedClose_.store(false);
111     isTimerRefresh_.store(false);
112     cv_.notify_all();
113     if (handler_ != nullptr) {
114         dlclose(handler_);
115         handler_ = nullptr;
116         MEDIA_DEBUG_LOG("Dynamic library libmedia_mtp.z.so closed");
117     }
118 }
119 } // namespace Media
120 } // namespace OHOS