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