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
16 #define MLOG_TAG "Scanner"
17
18 #include "ringtone_scanner_manager.h"
19
20 #include "directory_ex.h"
21 #include "ringtone_log.h"
22 #include "ringtone_scanner_utils.h"
23 #include "ringtone_tracer.h"
24
25 namespace OHOS {
26 namespace Media {
27 std::shared_ptr<RingtoneScannerManager> RingtoneScannerManager::instance_ = nullptr;
28 std::mutex RingtoneScannerManager::instanceMutex_;
29
GetInstance()30 std::shared_ptr<RingtoneScannerManager> RingtoneScannerManager::GetInstance()
31 {
32 if (instance_ == nullptr) {
33 std::lock_guard<std::mutex> guard(instanceMutex_);
34
35 if (instance_ != nullptr) {
36 return instance_;
37 }
38
39 instance_ = std::make_shared<RingtoneScannerManager>();
40 }
41
42 return instance_;
43 }
44
ScanFile(const std::string & path,const std::shared_ptr<IRingtoneScannerCallback> & callback)45 int32_t RingtoneScannerManager::ScanFile(const std::string &path,
46 const std::shared_ptr<IRingtoneScannerCallback> &callback)
47 {
48 RINGTONE_DEBUG_LOG("scan file %{private}s", path.c_str());
49
50 std::string realPath;
51 if (!PathToRealPath(path, realPath)) {
52 RINGTONE_ERR_LOG("failed to get real path %{private}s, errno %{public}d", path.c_str(), errno);
53 return E_INVALID_PATH;
54 }
55
56 if (!RingtoneScannerUtils::IsRegularFile(realPath)) {
57 RINGTONE_ERR_LOG("the path %{private}s is not a regular file", realPath.c_str());
58 return E_INVALID_PATH;
59 }
60
61 std::unique_ptr<RingtoneScannerObj> scanner =
62 std::make_unique<RingtoneScannerObj>(realPath, callback, RingtoneScannerObj::FILE);
63 executor_.Commit(move(scanner));
64
65 return E_OK;
66 }
67
ScanFileSync(const std::string & path,const std::shared_ptr<IRingtoneScannerCallback> & callback,bool isForceScan)68 int32_t RingtoneScannerManager::ScanFileSync(const std::string &path,
69 const std::shared_ptr<IRingtoneScannerCallback> &callback, bool isForceScan)
70 {
71 RINGTONE_DEBUG_LOG("scan file %{private}s", path.c_str());
72
73 std::string realPath;
74 if (!PathToRealPath(path, realPath)) {
75 RINGTONE_ERR_LOG("failed to get real path %{private}s, errno %{public}d", path.c_str(), errno);
76 return E_INVALID_PATH;
77 }
78
79 if (!RingtoneScannerUtils::IsRegularFile(realPath)) {
80 RINGTONE_ERR_LOG("the path %{private}s is not a regular file", realPath.c_str());
81 return E_INVALID_PATH;
82 }
83
84 RingtoneScannerObj scanner = RingtoneScannerObj(realPath, callback, RingtoneScannerObj::FILE);
85 if (isForceScan) {
86 scanner.SetForceScan(true);
87 }
88 scanner.Scan();
89
90 return E_OK;
91 }
92
ScanDir(const std::string & path,const std::shared_ptr<IRingtoneScannerCallback> & callback)93 int32_t RingtoneScannerManager::ScanDir(const std::string &path,
94 const std::shared_ptr<IRingtoneScannerCallback> &callback)
95 {
96 RINGTONE_DEBUG_LOG("scan dir %{private}s", path.c_str());
97
98 std::string realPath;
99 if (!PathToRealPath(path, realPath)) {
100 RINGTONE_ERR_LOG("failed to get real path %{private}s, errno %{public}d", path.c_str(), errno);
101 return E_INVALID_PATH;
102 }
103
104 if (!RingtoneScannerUtils::IsDirectory(realPath)) {
105 RINGTONE_ERR_LOG("the path %{private}s is not a directory", realPath.c_str());
106 return E_INVALID_PATH;
107 }
108
109 std::unique_ptr<RingtoneScannerObj> scanner = std::make_unique<RingtoneScannerObj>(realPath, callback,
110 RingtoneScannerObj::DIRECTORY);
111 executor_.Commit(move(scanner));
112
113 return E_OK;
114 }
115
ScanDirSync(const std::string & path,const std::shared_ptr<IRingtoneScannerCallback> & callback)116 int32_t RingtoneScannerManager::ScanDirSync(const std::string &path,
117 const std::shared_ptr<IRingtoneScannerCallback> &callback)
118 {
119 RINGTONE_DEBUG_LOG("scan dir %{private}s", path.c_str());
120
121 std::string realPath;
122 if (!PathToRealPath(path, realPath)) {
123 RINGTONE_ERR_LOG("failed to get real path %{private}s, errno %{public}d", path.c_str(), errno);
124 return E_INVALID_PATH;
125 }
126
127 if (!RingtoneScannerUtils::IsDirectory(realPath)) {
128 RINGTONE_ERR_LOG("the path %{private}s is not a directory", realPath.c_str());
129 return E_INVALID_PATH;
130 }
131
132 RingtoneScannerObj scanner = RingtoneScannerObj(realPath, callback, RingtoneScannerObj::DIRECTORY);
133 scanner.Scan();
134
135 return E_OK;
136 }
137
Start(bool isSync)138 void RingtoneScannerManager::Start(bool isSync)
139 {
140 RingtoneTracer tracer;
141 tracer.Start("Ringtone Scanner Start");
142 if (isSync) {
143 RINGTONE_DEBUG_LOG("scan start, isSync = %{public}d", isSync);
144 RingtoneScannerObj scanner = RingtoneScannerObj(RingtoneScannerObj::START);
145 scanner.Scan();
146 RINGTONE_DEBUG_LOG("scan finished");
147 } else {
148 RINGTONE_DEBUG_LOG("scan start, isSync = %{public}d", isSync);
149 executor_.Start();
150 std::shared_ptr<RingtoneScannerObj> scanner = std::make_shared<RingtoneScannerObj>(RingtoneScannerObj::START);
151 executor_.Commit(scanner);
152 scanner->WaitFor();
153 RINGTONE_DEBUG_LOG("scan finished");
154 }
155 }
156
Stop()157 void RingtoneScannerManager::Stop()
158 {
159 /* stop all working threads */
160 this->executor_.Stop();
161 }
162 } // namespace Media
163 } // namespace OHOS
164