• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "medialibrary_unittest_utils.h"
17 
18 #include <cerrno>
19 #include <fstream>
20 #include <sys/stat.h>
21 
22 #include "ability_context_impl.h"
23 #include "fetch_result.h"
24 #include "media_log.h"
25 #include "media_file_utils.h"
26 #include "media_smart_map_column.h"
27 #include "medialibrary_data_manager.h"
28 #include "medialibrary_unistore_manager.h"
29 #include "mimetype_utils.h"
30 #include "result_set_utils.h"
31 #include "scanner_utils.h"
32 #include "userfilemgr_uri.h"
33 #include "data_secondary_directory_uri.h"
34 
35 using namespace std;
36 using namespace OHOS::DataShare;
37 using namespace OHOS::AppExecFwk;
38 namespace OHOS {
39 namespace Media {
40 mutex MediaLibraryUnitTestUtils::Mutex_;
41 
IsValid()42 bool MediaLibraryUnitTestUtils::IsValid()
43 {
44     return isValid_;
45 }
46 
Init()47 void MediaLibraryUnitTestUtils::Init()
48 {
49     std::lock_guard<std::mutex> lock(Mutex_);
50     auto stageContext = std::make_shared<AbilityRuntime::ContextImpl>();
51     auto abilityContextImpl = std::make_shared<OHOS::AbilityRuntime::AbilityContextImpl>();
52     abilityContextImpl->SetStageContext(stageContext);
53     int32_t sceneCode = 0;
54     MediaLibraryDataManager::GetInstance()->InitMediaLibraryMgr(abilityContextImpl, abilityContextImpl, sceneCode);
55     auto ret = MediaLibraryDataManager::GetInstance()->InitMediaLibraryMgr(abilityContextImpl, abilityContextImpl,
56         sceneCode);
57     CHECK_AND_RETURN_LOG(ret == E_OK, "InitMediaLibraryMgr failed, ret: %{public}d", ret);
58     isValid_ = true;
59 }
60 
InitUnistore()61 int32_t MediaLibraryUnitTestUtils::InitUnistore()
62 {
63     std::lock_guard<std::mutex> lock(Mutex_);
64     auto stageContext = std::make_shared<AbilityRuntime::ContextImpl>();
65     auto abilityContextImpl = std::make_shared<OHOS::AbilityRuntime::AbilityContextImpl>();
66     abilityContextImpl -> SetStageContext(stageContext);
67     int32_t ret = MediaLibraryUnistoreManager::GetInstance().Init(abilityContextImpl);
68     if (ret != E_OK) {
69         MEDIA_ERR_LOG("init MediaLibraryUnistoreManager failed");
70     }
71     return ret;
72 }
73 
InitUnistore(const NativeRdb::RdbStoreConfig & config,int version,NativeRdb::RdbOpenCallback & openCallback)74 int32_t MediaLibraryUnitTestUtils::InitUnistore(const NativeRdb::RdbStoreConfig &config, int version,
75     NativeRdb::RdbOpenCallback &openCallback)
76 {
77     std::lock_guard<std::mutex> lock(Mutex_);
78     auto stageContext = std::make_shared<AbilityRuntime::ContextImpl>();
79     auto abilityContextImpl = std::make_shared<OHOS::AbilityRuntime::AbilityContextImpl>();
80     abilityContextImpl->SetStageContext(stageContext);
81     int32_t ret = MediaLibraryUnistoreManager::GetInstance().Init(abilityContextImpl, config, version, openCallback);
82     MediaLibraryDataManager::GetInstance()->rdbStore_ = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
83     if (ret != E_OK) {
84         MEDIA_ERR_LOG("init MediaLibraryUnistoreManager with config failed");
85     }
86     return ret;
87 }
88 
StopUnistore()89 void MediaLibraryUnitTestUtils::StopUnistore()
90 {
91     std::lock_guard<std::mutex> lock(Mutex_);
92     MediaLibraryDataManager::GetInstance()->rdbStore_ = nullptr;
93     MediaLibraryUnistoreManager::GetInstance().Stop();
94 }
95 
InitRootDirs()96 void MediaLibraryUnitTestUtils::InitRootDirs()
97 {
98     std::lock_guard<std::mutex> lock(Mutex_);
99     for (const auto &dir : TEST_ROOT_DIRS) {
100         shared_ptr<FileAsset> dirAsset = nullptr;
101         if (!CreateAlbum(dir, nullptr, dirAsset)) {
102             isValid_ = false;
103             return;
104         }
105         rootDirAssetMap_[dir] = dirAsset;
106     }
107 }
108 
CleanTestFiles()109 void MediaLibraryUnitTestUtils::CleanTestFiles()
110 {
111     std::lock_guard<std::mutex> lock(Mutex_);
112     system("rm -rf /storage/cloud/files/Audio/*");
113     system("rm -rf /storage/cloud/files/Audios/*");
114     system("rm -rf /storage/cloud/files/Camera/*");
115     system("rm -rf /storage/cloud/files/Docs/Documents/*");
116     system("rm -rf /storage/cloud/files/Docs/Download/*");
117     system("rm -rf /storage/cloud/files/Photo/*");
118     system("rm -rf /storage/cloud/files/Pictures/*");
119     system("rm -rf /storage/cloud/files/Pictures/*");
120     system("rm -rf /storage/cloud/files/Videos/*");
121     system("rm -rf /storage/cloud/files/.*");
122     auto rdbStore = MediaLibraryDataManager::GetInstance()->rdbStore_;
123     NativeRdb::AbsRdbPredicates predicates(MEDIALIBRARY_TABLE);
124     predicates.GreaterThan(MEDIA_DATA_DB_ID, to_string(0));
125     int32_t deletedRows = -1;
126     auto ret = rdbStore->Delete(deletedRows, predicates);
127     MEDIA_INFO_LOG("CleanTestFiles Delete retVal: %{public}d, deletedRows: %{public}d", ret, deletedRows);
128 }
129 
ClearTable(const string & table)130 void MediaLibraryUnitTestUtils::ClearTable(const string &table)
131 {
132     auto rdbStore = MediaLibraryDataManager::GetInstance()->rdbStore_;
133     NativeRdb::RdbPredicates predicates(table);
134     int32_t rows = 0;
135     int32_t ret = rdbStore->Delete(rows, predicates);
136     MEDIA_INFO_LOG("CleanTable Delete retVal: %{public}d, deletedRows: %{public}d", ret, rows);
137 }
138 
CleanBundlePermission()139 void MediaLibraryUnitTestUtils::CleanBundlePermission()
140 {
141     std::lock_guard<std::mutex> lock(Mutex_);
142     auto rdbStore = MediaLibraryDataManager::GetInstance()->rdbStore_;
143     NativeRdb::AbsRdbPredicates predicates(BUNDLE_PERMISSION_TABLE);
144     predicates.GreaterThan(MEDIA_DATA_DB_ID, to_string(0));
145     int32_t deletedRows = -1;
146     auto ret = rdbStore->Delete(deletedRows, predicates);
147     MEDIA_INFO_LOG("CleanBundlePermission Delete retVal: %{public}d, deletedRows: %{public}d", ret, deletedRows);
148 }
149 
GetRootAsset(const string & dir)150 shared_ptr<FileAsset> MediaLibraryUnitTestUtils::GetRootAsset(const string &dir)
151 {
152     std::lock_guard<std::mutex> lock(Mutex_);
153     if (rootDirAssetMap_.find(dir) != rootDirAssetMap_.end()) {
154         return rootDirAssetMap_[dir];
155     }
156     return nullptr;
157 }
158 
IsFileExists(const string filePath)159 bool MediaLibraryUnitTestUtils::IsFileExists(const string filePath)
160 {
161     std::lock_guard<std::mutex> lock(Mutex_);
162     struct stat statInfo {};
163     int errCode = stat(filePath.c_str(), &statInfo);
164     return (errCode == 0);
165 }
166 
GetFileAsset(const int fileId,shared_ptr<FileAsset> & fileAsset)167 bool MediaLibraryUnitTestUtils::GetFileAsset(const int fileId, shared_ptr<FileAsset> &fileAsset)
168 {
169     if (!MediaLibraryUnitTestUtils::IsValid()) {
170         MEDIA_ERR_LOG("MediaLibraryDataManager invalid");
171         exit(1);
172     }
173     vector<string> columns;
174     DataSharePredicates predicates;
175     string selections = MEDIA_DATA_DB_ID + " = " + to_string(fileId);
176     predicates.SetWhereClause(selections);
177     Uri queryFileUri(MEDIALIBRARY_DATA_URI);
178     int errCode = 0;
179     MediaLibraryCommand cmd(queryFileUri, Media::OperationType::QUERY);
180     auto resultSet = MediaLibraryDataManager::GetInstance()->Query(cmd, columns, predicates, errCode);
181     if (resultSet == nullptr) {
182         MEDIA_ERR_LOG("GetFileAsset::resultSet == nullptr");
183         return false;
184     }
185     auto result = make_shared<DataShareResultSet>(resultSet);
186     shared_ptr<FetchResult<FileAsset>> fetchFileResult = make_unique<FetchResult<FileAsset>>(move(result));
187     if (fetchFileResult->GetCount() <= 0) {
188         MEDIA_ERR_LOG("GetFileAsset::GetCount <= 0");
189         return false;
190     }
191     auto firstAsset = fetchFileResult->GetFirstObject();
192     fileAsset = move(firstAsset);
193     if (fileAsset == nullptr) {
194         MEDIA_ERR_LOG("GetFileAsset::fileAsset = nullptr.");
195         return false;
196     }
197     return true;
198 }
199 
CreateAlbum(string displayName,shared_ptr<FileAsset> parentAlbumAsset,shared_ptr<FileAsset> & albumAsset)200 bool MediaLibraryUnitTestUtils::CreateAlbum(string displayName, shared_ptr<FileAsset> parentAlbumAsset,
201     shared_ptr<FileAsset> &albumAsset)
202 {
203     if (!MediaLibraryUnitTestUtils::IsValid()) {
204         MEDIA_ERR_LOG("MediaLibraryDataManager invalid");
205         exit(1);
206     }
207     Uri createAlbumUri(MEDIALIBRARY_DATA_URI + "/" + MEDIA_ALBUMOPRN + "/" + MEDIA_ALBUMOPRN_CREATEALBUM);
208     string dirPath;
209     if (parentAlbumAsset == nullptr) {
210         dirPath = ROOT_MEDIA_DIR + displayName;
211     } else {
212         dirPath = parentAlbumAsset->GetPath() + "/" + displayName;
213     }
214     DataShareValuesBucket valuesBucket;
215     valuesBucket.Put(MEDIA_DATA_DB_FILE_PATH, dirPath);
216     valuesBucket.Put(MEDIA_DATA_DB_NAME, displayName);
217     MediaLibraryCommand cmd(createAlbumUri);
218     auto retVal = MediaLibraryDataManager::GetInstance()->Insert(cmd, valuesBucket);
219     MEDIA_INFO_LOG("CreateAlbum:: %{private}s, retVal: %{public}d", dirPath.c_str(), retVal);
220     if (retVal <= 0) {
221         MEDIA_ERR_LOG("CreateAlbum::create failed, %{private}s", dirPath.c_str());
222         return false;
223     }
224     if (!GetFileAsset(retVal, albumAsset)) {
225         MEDIA_ERR_LOG("CreateAlbum::GetFileAsset failed, %{private}s", dirPath.c_str());
226         return false;
227     }
228     return true;
229 }
230 
CreateFile(string displayName,shared_ptr<FileAsset> parentAlbumAsset,shared_ptr<FileAsset> & fileAsset)231 bool MediaLibraryUnitTestUtils::CreateFile(string displayName, shared_ptr<FileAsset> parentAlbumAsset,
232     shared_ptr<FileAsset> &fileAsset)
233 {
234     std::lock_guard<std::mutex> lock(Mutex_);
235     if (!MediaLibraryUnitTestUtils::IsValid()) {
236         MEDIA_ERR_LOG("MediaLibraryDataManager invalid");
237         exit(1);
238     }
239     Uri createAssetUri(MEDIALIBRARY_DATA_URI + "/" + Media::MEDIA_FILEOPRN + "/" + Media::MEDIA_FILEOPRN_CREATEASSET);
240     DataShareValuesBucket valuesBucket;
241     string relativePath = MediaFileUtils::AddDocsToRelativePath(parentAlbumAsset->GetRelativePath() +
242         parentAlbumAsset->GetDisplayName() + "/");
243     string mimeType = MimeTypeUtils::GetMimeTypeFromExtension(ScannerUtils::GetFileExtension(displayName));
244     MediaType mediaType = MimeTypeUtils::GetMediaTypeFromMimeType(mimeType);
245     valuesBucket.Put(MEDIA_DATA_DB_MEDIA_TYPE, mediaType);
246     valuesBucket.Put(MEDIA_DATA_DB_NAME, displayName);
247     valuesBucket.Put(MEDIA_DATA_DB_RELATIVE_PATH, relativePath);
248     MediaLibraryCommand cmd(createAssetUri);
249     int32_t retVal = MediaLibraryDataManager::GetInstance()->Insert(cmd, valuesBucket);
250     MEDIA_INFO_LOG("CreateFile:: %{private}s, retVal: %{public}d", (relativePath + displayName).c_str(), retVal);
251     if (retVal <= 0) {
252         MEDIA_ERR_LOG("CreateFile::create failed, %{private}s", (relativePath + displayName).c_str());
253         return false;
254     }
255     if (!GetFileAsset(retVal, fileAsset)) {
256         MEDIA_ERR_LOG("CreateFile::GetFileAsset failed, %{private}s", (relativePath + displayName).c_str());
257         return false;
258     }
259     return true;
260 }
261 
CreateFileFS(const string & filePath)262 bool MediaLibraryUnitTestUtils::CreateFileFS(const string &filePath)
263 {
264     std::lock_guard<std::mutex> lock(Mutex_);
265     bool errCode = false;
266 
267     if (filePath.empty()) {
268         return errCode;
269     }
270 
271     ofstream file(filePath);
272     if (!file) {
273         MEDIA_ERR_LOG("Output file path could not be created");
274         return errCode;
275     }
276 
277     const mode_t CHOWN_RW_UG = 0660;
278     if (chmod(filePath.c_str(), CHOWN_RW_UG) == 0) {
279         errCode = true;
280     }
281 
282     file.close();
283 
284     return errCode;
285 }
286 
DeleteDir(const string & path,const string & dirId)287 bool MediaLibraryUnitTestUtils::DeleteDir(const string &path, const string &dirId)
288 {
289     std::lock_guard<std::mutex> lock(Mutex_);
290     string cmd = "rm -rf " + path;
291     system(cmd.c_str());
292 
293     auto rdbStore = MediaLibraryDataManager::GetInstance()->rdbStore_;
294     NativeRdb::AbsRdbPredicates predicates(MEDIALIBRARY_TABLE);
295     predicates.EqualTo(MEDIA_DATA_DB_ID, dirId)->Or()->EqualTo(MEDIA_DATA_DB_PARENT_ID, dirId);
296     int32_t deletedRows = -1;
297     auto ret = rdbStore->Delete(deletedRows, predicates);
298     return ret == 0;
299 }
300 
TrashFile(shared_ptr<FileAsset> & fileAsset)301 void MediaLibraryUnitTestUtils::TrashFile(shared_ptr<FileAsset> &fileAsset)
302 {
303     std::lock_guard<std::mutex> lock(Mutex_);
304     DataShareValuesBucket valuesBucket;
305     valuesBucket.Put(SMARTALBUMMAP_DB_ALBUM_ID, TRASH_ALBUM_ID_VALUES);
306     valuesBucket.Put(SMARTALBUMMAP_DB_CHILD_ASSET_ID, fileAsset->GetId());
307     string uriString = MEDIALIBRARY_DATA_URI + "/" + MEDIA_SMARTALBUMMAPOPRN + "/" +
308         MEDIA_SMARTALBUMMAPOPRN_ADDSMARTALBUM;
309     Uri uri(uriString);
310     MediaLibraryCommand cmd(uri);
311     MediaLibraryDataManager::GetInstance()->Insert(cmd, valuesBucket);
312 }
313 
RecoveryFile(shared_ptr<FileAsset> & fileAsset)314 void MediaLibraryUnitTestUtils::RecoveryFile(shared_ptr<FileAsset> &fileAsset)
315 {
316     std::lock_guard<std::mutex> lock(Mutex_);
317     DataShareValuesBucket valuesBucket;
318     valuesBucket.Put(SMARTALBUMMAP_DB_ALBUM_ID, TRASH_ALBUM_ID_VALUES);
319     valuesBucket.Put(SMARTALBUMMAP_DB_CHILD_ASSET_ID, fileAsset->GetId());
320     string uriString = MEDIALIBRARY_DATA_URI + "/" + MEDIA_SMARTALBUMMAPOPRN + "/" +
321         MEDIA_SMARTALBUMMAPOPRN_REMOVESMARTALBUM;
322     Uri uri(uriString);
323     MediaLibraryCommand cmd(uri);
324     MediaLibraryDataManager::GetInstance()->Insert(cmd, valuesBucket);
325 }
326 
WaitForCallback(shared_ptr<TestScannerCallback> callback)327 void MediaLibraryUnitTestUtils::WaitForCallback(shared_ptr<TestScannerCallback> callback)
328 {
329     std::mutex mutex;
330     std::unique_lock<std::mutex> lock(mutex);
331     const int waitSeconds = 10;
332     callback->condVar_.wait_until(lock, std::chrono::system_clock::now() + std::chrono::seconds(waitSeconds));
333 }
334 
GrantUriPermission(const int32_t fileId,const string & bundleName,const string & mode,const int32_t tableType)335 int32_t MediaLibraryUnitTestUtils::GrantUriPermission(const int32_t fileId, const string &bundleName,
336     const string &mode, const int32_t tableType)
337 {
338     std::lock_guard<std::mutex> lock(Mutex_);
339     Uri addPermission(MEDIALIBRARY_BUNDLEPERM_URI + "/" + BUNDLE_PERMISSION_INSERT);
340     DataShareValuesBucket values;
341     values.Put(PERMISSION_FILE_ID, fileId);
342     values.Put(PERMISSION_BUNDLE_NAME, bundleName);
343     values.Put(PERMISSION_MODE, mode);
344     values.Put(PERMISSION_TABLE_TYPE, tableType);
345     MediaLibraryCommand cmd(addPermission);
346     return MediaLibraryDataManager::GetInstance()->Insert(cmd, values);
347 }
348 
TestScannerCallback()349 TestScannerCallback::TestScannerCallback() : status_(-1) {}
350 
OnScanFinished(const int32_t status,const std::string & uri,const std::string & path)351 int32_t TestScannerCallback::OnScanFinished(const int32_t status, const std::string &uri, const std::string &path)
352 {
353     status_ = status;
354     condVar_.notify_all();
355     return E_OK;
356 }
357 
writeBytesToFile(size_t numBytes,const char * path,size_t & resultFileSize)358 bool MediaLibraryUnitTestUtils::writeBytesToFile(size_t numBytes, const char* path, size_t& resultFileSize)
359 {
360     std::lock_guard<std::mutex> lock(Mutex_);
361     int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
362     if (fd == -1) {
363         MEDIA_ERR_LOG("Error: Unable to open file %{public}s for writing, errno: %{public}d", path, errno);
364         return false;
365     }
366 
367     char dummyByte = '\0'; // A dummy byte to be written
368 
369     for (size_t i = 0; i < numBytes; ++i) {
370         if (write(fd, &dummyByte, sizeof(char)) == -1) {
371             MEDIA_ERR_LOG("Error while writing to file %{public}s, errno: %{public}d", path, errno);
372             close(fd);
373             return false;
374         }
375     }
376 
377     close(fd);
378 
379     struct stat statbuf;
380     if (lstat(path, &statbuf) == -1) {
381         MEDIA_ERR_LOG("Failed to get file size of %{public}s, errno is %{public}d", path, errno);
382         return false;
383     }
384 
385     resultFileSize = statbuf.st_size;
386     MEDIA_INFO_LOG("File %{public}s successfully written, File size after writing: %{public}zu", path, resultFileSize);
387 
388     return true;
389 }
390 }
391 }
392