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 
16 #ifndef MEDIA_SCANNER_OBJ_H
17 #define MEDIA_SCANNER_OBJ_H
18 
19 #include <algorithm>
20 #include <cerrno>
21 #include <dirent.h>
22 #include <fcntl.h>
23 #include <fstream>
24 #include <ftw.h>
25 #include <iostream>
26 #include <iterator>
27 #include <limits.h>
28 #include <securec.h>
29 #include <stdlib.h>
30 #include <string>
31 #include <sys/stat.h>
32 #include <unistd.h>
33 #include <unordered_map>
34 #include <unordered_set>
35 #include <vector>
36 #include <memory>
37 
38 #include "medialibrary_type_const.h"
39 #include "medialibrary_errno.h"
40 #include "media_scanner_const.h"
41 #include "media_scanner_db.h"
42 #include "metadata.h"
43 #include "metadata_extractor.h"
44 #include "scanner_utils.h"
45 #include "imedia_scanner_callback.h"
46 #include "iremote_object.h"
47 #include "userfile_manager_types.h"
48 
49 #define FREE_MEMORY_AND_SET_NULL(fName)      \
50     do {                                     \
51         free(fName);                         \
52         fName = nullptr;                     \
53     } while (0)
54 
55 namespace OHOS {
56 namespace Media {
57 #define EXPORT __attribute__ ((visibility ("default")))
58 /**
59  * Media Scanner class for scanning files and folders in MediaLibrary Database
60  * and updating the metadata for each media file
61  *
62  * @since 1.0
63  * @version 1.0
64  */
65 class MediaScannerObj {
66 public:
67     enum ScanType {
68         FILE,
69         DIRECTORY,
70         START,
71         ERROR,
72         SET_ERROR
73     };
74 
75     EXPORT MediaScannerObj(const std::string &path, const std::shared_ptr<IMediaScannerCallback> &callback,
76         MediaScannerObj::ScanType type, MediaLibraryApi api = MediaLibraryApi::API_OLD);
77     EXPORT MediaScannerObj(MediaScannerObj::ScanType type, MediaLibraryApi api = MediaLibraryApi::API_OLD);
78     EXPORT virtual ~MediaScannerObj() = default;
79 
80     EXPORT void Scan();
81 
82     /* stop */
83     EXPORT void SetStopFlag(std::shared_ptr<bool> &stopFlag);
84 
85     /* Record Error */
86     void SetErrorPath(const std::string &path);
87 
88     /* set is Force Scan */
89     void SetForceScan(bool isForceScan);
90 
91     void SetFileId(int32_t fileId);
92 
93     void SetIsSkipAlbumUpdate(bool isSkipAlbumUpdate);
94 
95 private:
96     /* file */
97     EXPORT int32_t ScanFile();
98     EXPORT int32_t ScanFileInternal();
99     int32_t BuildFileInfo(const std::string &parent, int32_t parentId);
100     int32_t BuildData(const struct stat &statInfo);
101     EXPORT int32_t GetFileMetadata();
102     EXPORT int32_t GetParentDirInfo(const std::string &parent, int32_t parentId);
103     EXPORT int32_t GetMediaInfo();
104 #ifdef MEDIALIBRARY_COMPATIBILITY
105     void SetPhotoSubType(const std::string &parent);
106 #endif
107 
108     /* dir */
109     EXPORT int32_t ScanDir();
110     EXPORT int32_t ScanDirInternal();
111     EXPORT int32_t ScanFileInTraversal(const std::string &path, const std::string &parent, int32_t parentId);
112     EXPORT int32_t WalkFileTree(const std::string &path, int32_t parentId);
113     EXPORT int32_t CleanupDirectory();
114     EXPORT int32_t InsertOrUpdateAlbumInfo(const std::string &albumPath, int32_t parentId,
115         const std::string &albumName);
116 
117     /* error */
118     int32_t Start();
119     int32_t ScanError(bool isBoot = false);
120 
121     /* set error */
122     int32_t SetError();
123 
124     /* db ops */
125     EXPORT int32_t Commit();
126     EXPORT int32_t AddToTransaction();
127     EXPORT int32_t CommitTransaction();
128 
129     /* callback */
130     EXPORT int32_t InvokeCallback(int32_t code);
131 
132     ScanType type_;
133     std::string path_;
134     std::string dir_;
135     std::string uri_;
136     std::string errorPath_;
137     bool skipPhoto_ = true;
138     std::unique_ptr<MediaScannerDb> mediaScannerDb_;
139     std::shared_ptr<IMediaScannerCallback> callback_;
140     std::shared_ptr<bool> stopFlag_;
141 
142     std::unique_ptr<Metadata> data_;
143     std::unordered_map<std::string, Metadata> albumMap_;
144     std::set<std::pair<std::string, int32_t>> scannedIds_;
145     std::vector<std::unique_ptr<Metadata>> dataBuffer_;
146     MediaLibraryApi api_;
147     bool isForceScan_ = false;
148     int32_t fileId_ = 0;
149     bool isSkipAlbumUpdate_ = false;
150 };
151 
152 class ScanErrCallback : public IMediaScannerCallback {
153 public:
ScanErrCallback(const std::string & err)154     ScanErrCallback(const std::string &err) : err_(err) {};
155     ~ScanErrCallback() = default;
156 
OnScanFinished(const int32_t status,const std::string & uri,const std::string & path)157     int32_t OnScanFinished(const int32_t status, const std::string &uri, const std::string &path) override
158     {
159         if (status == E_OK) {
160             return MediaScannerDb::GetDatabaseInstance()->DeleteError(err_);
161         }
162 
163         return E_OK;
164     }
165 
166 private:
167     std::string err_;
168 };
169 } // namespace Media
170 } // namespace OHOS
171 
172 #endif // MEDIA_SCANNER_OBJ_H
173