1 /*
2 * Copyright (C) 2024 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 #define MLOG_TAG "MtpManager"
16
17 #include "mtp_manager.h"
18 #include "media_log.h"
19 #include "mtp_file_observer.h"
20 #include "mtp_service.h"
21 #include "mtp_store_observer.h"
22 #include "mtp_subscriber.h"
23 #include "mtp_medialibrary_manager.h"
24 #include "os_account_manager.h"
25 #include "usb_srv_client.h"
26 #include "usb_srv_support.h"
27 #include "mtp_medialibrary_manager.h"
28
29 #include <thread>
30
31 namespace OHOS {
32 namespace Media {
33 namespace {
34 static std::mutex mutex_;
35 std::shared_ptr<MtpService> mtpServicePtr = nullptr;
36 std::atomic<bool> isMtpServiceRunning = false;
37 } // namespace
38
GetInstance()39 MtpManager &MtpManager::GetInstance()
40 {
41 static MtpManager instance;
42 return instance;
43 }
44
GetMtpService()45 std::shared_ptr<MtpService> GetMtpService()
46 {
47 static std::once_flag oc;
48 std::call_once(oc, []() {
49 mtpServicePtr = std::make_shared<MtpService>();
50 });
51 return mtpServicePtr;
52 }
53
Init()54 void MtpManager::Init()
55 {
56 std::thread([]() {
57 MEDIA_INFO_LOG("MtpManager Init");
58 bool result = MtpSubscriber::Subscribe();
59 MEDIA_INFO_LOG("MtpManager Subscribe result = %{public}d", result);
60
61 int32_t funcs = 0;
62 int ret = OHOS::USB::UsbSrvClient::GetInstance().GetCurrentFunctions(funcs);
63 MEDIA_INFO_LOG("MtpManager Init GetCurrentFunctions = %{public}d ret = %{public}d", funcs, ret);
64 CHECK_AND_RETURN_LOG(ret == 0, "GetCurrentFunctions failed");
65 uint32_t unsignedfuncs = static_cast<uint32_t>(funcs);
66 if (unsignedfuncs & USB::UsbSrvSupport::Function::FUNCTION_MTP) {
67 MtpManager::GetInstance().StartMtpService(MtpMode::MTP_MODE);
68 return;
69 }
70 if (unsignedfuncs & USB::UsbSrvSupport::Function::FUNCTION_PTP) {
71 MtpManager::GetInstance().StartMtpService(MtpMode::PTP_MODE);
72 return;
73 }
74 if (unsignedfuncs & USB::UsbSrvSupport::Function::FUNCTION_HDC) {
75 MtpManager::GetInstance().StopMtpService();
76 }
77 MEDIA_INFO_LOG("MtpManager Init success end");
78 }).detach();
79 }
80
StartMtpService(const MtpMode mode)81 void MtpManager::StartMtpService(const MtpMode mode)
82 {
83 MEDIA_INFO_LOG("MtpManager::StartMtpService is called");
84 bool isForeground = true;
85 OHOS::ErrCode errCode = OHOS::AccountSA::OsAccountManager::IsOsAccountForeground(isForeground);
86 // not current user foreground, return
87 if (errCode == ERR_OK && !isForeground) {
88 MEDIA_ERR_LOG("StartMtpService errCode = %{public}d isForeground %{public}d", errCode, isForeground);
89 return;
90 }
91 {
92 std::unique_lock lock(mutex_);
93 if (isMtpServiceRunning.load()) {
94 MEDIA_INFO_LOG("MtpManager::StartMtpService -- service is already running");
95 return;
96 }
97 auto service = GetMtpService();
98 CHECK_AND_RETURN_LOG(service != nullptr, "MtpManager mtpServicePtr is nullptr");
99 if (mtpMode_ != MtpMode::NONE_MODE) {
100 service->StopService();
101 }
102 mtpMode_ = mode;
103 if (mode == MtpMode::MTP_MODE) {
104 MtpFileObserver::GetInstance().StartFileInotify();
105 MtpStoreObserver::StartObserver();
106 }
107 service->StartService();
108 isMtpServiceRunning = true;
109 }
110 }
111
StopMtpService()112 void MtpManager::StopMtpService()
113 {
114 MEDIA_INFO_LOG("MtpManager::StopMtpService is called");
115 {
116 std::unique_lock lock(mutex_);
117 if (!isMtpServiceRunning.load()) {
118 MEDIA_INFO_LOG("MtpManager::StopMtpService -- service is already stopped");
119 return;
120 }
121 auto service = GetMtpService();
122 CHECK_AND_RETURN_LOG(service != nullptr, "MtpManager mtpServicePtr is nullptr");
123 if (mtpMode_ == MtpMode::MTP_MODE) {
124 MtpFileObserver::GetInstance().StopFileInotify();
125 MtpStoreObserver::StopObserver();
126 } else if (mtpMode_ == MtpMode::PTP_MODE) {
127 MtpMedialibraryManager::GetInstance()->Clear();
128 }
129 mtpMode_ = MtpMode::NONE_MODE;
130 service->StopService();
131 isMtpServiceRunning = false;
132 }
133 }
134
135 } // namespace Media
136 } // namespace OHOS
137