1 /*
2 * Copyright (C) 2022 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 "media_scanner_manager.h"
19
20 #include "directory_ex.h"
21
22 #include "media_log.h"
23 #include "medialibrary_errno.h"
24 #include "media_scanner_db.h"
25
26 namespace OHOS {
27 namespace Media {
28 std::shared_ptr<MediaScannerManager> MediaScannerManager::instance_ = nullptr;
29 std::mutex MediaScannerManager::instanceMutex_;
30
GetInstance()31 std::shared_ptr<MediaScannerManager> MediaScannerManager::GetInstance()
32 {
33 if (instance_ == nullptr) {
34 std::lock_guard<std::mutex> guard(instanceMutex_);
35
36 if (instance_ != nullptr) {
37 return instance_;
38 }
39
40 instance_ = std::shared_ptr<MediaScannerManager>(new (std::nothrow) MediaScannerManager());
41 }
42
43 return instance_;
44 }
45
ScanFile(const std::string & path,const std::shared_ptr<IMediaScannerCallback> & callback,MediaLibraryApi api)46 int32_t MediaScannerManager::ScanFile(const std::string &path, const std::shared_ptr<IMediaScannerCallback> &callback,
47 MediaLibraryApi api)
48 {
49 MEDIA_DEBUG_LOG("scan file %{private}s, api%{public}d", path.c_str(), static_cast<int>(api));
50
51 string realPath;
52 if (!PathToRealPath(path, realPath)) {
53 MEDIA_ERR_LOG("failed to get real path %{private}s, errno %{public}d", path.c_str(), errno);
54 return E_INVALID_PATH;
55 }
56
57 if (!ScannerUtils::IsRegularFile(realPath)) {
58 MEDIA_ERR_LOG("the path %{private}s is not a regular file", realPath.c_str());
59 return E_INVALID_PATH;
60 }
61
62 std::unique_ptr<MediaScannerObj> scanner =
63 std::make_unique<MediaScannerObj>(realPath, callback, MediaScannerObj::FILE, api);
64 executor_.Commit(move(scanner));
65
66 return E_OK;
67 }
68
ScanFileSync(const std::string & path,const std::shared_ptr<IMediaScannerCallback> & callback,MediaLibraryApi api,bool isForceScan,int32_t fileId)69 int32_t MediaScannerManager::ScanFileSync(const std::string &path,
70 const std::shared_ptr<IMediaScannerCallback> &callback, MediaLibraryApi api, bool isForceScan, int32_t fileId)
71 {
72 MEDIA_DEBUG_LOG("scan file %{private}s, api%{public}d", path.c_str(), static_cast<int>(api));
73
74 string realPath;
75 if (!PathToRealPath(path, realPath)) {
76 MEDIA_ERR_LOG("failed to get real path %{private}s, errno %{public}d", path.c_str(), errno);
77 return E_INVALID_PATH;
78 }
79
80 if (!ScannerUtils::IsRegularFile(realPath)) {
81 MEDIA_ERR_LOG("the path %{private}s is not a regular file", realPath.c_str());
82 return E_INVALID_PATH;
83 }
84
85 MediaScannerObj scanner = MediaScannerObj(realPath, callback, MediaScannerObj::FILE, api);
86 if (isForceScan) {
87 scanner.SetForceScan(true);
88 }
89 scanner.SetFileId(fileId);
90 scanner.Scan();
91
92 return E_OK;
93 }
94
ScanFileSyncWithoutAlbumUpdate(const std::string & path,const std::shared_ptr<IMediaScannerCallback> & callback,MediaLibraryApi api,bool isForceScan,int32_t fileId)95 int32_t MediaScannerManager::ScanFileSyncWithoutAlbumUpdate(const std::string &path,
96 const std::shared_ptr<IMediaScannerCallback> &callback, MediaLibraryApi api, bool isForceScan, int32_t fileId)
97 {
98 MEDIA_DEBUG_LOG("scan file %{private}s, api%{public}d", path.c_str(), static_cast<int>(api));
99
100 string realPath;
101 if (!PathToRealPath(path, realPath)) {
102 MEDIA_ERR_LOG("failed to get real path %{private}s, errno %{public}d", path.c_str(), errno);
103 return E_INVALID_PATH;
104 }
105
106 if (!ScannerUtils::IsRegularFile(realPath)) {
107 MEDIA_ERR_LOG("the path %{private}s is not a regular file", realPath.c_str());
108 return E_INVALID_PATH;
109 }
110
111 MediaScannerObj scanner = MediaScannerObj(realPath, callback, MediaScannerObj::FILE, api);
112 if (isForceScan) {
113 scanner.SetForceScan(true);
114 }
115 scanner.SetFileId(fileId);
116 scanner.SetIsSkipAlbumUpdate(true);
117 scanner.Scan();
118
119 return E_OK;
120 }
121
ScanDir(const std::string & path,const std::shared_ptr<IMediaScannerCallback> & callback)122 int32_t MediaScannerManager::ScanDir(const std::string &path, const std::shared_ptr<IMediaScannerCallback> &callback)
123 {
124 MEDIA_DEBUG_LOG("scan dir %{private}s", path.c_str());
125
126 string realPath;
127 if (!PathToRealPath(path, realPath)) {
128 MEDIA_ERR_LOG("failed to get real path %{private}s, errno %{public}d", path.c_str(), errno);
129 return E_INVALID_PATH;
130 }
131
132 if (!ScannerUtils::IsDirectory(realPath)) {
133 MEDIA_ERR_LOG("the path %{private}s is not a directory", realPath.c_str());
134 return E_INVALID_PATH;
135 }
136
137 std::unique_ptr<MediaScannerObj> scanner = std::make_unique<MediaScannerObj>(realPath, callback,
138 MediaScannerObj::DIRECTORY);
139 executor_.Commit(move(scanner));
140
141 return E_OK;
142 }
143
ScanDirSync(const std::string & path,const std::shared_ptr<IMediaScannerCallback> & callback)144 int32_t MediaScannerManager::ScanDirSync(const std::string &path,
145 const std::shared_ptr<IMediaScannerCallback> &callback)
146 {
147 MEDIA_DEBUG_LOG("scan dir %{private}s", path.c_str());
148
149 string realPath;
150 if (!PathToRealPath(path, realPath)) {
151 MEDIA_ERR_LOG("failed to get real path %{private}s, errno %{public}d", path.c_str(), errno);
152 return E_INVALID_PATH;
153 }
154
155 if (!ScannerUtils::IsDirectory(realPath)) {
156 MEDIA_ERR_LOG("the path %{private}s is not a directory", realPath.c_str());
157 return E_INVALID_PATH;
158 }
159
160 MediaScannerObj scanner = MediaScannerObj(realPath, callback, MediaScannerObj::DIRECTORY);
161 scanner.Scan();
162
163 return E_OK;
164 }
165
Start()166 void MediaScannerManager::Start()
167 {
168 executor_.Start();
169
170 std::unique_ptr<MediaScannerObj> scanner = std::make_unique<MediaScannerObj>(MediaScannerObj::START);
171 executor_.Commit(move(scanner));
172 }
173
Stop()174 void MediaScannerManager::Stop()
175 {
176 /* stop all working threads */
177 this->executor_.Stop();
178
179 MediaScannerDb::GetDatabaseInstance()->DeleteError(ROOT_MEDIA_DIR);
180 }
181
ScanError()182 void MediaScannerManager::ScanError()
183 {
184 std::unique_ptr<MediaScannerObj> scanner = std::make_unique<MediaScannerObj>(MediaScannerObj::ERROR);
185 executor_.Commit(move(scanner));
186 }
187
ErrorRecord(const std::string & path)188 void MediaScannerManager::ErrorRecord(const std::string &path)
189 {
190 std::unique_ptr<MediaScannerObj> scanner = std::make_unique<MediaScannerObj>(MediaScannerObj::SET_ERROR);
191 scanner->SetErrorPath(path);
192 executor_.Commit(move(scanner));
193 }
194 } // namespace Media
195 } // namespace OHOS