1 /*
2 * Copyright (C) 2021-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 "DataManager"
17
18 #include "medialibrary_data_manager.h"
19
20 #include <shared_mutex>
21 #include <unordered_set>
22
23 #include "ability_scheduler_interface.h"
24 #include "abs_rdb_predicates.h"
25 #include "datashare_abs_result_set.h"
26 #ifdef DISTRIBUTED
27 #include "device_manager.h"
28 #include "device_manager_callback.h"
29 #endif
30 #include "hitrace_meter.h"
31 #include "ipc_skeleton.h"
32 #include "media_column.h"
33 #include "media_datashare_ext_ability.h"
34 #include "media_file_utils.h"
35 #include "media_log.h"
36 #include "media_scanner_manager.h"
37 #include "medialibrary_album_operations.h"
38 #include "medialibrary_asset_operations.h"
39 #include "medialibrary_audio_operations.h"
40 #include "medialibrary_bundle_manager.h"
41 #include "medialibrary_common_utils.h"
42 #ifdef DISTRIBUTED
43 #include "medialibrary_device.h"
44 #include "medialibrary_device_info.h"
45 #endif
46 #include "medialibrary_dir_operations.h"
47 #include "medialibrary_errno.h"
48 #include "medialibrary_file_operations.h"
49 #include "medialibrary_inotify.h"
50 #include "medialibrary_object_utils.h"
51 #include "medialibrary_smartalbum_map_operations.h"
52 #include "medialibrary_smartalbum_operations.h"
53 #include "medialibrary_sync_operation.h"
54 #include "medialibrary_tracer.h"
55 #include "medialibrary_unistore_manager.h"
56 #include "medialibrary_uripermission_operations.h"
57 #include "mimetype_utils.h"
58 #include "permission_utils.h"
59 #include "photo_map_operations.h"
60 #include "rdb_store.h"
61 #include "rdb_utils.h"
62 #include "result_set_utils.h"
63 #include "system_ability_definition.h"
64 #include "timer.h"
65 #include "trash_async_worker.h"
66 #include "value_object.h"
67
68 using namespace std;
69 using namespace OHOS::AppExecFwk;
70 using namespace OHOS::AbilityRuntime;
71 using namespace OHOS::NativeRdb;
72 using namespace OHOS::DistributedKv;
73 using namespace OHOS::DataShare;
74 using namespace OHOS::RdbDataShareAdapter;
75
76 namespace {
77 const OHOS::DistributedKv::AppId KVSTORE_APPID = {"com.ohos.medialibrary.medialibrarydata"};
78 const OHOS::DistributedKv::StoreId KVSTORE_STOREID = {"medialibrary_thumbnail"};
79 };
80
81 namespace OHOS {
82 namespace Media {
83
84 shared_ptr<MediaLibraryDataManager> MediaLibraryDataManager::instance_ = nullptr;
85 unordered_map<string, DirAsset> MediaLibraryDataManager::dirQuerySetMap_ = {};
86 mutex MediaLibraryDataManager::mutex_;
87 static constexpr int REVERT_DAYS = 7;
88 static constexpr int DAY_HOURS = 24;
89 static constexpr int PER_HOUR_MINUTES = 60;
90 static constexpr int PER_MINUTE_SECONDS = 60;
91 #ifdef DISTRIBUTED
92 static constexpr int MAX_QUERY_THUMBNAIL_KEY_COUNT = 20;
93 #endif
MediaLibraryDataManager(void)94 MediaLibraryDataManager::MediaLibraryDataManager(void)
95 {
96 }
97
~MediaLibraryDataManager(void)98 MediaLibraryDataManager::~MediaLibraryDataManager(void)
99 {
100 if (kvStorePtr_ != nullptr) {
101 dataManager_.CloseKvStore(KVSTORE_APPID, kvStorePtr_);
102 kvStorePtr_ = nullptr;
103 }
104 }
105
GetInstance()106 shared_ptr<MediaLibraryDataManager> MediaLibraryDataManager::GetInstance()
107 {
108 if (instance_ == nullptr) {
109 lock_guard<mutex> lock(mutex_);
110 if (instance_ == nullptr) {
111 instance_ = make_shared<MediaLibraryDataManager>();
112 }
113 }
114 return instance_;
115 }
116
MediaDataShareCreator(const unique_ptr<Runtime> & runtime)117 static DataShare::DataShareExtAbility *MediaDataShareCreator(const unique_ptr<Runtime> &runtime)
118 {
119 MEDIA_DEBUG_LOG("MediaLibraryCreator::%{public}s", __func__);
120 return MediaDataShareExtAbility::Create(runtime);
121 }
122
RegisterDataShareCreator()123 __attribute__((constructor)) void RegisterDataShareCreator()
124 {
125 MEDIA_DEBUG_LOG("MediaLibraryDataMgr::%{public}s", __func__);
126 DataShare::DataShareExtAbility::SetCreator(MediaDataShareCreator);
127 }
128
MakeRootDirs()129 static void MakeRootDirs()
130 {
131 for (auto &dir : PRESET_ROOT_DIRS) {
132 Uri createAlbumUri(MEDIALIBRARY_DATA_URI + "/" + MEDIA_ALBUMOPRN + "/" + MEDIA_ALBUMOPRN_CREATEALBUM);
133 ValuesBucket valuesBucket;
134 valuesBucket.PutString(MEDIA_DATA_DB_FILE_PATH, ROOT_MEDIA_DIR + dir);
135 MediaLibraryCommand cmd(createAlbumUri, valuesBucket);
136 auto ret = MediaLibraryAlbumOperations::CreateAlbumOperation(cmd);
137 if (ret == E_FILE_EXIST) {
138 MEDIA_INFO_LOG("Root dir: %{public}s is exist", dir.c_str());
139 } else if (ret <= 0) {
140 MEDIA_ERR_LOG("Failed to preset root dir: %{public}s", dir.c_str());
141 }
142 if (dir == DOC_DIR_VALUES || dir == DOWNLOAD_DIR_VALUES) {
143 continue;
144 }
145 MediaFileUtils::CreateDirectory(ROOT_MEDIA_DIR + dir + ".recycle");
146 }
147 }
148
InitMediaLibraryMgr(const shared_ptr<OHOS::AbilityRuntime::Context> & context,const shared_ptr<OHOS::AbilityRuntime::Context> & extensionContext)149 int32_t MediaLibraryDataManager::InitMediaLibraryMgr(const shared_ptr<OHOS::AbilityRuntime::Context> &context,
150 const shared_ptr<OHOS::AbilityRuntime::Context> &extensionContext)
151 {
152 lock_guard<shared_mutex> lock(mgrSharedMutex_);
153
154 if (refCnt_.load() > 0) {
155 MEDIA_DEBUG_LOG("already initialized");
156 refCnt_++;
157 return E_OK;
158 }
159
160 context_ = context;
161 int32_t errCode = InitMediaLibraryRdbStore();
162 CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "failed at InitMediaLibraryRdbStore");
163
164 #ifdef DISTRIBUTED
165 errCode = InitDeviceData();
166 CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "failed at InitDeviceData");
167 #endif
168
169 MimeTypeUtils::InitMimeTypeMap();
170 errCode = MakeDirQuerySetMap(dirQuerySetMap_);
171 CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "failed at MakeDirQuerySetMap");
172
173 MakeRootDirs();
174
175 errCode = InitialiseThumbnailService(extensionContext);
176 CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "failed at InitialiseThumbnailService");
177
178 errCode = DoTrashAging();
179 if (errCode != E_OK) {
180 MEDIA_WARN_LOG("Ignore trash aging failures, just continue");
181 }
182 refCnt_++;
183 return E_OK;
184 }
185
186 #ifdef DISTRIBUTED
InitDeviceData()187 int32_t MediaLibraryDataManager::InitDeviceData()
188 {
189 if (rdbStore_ == nullptr) {
190 MEDIA_ERR_LOG("MediaLibraryDataManager InitDeviceData rdbStore is null");
191 return E_ERR;
192 }
193
194 MediaLibraryTracer tracer;
195 tracer.Start("InitDeviceRdbStoreTrace");
196 if (!MediaLibraryDevice::GetInstance()->InitDeviceRdbStore(rdbStore_)) {
197 MEDIA_ERR_LOG("MediaLibraryDataManager InitDeviceData failed!");
198 return E_ERR;
199 }
200 return E_OK;
201 }
202 #endif
203
ClearMediaLibraryMgr()204 void MediaLibraryDataManager::ClearMediaLibraryMgr()
205 {
206 lock_guard<shared_mutex> lock(mgrSharedMutex_);
207
208 refCnt_--;
209 if (refCnt_.load() > 0) {
210 MEDIA_DEBUG_LOG("still other extension exist");
211 return;
212 }
213
214 rdbStore_ = nullptr;
215
216 if (kvStorePtr_ != nullptr) {
217 dataManager_.CloseKvStore(KVSTORE_APPID, kvStorePtr_);
218 kvStorePtr_ = nullptr;
219 }
220
221 #ifdef DISTRIBUTED
222 if (MediaLibraryDevice::GetInstance()) {
223 MediaLibraryDevice::GetInstance()->Stop();
224 };
225 #endif
226
227 if (thumbnailService_ != nullptr) {
228 thumbnailService_->ReleaseService();
229 thumbnailService_ = nullptr;
230 }
231 auto watch = MediaLibraryInotify::GetInstance();
232 if (watch != nullptr) {
233 watch->DoStop();
234 }
235 MediaLibraryUnistoreManager::GetInstance().Stop();
236 extension_ = nullptr;
237 }
238
InitMediaLibraryRdbStore()239 int32_t MediaLibraryDataManager::InitMediaLibraryRdbStore()
240 {
241 if (rdbStore_) {
242 return E_OK;
243 }
244
245 int32_t ret = MediaLibraryUnistoreManager::GetInstance().Init(context_);
246 if (ret != E_OK) {
247 MEDIA_ERR_LOG("init MediaLibraryUnistoreManager failed");
248 return ret;
249 }
250 rdbStore_ = MediaLibraryUnistoreManager::GetInstance().GetRdbStoreRaw()->GetRaw();
251 if (ret != E_OK) {
252 MEDIA_ERR_LOG("rdbStore is nullptr");
253 return E_ERR;
254 }
255
256 return E_OK;
257 }
258
InitialiseKvStore()259 int32_t MediaLibraryDataManager::InitialiseKvStore()
260 {
261 if (kvStorePtr_ != nullptr) {
262 return E_OK;
263 }
264
265 Options options = {
266 .createIfMissing = true,
267 .encrypt = false,
268 .backup = false,
269 .autoSync = false,
270 .securityLevel = DistributedKv::SecurityLevel::S3,
271 .area = DistributedKv::Area::EL2,
272 .kvStoreType = KvStoreType::SINGLE_VERSION,
273 .baseDir = context_->GetDatabaseDir(),
274 };
275
276 Status status = dataManager_.GetSingleKvStore(options, KVSTORE_APPID, KVSTORE_STOREID, kvStorePtr_);
277 if (status != Status::SUCCESS || kvStorePtr_ == nullptr) {
278 MEDIA_ERR_LOG("MediaLibraryDataManager::InitialiseKvStore failed %{private}d", status);
279 return E_ERR;
280 }
281 #ifdef DISTRIBUTED
282 if (!MediaLibraryDevice::GetInstance()->InitDeviceKvStore(kvStorePtr_)) {
283 return E_FAIL;
284 }
285 #endif
286 return E_OK;
287 }
288
GetOwner()289 shared_ptr<MediaDataShareExtAbility> MediaLibraryDataManager::GetOwner()
290 {
291 return extension_;
292 }
293
SetOwner(const shared_ptr<MediaDataShareExtAbility> & datashareExternsion)294 void MediaLibraryDataManager::SetOwner(const shared_ptr<MediaDataShareExtAbility> &datashareExternsion)
295 {
296 extension_ = datashareExternsion;
297 }
298
GetType(const Uri & uri)299 string MediaLibraryDataManager::GetType(const Uri &uri)
300 {
301 MEDIA_INFO_LOG("GetType uri: %{public}s", uri.ToString().c_str());
302 return "";
303 }
304
MakeDirQuerySetMap(unordered_map<string,DirAsset> & outDirQuerySetMap)305 int32_t MediaLibraryDataManager::MakeDirQuerySetMap(unordered_map<string, DirAsset> &outDirQuerySetMap)
306 {
307 int32_t count = -1;
308 vector<string> columns;
309 AbsRdbPredicates dirAbsPred(MEDIATYPE_DIRECTORY_TABLE);
310 auto queryResultSet = rdbStore_->QueryByStep(dirAbsPred, columns);
311 auto ret = queryResultSet->GetRowCount(count);
312 if (ret != NativeRdb::E_OK) {
313 MEDIA_ERR_LOG("rdb failed");
314 return E_ERR;
315 }
316 MEDIA_INFO_LOG("MakeDirQuerySetMap count = %{public}d", count);
317 if (count == 0) {
318 MEDIA_ERR_LOG("can not find any dirAsset");
319 return E_ERR;
320 }
321 DirAsset dirAsset;
322 string dirVal;
323 outDirQuerySetMap.clear();
324 while (queryResultSet->GoToNextRow() == NativeRdb::E_OK) {
325 dirVal = get<string>(
326 ResultSetUtils::GetValFromColumn(DIRECTORY_DB_DIRECTORY, queryResultSet, TYPE_STRING));
327 dirAsset.SetDirectory(dirVal);
328 dirAsset.SetDirType(get<int32_t>(
329 ResultSetUtils::GetValFromColumn(DIRECTORY_DB_DIRECTORY_TYPE, queryResultSet, TYPE_INT32)));
330 dirAsset.SetMediaTypes(get<string>(
331 ResultSetUtils::GetValFromColumn(DIRECTORY_DB_MEDIA_TYPE, queryResultSet, TYPE_STRING)));
332 dirAsset.SetExtensions(get<string>(
333 ResultSetUtils::GetValFromColumn(DIRECTORY_DB_EXTENSION, queryResultSet, TYPE_STRING)));
334 outDirQuerySetMap.insert(make_pair(dirVal, dirAsset));
335 }
336 return E_OK;
337 }
338
GetDirQuerySetMap()339 unordered_map<string, DirAsset> MediaLibraryDataManager::GetDirQuerySetMap()
340 {
341 return dirQuerySetMap_;
342 }
343
344 #ifdef MEDIALIBRARY_COMPATIBILITY
ChangeUriFromValuesBucket(ValuesBucket & values)345 static void ChangeUriFromValuesBucket(ValuesBucket &values)
346 {
347 if (!values.HasColumn(MEDIA_DATA_DB_URI)) {
348 return;
349 }
350
351 ValueObject value;
352 if (!values.GetObject(MEDIA_DATA_DB_URI, value)) {
353 return;
354 }
355 string oldUri;
356 if (value.GetString(oldUri) != NativeRdb::E_OK) {
357 return;
358 }
359 string newUri = MediaFileUtils::GetRealUriFromVirtualUri(oldUri);
360 values.Delete(MEDIA_DATA_DB_URI);
361 values.PutString(MEDIA_DATA_DB_URI, newUri);
362 }
363 #endif
364
SolveInsertCmd(MediaLibraryCommand & cmd)365 int32_t MediaLibraryDataManager::SolveInsertCmd(MediaLibraryCommand &cmd)
366 {
367 switch (cmd.GetOprnObject()) {
368 case OperationObject::FILESYSTEM_ASSET: {
369 return MediaLibraryFileOperations::HandleFileOperation(cmd);
370 }
371 case OperationObject::FILESYSTEM_PHOTO:
372 case OperationObject::FILESYSTEM_AUDIO: {
373 return MediaLibraryAssetOperations::HandleInsertOperation(cmd);
374 }
375 case OperationObject::FILESYSTEM_ALBUM: {
376 return MediaLibraryAlbumOperations::CreateAlbumOperation(cmd);
377 }
378 case OperationObject::PHOTO_ALBUM: {
379 return MediaLibraryAlbumOperations::HandlePhotoAlbumOperations(cmd);
380 }
381 case OperationObject::FILESYSTEM_DIR: {
382 return MediaLibraryDirOperations::HandleDirOperation(cmd);
383 }
384 case OperationObject::SMART_ALBUM: {
385 return MediaLibrarySmartAlbumOperations::HandleSmartAlbumOperation(cmd);
386 }
387 case OperationObject::SMART_ALBUM_MAP: {
388 return MediaLibrarySmartAlbumMapOperations::HandleSmartAlbumMapOperation(cmd);
389 }
390 case OperationObject::THUMBNAIL: {
391 return HandleThumbnailOperations(cmd);
392 }
393 case OperationObject::BUNDLE_PERMISSION: {
394 return UriPermissionOperations::HandleUriPermOperations(cmd);
395 }
396 default: {
397 MEDIA_ERR_LOG("MediaLibraryDataManager SolveInsertCmd: unsupported OperationObject: %{public}d",
398 cmd.GetOprnObject());
399 return E_FAIL;
400 }
401 }
402 }
403
Insert(MediaLibraryCommand & cmd,const DataShareValuesBucket & dataShareValue)404 int32_t MediaLibraryDataManager::Insert(MediaLibraryCommand &cmd, const DataShareValuesBucket &dataShareValue)
405 {
406 shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
407 if (refCnt_.load() <= 0) {
408 MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
409 return E_FAIL;
410 }
411
412 ValuesBucket value = RdbUtils::ToValuesBucket(dataShareValue);
413 if (value.IsEmpty()) {
414 MEDIA_ERR_LOG("MediaLibraryDataManager Insert: Input parameter is invalid");
415 return E_INVALID_VALUES;
416 }
417 #ifdef MEDIALIBRARY_COMPATIBILITY
418 ChangeUriFromValuesBucket(value);
419 #endif
420 cmd.SetValueBucket(value);
421
422 OperationType oprnType = cmd.GetOprnType();
423 if (oprnType == OperationType::CREATE) {
424 if (SetCmdBundleAndDevice(cmd) != ERR_OK) {
425 MEDIA_ERR_LOG("MediaLibraryDataManager SetCmdBundleAndDevice failed.");
426 }
427 }
428 // boardcast operation
429 if (oprnType == OperationType::SCAN) {
430 return MediaScannerManager::GetInstance()->ScanDir(ROOT_MEDIA_DIR, nullptr);
431 } else if (oprnType == OperationType::DELETE_TOOL) {
432 return MediaLibraryAssetOperations::DeleteToolOperation(cmd);
433 }
434 return SolveInsertCmd(cmd);
435 }
436
InsertExt(MediaLibraryCommand & cmd,const DataShareValuesBucket & dataShareValue,string & result)437 int32_t MediaLibraryDataManager::InsertExt(MediaLibraryCommand &cmd, const DataShareValuesBucket &dataShareValue,
438 string &result)
439 {
440 int32_t res = Insert(cmd, dataShareValue);
441 result = cmd.GetResult();
442 return res;
443 }
444
HandleThumbnailOperations(MediaLibraryCommand & cmd)445 int32_t MediaLibraryDataManager::HandleThumbnailOperations(MediaLibraryCommand &cmd)
446 {
447 if (thumbnailService_ == nullptr) {
448 return E_THUMBNAIL_SERVICE_NULLPTR;
449 }
450 int32_t result = E_FAIL;
451 switch (cmd.GetOprnType()) {
452 case OperationType::GENERATE:
453 result = thumbnailService_->GenerateThumbnails();
454 break;
455 case OperationType::AGING:
456 result = thumbnailService_->LcdAging();
457 break;
458 #ifdef DISTRIBUTED
459 case OperationType::DISTRIBUTE_AGING:
460 result = DistributeDeviceAging();
461 break;
462 #endif
463 default:
464 MEDIA_ERR_LOG("bad operation type %{public}u", cmd.GetOprnType());
465 }
466 return result;
467 }
468
BatchInsert(MediaLibraryCommand & cmd,const vector<DataShareValuesBucket> & values)469 int32_t MediaLibraryDataManager::BatchInsert(MediaLibraryCommand &cmd, const vector<DataShareValuesBucket> &values)
470 {
471 shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
472 if (refCnt_.load() <= 0) {
473 MEDIA_ERR_LOG("MediaLibraryDataManager is not initialized");
474 return E_FAIL;
475 }
476
477 string uriString = cmd.GetUri().ToString();
478 if (uriString == UFM_PHOTO_ALBUM_ADD_ASSET || uriString == PAH_PHOTO_ALBUM_ADD_ASSET) {
479 return PhotoMapOperations::AddPhotoAssets(values);
480 }
481 if (uriString.find(MEDIALIBRARY_DATA_URI) == string::npos) {
482 MEDIA_ERR_LOG("MediaLibraryDataManager BatchInsert: Input parameter is invalid");
483 return E_INVALID_URI;
484 }
485 int32_t rowCount = 0;
486 for (auto it = values.begin(); it != values.end(); it++) {
487 if (Insert(cmd, *it) >= 0) {
488 rowCount++;
489 }
490 }
491
492 return rowCount;
493 }
494
Delete(MediaLibraryCommand & cmd,const DataSharePredicates & predicates)495 int32_t MediaLibraryDataManager::Delete(MediaLibraryCommand &cmd, const DataSharePredicates &predicates)
496 {
497 shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
498 if (refCnt_.load() <= 0) {
499 MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
500 return E_FAIL;
501 }
502 if (cmd.GetUri().ToString().find(MEDIALIBRARY_DATA_URI) == string::npos) {
503 MEDIA_ERR_LOG("Not Data ability Uri");
504 return E_INVALID_URI;
505 }
506 MediaLibraryTracer tracer;
507 tracer.Start("CheckWhereClause");
508 auto whereClause = predicates.GetWhereClause();
509 if (!MediaLibraryCommonUtils::CheckWhereClause(whereClause)) {
510 MEDIA_ERR_LOG("illegal query whereClause input %{public}s", whereClause.c_str());
511 return E_SQL_CHECK_FAIL;
512 }
513 tracer.Finish();
514
515 // MEDIALIBRARY_TABLE just for RdbPredicates
516 NativeRdb::RdbPredicates rdbPredicate = RdbUtils::ToPredicates(predicates,
517 cmd.GetTableName());
518 cmd.GetAbsRdbPredicates()->SetWhereClause(rdbPredicate.GetWhereClause());
519 cmd.GetAbsRdbPredicates()->SetWhereArgs(rdbPredicate.GetWhereArgs());
520
521 switch (cmd.GetOprnObject()) {
522 case OperationObject::FILESYSTEM_ASSET:
523 case OperationObject::FILESYSTEM_DIR:
524 case OperationObject::FILESYSTEM_ALBUM: {
525 vector<string> columns = { MEDIA_DATA_DB_ID, MEDIA_DATA_DB_FILE_PATH, MEDIA_DATA_DB_PARENT_ID,
526 MEDIA_DATA_DB_MEDIA_TYPE, MEDIA_DATA_DB_IS_TRASH, MEDIA_DATA_DB_RELATIVE_PATH };
527 auto fileAsset = MediaLibraryObjectUtils::GetFileAssetByPredicates(*cmd.GetAbsRdbPredicates(), columns);
528 CHECK_AND_RETURN_RET_LOG(fileAsset != nullptr, E_INVALID_ARGUMENTS, "Get fileAsset failed.");
529 if (fileAsset->GetRelativePath() == "") {
530 return E_DELETE_DENIED;
531 }
532 return (fileAsset->GetMediaType() != MEDIA_TYPE_ALBUM) ?
533 MediaLibraryObjectUtils::DeleteFileObj(move(fileAsset)) :
534 MediaLibraryObjectUtils::DeleteDirObj(move(fileAsset));
535 }
536 case OperationObject::PHOTO_ALBUM: {
537 return MediaLibraryAlbumOperations::DeletePhotoAlbum(rdbPredicate);
538 }
539 case OperationObject::PHOTO_MAP: {
540 return PhotoMapOperations::RemovePhotoAssets(rdbPredicate);
541 }
542 case OperationObject::FILESYSTEM_PHOTO:
543 case OperationObject::FILESYSTEM_AUDIO: {
544 return MediaLibraryAssetOperations::DeleteOperation(cmd);
545 }
546 default:
547 break;
548 }
549
550 return E_FAIL;
551 }
552
Update(MediaLibraryCommand & cmd,const DataShareValuesBucket & dataShareValue,const DataSharePredicates & predicates)553 int32_t MediaLibraryDataManager::Update(MediaLibraryCommand &cmd, const DataShareValuesBucket &dataShareValue,
554 const DataSharePredicates &predicates)
555 {
556 MEDIA_DEBUG_LOG("MediaLibraryDataManager::Update");
557 shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
558 if (refCnt_.load() <= 0) {
559 MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
560 return E_FAIL;
561 }
562
563 ValuesBucket value = RdbUtils::ToValuesBucket(dataShareValue);
564 if (value.IsEmpty()) {
565 MEDIA_ERR_LOG("MediaLibraryDataManager Update:Input parameter is invalid ");
566 return E_INVALID_VALUES;
567 }
568
569 #ifdef MEDIALIBRARY_COMPATIBILITY
570 ChangeUriFromValuesBucket(value);
571 #endif
572
573 cmd.SetValueBucket(value);
574 cmd.SetDataSharePred(predicates);
575 cmd.GetAbsRdbPredicates()->SetWhereClause(predicates.GetWhereClause());
576 cmd.GetAbsRdbPredicates()->SetWhereArgs(predicates.GetWhereArgs());
577
578 switch (cmd.GetOprnObject()) {
579 case OperationObject::FILESYSTEM_ASSET: {
580 auto ret = MediaLibraryFileOperations::ModifyFileOperation(cmd);
581 if (ret == E_SAME_PATH) {
582 break;
583 } else {
584 return ret;
585 }
586 }
587 case OperationObject::FILESYSTEM_DIR:
588 // supply a ModifyDirOperation here to replace
589 // modify in the HandleDirOperations in Insert function, if need
590 break;
591 case OperationObject::FILESYSTEM_ALBUM: {
592 return MediaLibraryAlbumOperations::ModifyAlbumOperation(cmd);
593 }
594 case OperationObject::FILESYSTEM_PHOTO:
595 case OperationObject::FILESYSTEM_AUDIO: {
596 return MediaLibraryAssetOperations::UpdateOperation(cmd);
597 }
598 case OperationObject::PHOTO_ALBUM: {
599 return MediaLibraryAlbumOperations::HandlePhotoAlbum(cmd.GetOprnType(), value, predicates);
600 }
601 default:
602 break;
603 }
604 // ModifyInfoByIdInDb can finish the default update of smartalbum and smartmap,
605 // so no need to distinct them in switch-case deliberately
606 cmd.SetValueBucket(value);
607 return MediaLibraryObjectUtils::ModifyInfoByIdInDb(cmd);
608 }
609
InterruptBgworker()610 void MediaLibraryDataManager::InterruptBgworker()
611 {
612 shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
613 if (refCnt_.load() <= 0) {
614 MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
615 return;
616 }
617
618 if (thumbnailService_ == nullptr) {
619 return;
620 }
621 thumbnailService_->InterruptBgworker();
622 shared_ptr<TrashAsyncTaskWorker> asyncWorker = TrashAsyncTaskWorker::GetInstance();
623 if (asyncWorker == nullptr) {
624 MEDIA_ERR_LOG("asyncWorker null");
625 return;
626 }
627 asyncWorker->Interrupt();
628 }
629
GenerateThumbnails()630 int32_t MediaLibraryDataManager::GenerateThumbnails()
631 {
632 shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
633 if (refCnt_.load() <= 0) {
634 MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
635 return E_FAIL;
636 }
637
638 if (thumbnailService_ == nullptr) {
639 return E_THUMBNAIL_SERVICE_NULLPTR;
640 }
641 return thumbnailService_->GenerateThumbnails();
642 }
643
DoAging()644 int32_t MediaLibraryDataManager::DoAging()
645 {
646 shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
647 MEDIA_DEBUG_LOG("MediaLibraryDataManager::DoAging IN");
648 if (refCnt_.load() <= 0) {
649 MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
650 return E_FAIL;
651 }
652
653 if (thumbnailService_ == nullptr) {
654 return E_THUMBNAIL_SERVICE_NULLPTR;
655 }
656 int32_t errorCode = thumbnailService_->LcdAging();
657 if (errorCode != 0) {
658 MEDIA_ERR_LOG("LcdAging exist error %{public}d", errorCode);
659 }
660
661 shared_ptr<TrashAsyncTaskWorker> asyncWorker = TrashAsyncTaskWorker::GetInstance();
662 if (asyncWorker == nullptr) {
663 MEDIA_ERR_LOG("asyncWorker null");
664 return E_FAIL;
665 }
666 asyncWorker->Init();
667 return errorCode;
668 }
669
670 #ifdef DISTRIBUTED
LcdDistributeAging()671 int32_t MediaLibraryDataManager::LcdDistributeAging()
672 {
673 MEDIA_DEBUG_LOG("MediaLibraryDataManager::LcdDistributeAging IN");
674 auto deviceInstance = MediaLibraryDevice::GetInstance();
675 if ((thumbnailService_ == nullptr) || (deviceInstance == nullptr)) {
676 return E_THUMBNAIL_SERVICE_NULLPTR;
677 }
678 int32_t result = E_SUCCESS;
679 vector<string> deviceUdids;
680 deviceInstance->QueryAllDeviceUdid(deviceUdids);
681 for (string &udid : deviceUdids) {
682 result = thumbnailService_->LcdDistributeAging(udid);
683 if (result != E_SUCCESS) {
684 MEDIA_ERR_LOG("LcdDistributeAging fail result is %{public}d", result);
685 break;
686 }
687 }
688 return result;
689 }
690
DistributeDeviceAging()691 int32_t MediaLibraryDataManager::DistributeDeviceAging()
692 {
693 MEDIA_DEBUG_LOG("MediaLibraryDataManager::DistributeDeviceAging IN");
694 auto deviceInstance = MediaLibraryDevice::GetInstance();
695 if ((thumbnailService_ == nullptr) || (deviceInstance == nullptr)) {
696 return E_FAIL;
697 }
698 int32_t result = E_FAIL;
699 vector<MediaLibraryDeviceInfo> deviceDataBaseList;
700 deviceInstance->QueryAgingDeviceInfos(deviceDataBaseList);
701 MEDIA_DEBUG_LOG("MediaLibraryDevice InitDeviceRdbStore deviceDataBaseList size = %{public}d",
702 (int) deviceDataBaseList.size());
703 for (MediaLibraryDeviceInfo deviceInfo : deviceDataBaseList) {
704 result = thumbnailService_->InvalidateDistributeThumbnail(deviceInfo.deviceUdid);
705 if (result != E_SUCCESS) {
706 MEDIA_ERR_LOG("invalidate fail %{public}d", result);
707 continue;
708 }
709 }
710 return result;
711 }
712 #endif
713
GetThumbnail(const string & uri)714 int MediaLibraryDataManager::GetThumbnail(const string &uri)
715 {
716 if (thumbnailService_ == nullptr) {
717 return E_THUMBNAIL_SERVICE_NULLPTR;
718 }
719 if (!uri.empty() && MediaLibraryObjectUtils::CheckUriPending(uri)) {
720 MEDIA_ERR_LOG("failed to get thumbnail, the file:%{public}s is pending", uri.c_str());
721 return E_FAIL;
722 }
723 return thumbnailService_->GetThumbnailFd(uri);
724 }
725
CreateThumbnailAsync(const string & uri,const string & path)726 void MediaLibraryDataManager::CreateThumbnailAsync(const string &uri, const string &path)
727 {
728 shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
729 if (refCnt_.load() <= 0) {
730 MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
731 return;
732 }
733
734 if (thumbnailService_ == nullptr) {
735 return;
736 }
737 if (!uri.empty()) {
738 if (MediaLibraryObjectUtils::CheckUriPending(uri)) {
739 MEDIA_ERR_LOG("failed to get thumbnail, the file:%{public}s is pending", uri.c_str());
740 return;
741 }
742 int32_t err = thumbnailService_->CreateThumbnail(uri, path);
743 if (err != E_SUCCESS) {
744 MEDIA_ERR_LOG("ThumbnailService CreateThumbnail failed : %{public}d", err);
745 }
746 }
747 }
748
NeedQuerySync(const string & networkId,OperationObject oprnObject)749 void MediaLibraryDataManager::NeedQuerySync(const string &networkId, OperationObject oprnObject)
750 {
751 if (networkId.empty()) {
752 return;
753 }
754 // tabletype mapping into tablename
755 string tableName = MEDIALIBRARY_TABLE;
756 switch (oprnObject) {
757 case OperationObject::SMART_ALBUM:
758 tableName = SMARTALBUM_TABLE;
759 break;
760 case OperationObject::SMART_ALBUM_MAP:
761 tableName = SMARTALBUM_MAP_TABLE;
762 break;
763 case OperationObject::FILESYSTEM_PHOTO:
764 tableName = PhotoColumn::PHOTOS_TABLE;
765 break;
766 case OperationObject::FILESYSTEM_AUDIO:
767 tableName = AudioColumn::AUDIOS_TABLE;
768 break;
769 default:
770 break;
771 }
772
773 #ifdef DISTRIBUTED
774 if ((oprnObject != OperationObject::ASSETMAP) && (oprnObject != OperationObject::SMART_ALBUM_ASSETS)) {
775 MediaLibraryTracer tracer;
776 tracer.Start("QuerySync");
777 auto ret = QuerySync(networkId, tableName);
778 MEDIA_INFO_LOG("MediaLibraryDataManager QuerySync result = %{private}d", ret);
779 }
780 #endif
781 }
782
Query(MediaLibraryCommand & cmd,const vector<string> & columns,const DataSharePredicates & predicates,int & errCode)783 shared_ptr<ResultSetBridge> MediaLibraryDataManager::Query(MediaLibraryCommand &cmd,
784 const vector<string> &columns, const DataSharePredicates &predicates, int &errCode)
785 {
786 shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
787 if (refCnt_.load() <= 0) {
788 errCode = E_FAIL;
789 MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
790 return nullptr;
791 }
792
793 MediaLibraryTracer tracer;
794 tracer.Start("MediaLibraryDataManager::Query");
795 if (rdbStore_ == nullptr) {
796 errCode = E_FAIL;
797 MEDIA_ERR_LOG("Rdb Store is not initialized");
798 return nullptr;
799 }
800
801 auto absResultSet = QueryRdb(cmd, columns, predicates, errCode);
802 if (absResultSet == nullptr) {
803 errCode = (errCode != E_OK) ? errCode : E_FAIL;
804 return nullptr;
805 }
806 return RdbUtils::ToResultSetBridge(absResultSet);
807 }
808
809 #ifdef DISTRIBUTED
SyncPullThumbnailKeys(const Uri & uri)810 int32_t MediaLibraryDataManager::SyncPullThumbnailKeys(const Uri &uri)
811 {
812 if (MediaLibraryDevice::GetInstance() == nullptr || !MediaLibraryDevice::GetInstance()->IsHasActiveDevice()) {
813 return E_ERR;
814 }
815 if (kvStorePtr_ == nullptr) {
816 return E_ERR;
817 }
818
819 MediaLibraryCommand cmd(uri, OperationType::QUERY);
820 cmd.GetAbsRdbPredicates()->BeginWrap()->EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, to_string(MEDIA_TYPE_IMAGE))
821 ->Or()->EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, to_string(MEDIA_TYPE_VIDEO))->EndWrap()
822 ->And()->EqualTo(MEDIA_DATA_DB_DATE_TRASHED, to_string(0))
823 ->And()->NotEqualTo(MEDIA_DATA_DB_MEDIA_TYPE, to_string(MEDIA_TYPE_ALBUM))
824 ->OrderByDesc(MEDIA_DATA_DB_DATE_ADDED);
825 vector<string> columns = { MEDIA_DATA_DB_THUMBNAIL, MEDIA_DATA_DB_LCD };
826 auto resultset = MediaLibraryFileOperations::QueryFileOperation(cmd, columns);
827 if (resultset == nullptr) {
828 return E_HAS_DB_ERROR;
829 }
830
831 vector<string> thumbnailKeys;
832 int count = 0;
833 while (resultset->GoToNextRow() == NativeRdb::E_OK && count < MAX_QUERY_THUMBNAIL_KEY_COUNT) {
834 string thumbnailKey =
835 get<string>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_THUMBNAIL, resultset, TYPE_STRING));
836 thumbnailKeys.push_back(thumbnailKey);
837 string lcdKey = get<string>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_LCD, resultset, TYPE_STRING));
838 thumbnailKeys.push_back(lcdKey);
839 count++;
840 }
841
842 if (thumbnailKeys.empty()) {
843 return E_NO_SUCH_FILE;
844 }
845 MediaLibrarySyncOperation::SyncPullKvstore(kvStorePtr_, thumbnailKeys,
846 MediaFileUtils::GetNetworkIdFromUri(uri.ToString()));
847 return E_SUCCESS;
848 }
849 #endif
850
QueryRdb(MediaLibraryCommand & cmd,const vector<string> & columns,const DataSharePredicates & predicates,int & errCode)851 shared_ptr<NativeRdb::ResultSet> MediaLibraryDataManager::QueryRdb(MediaLibraryCommand &cmd,
852 const vector<string> &columns, const DataSharePredicates &predicates, int &errCode)
853 {
854 shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
855 if (refCnt_.load() <= 0) {
856 errCode = E_FAIL;
857 MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
858 return nullptr;
859 }
860 MediaLibraryTracer tracer;
861 tracer.Start("QueryRdb");
862 static const map<OperationObject, string> queryConditionMap {
863 { OperationObject::SMART_ALBUM, SMARTALBUM_DB_ID },
864 { OperationObject::SMART_ALBUM_MAP, SMARTALBUMMAP_DB_ALBUM_ID },
865 { OperationObject::FILESYSTEM_DIR, MEDIA_DATA_DB_ID },
866 { OperationObject::ALL_DEVICE, "" },
867 { OperationObject::ACTIVE_DEVICE, "" },
868 { OperationObject::ASSETMAP, "" },
869 { OperationObject::SMART_ALBUM_ASSETS, "" },
870 { OperationObject::BUNDLE_PERMISSION, "" },
871 };
872
873 tracer.Start("CheckWhereClause");
874 auto whereClause = predicates.GetWhereClause();
875 if (!MediaLibraryCommonUtils::CheckWhereClause(whereClause)) {
876 errCode = E_INVALID_VALUES;
877 MEDIA_ERR_LOG("illegal query whereClause input %{public}s", whereClause.c_str());
878 return nullptr;
879 }
880 tracer.Finish();
881
882 cmd.SetDataSharePred(predicates);
883 // MEDIALIBRARY_TABLE just for RdbPredicates
884 NativeRdb::RdbPredicates rdbPredicate = RdbUtils::ToPredicates(predicates,
885 MEDIALIBRARY_TABLE);
886 cmd.GetAbsRdbPredicates()->SetWhereClause(rdbPredicate.GetWhereClause());
887 cmd.GetAbsRdbPredicates()->SetWhereArgs(rdbPredicate.GetWhereArgs());
888 cmd.GetAbsRdbPredicates()->SetOrder(rdbPredicate.GetOrder());
889
890 shared_ptr<NativeRdb::ResultSet> queryResultSet;
891 OperationObject oprnObject = cmd.GetOprnObject();
892 auto it = queryConditionMap.find(oprnObject);
893 if (it != queryConditionMap.end()) {
894 queryResultSet = MediaLibraryObjectUtils::QueryWithCondition(cmd, columns, it->second);
895 } else if (oprnObject == OperationObject::FILESYSTEM_ALBUM || oprnObject == OperationObject::MEDIA_VOLUME) {
896 queryResultSet = MediaLibraryAlbumOperations::QueryAlbumOperation(cmd, columns);
897 } else if (oprnObject == OperationObject::PHOTO_ALBUM) {
898 queryResultSet = MediaLibraryAlbumOperations::QueryPhotoAlbum(cmd, columns);
899 } else if (oprnObject == OperationObject::PHOTO_MAP) {
900 queryResultSet = PhotoMapOperations::QueryPhotoAssets(
901 RdbUtils::ToPredicates(predicates, PhotoColumn::PHOTOS_TABLE), columns);
902 } else if (oprnObject == OperationObject::FILESYSTEM_PHOTO || oprnObject == OperationObject::FILESYSTEM_AUDIO) {
903 queryResultSet = MediaLibraryAssetOperations::QueryOperation(cmd, columns);
904 } else {
905 tracer.Start("QueryFile");
906 queryResultSet = MediaLibraryFileOperations::QueryFileOperation(cmd, columns);
907 }
908 return queryResultSet;
909 }
910
911 #ifdef DISTRIBUTED
QuerySync(const string & networkId,const string & tableName)912 bool MediaLibraryDataManager::QuerySync(const string &networkId, const string &tableName)
913 {
914 if (networkId.empty() || tableName.empty()) {
915 return false;
916 }
917
918 OHOS::DistributedHardware::DmDeviceInfo deviceInfo;
919 auto &deviceManager = OHOS::DistributedHardware::DeviceManager::GetInstance();
920 auto ret = deviceManager.GetLocalDeviceInfo(bundleName_, deviceInfo);
921 if (ret != ERR_OK) {
922 MEDIA_ERR_LOG("MediaLibraryDataManager QuerySync Failed to get local device info.");
923 return false;
924 }
925
926 if (networkId == string(deviceInfo.networkId)) {
927 return true;
928 }
929
930 int32_t syncStatus = DEVICE_SYNCSTATUSING;
931 auto result = MediaLibraryDevice::GetInstance()->GetDeviceSyncStatus(networkId, tableName, syncStatus);
932 if (result && syncStatus == DEVICE_SYNCSTATUS_COMPLETE) {
933 return true;
934 }
935
936 vector<string> devices = { networkId };
937 MediaLibrarySyncOpts syncOpts;
938 syncOpts.rdbStore = rdbStore_;
939 syncOpts.table = tableName;
940 syncOpts.bundleName = bundleName_;
941 return MediaLibrarySyncOperation::SyncPullTable(syncOpts, devices);
942 }
943 #endif
944
OpenFile(MediaLibraryCommand & cmd,const string & mode)945 int32_t MediaLibraryDataManager::OpenFile(MediaLibraryCommand &cmd, const string &mode)
946 {
947 MediaLibraryTracer tracer;
948 tracer.Start("MediaLibraryDataManager::OpenFile");
949 auto oprnObject = cmd.GetOprnObject();
950 if (oprnObject == OperationObject::FILESYSTEM_PHOTO || oprnObject == OperationObject::FILESYSTEM_AUDIO) {
951 return MediaLibraryAssetOperations::OpenOperation(cmd, mode);
952 }
953
954 #ifdef MEDIALIBRARY_COMPATIBILITY
955 if (oprnObject != OperationObject::THUMBNAIL) {
956 string opObject = MediaFileUri::GetPathFirstDentry(const_cast<Uri &>(cmd.GetUri()));
957 if (opObject == IMAGE_ASSET_TYPE || opObject == VIDEO_ASSET_TYPE || opObject == URI_TYPE_PHOTO) {
958 cmd.SetOprnObject(OperationObject::FILESYSTEM_PHOTO);
959 return MediaLibraryAssetOperations::OpenOperation(cmd, mode);
960 }
961 if (opObject == AUDIO_ASSET_TYPE || opObject == URI_TYPE_AUDIO_V10) {
962 cmd.SetOprnObject(OperationObject::FILESYSTEM_AUDIO);
963 return MediaLibraryAssetOperations::OpenOperation(cmd, mode);
964 }
965 }
966 #endif
967
968 return MediaLibraryObjectUtils::OpenFile(cmd, mode);
969 }
970
NotifyChange(const Uri & uri)971 void MediaLibraryDataManager::NotifyChange(const Uri &uri)
972 {
973 shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
974 if (refCnt_.load() <= 0) {
975 MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
976 return;
977 }
978
979 if (extension_ == nullptr) {
980 MEDIA_ERR_LOG("MediaLibraryDataManager::NotifyChange failed");
981 return;
982 }
983
984 extension_->NotifyChange(uri);
985 }
986
InitialiseThumbnailService(const shared_ptr<OHOS::AbilityRuntime::Context> & extensionContext)987 int32_t MediaLibraryDataManager::InitialiseThumbnailService(
988 const shared_ptr<OHOS::AbilityRuntime::Context> &extensionContext)
989 {
990 if (thumbnailService_ != nullptr) {
991 return E_OK;
992 }
993 thumbnailService_ = ThumbnailService::GetInstance();
994 if (thumbnailService_ == nullptr) {
995 return E_THUMBNAIL_SERVICE_NULLPTR;
996 }
997 int ret = thumbnailService_->Init(rdbStore_, kvStorePtr_, extensionContext);
998 if (ret != E_OK) {
999 MEDIA_ERR_LOG("Failed to init ThumbnailService, err %{public}d", ret);
1000 return E_ERR;
1001 }
1002 return E_OK;
1003 }
1004
OnScanFinished(const int32_t status,const string & uri,const string & path)1005 int32_t ScanFileCallback::OnScanFinished(const int32_t status, const string &uri, const string &path)
1006 {
1007 auto instance = MediaLibraryDataManager::GetInstance();
1008 if (instance != nullptr) {
1009 instance->CreateThumbnailAsync(uri, path);
1010 }
1011 return E_OK;
1012 }
1013
SetCmdBundleAndDevice(MediaLibraryCommand & outCmd)1014 int32_t MediaLibraryDataManager::SetCmdBundleAndDevice(MediaLibraryCommand &outCmd)
1015 {
1016 string clientBundle = MediaLibraryBundleManager::GetInstance()->GetClientBundleName();
1017 if (clientBundle.empty()) {
1018 MEDIA_ERR_LOG("GetClientBundleName failed");
1019 return E_GET_CLIENTBUNDLE_FAIL;
1020 }
1021 outCmd.SetBundleName(clientBundle);
1022 #ifdef DISTRIBUTED
1023 OHOS::DistributedHardware::DmDeviceInfo deviceInfo;
1024 auto &deviceManager = OHOS::DistributedHardware::DeviceManager::GetInstance();
1025 int32_t ret = deviceManager.GetLocalDeviceInfo(bundleName_, deviceInfo);
1026 if (ret < 0) {
1027 MEDIA_ERR_LOG("GetLocalDeviceInfo ret = %{public}d", ret);
1028 } else {
1029 outCmd.SetDeviceName(deviceInfo.deviceName);
1030 }
1031 return ret;
1032 #endif
1033 return 0;
1034 }
1035
DoTrashAging()1036 int32_t MediaLibraryDataManager::DoTrashAging()
1037 {
1038 MediaLibrarySmartAlbumMapOperations::HandleAgingOperation();
1039 MediaLibraryAlbumOperations::HandlePhotoAlbum(OperationType::AGING, {}, {});
1040 MediaLibraryAudioOperations::TrashAging();
1041 return E_SUCCESS;
1042 }
1043
RevertPendingByFileId(const std::string & fileId)1044 int32_t MediaLibraryDataManager::RevertPendingByFileId(const std::string &fileId)
1045 {
1046 MediaLibraryCommand cmd(OperationObject::FILESYSTEM_ASSET, OperationType::UPDATE);
1047 ValuesBucket values;
1048 values.PutLong(Media::MEDIA_DATA_DB_TIME_PENDING, 0);
1049 cmd.SetValueBucket(values);
1050 int32_t retVal = MediaLibraryObjectUtils::ModifyInfoByIdInDb(cmd, fileId);
1051 if (retVal <= 0) {
1052 MEDIA_ERR_LOG("failed to revert pending error, fileId:%{public}s", fileId.c_str());
1053 return retVal;
1054 }
1055 auto fileAsset = MediaLibraryObjectUtils::GetFileAssetFromId(fileId);
1056 string srcPath = fileAsset->GetPath();
1057 MediaLibraryObjectUtils::ScanFileAsync(srcPath, fileId, MediaLibraryApi::API_10);
1058 return E_SUCCESS;
1059 }
1060
RevertPendingByPackage(const std::string & bundleName)1061 int32_t MediaLibraryDataManager::RevertPendingByPackage(const std::string &bundleName)
1062 {
1063 MediaLibraryCommand queryCmd(OperationObject::FILESYSTEM_ASSET, OperationType::QUERY);
1064 queryCmd.GetAbsRdbPredicates()
1065 ->EqualTo(MEDIA_DATA_DB_OWNER_PACKAGE, bundleName)
1066 ->And()
1067 ->NotEqualTo(MEDIA_DATA_DB_TIME_PENDING, to_string(0));
1068 vector<string> columns = { MEDIA_DATA_DB_ID };
1069 auto result = MediaLibraryObjectUtils::QueryWithCondition(queryCmd, columns);
1070 if (result == nullptr) {
1071 return E_HAS_DB_ERROR;
1072 }
1073
1074 int32_t ret = E_SUCCESS;
1075 while (result->GoToNextRow() == NativeRdb::E_OK) {
1076 int32_t id = GetInt32Val(MEDIA_DATA_DB_ID, result);
1077 int32_t retVal = RevertPendingByFileId(to_string(id));
1078 if (retVal != E_SUCCESS) {
1079 ret = retVal;
1080 MEDIA_ERR_LOG("Revert file %{public}d failed, ret=%{public}d", id, retVal);
1081 continue;
1082 }
1083 }
1084 return ret;
1085 }
1086
HandleRevertPending()1087 int32_t MediaLibraryDataManager::HandleRevertPending()
1088 {
1089 int64_t time = MediaFileUtils::UTCTimeSeconds();
1090 time -= REVERT_DAYS * DAY_HOURS * PER_MINUTE_SECONDS * PER_HOUR_MINUTES;
1091 if (time < 0) {
1092 MEDIA_ERR_LOG("the time of revert is error, time=%{public}ld", (long)time);
1093 return E_INVALID_VALUES;
1094 }
1095 MediaLibraryCommand queryCmd(OperationObject::FILESYSTEM_ASSET, OperationType::QUERY);
1096 queryCmd.GetAbsRdbPredicates()->LessThan(MEDIA_DATA_DB_TIME_PENDING, to_string(time))
1097 ->And()->GreaterThan(MEDIA_DATA_DB_TIME_PENDING, to_string(0));
1098 vector<string> columns = { MEDIA_DATA_DB_ID };
1099 auto result = MediaLibraryObjectUtils::QueryWithCondition(queryCmd, columns);
1100 if (result == nullptr) {
1101 return E_HAS_DB_ERROR;
1102 }
1103
1104 int32_t ret = E_SUCCESS;
1105 while (result->GoToNextRow() == NativeRdb::E_OK) {
1106 int32_t id = GetInt32Val(MEDIA_DATA_DB_ID, result);
1107 int32_t retVal = RevertPendingByFileId(to_string(id));
1108 if (retVal != E_SUCCESS) {
1109 ret = retVal;
1110 MEDIA_ERR_LOG("Revert file %{public}d failed, ret=%{public}d", id, retVal);
1111 continue;
1112 }
1113 }
1114 return ret;
1115 }
1116 } // namespace Media
1117 } // namespace OHOS
1118