• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "Scanner"
16 
17 #include "scanner_utils.h"
18 
19 #include <cerrno>
20 #include <fstream>
21 
22 #include "directory_ex.h"
23 
24 #include "media_log.h"
25 
26 namespace OHOS {
27 namespace Media {
28 using namespace std;
29 
30 std::vector<size_t> ScannerUtils::skipList_;
31 
32 // Check if file exists or not
IsExists(const string & path)33 bool ScannerUtils::IsExists(const string &path)
34 {
35     struct stat statInfo {};
36 
37     if (path.empty()) {
38         MEDIA_ERR_LOG("Given path name is empty");
39         return false;
40     }
41 
42     return ((stat(path.c_str(), &statInfo)) == ERR_SUCCESS);
43 }
44 
45 // Get the file name from file URI
GetFileNameFromUri(const string & path)46 string ScannerUtils::GetFileNameFromUri(const string &path)
47 {
48     if (!path.empty()) {
49         size_t lastSlashPosition = path.rfind("/");
50         if (lastSlashPosition != string::npos) {
51             if (path.size() > lastSlashPosition) {
52                 return path.substr(lastSlashPosition + 1);
53             }
54         }
55     }
56 
57     MEDIA_ERR_LOG("Failed to obtain file name because given pathname is empty");
58     return "";
59 }
60 
61 // Get file extension from the given filepath uri
GetFileExtensionFromFileUri(const string & path)62 string ScannerUtils::GetFileExtensionFromFileUri(const string &path)
63 {
64     if (!path.empty()) {
65         size_t dotIndex = path.rfind(".");
66         if (dotIndex != string::npos) {
67             return path.substr(dotIndex + 1);
68         }
69     }
70 
71     MEDIA_ERR_LOG("Failed to obtain file extension because given pathname is empty");
72     return "";
73 }
74 
GetMediatypeFromMimetype(const string & mimetype)75 MediaType ScannerUtils::GetMediatypeFromMimetype(const string &mimetype)
76 {
77     MediaType mediaType = MEDIA_TYPE_FILE;
78 
79     if (!mimetype.empty()) {
80         if (mimetype == DEFAULT_AUDIO_MIME_TYPE) {
81             mediaType = MEDIA_TYPE_AUDIO;
82         } else if (mimetype == DEFAULT_VIDEO_MIME_TYPE) {
83             mediaType = MEDIA_TYPE_VIDEO;
84         } else if (mimetype == DEFAULT_IMAGE_MIME_TYPE) {
85             mediaType = MEDIA_TYPE_IMAGE;
86         }
87     }
88 
89     return mediaType;
90 }
91 
92 // Obtain Mime type from the file extension
GetMimeTypeFromExtension(const string & extension)93 string ScannerUtils::GetMimeTypeFromExtension(const string &extension)
94 {
95     string mimeType = DEFAULT_FILE_MIME_TYPE;
96     string extn = extension;
97 
98     if (extn.empty()) {
99         MEDIA_ERR_LOG("Given file extension is empty");
100         return mimeType;
101     }
102 
103     transform(extn.begin(), extn.end(), extn.begin(), ::tolower);
104     if (SUPPORTED_AUDIO_FORMATS_SET.find(extn) != SUPPORTED_AUDIO_FORMATS_SET.end()) {
105         mimeType = DEFAULT_AUDIO_MIME_TYPE;
106     } else if (SUPPORTED_VIDEO_FORMATS_SET.find(extn) != SUPPORTED_VIDEO_FORMATS_SET.end()) {
107         mimeType = DEFAULT_VIDEO_MIME_TYPE;
108     } else if (SUPPORTED_IMAGE_FORMATS_SET.find(extn) != SUPPORTED_IMAGE_FORMATS_SET.end()) {
109         mimeType = DEFAULT_IMAGE_MIME_TYPE;
110     }
111 
112     return mimeType;
113 }
114 
115 // Check if the given path is a directory path
IsDirectory(const string & path)116 bool ScannerUtils::IsDirectory(const string &path)
117 {
118     struct stat s;
119 
120     if (!path.empty()) {
121         if (stat(path.c_str(), &s) == 0) {
122             if (s.st_mode & S_IFDIR) {
123                 return true;
124             }
125         }
126     }
127 
128     MEDIA_ERR_LOG("Either path is empty or it is not a directory");
129     return false;
130 }
131 
132 // Check if the given file starts with '.' , i.e. if it is hidden
IsFileHidden(const string & path)133 bool ScannerUtils::IsFileHidden(const string &path)
134 {
135     if (!path.empty()) {
136         string fileName = GetFileNameFromUri(path);
137         if (!fileName.empty() && fileName.at(0) == '.') {
138             return true;
139         }
140     }
141 
142     MEDIA_ERR_LOG("Either filepath is empty or it is not hidden");
143     return false;
144 }
145 
146 // Get the parent path
GetParentPath(const string & path)147 string ScannerUtils::GetParentPath(const string &path)
148 {
149     if (!path.empty()) {
150         size_t lastSlashPosition = path.rfind("/");
151         if (lastSlashPosition != string::npos && path.size() > lastSlashPosition) {
152             return path.substr(0, lastSlashPosition);
153         }
154     }
155 
156     MEDIA_ERR_LOG("Failed to obtain the parent path");
157     return "";
158 }
159 
GetRootMediaDir(string & dir)160 void ScannerUtils::GetRootMediaDir(string &dir)
161 {
162     dir = ROOT_MEDIA_DIR;
163 }
164 
GetFileTitle(const string & displayName)165 string ScannerUtils::GetFileTitle(const string &displayName)
166 {
167     string title = "";
168     if (!displayName.empty()) {
169         string::size_type pos = displayName.find_first_of('.');
170         if (pos == displayName.length()) {
171             return displayName;
172         }
173         title = displayName.substr(0, pos);
174     }
175     return title;
176 }
177 
IsDirHidden(const string & path)178 bool ScannerUtils::IsDirHidden(const string &path)
179 {
180     bool dirHid = false;
181 
182     if (!path.empty()) {
183         string dirName = ScannerUtils::GetFileNameFromUri(path);
184         if (!dirName.empty() && dirName.at(0) == '.') {
185             MEDIA_ERR_LOG("Directory is of hidden type");
186             return true;
187         }
188 
189         string curPath = path;
190         string excludePath = curPath.append("/.nomedia");
191         // Check is the folder consist of .nomedia file
192         if (ScannerUtils::IsExists(excludePath)) {
193             return true;
194         }
195 
196         // Check is the dir is part of skiplist
197         if (CheckSkipScanList(path)) {
198             return true;
199         }
200     }
201 
202     return dirHid;
203 }
204 
IsDirHiddenRecursive(const string & path)205 bool ScannerUtils::IsDirHiddenRecursive(const string &path)
206 {
207     bool dirHid = false;
208     string curPath = path;
209 
210     do {
211         dirHid = IsDirHidden(curPath);
212         if (dirHid) {
213             break;
214         }
215 
216         curPath = ScannerUtils::GetParentPath(curPath);
217         if (curPath.empty()) {
218             break;
219         }
220     } while (true);
221 
222     return dirHid;
223 }
224 
225 // Initialize the skip list
InitSkipList()226 void ScannerUtils::InitSkipList()
227 {
228     hash<string> hashStr;
229     size_t hashPath;
230     string path;
231 
232     /*
233      * 1. file path: in disk or hard code? path?
234      * 2. call_once: no need to init again if it is really empty
235      * 3. add lock
236      */
237     ifstream skipFile(SKIPLIST_FILE_PATH.c_str());
238     if (skipFile.is_open()) {
239         while (getline(skipFile, path)) {
240             hashPath = hashStr(path);
241             skipList_.insert(skipList_.begin(), hashPath);
242         }
243         skipFile.close();
244     }
245 
246     return;
247 }
248 
249 // Check if path is part of Skip scan list
CheckSkipScanList(const string & path)250 bool ScannerUtils::CheckSkipScanList(const string &path)
251 {
252     hash<string> hashStr;
253     size_t hashPath;
254 
255     if (skipList_.empty()) {
256         InitSkipList();
257     }
258 
259     hashPath = hashStr(path);
260     if (find(skipList_.begin(), skipList_.end(), hashPath) != skipList_.end()) {
261         return true;
262     }
263 
264     return false;
265 }
266 } // namespace Media
267 } // namespace OHOS
268