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