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