• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2023 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 "acl.h"
26 #include "background_task_mgr_helper.h"
27 #include "cloud_sync_helper.h"
28 #include "datashare_abs_result_set.h"
29 #ifdef DISTRIBUTED
30 #include "device_manager.h"
31 #include "device_manager_callback.h"
32 #endif
33 #include "efficiency_resource_info.h"
34 #include "hitrace_meter.h"
35 #include "ipc_skeleton.h"
36 #include "media_column.h"
37 #include "media_datashare_ext_ability.h"
38 #include "media_file_utils.h"
39 #include "media_log.h"
40 #include "media_scanner_manager.h"
41 #include "medialibrary_album_operations.h"
42 #include "medialibrary_asset_operations.h"
43 #include "medialibrary_async_worker.h"
44 #include "medialibrary_audio_operations.h"
45 #include "medialibrary_bundle_manager.h"
46 #include "medialibrary_common_utils.h"
47 #ifdef DISTRIBUTED
48 #include "medialibrary_device.h"
49 #include "medialibrary_device_info.h"
50 #endif
51 #include "medialibrary_dir_operations.h"
52 #include "medialibrary_errno.h"
53 #include "medialibrary_file_operations.h"
54 #include "medialibrary_inotify.h"
55 #include "medialibrary_kvstore_manager.h"
56 #include "medialibrary_location_operations.h"
57 #include "medialibrary_object_utils.h"
58 #include "medialibrary_rdb_utils.h"
59 #include "medialibrary_rdbstore.h"
60 #include "medialibrary_smartalbum_map_operations.h"
61 #include "medialibrary_smartalbum_operations.h"
62 #include "medialibrary_sync_operation.h"
63 #include "medialibrary_tracer.h"
64 #include "medialibrary_unistore_manager.h"
65 #include "medialibrary_uripermission_operations.h"
66 #include "medialibrary_vision_operations.h"
67 #include "medialibrary_search_operations.h"
68 #include "mimetype_utils.h"
69 #include "multistages_capture_manager.h"
70 #include "permission_utils.h"
71 #include "photo_map_operations.h"
72 #include "resource_type.h"
73 #include "rdb_store.h"
74 #include "rdb_utils.h"
75 #include "result_set_utils.h"
76 #include "system_ability_definition.h"
77 #include "timer.h"
78 #include "trash_async_worker.h"
79 #include "value_object.h"
80 #include "post_event_utils.h"
81 #include "medialibrary_formmap_operations.h"
82 #include "ithumbnail_helper.h"
83 
84 using namespace std;
85 using namespace OHOS::AppExecFwk;
86 using namespace OHOS::AbilityRuntime;
87 using namespace OHOS::NativeRdb;
88 using namespace OHOS::DistributedKv;
89 using namespace OHOS::DataShare;
90 using namespace OHOS::RdbDataShareAdapter;
91 
92 namespace {
93 const OHOS::DistributedKv::AppId KVSTORE_APPID = {"com.ohos.medialibrary.medialibrarydata"};
94 const OHOS::DistributedKv::StoreId KVSTORE_STOREID = {"medialibrary_thumbnail"};
95 };
96 
97 namespace OHOS {
98 namespace Media {
99 shared_ptr<MediaLibraryDataManager> MediaLibraryDataManager::instance_ = nullptr;
100 unordered_map<string, DirAsset> MediaLibraryDataManager::dirQuerySetMap_ = {};
101 mutex MediaLibraryDataManager::mutex_;
102 Utils::Timer MediaLibraryDataManager::timer_("download_cloud_files");
103 uint32_t MediaLibraryDataManager::timerId_ = 0;
104 
105 static constexpr int32_t LOCAL_FILES_COUNT_THRESHOLD = 10000;
106 static constexpr int32_t DOWNLOAD_BATCH_SIZE = 5;
107 static constexpr int32_t BATCH_DOWNLOAD_INTERVAL = 60 * 1000; // 1min
108 
109 #ifdef DISTRIBUTED
110 static constexpr int MAX_QUERY_THUMBNAIL_KEY_COUNT = 20;
111 #endif
MediaLibraryDataManager(void)112 MediaLibraryDataManager::MediaLibraryDataManager(void)
113 {
114 }
115 
~MediaLibraryDataManager(void)116 MediaLibraryDataManager::~MediaLibraryDataManager(void)
117 {
118     MediaLibraryKvStoreManager::GetInstance().CloseAllKvStore();
119 #ifdef DISTRIBUTED
120     if (kvStorePtr_ != nullptr) {
121         dataManager_.CloseKvStore(KVSTORE_APPID, kvStorePtr_);
122         kvStorePtr_ = nullptr;
123     }
124 #endif
125 }
126 
GetInstance()127 shared_ptr<MediaLibraryDataManager> MediaLibraryDataManager::GetInstance()
128 {
129     if (instance_ == nullptr) {
130         lock_guard<mutex> lock(mutex_);
131         if (instance_ == nullptr) {
132             instance_ = make_shared<MediaLibraryDataManager>();
133         }
134     }
135     return instance_;
136 }
137 
MediaDataShareCreator(const unique_ptr<Runtime> & runtime)138 static DataShare::DataShareExtAbility *MediaDataShareCreator(const unique_ptr<Runtime> &runtime)
139 {
140     MEDIA_DEBUG_LOG("MediaLibraryCreator::%{public}s", __func__);
141     return  MediaDataShareExtAbility::Create(runtime);
142 }
143 
RegisterDataShareCreator()144 __attribute__((constructor)) void RegisterDataShareCreator()
145 {
146     MEDIA_DEBUG_LOG("MediaLibraryDataManager::%{public}s", __func__);
147     DataShare::DataShareExtAbility::SetCreator(MediaDataShareCreator);
148     MEDIA_DEBUG_LOG("MediaLibraryDataManager::%{public}s End", __func__);
149 }
150 
MakeRootDirs(AsyncTaskData * data)151 static void MakeRootDirs(AsyncTaskData *data)
152 {
153     for (auto &dir : PRESET_ROOT_DIRS) {
154         Uri createAlbumUri(MEDIALIBRARY_DATA_URI + "/" + MEDIA_ALBUMOPRN + "/" + MEDIA_ALBUMOPRN_CREATEALBUM);
155         ValuesBucket valuesBucket;
156         valuesBucket.PutString(MEDIA_DATA_DB_FILE_PATH, ROOT_MEDIA_DIR + dir);
157         MediaLibraryCommand cmd(createAlbumUri, valuesBucket);
158         auto ret = MediaLibraryAlbumOperations::CreateAlbumOperation(cmd);
159         if (ret == E_FILE_EXIST) {
160             MEDIA_INFO_LOG("Root dir: %{private}s is exist", dir.c_str());
161         } else if (ret <= 0) {
162             MEDIA_ERR_LOG("Failed to preset root dir: %{private}s", dir.c_str());
163         }
164         MediaFileUtils::CreateDirectory(ROOT_MEDIA_DIR + dir + ".recycle");
165     }
166 }
167 
InitMediaLibraryMgr(const shared_ptr<OHOS::AbilityRuntime::Context> & context,const shared_ptr<OHOS::AbilityRuntime::Context> & extensionContext)168 int32_t MediaLibraryDataManager::InitMediaLibraryMgr(const shared_ptr<OHOS::AbilityRuntime::Context> &context,
169     const shared_ptr<OHOS::AbilityRuntime::Context> &extensionContext)
170 {
171     lock_guard<shared_mutex> lock(mgrSharedMutex_);
172 
173     if (refCnt_.load() > 0) {
174         MEDIA_DEBUG_LOG("already initialized");
175         refCnt_++;
176         return E_OK;
177     }
178 
179     BackgroundTaskMgr::EfficiencyResourceInfo resourceInfo =
180         BackgroundTaskMgr::EfficiencyResourceInfo(BackgroundTaskMgr::ResourceType::CPU, true, 0, "apply", true, true);
181     BackgroundTaskMgr::BackgroundTaskMgrHelper::ApplyEfficiencyResources(resourceInfo);
182 
183     context_ = context;
184     int32_t errCode = InitMediaLibraryRdbStore();
185     CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "failed at InitMediaLibraryRdbStore");
186 
187 #ifdef DISTRIBUTED
188     errCode = InitDeviceData();
189     CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "failed at InitDeviceData");
190 #endif
191 
192     MimeTypeUtils::InitMimeTypeMap();
193     errCode = MakeDirQuerySetMap(dirQuerySetMap_);
194     CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "failed at MakeDirQuerySetMap");
195 
196     InitACLPermission();
197 
198     shared_ptr<MediaLibraryAsyncWorker> asyncWorker = MediaLibraryAsyncWorker::GetInstance();
199     if (asyncWorker == nullptr) {
200         MEDIA_ERR_LOG("Can not get asyncWorker");
201         return E_ERR;
202     }
203     shared_ptr<MediaLibraryAsyncTask> makeRootDirTask = make_shared<MediaLibraryAsyncTask>(MakeRootDirs, nullptr);
204     if (makeRootDirTask != nullptr) {
205         asyncWorker->AddTask(makeRootDirTask, true);
206     } else {
207         MEDIA_WARN_LOG("Can not init make root dir task");
208     }
209 
210     errCode = InitialiseThumbnailService(extensionContext);
211     CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "failed at InitialiseThumbnailService");
212 
213     InitRefreshAlbum();
214 
215     cloudDataObserver_ = std::make_shared<CloudThumbnailObserver>();
216     auto shareHelper = MediaLibraryHelperContainer::GetInstance()->GetDataShareHelper();
217     shareHelper->RegisterObserverExt(Uri(PHOTO_URI_PREFIX), cloudDataObserver_, true);
218 
219     refCnt_++;
220     return E_OK;
221 }
222 
223 #ifdef DISTRIBUTED
InitDeviceData()224 int32_t MediaLibraryDataManager::InitDeviceData()
225 {
226     if (rdbStore_ == nullptr) {
227         MEDIA_ERR_LOG("MediaLibraryDataManager InitDeviceData rdbStore is null");
228         return E_ERR;
229     }
230 
231     MediaLibraryTracer tracer;
232     tracer.Start("InitDeviceRdbStoreTrace");
233     if (!MediaLibraryDevice::GetInstance()->InitDeviceRdbStore(rdbStore_)) {
234         MEDIA_ERR_LOG("MediaLibraryDataManager InitDeviceData failed!");
235         return E_ERR;
236     }
237     return E_OK;
238 }
239 #endif
240 
ClearMediaLibraryMgr()241 void MediaLibraryDataManager::ClearMediaLibraryMgr()
242 {
243     lock_guard<shared_mutex> lock(mgrSharedMutex_);
244 
245     refCnt_--;
246     if (refCnt_.load() > 0) {
247         MEDIA_DEBUG_LOG("still other extension exist");
248         return;
249     }
250 
251     UnregisterTimer();
252     auto shareHelper = MediaLibraryHelperContainer::GetInstance()->GetDataShareHelper();
253     shareHelper->UnregisterObserverExt(Uri(PHOTO_URI_PREFIX), cloudDataObserver_);
254     rdbStore_ = nullptr;
255     MediaLibraryKvStoreManager::GetInstance().CloseAllKvStore();
256 
257 #ifdef DISTRIBUTED
258     if (kvStorePtr_ != nullptr) {
259         dataManager_.CloseKvStore(KVSTORE_APPID, kvStorePtr_);
260         kvStorePtr_ = nullptr;
261     }
262 
263     if (MediaLibraryDevice::GetInstance()) {
264         MediaLibraryDevice::GetInstance()->Stop();
265     };
266 #endif
267 
268     if (thumbnailService_ != nullptr) {
269         thumbnailService_->ReleaseService();
270         thumbnailService_ = nullptr;
271     }
272     auto watch = MediaLibraryInotify::GetInstance();
273     if (watch != nullptr) {
274         watch->DoStop();
275     }
276     MediaLibraryUnistoreManager::GetInstance().Stop();
277     extension_ = nullptr;
278 }
279 
InitMediaLibraryRdbStore()280 int32_t MediaLibraryDataManager::InitMediaLibraryRdbStore()
281 {
282     if (rdbStore_) {
283         return E_OK;
284     }
285 
286     int32_t ret = MediaLibraryUnistoreManager::GetInstance().Init(context_);
287     if (ret != E_OK) {
288         MEDIA_ERR_LOG("init MediaLibraryUnistoreManager failed");
289         return ret;
290     }
291     rdbStore_ = MediaLibraryUnistoreManager::GetInstance().GetRdbStoreRaw()->GetRaw();
292     if (ret != E_OK) {
293         MEDIA_ERR_LOG("rdbStore is nullptr");
294         return E_ERR;
295     }
296 
297     return E_OK;
298 }
299 
InitRefreshAlbum()300 void MediaLibraryDataManager::InitRefreshAlbum()
301 {
302     bool isNeedRefresh = false;
303     int32_t ret = MediaLibraryRdbUtils::IsNeedRefreshByCheckTable(rdbStore_, isNeedRefresh);
304     if (ret != E_OK || isNeedRefresh) {
305         // Only set flag here, should not do any task in InitDataMgr
306         MediaLibraryRdbUtils::SetNeedRefreshAlbum(true);
307     }
308 }
309 
GetOwner()310 shared_ptr<MediaDataShareExtAbility> MediaLibraryDataManager::GetOwner()
311 {
312     return extension_;
313 }
314 
SetOwner(const shared_ptr<MediaDataShareExtAbility> & datashareExternsion)315 void MediaLibraryDataManager::SetOwner(const shared_ptr<MediaDataShareExtAbility> &datashareExternsion)
316 {
317     extension_ = datashareExternsion;
318 }
319 
GetType(const Uri & uri)320 string MediaLibraryDataManager::GetType(const Uri &uri)
321 {
322     MEDIA_INFO_LOG("GetType uri: %{private}s", uri.ToString().c_str());
323     return "";
324 }
325 
MakeDirQuerySetMap(unordered_map<string,DirAsset> & outDirQuerySetMap)326 int32_t MediaLibraryDataManager::MakeDirQuerySetMap(unordered_map<string, DirAsset> &outDirQuerySetMap)
327 {
328     int32_t count = -1;
329     vector<string> columns;
330     AbsRdbPredicates dirAbsPred(MEDIATYPE_DIRECTORY_TABLE);
331     auto queryResultSet = rdbStore_->QueryByStep(dirAbsPred, columns);
332     auto ret = queryResultSet->GetRowCount(count);
333     if (ret != NativeRdb::E_OK) {
334         MEDIA_ERR_LOG("rdb failed");
335         return E_ERR;
336     }
337     MEDIA_INFO_LOG("MakeDirQuerySetMap count = %{public}d", count);
338     if (count == 0) {
339         MEDIA_ERR_LOG("can not find any dirAsset");
340         return E_ERR;
341     }
342     DirAsset dirAsset;
343     string dirVal;
344     outDirQuerySetMap.clear();
345     while (queryResultSet->GoToNextRow() == NativeRdb::E_OK) {
346         dirVal = get<string>(
347             ResultSetUtils::GetValFromColumn(DIRECTORY_DB_DIRECTORY, queryResultSet, TYPE_STRING));
348         dirAsset.SetDirectory(dirVal);
349         dirAsset.SetDirType(get<int32_t>(
350             ResultSetUtils::GetValFromColumn(DIRECTORY_DB_DIRECTORY_TYPE, queryResultSet, TYPE_INT32)));
351         dirAsset.SetMediaTypes(get<string>(
352             ResultSetUtils::GetValFromColumn(DIRECTORY_DB_MEDIA_TYPE, queryResultSet, TYPE_STRING)));
353         dirAsset.SetExtensions(get<string>(
354             ResultSetUtils::GetValFromColumn(DIRECTORY_DB_EXTENSION, queryResultSet, TYPE_STRING)));
355         outDirQuerySetMap.insert(make_pair(dirVal, dirAsset));
356     }
357     return E_OK;
358 }
359 
GetDirQuerySetMap()360 unordered_map<string, DirAsset> MediaLibraryDataManager::GetDirQuerySetMap()
361 {
362     return dirQuerySetMap_;
363 }
364 
365 #ifdef MEDIALIBRARY_COMPATIBILITY
ChangeUriFromValuesBucket(ValuesBucket & values)366 static void ChangeUriFromValuesBucket(ValuesBucket &values)
367 {
368     if (!values.HasColumn(MEDIA_DATA_DB_URI)) {
369         return;
370     }
371 
372     ValueObject value;
373     if (!values.GetObject(MEDIA_DATA_DB_URI, value)) {
374         return;
375     }
376     string oldUri;
377     if (value.GetString(oldUri) != NativeRdb::E_OK) {
378         return;
379     }
380     string newUri = MediaFileUtils::GetRealUriFromVirtualUri(oldUri);
381     values.Delete(MEDIA_DATA_DB_URI);
382     values.PutString(MEDIA_DATA_DB_URI, newUri);
383 }
384 #endif
385 
SolveInsertCmd(MediaLibraryCommand & cmd)386 int32_t MediaLibraryDataManager::SolveInsertCmd(MediaLibraryCommand &cmd)
387 {
388     switch (cmd.GetOprnObject()) {
389         case OperationObject::FILESYSTEM_ASSET:
390             return MediaLibraryFileOperations::HandleFileOperation(cmd);
391 
392         case OperationObject::FILESYSTEM_PHOTO:
393         case OperationObject::FILESYSTEM_AUDIO:
394             return MediaLibraryAssetOperations::HandleInsertOperation(cmd);
395 
396         case OperationObject::FILESYSTEM_ALBUM:
397             return MediaLibraryAlbumOperations::CreateAlbumOperation(cmd);
398 
399         case OperationObject::ANALYSIS_PHOTO_ALBUM:
400         case OperationObject::PHOTO_ALBUM:
401             return MediaLibraryAlbumOperations::HandlePhotoAlbumOperations(cmd);
402 
403         case OperationObject::FILESYSTEM_DIR:
404             return MediaLibraryDirOperations::HandleDirOperation(cmd);
405 
406         case OperationObject::SMART_ALBUM:
407             return MediaLibrarySmartAlbumOperations::HandleSmartAlbumOperation(cmd);
408 
409         case OperationObject::SMART_ALBUM_MAP:
410             return MediaLibrarySmartAlbumMapOperations::HandleSmartAlbumMapOperation(cmd);
411 
412         case OperationObject::THUMBNAIL:
413             return HandleThumbnailOperations(cmd);
414 
415         case OperationObject::BUNDLE_PERMISSION:
416             return UriPermissionOperations::HandleUriPermOperations(cmd);
417 
418         case OperationObject::VISION_START ... OperationObject::VISION_END:
419             return MediaLibraryVisionOperations::InsertOperation(cmd);
420 
421         case OperationObject::GEO_DICTIONARY:
422         case OperationObject::GEO_KNOWLEDGE:
423         case OperationObject::GEO_PHOTO:
424             return MediaLibraryLocationOperations::InsertOperation(cmd);
425 
426         case OperationObject::PAH_FORM_MAP:
427             return MediaLibraryFormMapOperations::HandleStoreFormIdOperation(cmd);
428         case OperationObject::SEARCH_TOTAL: {
429             return MediaLibrarySearchOperations::InsertOperation(cmd);
430         }
431 
432         case OperationObject::ANALYSIS_PHOTO_MAP: {
433             return MediaLibrarySearchOperations::InsertOperation(cmd);
434         }
435 
436         default:
437             MEDIA_ERR_LOG("MediaLibraryDataManager SolveInsertCmd: unsupported OperationObject: %{public}d",
438                 cmd.GetOprnObject());
439             return E_FAIL;
440     }
441 }
442 
Insert(MediaLibraryCommand & cmd,const DataShareValuesBucket & dataShareValue)443 int32_t MediaLibraryDataManager::Insert(MediaLibraryCommand &cmd, const DataShareValuesBucket &dataShareValue)
444 {
445     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
446     if (refCnt_.load() <= 0) {
447         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
448         return E_FAIL;
449     }
450 
451     ValuesBucket value = RdbUtils::ToValuesBucket(dataShareValue);
452     if (value.IsEmpty()) {
453         MEDIA_ERR_LOG("MediaLibraryDataManager Insert: Input parameter is invalid");
454         return E_INVALID_VALUES;
455     }
456 #ifdef MEDIALIBRARY_COMPATIBILITY
457     ChangeUriFromValuesBucket(value);
458 #endif
459     cmd.SetValueBucket(value);
460 
461     OperationType oprnType = cmd.GetOprnType();
462     if (oprnType == OperationType::CREATE || oprnType == OperationType::SUBMIT_CACHE) {
463         if (SetCmdBundleAndDevice(cmd) != ERR_OK) {
464             MEDIA_ERR_LOG("MediaLibraryDataManager SetCmdBundleAndDevice failed.");
465         }
466     }
467     // boardcast operation
468     if (oprnType == OperationType::SCAN) {
469         return MediaScannerManager::GetInstance()->ScanDir(ROOT_MEDIA_DIR, nullptr);
470 #ifdef MEDIALIBRARY_MEDIATOOL_ENABLE
471     } else if (oprnType == OperationType::DELETE_TOOL) {
472         return MediaLibraryAssetOperations::DeleteToolOperation(cmd);
473 #endif
474     }
475     return SolveInsertCmd(cmd);
476 }
477 
InsertExt(MediaLibraryCommand & cmd,const DataShareValuesBucket & dataShareValue,string & result)478 int32_t MediaLibraryDataManager::InsertExt(MediaLibraryCommand &cmd, const DataShareValuesBucket &dataShareValue,
479     string &result)
480 {
481     int32_t res = Insert(cmd, dataShareValue);
482     result = cmd.GetResult();
483     return res;
484 }
485 
HandleThumbnailOperations(MediaLibraryCommand & cmd)486 int32_t MediaLibraryDataManager::HandleThumbnailOperations(MediaLibraryCommand &cmd)
487 {
488     if (thumbnailService_ == nullptr) {
489         return E_THUMBNAIL_SERVICE_NULLPTR;
490     }
491     int32_t result = E_FAIL;
492     switch (cmd.GetOprnType()) {
493         case OperationType::GENERATE:
494             result = thumbnailService_->GenerateThumbnails();
495             break;
496         case OperationType::AGING:
497             result = thumbnailService_->LcdAging();
498             break;
499 #ifdef DISTRIBUTED
500         case OperationType::DISTRIBUTE_AGING:
501             result = DistributeDeviceAging();
502             break;
503 #endif
504         default:
505             MEDIA_ERR_LOG("bad operation type %{public}u", cmd.GetOprnType());
506     }
507     return result;
508 }
509 
BatchInsert(MediaLibraryCommand & cmd,const vector<DataShareValuesBucket> & values)510 int32_t MediaLibraryDataManager::BatchInsert(MediaLibraryCommand &cmd, const vector<DataShareValuesBucket> &values)
511 {
512     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
513     if (refCnt_.load() <= 0) {
514         MEDIA_ERR_LOG("MediaLibraryDataManager is not initialized");
515         return E_FAIL;
516     }
517 
518     string uriString = cmd.GetUri().ToString();
519     if (uriString == UFM_PHOTO_ALBUM_ADD_ASSET || uriString == PAH_PHOTO_ALBUM_ADD_ASSET) {
520         return PhotoMapOperations::AddPhotoAssets(values);
521     } else if (cmd.GetOprnObject() == OperationObject::ANALYSIS_PHOTO_MAP) {
522         return PhotoMapOperations::AddAnaLysisPhotoAssets(values);
523     }
524     if (uriString.find(MEDIALIBRARY_DATA_URI) == string::npos) {
525         MEDIA_ERR_LOG("MediaLibraryDataManager BatchInsert: Input parameter is invalid");
526         return E_INVALID_URI;
527     }
528     int32_t rowCount = 0;
529     for (auto it = values.begin(); it != values.end(); it++) {
530         if (Insert(cmd, *it) >= 0) {
531             rowCount++;
532         }
533     }
534 
535     return rowCount;
536 }
537 
Delete(MediaLibraryCommand & cmd,const DataSharePredicates & predicates)538 int32_t MediaLibraryDataManager::Delete(MediaLibraryCommand &cmd, const DataSharePredicates &predicates)
539 {
540     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
541     if (refCnt_.load() <= 0) {
542         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
543         return E_FAIL;
544     }
545 
546     string uriString = cmd.GetUri().ToString();
547     if (MediaFileUtils::StartsWith(uriString, PhotoColumn::PHOTO_CACHE_URI_PREFIX)) {
548         return MediaLibraryAssetOperations::DeleteOperation(cmd);
549     }
550 
551     if (uriString.find(MEDIALIBRARY_DATA_URI) == string::npos) {
552         MEDIA_ERR_LOG("Not Data ability Uri");
553         return E_INVALID_URI;
554     }
555     MediaLibraryTracer tracer;
556     tracer.Start("CheckWhereClause");
557     auto whereClause = predicates.GetWhereClause();
558     if (!MediaLibraryCommonUtils::CheckWhereClause(whereClause)) {
559         MEDIA_ERR_LOG("illegal query whereClause input %{private}s", whereClause.c_str());
560         return E_SQL_CHECK_FAIL;
561     }
562     tracer.Finish();
563 
564     // MEDIALIBRARY_TABLE just for RdbPredicates
565     NativeRdb::RdbPredicates rdbPredicate = RdbUtils::ToPredicates(predicates,
566         cmd.GetTableName());
567     cmd.GetAbsRdbPredicates()->SetWhereClause(rdbPredicate.GetWhereClause());
568     cmd.GetAbsRdbPredicates()->SetWhereArgs(rdbPredicate.GetWhereArgs());
569     return DeleteInRdbPredicates(cmd, rdbPredicate);
570 }
571 
CheckIsDismissAsset(NativeRdb::RdbPredicates & rdbPredicate)572 bool CheckIsDismissAsset(NativeRdb::RdbPredicates &rdbPredicate)
573 {
574     auto whereClause = rdbPredicate.GetWhereClause();
575     if (whereClause.find(MAP_ALBUM) != string::npos && whereClause.find(MAP_ASSET) != string::npos) {
576         return true;
577     }
578     return false;
579 }
580 
DeleteInRdbPredicates(MediaLibraryCommand & cmd,NativeRdb::RdbPredicates & rdbPredicate)581 int32_t MediaLibraryDataManager::DeleteInRdbPredicates(MediaLibraryCommand &cmd, NativeRdb::RdbPredicates &rdbPredicate)
582 {
583     switch (cmd.GetOprnObject()) {
584         case OperationObject::FILESYSTEM_ASSET:
585         case OperationObject::FILESYSTEM_DIR:
586         case OperationObject::FILESYSTEM_ALBUM: {
587             vector<string> columns = { MEDIA_DATA_DB_ID, MEDIA_DATA_DB_FILE_PATH, MEDIA_DATA_DB_PARENT_ID,
588                 MEDIA_DATA_DB_MEDIA_TYPE, MEDIA_DATA_DB_IS_TRASH, MEDIA_DATA_DB_RELATIVE_PATH };
589             auto fileAsset = MediaLibraryObjectUtils::GetFileAssetByPredicates(*cmd.GetAbsRdbPredicates(), columns);
590             CHECK_AND_RETURN_RET_LOG(fileAsset != nullptr, E_INVALID_ARGUMENTS, "Get fileAsset failed.");
591             if (fileAsset->GetRelativePath() == "") {
592                 return E_DELETE_DENIED;
593             }
594             return (fileAsset->GetMediaType() != MEDIA_TYPE_ALBUM) ?
595                 MediaLibraryObjectUtils::DeleteFileObj(move(fileAsset)) :
596                 MediaLibraryObjectUtils::DeleteDirObj(move(fileAsset));
597         }
598         case OperationObject::PHOTO_ALBUM: {
599             return MediaLibraryAlbumOperations::DeletePhotoAlbum(rdbPredicate);
600         }
601         case OperationObject::PHOTO_MAP: {
602             return PhotoMapOperations::RemovePhotoAssets(rdbPredicate);
603         }
604         case OperationObject::ANALYSIS_PHOTO_MAP: {
605             if (CheckIsDismissAsset(rdbPredicate)) {
606                 return PhotoMapOperations::DismissAssets(rdbPredicate);
607             }
608             break;
609         }
610         case OperationObject::FILESYSTEM_PHOTO:
611         case OperationObject::FILESYSTEM_AUDIO: {
612             return MediaLibraryAssetOperations::DeleteOperation(cmd);
613         }
614         case OperationObject::PAH_FORM_MAP: {
615             return MediaLibraryFormMapOperations::RemoveFormIdOperations(rdbPredicate);
616         }
617         default:
618             break;
619     }
620 
621     return DeleteInRdbPredicatesAnalysis(cmd, rdbPredicate);
622 }
623 
DeleteInRdbPredicatesAnalysis(MediaLibraryCommand & cmd,NativeRdb::RdbPredicates & rdbPredicate)624 int32_t MediaLibraryDataManager::DeleteInRdbPredicatesAnalysis(MediaLibraryCommand &cmd,
625     NativeRdb::RdbPredicates &rdbPredicate)
626 {
627     switch (cmd.GetOprnObject()) {
628         case OperationObject::VISION_START ... OperationObject::VISION_END: {
629             return MediaLibraryVisionOperations::DeleteOperation(cmd);
630         }
631         case OperationObject::GEO_DICTIONARY:
632         case OperationObject::GEO_KNOWLEDGE:
633         case OperationObject::GEO_PHOTO: {
634             return MediaLibraryLocationOperations::DeleteOperation(cmd);
635         }
636         case OperationObject::SEARCH_TOTAL: {
637             return MediaLibrarySearchOperations::DeleteOperation(cmd);
638         }
639         default:
640             break;
641     }
642 
643     return E_FAIL;
644 }
645 
Update(MediaLibraryCommand & cmd,const DataShareValuesBucket & dataShareValue,const DataSharePredicates & predicates)646 int32_t MediaLibraryDataManager::Update(MediaLibraryCommand &cmd, const DataShareValuesBucket &dataShareValue,
647     const DataSharePredicates &predicates)
648 {
649     MEDIA_DEBUG_LOG("MediaLibraryDataManager::Update");
650     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
651     if (refCnt_.load() <= 0) {
652         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
653         return E_FAIL;
654     }
655 
656     ValuesBucket value = RdbUtils::ToValuesBucket(dataShareValue);
657     if (value.IsEmpty()) {
658         MEDIA_ERR_LOG("MediaLibraryDataManager Update:Input parameter is invalid ");
659         return E_INVALID_VALUES;
660     }
661 
662 #ifdef MEDIALIBRARY_COMPATIBILITY
663     ChangeUriFromValuesBucket(value);
664 #endif
665 
666     cmd.SetValueBucket(value);
667     cmd.SetDataSharePred(predicates);
668     // MEDIALIBRARY_TABLE just for RdbPredicates
669     NativeRdb::RdbPredicates rdbPredicate = RdbUtils::ToPredicates(predicates,
670         cmd.GetTableName());
671     cmd.GetAbsRdbPredicates()->SetWhereClause(rdbPredicate.GetWhereClause());
672     cmd.GetAbsRdbPredicates()->SetWhereArgs(rdbPredicate.GetWhereArgs());
673     return UpdateInternal(cmd, value, predicates);
674 }
675 
UpdateInternal(MediaLibraryCommand & cmd,NativeRdb::ValuesBucket & value,const DataShare::DataSharePredicates & predicates)676 int32_t MediaLibraryDataManager::UpdateInternal(MediaLibraryCommand &cmd, NativeRdb::ValuesBucket &value,
677     const DataShare::DataSharePredicates &predicates)
678 {
679     switch (cmd.GetOprnObject()) {
680         case OperationObject::FILESYSTEM_ASSET: {
681             auto ret = MediaLibraryFileOperations::ModifyFileOperation(cmd);
682             if (ret == E_SAME_PATH) {
683                 break;
684             } else {
685                 return ret;
686             }
687         }
688         case OperationObject::FILESYSTEM_DIR:
689             // supply a ModifyDirOperation here to replace
690             // modify in the HandleDirOperations in Insert function, if need
691             break;
692         case OperationObject::FILESYSTEM_ALBUM: {
693             return MediaLibraryAlbumOperations::ModifyAlbumOperation(cmd);
694         }
695         case OperationObject::FILESYSTEM_PHOTO:
696         case OperationObject::FILESYSTEM_AUDIO: {
697             return MediaLibraryAssetOperations::UpdateOperation(cmd);
698         }
699         case OperationObject::ANALYSIS_PHOTO_ALBUM: {
700             if (cmd.GetOprnType() >= OperationType::PORTRAIT_DISPLAY_LEVEL &&
701                 cmd.GetOprnType() <= OperationType::PORTRAIT_COVER_URI) {
702                 return MediaLibraryAlbumOperations::HandleAnalysisPhotoAlbum(cmd.GetOprnType(), value, predicates);
703             }
704             break;
705         }
706         case OperationObject::PHOTO_ALBUM: {
707             return MediaLibraryAlbumOperations::HandlePhotoAlbum(cmd.GetOprnType(), value, predicates);
708         }
709         case OperationObject::GEO_DICTIONARY:
710         case OperationObject::GEO_KNOWLEDGE: {
711             return MediaLibraryLocationOperations::UpdateOperation(cmd);
712         }
713         case OperationObject::PAH_MULTISTAGES_CAPTURE: {
714             if (cmd.GetOprnType() == OperationType::ADD_IMAGE) {
715                 MultiStagesCaptureManager::GetInstance().HandleMultiStagesOperation(cmd, value.GetAll());
716             }
717             return E_OK;
718         }
719         default:
720             break;
721     }
722     // ModifyInfoByIdInDb can finish the default update of smartalbum and smartmap,
723     // so no need to distinct them in switch-case deliberately
724     cmd.SetValueBucket(value);
725     return MediaLibraryObjectUtils::ModifyInfoByIdInDb(cmd);
726 }
727 
InterruptBgworker()728 void MediaLibraryDataManager::InterruptBgworker()
729 {
730     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
731     if (refCnt_.load() <= 0) {
732         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
733         return;
734     }
735 
736     if (thumbnailService_ == nullptr) {
737         return;
738     }
739     thumbnailService_->InterruptBgworker();
740     shared_ptr<TrashAsyncTaskWorker> asyncWorker = TrashAsyncTaskWorker::GetInstance();
741     if (asyncWorker == nullptr) {
742         MEDIA_ERR_LOG("asyncWorker null");
743         return;
744     }
745     asyncWorker->Interrupt();
746 }
747 
GenerateThumbnails()748 int32_t MediaLibraryDataManager::GenerateThumbnails()
749 {
750     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
751     if (refCnt_.load() <= 0) {
752         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
753         return E_FAIL;
754     }
755 
756     if (thumbnailService_ == nullptr) {
757         return E_THUMBNAIL_SERVICE_NULLPTR;
758     }
759     return thumbnailService_->GenerateThumbnails();
760 }
761 
CacheAging()762 static void CacheAging()
763 {
764     filesystem::path cacheDir(MEDIA_CACHE_DIR);
765     if (!filesystem::exists(cacheDir)) {
766         return;
767     }
768 
769     std::error_code errCode;
770     time_t now = time(nullptr);
771     constexpr int thresholdSeconds = 7 * 24 * 60 * 60; // 7 days
772     for (const auto& entry : filesystem::recursive_directory_iterator(cacheDir)) {
773         const char* filePath = entry.path().string().c_str();
774         if (!entry.is_regular_file()) {
775             MEDIA_WARN_LOG("skip %{private}s, not regular file", filePath);
776             continue;
777         }
778 
779         struct stat statInfo {};
780         if (stat(filePath, &statInfo) != 0) {
781             MEDIA_WARN_LOG("skip %{private}s when stat error, errno: %{public}d", filePath, errno);
782             continue;
783         }
784         time_t timeModified = statInfo.st_mtime;
785         double duration = difftime(now, timeModified); // diff in seconds
786         if (duration < thresholdSeconds) {
787             continue;
788         }
789 
790         if (!filesystem::remove(entry.path(), errCode)) {
791             MEDIA_WARN_LOG("Failed to remove %{private}s, errCode: %{public}d", filePath, errCode.value());
792         }
793     }
794 }
795 
DoAging()796 int32_t MediaLibraryDataManager::DoAging()
797 {
798     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
799     MEDIA_DEBUG_LOG("MediaLibraryDataManager::DoAging IN");
800     if (refCnt_.load() <= 0) {
801         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
802         return E_FAIL;
803     }
804 
805     CacheAging(); // aging file in .cache
806 
807     shared_ptr<TrashAsyncTaskWorker> asyncWorker = TrashAsyncTaskWorker::GetInstance();
808     if (asyncWorker == nullptr) {
809         MEDIA_ERR_LOG("asyncWorker null");
810         return E_FAIL;
811     }
812     asyncWorker->Init();
813     return E_OK;
814 }
815 
816 #ifdef DISTRIBUTED
LcdDistributeAging()817 int32_t MediaLibraryDataManager::LcdDistributeAging()
818 {
819     MEDIA_DEBUG_LOG("MediaLibraryDataManager::LcdDistributeAging IN");
820     auto deviceInstance = MediaLibraryDevice::GetInstance();
821     if ((thumbnailService_ == nullptr) || (deviceInstance == nullptr)) {
822         return E_THUMBNAIL_SERVICE_NULLPTR;
823     }
824     int32_t result = E_SUCCESS;
825     vector<string> deviceUdids;
826     deviceInstance->QueryAllDeviceUdid(deviceUdids);
827     for (string &udid : deviceUdids) {
828         result = thumbnailService_->LcdDistributeAging(udid);
829         if (result != E_SUCCESS) {
830             MEDIA_ERR_LOG("LcdDistributeAging fail result is %{public}d", result);
831             break;
832         }
833     }
834     return result;
835 }
836 
DistributeDeviceAging()837 int32_t MediaLibraryDataManager::DistributeDeviceAging()
838 {
839     MEDIA_DEBUG_LOG("MediaLibraryDataManager::DistributeDeviceAging IN");
840     auto deviceInstance = MediaLibraryDevice::GetInstance();
841     if ((thumbnailService_ == nullptr) || (deviceInstance == nullptr)) {
842         return E_FAIL;
843     }
844     int32_t result = E_FAIL;
845     vector<MediaLibraryDeviceInfo> deviceDataBaseList;
846     deviceInstance->QueryAgingDeviceInfos(deviceDataBaseList);
847     MEDIA_DEBUG_LOG("MediaLibraryDevice InitDeviceRdbStore deviceDataBaseList size =  %{public}d",
848         (int) deviceDataBaseList.size());
849     for (MediaLibraryDeviceInfo deviceInfo : deviceDataBaseList) {
850         result = thumbnailService_->InvalidateDistributeThumbnail(deviceInfo.deviceUdid);
851         if (result != E_SUCCESS) {
852             MEDIA_ERR_LOG("invalidate fail %{public}d", result);
853             continue;
854         }
855     }
856     return result;
857 }
858 #endif
859 
GetThumbnail(const string & uri)860 int MediaLibraryDataManager::GetThumbnail(const string &uri)
861 {
862     if (thumbnailService_ == nullptr) {
863         return E_THUMBNAIL_SERVICE_NULLPTR;
864     }
865     if (!uri.empty() && MediaLibraryObjectUtils::CheckUriPending(uri)) {
866         MEDIA_ERR_LOG("failed to get thumbnail, the file:%{private}s is pending", uri.c_str());
867         return E_FAIL;
868     }
869     return thumbnailService_->GetThumbnailFd(uri);
870 }
871 
CreateThumbnailAsync(const string & uri,const string & path)872 void MediaLibraryDataManager::CreateThumbnailAsync(const string &uri, const string &path)
873 {
874     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
875     if (refCnt_.load() <= 0) {
876         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
877         return;
878     }
879 
880     if (thumbnailService_ == nullptr) {
881         return;
882     }
883     if (!uri.empty()) {
884         if (MediaLibraryObjectUtils::CheckUriPending(uri)) {
885             MEDIA_ERR_LOG("failed to get thumbnail, the file:%{private}s is pending", uri.c_str());
886             return;
887         }
888         int32_t err = thumbnailService_->CreateThumbnail(uri, path);
889         if (err != E_SUCCESS) {
890             MEDIA_ERR_LOG("ThumbnailService CreateThumbnail failed : %{public}d", err);
891         }
892     }
893 }
894 
Query(MediaLibraryCommand & cmd,const vector<string> & columns,const DataSharePredicates & predicates,int & errCode)895 shared_ptr<ResultSetBridge> MediaLibraryDataManager::Query(MediaLibraryCommand &cmd,
896     const vector<string> &columns, const DataSharePredicates &predicates, int &errCode)
897 {
898     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
899     if (refCnt_.load() <= 0) {
900         errCode = E_FAIL;
901         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
902         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, errCode},
903             {KEY_OPT_TYPE, OptType::QUERY}};
904         PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
905         return nullptr;
906     }
907 
908     MediaLibraryTracer tracer;
909     tracer.Start("MediaLibraryDataManager::Query");
910     if (rdbStore_ == nullptr) {
911         errCode = E_FAIL;
912         MEDIA_ERR_LOG("Rdb Store is not initialized");
913         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, errCode},
914             {KEY_OPT_TYPE, OptType::QUERY}};
915         PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
916         return nullptr;
917     }
918 
919     auto absResultSet = QueryRdb(cmd, columns, predicates, errCode);
920     if (absResultSet == nullptr) {
921         errCode = (errCode != E_OK) ? errCode : E_FAIL;
922         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, errCode},
923             {KEY_OPT_TYPE, OptType::QUERY}};
924         PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
925         return nullptr;
926     }
927     return RdbUtils::ToResultSetBridge(absResultSet);
928 }
929 
930 #ifdef DISTRIBUTED
SyncPullThumbnailKeys(const Uri & uri)931 int32_t MediaLibraryDataManager::SyncPullThumbnailKeys(const Uri &uri)
932 {
933     if (MediaLibraryDevice::GetInstance() == nullptr || !MediaLibraryDevice::GetInstance()->IsHasActiveDevice()) {
934         return E_ERR;
935     }
936     if (kvStorePtr_ == nullptr) {
937         return E_ERR;
938     }
939 
940     MediaLibraryCommand cmd(uri, OperationType::QUERY);
941     cmd.GetAbsRdbPredicates()->BeginWrap()->EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, to_string(MEDIA_TYPE_IMAGE))
942         ->Or()->EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, to_string(MEDIA_TYPE_VIDEO))->EndWrap()
943         ->And()->EqualTo(MEDIA_DATA_DB_DATE_TRASHED, to_string(0))
944         ->And()->NotEqualTo(MEDIA_DATA_DB_MEDIA_TYPE, to_string(MEDIA_TYPE_ALBUM))
945         ->OrderByDesc(MEDIA_DATA_DB_DATE_ADDED);
946     vector<string> columns = { MEDIA_DATA_DB_THUMBNAIL, MEDIA_DATA_DB_LCD };
947     auto resultset = MediaLibraryFileOperations::QueryFileOperation(cmd, columns);
948     if (resultset == nullptr) {
949         return E_HAS_DB_ERROR;
950     }
951 
952     vector<string> thumbnailKeys;
953     int count = 0;
954     while (resultset->GoToNextRow() == NativeRdb::E_OK && count < MAX_QUERY_THUMBNAIL_KEY_COUNT) {
955         string thumbnailKey =
956             get<string>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_THUMBNAIL, resultset, TYPE_STRING));
957         thumbnailKeys.push_back(thumbnailKey);
958         string lcdKey = get<string>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_LCD, resultset, TYPE_STRING));
959         thumbnailKeys.push_back(lcdKey);
960         count++;
961     }
962 
963     if (thumbnailKeys.empty()) {
964         return E_NO_SUCH_FILE;
965     }
966     MediaLibrarySyncOperation::SyncPullKvstore(kvStorePtr_, thumbnailKeys,
967         MediaFileUtils::GetNetworkIdFromUri(uri.ToString()));
968     return E_SUCCESS;
969 }
970 #endif
971 
972 static const map<OperationObject, string> QUERY_CONDITION_MAP {
973     { OperationObject::SMART_ALBUM, SMARTALBUM_DB_ID },
974     { OperationObject::SMART_ALBUM_MAP, SMARTALBUMMAP_DB_ALBUM_ID },
975     { OperationObject::FILESYSTEM_DIR, MEDIA_DATA_DB_ID },
976     { OperationObject::ALL_DEVICE, "" },
977     { OperationObject::ACTIVE_DEVICE, "" },
978     { OperationObject::ASSETMAP, "" },
979     { OperationObject::SMART_ALBUM_ASSETS, "" },
980     { OperationObject::BUNDLE_PERMISSION, "" },
981 };
982 
CheckIsPortraitAlbum(MediaLibraryCommand & cmd)983 bool CheckIsPortraitAlbum(MediaLibraryCommand &cmd)
984 {
985     auto predicates = cmd.GetAbsRdbPredicates();
986     auto whereClause = predicates->GetWhereClause();
987     if (whereClause.find(USER_DISPLAY_LEVEL) != string::npos || whereClause.find(IS_ME) != string::npos) {
988         return true;
989     }
990     return false;
991 }
992 
AddVirtualColumnsOfDateType(vector<string> & columns)993 static void AddVirtualColumnsOfDateType(vector<string> &columns)
994 {
995     vector<string> dateTypes = { MEDIA_DATA_DB_DATE_ADDED, MEDIA_DATA_DB_DATE_TRASHED, MEDIA_DATA_DB_DATE_MODIFIED };
996     vector<string> dateTypeSeconds = { MEDIA_DATA_DB_DATE_ADDED_TO_SECOND,
997             MEDIA_DATA_DB_DATE_TRASHED_TO_SECOND, MEDIA_DATA_DB_DATE_MODIFIED_TO_SECOND };
998     for (size_t i = 0; i < dateTypes.size(); i++) {
999         auto it = find(columns.begin(), columns.end(), dateTypes[i]);
1000         if (it != columns.end()) {
1001             columns.push_back(dateTypeSeconds[i]);
1002         }
1003     }
1004 }
1005 
QuerySet(MediaLibraryCommand & cmd,const vector<string> & columns,const DataSharePredicates & predicates,int & errCode)1006 shared_ptr<NativeRdb::ResultSet> MediaLibraryDataManager::QuerySet(MediaLibraryCommand &cmd,
1007     const vector<string> &columns, const DataSharePredicates &predicates, int &errCode)
1008 {
1009     MediaLibraryTracer tracer;
1010     tracer.Start("QueryRdb");
1011     tracer.Start("CheckWhereClause");
1012     MEDIA_DEBUG_LOG("CheckWhereClause start %{public}s", cmd.GetUri().ToString().c_str());
1013     auto whereClause = predicates.GetWhereClause();
1014     if (!MediaLibraryCommonUtils::CheckWhereClause(whereClause)) {
1015         errCode = E_INVALID_VALUES;
1016         MEDIA_ERR_LOG("illegal query whereClause input %{private}s", whereClause.c_str());
1017         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, errCode},
1018             {KEY_OPT_TYPE, OptType::QUERY}};
1019         PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
1020         return nullptr;
1021     }
1022     MEDIA_DEBUG_LOG("CheckWhereClause end");
1023     tracer.Finish();
1024 
1025     cmd.SetDataSharePred(predicates);
1026     // MEDIALIBRARY_TABLE just for RdbPredicates
1027     NativeRdb::RdbPredicates rdbPredicate = RdbUtils::ToPredicates(predicates,
1028         MEDIALIBRARY_TABLE);
1029     cmd.GetAbsRdbPredicates()->SetWhereClause(rdbPredicate.GetWhereClause());
1030     cmd.GetAbsRdbPredicates()->SetWhereArgs(rdbPredicate.GetWhereArgs());
1031     cmd.GetAbsRdbPredicates()->SetOrder(rdbPredicate.GetOrder());
1032     AddVirtualColumnsOfDateType(const_cast<vector<string> &>(columns));
1033 
1034     shared_ptr<NativeRdb::ResultSet> queryResultSet;
1035     OperationObject oprnObject = cmd.GetOprnObject();
1036     auto it = QUERY_CONDITION_MAP.find(oprnObject);
1037     if (it != QUERY_CONDITION_MAP.end()) {
1038         queryResultSet = MediaLibraryObjectUtils::QueryWithCondition(cmd, columns, it->second);
1039     } else if (oprnObject == OperationObject::FILESYSTEM_ALBUM || oprnObject == OperationObject::MEDIA_VOLUME) {
1040         queryResultSet = MediaLibraryAlbumOperations::QueryAlbumOperation(cmd, columns);
1041     } else if (oprnObject == OperationObject::PHOTO_ALBUM) {
1042         queryResultSet = MediaLibraryAlbumOperations::QueryPhotoAlbum(cmd, columns);
1043     } else if (oprnObject == OperationObject::ANALYSIS_PHOTO_ALBUM && CheckIsPortraitAlbum(cmd)) {
1044         queryResultSet = MediaLibraryAlbumOperations::QueryPortraitAlbum(cmd, columns);
1045     } else if (oprnObject == OperationObject::PHOTO_MAP || oprnObject == OperationObject::ANALYSIS_PHOTO_MAP) {
1046         queryResultSet = PhotoMapOperations::QueryPhotoAssets(
1047             RdbUtils::ToPredicates(predicates, PhotoColumn::PHOTOS_TABLE), columns);
1048     } else if (oprnObject == OperationObject::FILESYSTEM_PHOTO || oprnObject == OperationObject::FILESYSTEM_AUDIO) {
1049         queryResultSet = MediaLibraryAssetOperations::QueryOperation(cmd, columns);
1050     } else if (oprnObject >= OperationObject::VISION_OCR && oprnObject <= OperationObject::ANALYSIS_PHOTO_ALBUM) {
1051         queryResultSet = MediaLibraryRdbStore::Query(RdbUtils::ToPredicates(predicates, cmd.GetTableName()), columns);
1052     } else if (oprnObject == OperationObject::SEARCH_TOTAL) {
1053         queryResultSet = MediaLibraryRdbStore::Query(RdbUtils::ToPredicates(predicates, cmd.GetTableName()), columns);
1054     } else {
1055         tracer.Start("QueryFile");
1056         queryResultSet = MediaLibraryFileOperations::QueryFileOperation(cmd, columns);
1057     }
1058     return queryResultSet;
1059 }
1060 
QueryRdb(MediaLibraryCommand & cmd,const vector<string> & columns,const DataSharePredicates & predicates,int & errCode)1061 shared_ptr<NativeRdb::ResultSet> MediaLibraryDataManager::QueryRdb(MediaLibraryCommand &cmd,
1062     const vector<string> &columns, const DataSharePredicates &predicates, int &errCode)
1063 {
1064     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
1065     if (refCnt_.load() <= 0) {
1066         errCode = E_FAIL;
1067         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, errCode},
1068             {KEY_OPT_TYPE, OptType::QUERY}};
1069         PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
1070         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
1071         return nullptr;
1072     }
1073 
1074     return QuerySet(cmd, columns, predicates, errCode);
1075 }
1076 
1077 #ifdef DISTRIBUTED
QuerySync(const string & networkId,const string & tableName)1078 bool MediaLibraryDataManager::QuerySync(const string &networkId, const string &tableName)
1079 {
1080     if (networkId.empty() || tableName.empty()) {
1081         return false;
1082     }
1083 
1084     OHOS::DistributedHardware::DmDeviceInfo deviceInfo;
1085     auto &deviceManager = OHOS::DistributedHardware::DeviceManager::GetInstance();
1086     auto ret = deviceManager.GetLocalDeviceInfo(bundleName_, deviceInfo);
1087     if (ret != ERR_OK) {
1088         MEDIA_ERR_LOG("MediaLibraryDataManager QuerySync Failed to get local device info.");
1089         return false;
1090     }
1091 
1092     if (networkId == string(deviceInfo.networkId)) {
1093         return true;
1094     }
1095 
1096     int32_t syncStatus = DEVICE_SYNCSTATUSING;
1097     auto result = MediaLibraryDevice::GetInstance()->GetDeviceSyncStatus(networkId, tableName, syncStatus);
1098     if (result && syncStatus == DEVICE_SYNCSTATUS_COMPLETE) {
1099         return true;
1100     }
1101 
1102     vector<string> devices = { networkId };
1103     MediaLibrarySyncOpts syncOpts;
1104     syncOpts.rdbStore = rdbStore_;
1105     syncOpts.table = tableName;
1106     syncOpts.bundleName = bundleName_;
1107     return MediaLibrarySyncOperation::SyncPullTable(syncOpts, devices);
1108 }
1109 #endif
1110 
OpenFile(MediaLibraryCommand & cmd,const string & mode)1111 int32_t MediaLibraryDataManager::OpenFile(MediaLibraryCommand &cmd, const string &mode)
1112 {
1113     MediaLibraryTracer tracer;
1114     tracer.Start("MediaLibraryDataManager::OpenFile");
1115     auto oprnObject = cmd.GetOprnObject();
1116     if (oprnObject == OperationObject::FILESYSTEM_PHOTO || oprnObject == OperationObject::FILESYSTEM_AUDIO) {
1117         return MediaLibraryAssetOperations::OpenOperation(cmd, mode);
1118     }
1119 
1120 #ifdef MEDIALIBRARY_COMPATIBILITY
1121     if (oprnObject != OperationObject::THUMBNAIL && oprnObject != OperationObject::THUMBNAIL_ASTC) {
1122         string opObject = MediaFileUri::GetPathFirstDentry(const_cast<Uri &>(cmd.GetUri()));
1123         if (opObject == IMAGE_ASSET_TYPE || opObject == VIDEO_ASSET_TYPE || opObject == URI_TYPE_PHOTO) {
1124             cmd.SetOprnObject(OperationObject::FILESYSTEM_PHOTO);
1125             return MediaLibraryAssetOperations::OpenOperation(cmd, mode);
1126         }
1127         if (opObject == AUDIO_ASSET_TYPE || opObject == URI_TYPE_AUDIO_V10) {
1128             cmd.SetOprnObject(OperationObject::FILESYSTEM_AUDIO);
1129             return MediaLibraryAssetOperations::OpenOperation(cmd, mode);
1130         }
1131     }
1132 #endif
1133 
1134     return MediaLibraryObjectUtils::OpenFile(cmd, mode);
1135 }
1136 
NotifyChange(const Uri & uri)1137 void MediaLibraryDataManager::NotifyChange(const Uri &uri)
1138 {
1139     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
1140     if (refCnt_.load() <= 0) {
1141         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
1142         return;
1143     }
1144 
1145     if (extension_ == nullptr) {
1146         MEDIA_ERR_LOG("MediaLibraryDataManager::NotifyChange failed");
1147         return;
1148     }
1149 
1150     extension_->NotifyChange(uri);
1151 }
1152 
InitialiseThumbnailService(const shared_ptr<OHOS::AbilityRuntime::Context> & extensionContext)1153 int32_t MediaLibraryDataManager::InitialiseThumbnailService(
1154     const shared_ptr<OHOS::AbilityRuntime::Context> &extensionContext)
1155 {
1156     if (thumbnailService_ != nullptr) {
1157         return E_OK;
1158     }
1159     thumbnailService_ = ThumbnailService::GetInstance();
1160     if (thumbnailService_ == nullptr) {
1161         return E_THUMBNAIL_SERVICE_NULLPTR;
1162     }
1163 #ifdef DISTRIBUTED
1164     thumbnailService_->Init(rdbStore_, kvStorePtr_, extensionContext);
1165 #else
1166     thumbnailService_->Init(rdbStore_,  extensionContext);
1167 #endif
1168     return E_OK;
1169 }
1170 
InitACLPermission()1171 void MediaLibraryDataManager::InitACLPermission()
1172 {
1173     if (access(THUMB_DIR.c_str(), F_OK) == 0) {
1174         return;
1175     }
1176 
1177     if (!MediaFileUtils::CreateDirectory(THUMB_DIR)) {
1178         MEDIA_ERR_LOG("Failed create thumbs Photo dir");
1179         return;
1180     }
1181 
1182     if (Acl::AclSetDefault() != E_OK) {
1183         MEDIA_ERR_LOG("Failed to set the acl read permission for the thumbs Photo dir");
1184     }
1185 }
1186 
OnScanFinished(const int32_t status,const string & uri,const string & path)1187 int32_t ScanFileCallback::OnScanFinished(const int32_t status, const string &uri, const string &path)
1188 {
1189     auto instance = MediaLibraryDataManager::GetInstance();
1190     if (instance != nullptr) {
1191         instance->CreateThumbnailAsync(uri, path);
1192     }
1193     return E_OK;
1194 }
1195 
SetCmdBundleAndDevice(MediaLibraryCommand & outCmd)1196 int32_t MediaLibraryDataManager::SetCmdBundleAndDevice(MediaLibraryCommand &outCmd)
1197 {
1198     string clientBundle = MediaLibraryBundleManager::GetInstance()->GetClientBundleName();
1199     if (clientBundle.empty()) {
1200         MEDIA_ERR_LOG("GetClientBundleName failed");
1201         return E_GET_CLIENTBUNDLE_FAIL;
1202     }
1203     outCmd.SetBundleName(clientBundle);
1204 #ifdef DISTRIBUTED
1205     OHOS::DistributedHardware::DmDeviceInfo deviceInfo;
1206     auto &deviceManager = OHOS::DistributedHardware::DeviceManager::GetInstance();
1207     int32_t ret = deviceManager.GetLocalDeviceInfo(bundleName_, deviceInfo);
1208     if (ret < 0) {
1209         MEDIA_ERR_LOG("GetLocalDeviceInfo ret = %{public}d", ret);
1210     } else {
1211         outCmd.SetDeviceName(deviceInfo.deviceName);
1212     }
1213     return ret;
1214 #endif
1215     return 0;
1216 }
1217 
DoTrashAging(shared_ptr<int> countPtr)1218 int32_t MediaLibraryDataManager::DoTrashAging(shared_ptr<int> countPtr)
1219 {
1220     shared_ptr<int> smartAlbumTrashPtr = make_shared<int>();
1221     MediaLibrarySmartAlbumMapOperations::HandleAgingOperation(smartAlbumTrashPtr);
1222 
1223     shared_ptr<int> albumTrashtPtr = make_shared<int>();
1224     MediaLibraryAlbumOperations::HandlePhotoAlbum(OperationType::AGING, {}, {}, albumTrashtPtr);
1225 
1226     shared_ptr<int> audioTrashtPtr = make_shared<int>();
1227     MediaLibraryAudioOperations::TrashAging(audioTrashtPtr);
1228 
1229     if (countPtr != nullptr) {
1230       *countPtr = *smartAlbumTrashPtr + *albumTrashtPtr + *audioTrashtPtr;
1231     }
1232     return E_SUCCESS;
1233 }
1234 
RevertPendingByFileId(const std::string & fileId)1235 int32_t MediaLibraryDataManager::RevertPendingByFileId(const std::string &fileId)
1236 {
1237     MediaLibraryCommand cmd(OperationObject::FILESYSTEM_ASSET, OperationType::UPDATE);
1238     ValuesBucket values;
1239     values.PutLong(Media::MEDIA_DATA_DB_TIME_PENDING, 0);
1240     cmd.SetValueBucket(values);
1241     int32_t retVal = MediaLibraryObjectUtils::ModifyInfoByIdInDb(cmd, fileId);
1242     if (retVal <= 0) {
1243         MEDIA_ERR_LOG("failed to revert pending error, fileId:%{private}s", fileId.c_str());
1244         return retVal;
1245     }
1246     auto fileAsset = MediaLibraryObjectUtils::GetFileAssetFromId(fileId);
1247     string srcPath = fileAsset->GetPath();
1248     MediaLibraryObjectUtils::ScanFileAsync(srcPath, fileId, MediaLibraryApi::API_10);
1249     return E_SUCCESS;
1250 }
1251 
RevertPendingByPackage(const std::string & bundleName)1252 int32_t MediaLibraryDataManager::RevertPendingByPackage(const std::string &bundleName)
1253 {
1254     MediaLibraryCommand queryCmd(OperationObject::FILESYSTEM_ASSET, OperationType::QUERY);
1255     queryCmd.GetAbsRdbPredicates()
1256         ->EqualTo(MEDIA_DATA_DB_OWNER_PACKAGE, bundleName)
1257         ->And()
1258         ->NotEqualTo(MEDIA_DATA_DB_TIME_PENDING, to_string(0));
1259     vector<string> columns = { MEDIA_DATA_DB_ID };
1260     auto result = MediaLibraryObjectUtils::QueryWithCondition(queryCmd, columns);
1261     if (result == nullptr) {
1262         return E_HAS_DB_ERROR;
1263     }
1264 
1265     int32_t ret = E_SUCCESS;
1266     while (result->GoToNextRow() == NativeRdb::E_OK) {
1267         int32_t id = GetInt32Val(MEDIA_DATA_DB_ID, result);
1268         int32_t retVal = RevertPendingByFileId(to_string(id));
1269         if (retVal != E_SUCCESS) {
1270             ret = retVal;
1271             MEDIA_ERR_LOG("Revert file %{public}d failed, ret=%{public}d", id, retVal);
1272             continue;
1273         }
1274     }
1275     return ret;
1276 }
1277 
1278 
GetAgingDataSize(const int64_t & time,int & count)1279 int32_t MediaLibraryDataManager::GetAgingDataSize(const int64_t &time, int &count)
1280 {
1281     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
1282     if (refCnt_.load() <= 0) {
1283         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
1284         return E_FAIL;
1285     }
1286 
1287     if (thumbnailService_ == nullptr) {
1288         return E_THUMBNAIL_SERVICE_NULLPTR;
1289     }
1290     return thumbnailService_->GetAgingDataSize(time, count);
1291 }
1292 
1293 
QueryNewThumbnailCount(const int64_t & time,int & count)1294 int32_t MediaLibraryDataManager::QueryNewThumbnailCount(const int64_t &time, int &count)
1295 {
1296     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
1297     if (refCnt_.load() <= 0) {
1298         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
1299         return E_FAIL;
1300     }
1301 
1302     if (thumbnailService_ == nullptr) {
1303         return E_THUMBNAIL_SERVICE_NULLPTR;
1304     }
1305     return thumbnailService_->QueryNewThumbnailCount(time, count);
1306 }
1307 
1308 class DownloadCloudFilesData : public AsyncTaskData {
1309 public:
1310     DownloadCloudFilesData() = default;
1311     ~DownloadCloudFilesData() override = default;
1312 
1313     vector<string> paths;
1314 };
1315 
DownloadCloudFilesExecutor(AsyncTaskData * data)1316 static void DownloadCloudFilesExecutor(AsyncTaskData* data)
1317 {
1318     auto *taskData = static_cast<DownloadCloudFilesData *>(data);
1319 
1320     MEDIA_DEBUG_LOG("Try to download %{public}zu cloud files.", taskData->paths.size());
1321     for (const auto &path : taskData->paths) {
1322         CloudSyncHelper::GetInstance()->StartDownloadFile(path);
1323     }
1324 }
1325 
AddDownloadTask(const vector<string> & photoPaths)1326 static int32_t AddDownloadTask(const vector<string> &photoPaths)
1327 {
1328     auto asyncWorker = MediaLibraryAsyncWorker::GetInstance();
1329     if (asyncWorker == nullptr) {
1330         MEDIA_ERR_LOG("Failed to get async worker instance!");
1331         return E_FAIL;
1332     }
1333     auto *taskData = new (nothrow)DownloadCloudFilesData();
1334     if (taskData == nullptr) {
1335         MEDIA_ERR_LOG("Failed to alloc async data for downloading cloud files!");
1336         return E_NO_MEMORY;
1337     }
1338     taskData->paths = photoPaths;
1339     auto asyncTask = make_shared<MediaLibraryAsyncTask>(DownloadCloudFilesExecutor, taskData);
1340     asyncWorker->AddTask(asyncTask, false);
1341     return E_OK;
1342 }
1343 
QueryCloudFiles()1344 static shared_ptr<NativeRdb::ResultSet> QueryCloudFiles()
1345 {
1346     const vector<string> photosType = {
1347         to_string(MEDIA_TYPE_IMAGE),
1348         to_string(MEDIA_TYPE_VIDEO)
1349     };
1350     const vector<string> columns = {
1351         PhotoColumn::MEDIA_FILE_PATH
1352     };
1353 
1354     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
1355     predicates.EqualTo(PhotoColumn::PHOTO_POSITION, to_string(POSITION_CLOUD));
1356     predicates.In(PhotoColumn::MEDIA_TYPE, photosType);
1357     predicates.Limit(DOWNLOAD_BATCH_SIZE);
1358     return MediaLibraryRdbStore::Query(predicates, columns);
1359 }
1360 
FillPhotoPaths(shared_ptr<NativeRdb::ResultSet> & resultSet,vector<string> & photoPaths)1361 static void FillPhotoPaths(shared_ptr<NativeRdb::ResultSet> &resultSet, vector<string> &photoPaths)
1362 {
1363     string path;
1364     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
1365         path = get<string>(ResultSetUtils::GetValFromColumn(PhotoColumn::MEDIA_FILE_PATH, resultSet, TYPE_STRING));
1366         if (path.empty()) {
1367             MEDIA_WARN_LOG("Failed to get cloud file uri!");
1368             continue;
1369         }
1370         photoPaths.push_back(path);
1371     }
1372 }
1373 
NeedDownloadCloudFiles()1374 static bool NeedDownloadCloudFiles()
1375 {
1376     const vector<string> localPositions = {
1377         to_string(POSITION_LOCAL),
1378         to_string((POSITION_LOCAL | POSITION_CLOUD)),
1379     };
1380     const vector<string> photosType = {
1381         to_string(MEDIA_TYPE_IMAGE),
1382         to_string(MEDIA_TYPE_VIDEO)
1383     };
1384     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
1385     predicates.In(PhotoColumn::PHOTO_POSITION, localPositions);
1386     predicates.In(PhotoColumn::MEDIA_TYPE, photosType);
1387     auto resultSet = MediaLibraryRdbStore::Query(predicates, { PhotoColumn::MEDIA_ID });
1388     if (resultSet == nullptr) {
1389         MEDIA_ERR_LOG("Failed to query local files!");
1390         return false;
1391     }
1392     int32_t count = 0;
1393     int32_t err = resultSet->GetRowCount(count);
1394     if (err != NativeRdb::E_OK) {
1395         MEDIA_ERR_LOG("Failed to get count, err: %{public}d", err);
1396         return false;
1397     }
1398     return count <= LOCAL_FILES_COUNT_THRESHOLD;
1399 }
1400 
DownloadCloudFiles()1401 static void DownloadCloudFiles()
1402 {
1403     if (!NeedDownloadCloudFiles()) {
1404         return;
1405     }
1406     vector<string> photoPaths;
1407     auto resultSet = QueryCloudFiles();
1408     if (resultSet == nullptr) {
1409         MEDIA_ERR_LOG("Failed to query cloud files!");
1410         return;
1411     }
1412     FillPhotoPaths(resultSet, photoPaths);
1413     if (photoPaths.empty()) {
1414         MEDIA_DEBUG_LOG("No cloud photos exist, no need to download");
1415         return;
1416     }
1417     int32_t err = AddDownloadTask(photoPaths);
1418     if (err) {
1419         MEDIA_WARN_LOG("Failed to add download task! err: %{public}d", err);
1420     }
1421 }
1422 
RegisterTimer()1423 void MediaLibraryDataManager::RegisterTimer()
1424 {
1425     UnregisterTimer();
1426     timerId_ = timer_.Register(DownloadCloudFiles, BATCH_DOWNLOAD_INTERVAL);
1427     timer_.Setup();
1428 }
1429 
StopTimer()1430 void MediaLibraryDataManager::StopTimer()
1431 {
1432     timer_.Shutdown();
1433 }
1434 
UnregisterTimer()1435 void MediaLibraryDataManager::UnregisterTimer()
1436 {
1437     timer_.Shutdown();
1438     timer_.Unregister(timerId_);
1439 }
1440 }  // namespace Media
1441 }  // namespace OHOS
1442