1 /*
2  * Copyright (C) 2021-2024 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 <cstdlib>
21 #include <shared_mutex>
22 #include <unordered_set>
23 #include <sstream>
24 
25 #include "ability_scheduler_interface.h"
26 #include "abs_rdb_predicates.h"
27 #include "acl.h"
28 #include "background_cloud_file_processor.h"
29 #include "background_task_mgr_helper.h"
30 #include "cloud_media_asset_manager.h"
31 #include "cloud_sync_switch_observer.h"
32 #include "datashare_abs_result_set.h"
33 #ifdef DISTRIBUTED
34 #include "device_manager.h"
35 #include "device_manager_callback.h"
36 #endif
37 #include "dfx_manager.h"
38 #include "dfx_reporter.h"
39 #include "dfx_utils.h"
40 #include "directory_ex.h"
41 #include "efficiency_resource_info.h"
42 #include "hitrace_meter.h"
43 #include "ipc_skeleton.h"
44 #include "media_column.h"
45 #include "media_datashare_ext_ability.h"
46 #include "media_directory_type_column.h"
47 #include "media_file_utils.h"
48 #include "media_log.h"
49 #include "media_old_photos_column.h"
50 #include "media_scanner_manager.h"
51 #include "media_smart_album_column.h"
52 #include "media_smart_map_column.h"
53 #include "medialibrary_album_operations.h"
54 #include "medialibrary_analysis_album_operations.h"
55 #include "medialibrary_asset_operations.h"
56 #include "medialibrary_app_uri_permission_operations.h"
57 #include "medialibrary_app_uri_sensitive_operations.h"
58 #include "medialibrary_async_worker.h"
59 #include "medialibrary_audio_operations.h"
60 #include "medialibrary_bundle_manager.h"
61 #include "medialibrary_common_utils.h"
62 #ifdef DISTRIBUTED
63 #include "medialibrary_device.h"
64 #include "medialibrary_device_info.h"
65 #endif
66 #include "medialibrary_dir_operations.h"
67 #include "medialibrary_errno.h"
68 #include "medialibrary_file_operations.h"
69 #include "medialibrary_inotify.h"
70 #include "medialibrary_kvstore_manager.h"
71 #include "medialibrary_location_operations.h"
72 #include "medialibrary_object_utils.h"
73 #include "medialibrary_rdb_utils.h"
74 #include "medialibrary_rdbstore.h"
75 #include "medialibrary_restore.h"
76 #include "medialibrary_smartalbum_map_operations.h"
77 #include "medialibrary_smartalbum_operations.h"
78 #include "medialibrary_story_operations.h"
79 #include "medialibrary_subscriber.h"
80 #include "medialibrary_sync_operation.h"
81 #include "medialibrary_tab_old_photos_operations.h"
82 #include "medialibrary_tracer.h"
83 #include "medialibrary_unistore_manager.h"
84 #include "medialibrary_uripermission_operations.h"
85 #include "medialibrary_urisensitive_operations.h"
86 #include "medialibrary_vision_operations.h"
87 #include "medialibrary_search_operations.h"
88 #include "mimetype_utils.h"
89 #include "multistages_capture_manager.h"
90 #include "enhancement_manager.h"
91 #include "permission_utils.h"
92 #include "photo_album_column.h"
93 #include "photo_day_month_year_operation.h"
94 #include "photo_map_operations.h"
95 #include "resource_type.h"
96 #include "rdb_store.h"
97 #include "rdb_utils.h"
98 #include "result_set_utils.h"
99 #include "system_ability_definition.h"
100 #include "timer.h"
101 #include "trash_async_worker.h"
102 #include "value_object.h"
103 #include "post_event_utils.h"
104 #include "medialibrary_formmap_operations.h"
105 #include "ithumbnail_helper.h"
106 #include "vision_face_tag_column.h"
107 #include "vision_photo_map_column.h"
108 #include "parameter.h"
109 #include "uuid.h"
110 #include "parameters.h"
111 #ifdef DEVICE_STANDBY_ENABLE
112 #include "medialibrary_standby_service_subscriber.h"
113 #endif
114 
115 using namespace std;
116 using namespace OHOS::AppExecFwk;
117 using namespace OHOS::AbilityRuntime;
118 using namespace OHOS::NativeRdb;
119 using namespace OHOS::DistributedKv;
120 using namespace OHOS::DataShare;
121 using namespace OHOS::RdbDataShareAdapter;
122 
123 namespace {
124 const OHOS::DistributedKv::AppId KVSTORE_APPID = {"com.ohos.medialibrary.medialibrarydata"};
125 const OHOS::DistributedKv::StoreId KVSTORE_STOREID = {"medialibrary_thumbnail"};
126 };
127 
128 namespace OHOS {
129 namespace Media {
130 unique_ptr<MediaLibraryDataManager> MediaLibraryDataManager::instance_ = nullptr;
131 unordered_map<string, DirAsset> MediaLibraryDataManager::dirQuerySetMap_ = {};
132 mutex MediaLibraryDataManager::mutex_;
133 static const int32_t UUID_STR_LENGTH = 37;
134 const int32_t WRONG_VALUE = 0;
135 const int32_t BATCH_QUERY_NUMBER = 200;
136 
137 #ifdef DEVICE_STANDBY_ENABLE
138 static const std::string SUBSCRIBER_NAME = "POWER_USAGE";
139 static const std::string MODULE_NAME = "com.ohos.medialibrary.medialibrarydata";
140 #endif
141 #ifdef DISTRIBUTED
142 static constexpr int MAX_QUERY_THUMBNAIL_KEY_COUNT = 20;
143 #endif
MediaLibraryDataManager(void)144 MediaLibraryDataManager::MediaLibraryDataManager(void)
145 {
146 }
147 
~MediaLibraryDataManager(void)148 MediaLibraryDataManager::~MediaLibraryDataManager(void)
149 {
150 #ifdef DISTRIBUTED
151     if (kvStorePtr_ != nullptr) {
152         dataManager_.CloseKvStore(KVSTORE_APPID, kvStorePtr_);
153         kvStorePtr_ = nullptr;
154     }
155 #endif
156 }
157 
GetInstance()158 MediaLibraryDataManager* MediaLibraryDataManager::GetInstance()
159 {
160     if (instance_ == nullptr) {
161         lock_guard<mutex> lock(mutex_);
162         if (instance_ == nullptr) {
163             instance_ = make_unique<MediaLibraryDataManager>();
164         }
165     }
166     return instance_.get();
167 }
168 
MediaDataShareCreator(const unique_ptr<Runtime> & runtime)169 static DataShare::DataShareExtAbility *MediaDataShareCreator(const unique_ptr<Runtime> &runtime)
170 {
171     MEDIA_INFO_LOG("MediaLibraryCreator::%{public}s", __func__);
172     return  MediaDataShareExtAbility::Create(runtime);
173 }
174 
RegisterDataShareCreator()175 __attribute__((constructor)) void RegisterDataShareCreator()
176 {
177     MEDIA_INFO_LOG("MediaLibraryDataManager::%{public}s", __func__);
178     DataShare::DataShareExtAbility::SetCreator(MediaDataShareCreator);
179     MEDIA_INFO_LOG("MediaLibraryDataManager::%{public}s End", __func__);
180 }
181 
MakeRootDirs(AsyncTaskData * data)182 static void MakeRootDirs(AsyncTaskData *data)
183 {
184     const unordered_set<string> DIR_CHECK_SET = { ROOT_MEDIA_DIR + BACKUP_DATA_DIR_VALUE,
185         ROOT_MEDIA_DIR + BACKUP_SINGLE_DATA_DIR_VALUE };
186     for (auto &dir : PRESET_ROOT_DIRS) {
187         Uri createAlbumUri(MEDIALIBRARY_DATA_URI + "/" + MEDIA_ALBUMOPRN + "/" + MEDIA_ALBUMOPRN_CREATEALBUM);
188         ValuesBucket valuesBucket;
189         valuesBucket.PutString(MEDIA_DATA_DB_FILE_PATH, ROOT_MEDIA_DIR + dir);
190         MediaLibraryCommand cmd(createAlbumUri, valuesBucket);
191         auto ret = MediaLibraryAlbumOperations::CreateAlbumOperation(cmd);
192         if (ret == E_FILE_EXIST) {
193             MEDIA_INFO_LOG("Root dir: %{private}s is exist", dir.c_str());
194         } else if (ret <= 0) {
195             MEDIA_ERR_LOG("Failed to preset root dir: %{private}s", dir.c_str());
196         }
197         MediaFileUtils::CheckDirStatus(DIR_CHECK_SET, ROOT_MEDIA_DIR + dir);
198     }
199     if (data->dataDisplay.compare(E_POLICY) == 0 && !PermissionUtils::SetEPolicy()) {
200         MEDIA_ERR_LOG("Failed to SetEPolicy fail");
201     }
202     MediaFileUtils::MediaFileDeletionRecord();
203     // recover temp dir
204     MediaFileUtils::RecoverMediaTempDir();
205 }
206 
ReCreateMediaDir()207 void MediaLibraryDataManager::ReCreateMediaDir()
208 {
209     MediaFileUtils::BackupPhotoDir();
210     // delete E policy dir
211     for (const string &dir : E_POLICY_DIRS) {
212         if (!MediaFileUtils::DeleteDir(dir)) {
213             MEDIA_ERR_LOG("Delete dir fail, dir: %{public}s", DfxUtils::GetSafePath(dir).c_str());
214         }
215     }
216     // create C policy dir
217     InitACLPermission();
218     shared_ptr<MediaLibraryAsyncWorker> asyncWorker = MediaLibraryAsyncWorker::GetInstance();
219     if (asyncWorker == nullptr) {
220         MEDIA_ERR_LOG("Can not get asyncWorker");
221         return;
222     }
223     AsyncTaskData* taskData = new (std::nothrow) AsyncTaskData();
224     if (taskData == nullptr) {
225         MEDIA_ERR_LOG("Failed to new taskData");
226         return;
227     }
228     shared_ptr<MediaLibraryAsyncTask> makeRootDirTask = make_shared<MediaLibraryAsyncTask>(MakeRootDirs, taskData);
229     if (makeRootDirTask != nullptr) {
230         asyncWorker->AddTask(makeRootDirTask, true);
231     } else {
232         MEDIA_WARN_LOG("Can not init make root dir task");
233     }
234 }
235 
ReconstructMediaLibraryPhotoMap()236 static int32_t ReconstructMediaLibraryPhotoMap()
237 {
238     if (system::GetParameter("persist.multimedia.medialibrary.albumFusion.status", "1") == "1") {
239         return E_OK;
240     }
241     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
242     if (rdbStore == nullptr) {
243         MEDIA_ERR_LOG("Failed to get rdbstore, try again!");
244         rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
245         if (rdbStore == nullptr) {
246             MEDIA_ERR_LOG("Fatal error! Failed to get rdbstore, new cloud data is not processed!!");
247             return E_DB_FAIL;
248         }
249     }
250     MediaLibraryRdbStore::ReconstructMediaLibraryStorageFormat(rdbStore);
251     return E_OK;
252 }
253 
HandleOtherInitOperations()254 void MediaLibraryDataManager::HandleOtherInitOperations()
255 {
256     InitRefreshAlbum();
257     UriPermissionOperations::DeleteAllTemporaryAsync();
258     UriSensitiveOperations::DeleteAllSensitiveAsync();
259 }
260 
ExcuteAsyncWork()261 static int32_t ExcuteAsyncWork()
262 {
263     shared_ptr<MediaLibraryAsyncWorker> asyncWorker = MediaLibraryAsyncWorker::GetInstance();
264     if (asyncWorker == nullptr) {
265         MEDIA_ERR_LOG("Can not get asyncWorker");
266         return E_ERR;
267     }
268     AsyncTaskData* taskData = new (std::nothrow) AsyncTaskData();
269     if (taskData == nullptr) {
270         MEDIA_ERR_LOG("Failed to new taskData");
271         return E_ERR;
272     }
273     taskData->dataDisplay = E_POLICY;
274     shared_ptr<MediaLibraryAsyncTask> makeRootDirTask = make_shared<MediaLibraryAsyncTask>(MakeRootDirs, taskData);
275     if (makeRootDirTask != nullptr) {
276         asyncWorker->AddTask(makeRootDirTask, true);
277     } else {
278         MEDIA_WARN_LOG("Can not init make root dir task");
279     }
280     return E_OK;
281 }
282 
InitMediaLibraryMgr(const shared_ptr<OHOS::AbilityRuntime::Context> & context,const shared_ptr<OHOS::AbilityRuntime::Context> & extensionContext,int32_t & sceneCode)283 __attribute__((no_sanitize("cfi"))) int32_t MediaLibraryDataManager::InitMediaLibraryMgr(
284     const shared_ptr<OHOS::AbilityRuntime::Context> &context,
285     const shared_ptr<OHOS::AbilityRuntime::Context> &extensionContext, int32_t &sceneCode)
286 {
287     lock_guard<shared_mutex> lock(mgrSharedMutex_);
288 
289     if (refCnt_.load() > 0) {
290         MEDIA_DEBUG_LOG("already initialized");
291         refCnt_++;
292         return E_OK;
293     }
294 
295     InitResourceInfo();
296     context_ = context;
297     int32_t errCode = InitMediaLibraryRdbStore();
298     if (errCode != E_OK) {
299         sceneCode = DfxType::START_RDB_STORE_FAIL;
300         return errCode;
301     }
302     if (!MediaLibraryKvStoreManager::GetInstance().InitMonthAndYearKvStore(KvStoreRoleType::OWNER)) {
303         MEDIA_ERR_LOG("failed at InitMonthAndYearKvStore");
304     }
305 #ifdef DISTRIBUTED
306     errCode = InitDeviceData();
307     CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "failed at InitDeviceData");
308 #endif
309     MimeTypeUtils::InitMimeTypeMap();
310     errCode = MakeDirQuerySetMap(dirQuerySetMap_);
311     CHECK_AND_WARN_LOG(errCode == E_OK, "failed at MakeDirQuerySetMap");
312     InitACLPermission();
313     InitDatabaseACLPermission();
314     errCode = ExcuteAsyncWork();
315     CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "failed at ExcuteAsyncWork");
316     errCode = InitialiseThumbnailService(extensionContext);
317     CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "failed at InitialiseThumbnailService");
318     ReconstructMediaLibraryPhotoMap();
319     HandleOtherInitOperations();
320 
321     auto shareHelper = MediaLibraryHelperContainer::GetInstance()->GetDataShareHelper();
322     cloudPhotoObserver_ = std::make_shared<CloudSyncObserver>();
323     cloudPhotoAlbumObserver_ = std::make_shared<CloudSyncObserver>();
324     shareHelper->RegisterObserverExt(Uri(PhotoColumn::PHOTO_CLOUD_URI_PREFIX), cloudPhotoObserver_, true);
325     shareHelper->RegisterObserverExt(Uri(PhotoAlbumColumns::ALBUM_CLOUD_URI_PREFIX), cloudPhotoAlbumObserver_, true);
326     HandleUpgradeRdbAsync();
327     CloudSyncSwitchManager cloudSyncSwitchManager;
328     cloudSyncSwitchManager.RegisterObserver();
329     SubscriberPowerConsumptionDetection();
330 
331     refCnt_++;
332     return E_OK;
333 }
334 
HandleUpgradeRdbAsyncExtension(const shared_ptr<MediaLibraryRdbStore> rdbStore,int32_t oldVersion)335 void HandleUpgradeRdbAsyncExtension(const shared_ptr<MediaLibraryRdbStore> rdbStore, int32_t oldVersion)
336 {
337     if (oldVersion < VERSION_ADD_READY_COUNT_INDEX) {
338         MediaLibraryRdbStore::AddReadyCountIndex(rdbStore);
339         rdbStore->SetOldVersion(VERSION_ADD_READY_COUNT_INDEX);
340     }
341 
342     if (oldVersion < VERSION_REVERT_FIX_DATE_ADDED_INDEX) {
343         MediaLibraryRdbStore::RevertFixDateAddedIndex(rdbStore);
344         rdbStore->SetOldVersion(VERSION_REVERT_FIX_DATE_ADDED_INDEX);
345     }
346 
347     if (oldVersion < VERSION_FIX_PICTURE_LCD_SIZE) {
348         MediaLibraryRdbStore::UpdateLcdStatusNotUploaded(rdbStore);
349         rdbStore->SetOldVersion(VERSION_FIX_PICTURE_LCD_SIZE);
350     }
351 
352     if (oldVersion < VERSION_UPDATE_PHOTOS_DATE_AND_IDX) {
353         PhotoDayMonthYearOperation::UpdatePhotosDateAndIdx(rdbStore);
354         rdbStore->SetOldVersion(VERSION_UPDATE_PHOTOS_DATE_AND_IDX);
355     }
356 }
357 
HandleUpgradeRdbAsync()358 void MediaLibraryDataManager::HandleUpgradeRdbAsync()
359 {
360     std::thread([&] {
361         auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
362         if (rdbStore == nullptr) {
363             MEDIA_ERR_LOG("rdbStore is nullptr!");
364             return;
365         }
366         int32_t oldVersion = rdbStore->GetOldVersion();
367         if (oldVersion == -1 || oldVersion >= MEDIA_RDB_VERSION) {
368             MEDIA_INFO_LOG("No need to upgrade rdb, oldVersion: %{public}d", oldVersion);
369             return;
370         }
371         MEDIA_INFO_LOG("oldVersion:%{public}d", oldVersion);
372         // compare older version, update and set old version
373         if (oldVersion < VERSION_CREATE_BURSTKEY_INDEX) {
374             MediaLibraryRdbStore::CreateBurstIndex(rdbStore);
375             rdbStore->SetOldVersion(VERSION_CREATE_BURSTKEY_INDEX);
376         }
377 
378         if (oldVersion < VERSION_UPDATE_BURST_DIRTY) {
379             MediaLibraryRdbStore::UpdateBurstDirty(rdbStore);
380             rdbStore->SetOldVersion(VERSION_UPDATE_BURST_DIRTY);
381         }
382 
383         if (oldVersion < VERSION_UPGRADE_THUMBNAIL) {
384             MediaLibraryRdbStore::UpdateReadyOnThumbnailUpgrade(rdbStore);
385             rdbStore->SetOldVersion(VERSION_UPGRADE_THUMBNAIL);
386         }
387 
388         if (oldVersion < VERSION_MOVE_AUDIOS) {
389             MediaLibraryAudioOperations::MoveToMusic();
390             MediaLibraryRdbStore::ClearAudios(rdbStore);
391             rdbStore->SetOldVersion(VERSION_MOVE_AUDIOS);
392         }
393 
394         if (oldVersion < VERSION_ADD_DETAIL_TIME) {
395             MediaLibraryRdbStore::UpdateDateTakenToMillionSecond(rdbStore);
396             MediaLibraryRdbStore::UpdateDateTakenIndex(rdbStore);
397             ThumbnailService::GetInstance()->AstcChangeKeyFromDateAddedToDateTaken();
398             rdbStore->SetOldVersion(VERSION_ADD_DETAIL_TIME);
399         }
400         if (oldVersion < VERSION_UPDATE_DATETAKEN_AND_DETAILTIME) {
401             MediaLibraryRdbStore::UpdateDateTakenAndDetalTime(rdbStore);
402             rdbStore->SetOldVersion(VERSION_UPDATE_DATETAKEN_AND_DETAILTIME);
403         }
404 
405         HandleUpgradeRdbAsyncExtension(rdbStore, oldVersion);
406         // !! Do not add upgrade code here !!
407 
408         rdbStore->SetOldVersion(MEDIA_RDB_VERSION);
409     }).detach();
410 }
411 
InitResourceInfo()412 void MediaLibraryDataManager::InitResourceInfo()
413 {
414     BackgroundTaskMgr::EfficiencyResourceInfo resourceInfo =
415         BackgroundTaskMgr::EfficiencyResourceInfo(BackgroundTaskMgr::ResourceType::CPU, true, 0, "apply", true, true);
416     BackgroundTaskMgr::BackgroundTaskMgrHelper::ApplyEfficiencyResources(resourceInfo);
417 }
418 
419 #ifdef DISTRIBUTED
InitDeviceData()420 int32_t MediaLibraryDataManager::InitDeviceData()
421 {
422     if (rdbStore_ == nullptr) {
423         MEDIA_ERR_LOG("MediaLibraryDataManager InitDeviceData rdbStore is null");
424         return E_ERR;
425     }
426 
427     MediaLibraryTracer tracer;
428     tracer.Start("InitDeviceRdbStoreTrace");
429     if (!MediaLibraryDevice::GetInstance()->InitDeviceRdbStore(rdbStore_)) {
430         MEDIA_ERR_LOG("MediaLibraryDataManager InitDeviceData failed!");
431         return E_ERR;
432     }
433     return E_OK;
434 }
435 #endif
436 
ClearMediaLibraryMgr()437 __attribute__((no_sanitize("cfi"))) void MediaLibraryDataManager::ClearMediaLibraryMgr()
438 {
439     lock_guard<shared_mutex> lock(mgrSharedMutex_);
440 
441     refCnt_--;
442     if (refCnt_.load() > 0) {
443         MEDIA_DEBUG_LOG("still other extension exist");
444         return;
445     }
446 
447     BackgroundCloudFileProcessor::StopTimer();
448 
449     auto shareHelper = MediaLibraryHelperContainer::GetInstance()->GetDataShareHelper();
450     if (shareHelper == nullptr) {
451         MEDIA_ERR_LOG("DataShareHelper is null");
452         return;
453     }
454     shareHelper->UnregisterObserverExt(Uri(PhotoColumn::PHOTO_CLOUD_URI_PREFIX), cloudPhotoObserver_);
455     shareHelper->UnregisterObserverExt(Uri(PhotoAlbumColumns::ALBUM_CLOUD_URI_PREFIX), cloudPhotoAlbumObserver_);
456     rdbStore_ = nullptr;
457     MediaLibraryKvStoreManager::GetInstance().CloseAllKvStore();
458     MEDIA_INFO_LOG("CloseKvStore success");
459 
460 #ifdef DISTRIBUTED
461     if (kvStorePtr_ != nullptr) {
462         dataManager_.CloseKvStore(KVSTORE_APPID, kvStorePtr_);
463         kvStorePtr_ = nullptr;
464     }
465 
466     if (MediaLibraryDevice::GetInstance()) {
467         MediaLibraryDevice::GetInstance()->Stop();
468     };
469 #endif
470 
471     if (thumbnailService_ != nullptr) {
472         thumbnailService_->ReleaseService();
473         thumbnailService_ = nullptr;
474     }
475     auto watch = MediaLibraryInotify::GetInstance();
476     if (watch != nullptr) {
477         watch->DoStop();
478     }
479     MediaLibraryUnistoreManager::GetInstance().Stop();
480     extension_ = nullptr;
481 }
482 
InitMediaLibraryRdbStore()483 int32_t MediaLibraryDataManager::InitMediaLibraryRdbStore()
484 {
485     if (rdbStore_) {
486         return E_OK;
487     }
488 
489     int32_t ret = MediaLibraryUnistoreManager::GetInstance().Init(context_);
490     if (ret != E_OK) {
491         MEDIA_ERR_LOG("init MediaLibraryUnistoreManager failed");
492         return ret;
493     }
494     rdbStore_ = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
495     if (ret != E_OK) {
496         MEDIA_ERR_LOG("rdbStore is nullptr");
497         return E_ERR;
498     }
499 
500     return E_OK;
501 }
502 
InitRefreshAlbum()503 void MediaLibraryDataManager::InitRefreshAlbum()
504 {
505     bool isNeedRefresh = false;
506     int32_t ret = MediaLibraryRdbUtils::IsNeedRefreshByCheckTable(rdbStore_, isNeedRefresh);
507     if (ret != E_OK || isNeedRefresh) {
508         // Only set flag here, should not do any task in InitDataMgr
509         MediaLibraryRdbUtils::SetNeedRefreshAlbum(true);
510     }
511 }
512 
GetOwner()513 shared_ptr<MediaDataShareExtAbility> MediaLibraryDataManager::GetOwner()
514 {
515     return extension_;
516 }
517 
SetOwner(const shared_ptr<MediaDataShareExtAbility> & datashareExternsion)518 void MediaLibraryDataManager::SetOwner(const shared_ptr<MediaDataShareExtAbility> &datashareExternsion)
519 {
520     extension_ = datashareExternsion;
521 }
522 
GetType(const Uri & uri)523 string MediaLibraryDataManager::GetType(const Uri &uri)
524 {
525     MEDIA_DEBUG_LOG("MediaLibraryDataManager::GetType");
526     MediaLibraryCommand cmd(uri);
527     switch (cmd.GetOprnObject()) {
528         case OperationObject::CLOUD_MEDIA_ASSET_OPERATE:
529             return CloudMediaAssetManager::GetInstance().HandleCloudMediaAssetGetTypeOperations(cmd);
530         default:
531             break;
532     }
533 
534     MEDIA_INFO_LOG("GetType uri: %{private}s", uri.ToString().c_str());
535     return "";
536 }
537 
MakeDirQuerySetMap(unordered_map<string,DirAsset> & outDirQuerySetMap)538 int32_t MediaLibraryDataManager::MakeDirQuerySetMap(unordered_map<string, DirAsset> &outDirQuerySetMap)
539 {
540     int32_t count = -1;
541     vector<string> columns;
542     AbsRdbPredicates dirAbsPred(MEDIATYPE_DIRECTORY_TABLE);
543     if (rdbStore_ == nullptr) {
544         MEDIA_ERR_LOG("rdbStore_ is nullptr");
545         return E_ERR;
546     }
547     auto queryResultSet = rdbStore_->QueryByStep(dirAbsPred, columns);
548     if (queryResultSet == nullptr) {
549         MEDIA_ERR_LOG("queryResultSet is nullptr");
550         return E_ERR;
551     }
552     auto ret = queryResultSet->GetRowCount(count);
553     if (ret != NativeRdb::E_OK) {
554         MEDIA_ERR_LOG("rdb failed");
555         return E_ERR;
556     }
557     MEDIA_INFO_LOG("MakeDirQuerySetMap count = %{public}d", count);
558     if (count == 0) {
559         MEDIA_ERR_LOG("can not find any dirAsset");
560         return E_ERR;
561     }
562     DirAsset dirAsset;
563     string dirVal;
564     outDirQuerySetMap.clear();
565     while (queryResultSet->GoToNextRow() == NativeRdb::E_OK) {
566         dirVal = get<string>(
567             ResultSetUtils::GetValFromColumn(DIRECTORY_DB_DIRECTORY, queryResultSet, TYPE_STRING));
568         dirAsset.SetDirectory(dirVal);
569         dirAsset.SetDirType(get<int32_t>(
570             ResultSetUtils::GetValFromColumn(DIRECTORY_DB_DIRECTORY_TYPE, queryResultSet, TYPE_INT32)));
571         dirAsset.SetMediaTypes(get<string>(
572             ResultSetUtils::GetValFromColumn(DIRECTORY_DB_MEDIA_TYPE, queryResultSet, TYPE_STRING)));
573         dirAsset.SetExtensions(get<string>(
574             ResultSetUtils::GetValFromColumn(DIRECTORY_DB_EXTENSION, queryResultSet, TYPE_STRING)));
575         outDirQuerySetMap.insert(make_pair(dirVal, dirAsset));
576     }
577     return E_OK;
578 }
579 
GetDirQuerySetMap()580 unordered_map<string, DirAsset> MediaLibraryDataManager::GetDirQuerySetMap()
581 {
582     return dirQuerySetMap_;
583 }
584 
585 #ifdef MEDIALIBRARY_COMPATIBILITY
ChangeUriFromValuesBucket(ValuesBucket & values)586 static void ChangeUriFromValuesBucket(ValuesBucket &values)
587 {
588     if (!values.HasColumn(MEDIA_DATA_DB_URI)) {
589         return;
590     }
591 
592     ValueObject value;
593     if (!values.GetObject(MEDIA_DATA_DB_URI, value)) {
594         return;
595     }
596     string oldUri;
597     if (value.GetString(oldUri) != NativeRdb::E_OK) {
598         return;
599     }
600     string newUri = MediaFileUtils::GetRealUriFromVirtualUri(oldUri);
601     values.Delete(MEDIA_DATA_DB_URI);
602     values.PutString(MEDIA_DATA_DB_URI, newUri);
603 }
604 #endif
605 
SolveInsertCmd(MediaLibraryCommand & cmd)606 int32_t MediaLibraryDataManager::SolveInsertCmd(MediaLibraryCommand &cmd)
607 {
608     switch (cmd.GetOprnObject()) {
609         case OperationObject::FILESYSTEM_ASSET:
610             return MediaLibraryFileOperations::HandleFileOperation(cmd);
611 
612         case OperationObject::FILESYSTEM_PHOTO:
613         case OperationObject::FILESYSTEM_AUDIO:
614         case OperationObject::PTP_OPERATION:
615             return MediaLibraryAssetOperations::HandleInsertOperation(cmd);
616 
617         case OperationObject::FILESYSTEM_ALBUM:
618             return MediaLibraryAlbumOperations::CreateAlbumOperation(cmd);
619 
620         case OperationObject::ANALYSIS_PHOTO_ALBUM:
621         case OperationObject::PHOTO_ALBUM:
622             return MediaLibraryAlbumOperations::HandlePhotoAlbumOperations(cmd);
623 
624         case OperationObject::FILESYSTEM_DIR:
625             return MediaLibraryDirOperations::HandleDirOperation(cmd);
626 
627         case OperationObject::SMART_ALBUM: {
628             string packageName = MediaLibraryBundleManager::GetInstance()->GetClientBundleName();
629             MEDIA_INFO_LOG("%{public}s call smart album insert!", packageName.c_str());
630             return MediaLibrarySmartAlbumOperations::HandleSmartAlbumOperation(cmd);
631         }
632         case OperationObject::SMART_ALBUM_MAP:
633             return MediaLibrarySmartAlbumMapOperations::HandleSmartAlbumMapOperation(cmd);
634 
635         case OperationObject::THUMBNAIL:
636             return HandleThumbnailOperations(cmd);
637 
638         case OperationObject::BUNDLE_PERMISSION:
639             return UriPermissionOperations::HandleUriPermOperations(cmd);
640         case OperationObject::APP_URI_PERMISSION_INNER: {
641             int32_t ret = UriSensitiveOperations::InsertOperation(cmd);
642             if (ret < 0) {
643                 return ret;
644             }
645             return UriPermissionOperations::InsertOperation(cmd);
646         }
647         case OperationObject::MEDIA_APP_URI_PERMISSION: {
648             int32_t ret = MediaLibraryAppUriSensitiveOperations::HandleInsertOperation(cmd);
649             if (ret != MediaLibraryAppUriSensitiveOperations::SUCCEED) {
650                 return ret;
651             }
652             return MediaLibraryAppUriPermissionOperations::HandleInsertOperation(cmd);
653         }
654         default:
655             break;
656     }
657     return SolveInsertCmdSub(cmd);
658 }
659 
SolveInsertCmdSub(MediaLibraryCommand & cmd)660 int32_t MediaLibraryDataManager::SolveInsertCmdSub(MediaLibraryCommand &cmd)
661 {
662     if (MediaLibraryRestore::GetInstance().IsBackuping() && !MediaLibraryRestore::GetInstance().IsWaiting()) {
663         MEDIA_INFO_LOG("[SolveInsertCmdSub] rdb is backuping");
664         return E_FAIL;
665     }
666     switch (cmd.GetOprnObject()) {
667         case OperationObject::VISION_START ... OperationObject::VISION_END:
668             return MediaLibraryVisionOperations::InsertOperation(cmd);
669 
670         case OperationObject::GEO_DICTIONARY:
671         case OperationObject::GEO_KNOWLEDGE:
672         case OperationObject::GEO_PHOTO:
673             return MediaLibraryLocationOperations::InsertOperation(cmd);
674 
675         case OperationObject::SEARCH_TOTAL:
676             return MediaLibrarySearchOperations::InsertOperation(cmd);
677 
678         case OperationObject::PAH_FORM_MAP:
679             return MediaLibraryFormMapOperations::HandleStoreFormIdOperation(cmd);
680 
681         case OperationObject::STORY_ALBUM:
682         case OperationObject::STORY_COVER:
683         case OperationObject::STORY_PLAY:
684         case OperationObject::USER_PHOTOGRAPHY:
685         case OperationObject::ANALYSIS_ASSET_SD_MAP:
686         case OperationObject::ANALYSIS_ALBUM_ASSET_MAP:
687             return MediaLibraryStoryOperations::InsertOperation(cmd);
688         case OperationObject::ANALYSIS_PHOTO_MAP: {
689             return MediaLibrarySearchOperations::InsertOperation(cmd);
690         }
691         default:
692             MEDIA_ERR_LOG("MediaLibraryDataManager SolveInsertCmd: unsupported OperationObject: %{public}d",
693                 cmd.GetOprnObject());
694             break;
695     }
696     return E_FAIL;
697 }
698 
LogMovingPhoto(MediaLibraryCommand & cmd,const DataShareValuesBucket & dataShareValue)699 static int32_t LogMovingPhoto(MediaLibraryCommand &cmd, const DataShareValuesBucket &dataShareValue)
700 {
701     bool isValid = false;
702     bool adapted = bool(dataShareValue.Get("adapted", isValid));
703     if (!isValid) {
704         MEDIA_ERR_LOG("Invalid adapted value");
705         return E_ERR;
706     }
707     string packageName = MediaLibraryBundleManager::GetInstance()->GetClientBundleName();
708     if (packageName.empty()) {
709         MEDIA_WARN_LOG("Package name is empty, adapted: %{public}d", static_cast<int>(adapted));
710     }
711     DfxManager::GetInstance()->HandleAdaptationToMovingPhoto(packageName, adapted);
712     return E_OK;
713 }
714 
LogMedialibraryAPI(MediaLibraryCommand & cmd,const DataShareValuesBucket & dataShareValue)715 static int32_t LogMedialibraryAPI(MediaLibraryCommand &cmd, const DataShareValuesBucket &dataShareValue)
716 {
717     string packageName = MediaLibraryBundleManager::GetInstance()->GetClientBundleName();
718     bool isValid = false;
719     string saveUri = string(dataShareValue.Get("saveUri", isValid));
720     CHECK_AND_RETURN_RET_LOG(isValid, E_FAIL, "Invalid saveUri value");
721     int32_t ret = DfxReporter::ReportMedialibraryAPI(packageName, saveUri);
722     if (ret != E_SUCCESS) {
723         MEDIA_ERR_LOG("Log medialibrary API failed");
724     }
725     return ret;
726 }
727 
SolveOtherInsertCmd(MediaLibraryCommand & cmd,const DataShareValuesBucket & dataShareValue,bool & solved)728 static int32_t SolveOtherInsertCmd(MediaLibraryCommand &cmd, const DataShareValuesBucket &dataShareValue,
729     bool &solved)
730 {
731     solved = false;
732     switch (cmd.GetOprnObject()) {
733         case OperationObject::MISCELLANEOUS: {
734             if (cmd.GetOprnType() == OperationType::LOG_MOVING_PHOTO) {
735                 solved = true;
736                 return LogMovingPhoto(cmd, dataShareValue);
737             }
738             if (cmd.GetOprnType() == OperationType::LOG_MEDIALIBRARY_API) {
739                 solved = true;
740                 return LogMedialibraryAPI(cmd, dataShareValue);
741             }
742             return E_OK;
743         }
744         default:
745             return E_FAIL;
746     }
747 }
748 
Insert(MediaLibraryCommand & cmd,const DataShareValuesBucket & dataShareValue)749 int32_t MediaLibraryDataManager::Insert(MediaLibraryCommand &cmd, const DataShareValuesBucket &dataShareValue)
750 {
751     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
752     if (refCnt_.load() <= 0) {
753         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
754         return E_FAIL;
755     }
756 
757     ValuesBucket value = RdbUtils::ToValuesBucket(dataShareValue);
758     if (value.IsEmpty()) {
759         MEDIA_ERR_LOG("MediaLibraryDataManager Insert: Input parameter is invalid");
760         return E_INVALID_VALUES;
761     }
762 #ifdef MEDIALIBRARY_COMPATIBILITY
763     ChangeUriFromValuesBucket(value);
764 #endif
765     cmd.SetValueBucket(value);
766 
767     OperationType oprnType = cmd.GetOprnType();
768     if (oprnType == OperationType::CREATE || oprnType == OperationType::SUBMIT_CACHE
769         || oprnType == OperationType::ADD_FILTERS) {
770         if (SetCmdBundleAndDevice(cmd) != ERR_OK) {
771             MEDIA_ERR_LOG("MediaLibraryDataManager SetCmdBundleAndDevice failed.");
772         }
773     }
774     // boardcast operation
775     if (oprnType == OperationType::SCAN) {
776         return MediaScannerManager::GetInstance()->ScanDir(ROOT_MEDIA_DIR, nullptr);
777     } else if (oprnType == OperationType::DELETE_TOOL) {
778         return MediaLibraryAssetOperations::DeleteToolOperation(cmd);
779     }
780 
781     bool solved = false;
782     int32_t ret = SolveOtherInsertCmd(cmd, dataShareValue, solved);
783     if (solved) {
784         return ret;
785     }
786     return SolveInsertCmd(cmd);
787 }
788 
InsertExt(MediaLibraryCommand & cmd,const DataShareValuesBucket & dataShareValue,string & result)789 int32_t MediaLibraryDataManager::InsertExt(MediaLibraryCommand &cmd, const DataShareValuesBucket &dataShareValue,
790     string &result)
791 {
792     int32_t ret = Insert(cmd, dataShareValue);
793     result = cmd.GetResult();
794     return ret;
795 }
796 
HandleThumbnailOperations(MediaLibraryCommand & cmd)797 int32_t MediaLibraryDataManager::HandleThumbnailOperations(MediaLibraryCommand &cmd)
798 {
799     if (thumbnailService_ == nullptr) {
800         return E_THUMBNAIL_SERVICE_NULLPTR;
801     }
802     int32_t result = E_FAIL;
803     switch (cmd.GetOprnType()) {
804         case OperationType::GENERATE:
805             result = thumbnailService_->GenerateThumbnailBackground();
806             break;
807         case OperationType::AGING:
808             result = thumbnailService_->LcdAging();
809             break;
810 #ifdef DISTRIBUTED
811         case OperationType::DISTRIBUTE_AGING:
812             result = DistributeDeviceAging();
813             break;
814 #endif
815         default:
816             MEDIA_ERR_LOG("bad operation type %{public}u", cmd.GetOprnType());
817     }
818     return result;
819 }
820 
BatchInsert(MediaLibraryCommand & cmd,const vector<DataShareValuesBucket> & values)821 int32_t MediaLibraryDataManager::BatchInsert(MediaLibraryCommand &cmd, const vector<DataShareValuesBucket> &values)
822 {
823     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
824     if (refCnt_.load() <= 0) {
825         MEDIA_ERR_LOG("MediaLibraryDataManager is not initialized");
826         return E_FAIL;
827     }
828 
829     string uriString = cmd.GetUri().ToString();
830     if (uriString == UFM_PHOTO_ALBUM_ADD_ASSET || uriString == PAH_PHOTO_ALBUM_ADD_ASSET) {
831         return PhotoMapOperations::AddPhotoAssets(values);
832     } else if (cmd.GetOprnObject() == OperationObject::ANALYSIS_PHOTO_MAP) {
833         return PhotoMapOperations::AddAnaLysisPhotoAssets(values);
834     } else if (cmd.GetOprnObject() == OperationObject::APP_URI_PERMISSION_INNER) {
835         int32_t ret = UriSensitiveOperations::GrantUriSensitive(cmd, values);
836         if (ret < 0) {
837             return ret;
838         }
839         return UriPermissionOperations::GrantUriPermission(cmd, values);
840     } else if (cmd.GetOprnObject() == OperationObject::MEDIA_APP_URI_PERMISSION) {
841         int32_t ret = MediaLibraryAppUriSensitiveOperations::BatchInsert(cmd, values);
842         if (ret != MediaLibraryAppUriSensitiveOperations::SUCCEED) {
843             return ret;
844         }
845         return MediaLibraryAppUriPermissionOperations::BatchInsert(cmd, values);
846     }
847     if (uriString.find(MEDIALIBRARY_DATA_URI) == string::npos) {
848         MEDIA_ERR_LOG("MediaLibraryDataManager BatchInsert: Input parameter is invalid");
849         return E_INVALID_URI;
850     }
851     int32_t rowCount = 0;
852     for (auto it = values.begin(); it != values.end(); it++) {
853         if (Insert(cmd, *it) >= 0) {
854             rowCount++;
855         }
856     }
857 
858     return rowCount;
859 }
860 
Delete(MediaLibraryCommand & cmd,const DataSharePredicates & predicates)861 int32_t MediaLibraryDataManager::Delete(MediaLibraryCommand &cmd, const DataSharePredicates &predicates)
862 {
863     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
864     if (refCnt_.load() <= 0) {
865         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
866         return E_FAIL;
867     }
868 
869     string uriString = cmd.GetUri().ToString();
870     if (MediaFileUtils::StartsWith(uriString, PhotoColumn::PHOTO_CACHE_URI_PREFIX)) {
871         return MediaLibraryAssetOperations::DeleteOperation(cmd);
872     }
873 
874     if (uriString.find(MEDIALIBRARY_DATA_URI) == string::npos) {
875         MEDIA_ERR_LOG("Not Data ability Uri");
876         return E_INVALID_URI;
877     }
878     MediaLibraryTracer tracer;
879     tracer.Start("CheckWhereClause");
880     auto whereClause = predicates.GetWhereClause();
881     if (!MediaLibraryCommonUtils::CheckWhereClause(whereClause)) {
882         MEDIA_ERR_LOG("illegal query whereClause input %{private}s", whereClause.c_str());
883         return E_SQL_CHECK_FAIL;
884     }
885     tracer.Finish();
886 
887     // MEDIALIBRARY_TABLE just for RdbPredicates
888     NativeRdb::RdbPredicates rdbPredicate = RdbUtils::ToPredicates(predicates,
889         cmd.GetTableName());
890     cmd.GetAbsRdbPredicates()->SetWhereClause(rdbPredicate.GetWhereClause());
891     cmd.GetAbsRdbPredicates()->SetWhereArgs(rdbPredicate.GetWhereArgs());
892     return DeleteInRdbPredicates(cmd, rdbPredicate);
893 }
894 
CheckIsDismissAsset(NativeRdb::RdbPredicates & rdbPredicate)895 bool CheckIsDismissAsset(NativeRdb::RdbPredicates &rdbPredicate)
896 {
897     auto whereClause = rdbPredicate.GetWhereClause();
898     if (whereClause.find(MAP_ALBUM) != string::npos && whereClause.find(MAP_ASSET) != string::npos) {
899         return true;
900     }
901     return false;
902 }
903 
DeleteInRdbPredicates(MediaLibraryCommand & cmd,NativeRdb::RdbPredicates & rdbPredicate)904 int32_t MediaLibraryDataManager::DeleteInRdbPredicates(MediaLibraryCommand &cmd, NativeRdb::RdbPredicates &rdbPredicate)
905 {
906     switch (cmd.GetOprnObject()) {
907         case OperationObject::FILESYSTEM_ASSET:
908         case OperationObject::FILESYSTEM_DIR:
909         case OperationObject::FILESYSTEM_ALBUM: {
910             vector<string> columns = { MEDIA_DATA_DB_ID, MEDIA_DATA_DB_FILE_PATH, MEDIA_DATA_DB_PARENT_ID,
911                 MEDIA_DATA_DB_MEDIA_TYPE, MEDIA_DATA_DB_IS_TRASH, MEDIA_DATA_DB_RELATIVE_PATH };
912             auto fileAsset = MediaLibraryObjectUtils::GetFileAssetByPredicates(*cmd.GetAbsRdbPredicates(), columns);
913             CHECK_AND_RETURN_RET_LOG(fileAsset != nullptr, E_INVALID_ARGUMENTS, "Get fileAsset failed.");
914             if (fileAsset->GetRelativePath() == "") {
915                 return E_DELETE_DENIED;
916             }
917             return (fileAsset->GetMediaType() != MEDIA_TYPE_ALBUM) ?
918                 MediaLibraryObjectUtils::DeleteFileObj(move(fileAsset)) :
919                 MediaLibraryObjectUtils::DeleteDirObj(move(fileAsset));
920         }
921         case OperationObject::PHOTO_ALBUM:
922             return MediaLibraryAlbumOperations::DeletePhotoAlbum(rdbPredicate);
923         case OperationObject::PHOTO_MAP:
924             return PhotoMapOperations::RemovePhotoAssets(rdbPredicate);
925         case OperationObject::ANALYSIS_PHOTO_MAP: {
926             if (CheckIsDismissAsset(rdbPredicate)) {
927                 return PhotoMapOperations::DismissAssets(rdbPredicate);
928             }
929             break;
930         }
931         case OperationObject::MEDIA_APP_URI_PERMISSION: {
932             return MediaLibraryAppUriPermissionOperations::DeleteOperation(rdbPredicate);
933         }
934         case OperationObject::FILESYSTEM_PHOTO:
935         case OperationObject::FILESYSTEM_AUDIO:
936             return MediaLibraryAssetOperations::DeleteOperation(cmd);
937         case OperationObject::PAH_FORM_MAP:
938             return MediaLibraryFormMapOperations::RemoveFormIdOperations(rdbPredicate);
939         default:
940             break;
941     }
942 
943     return DeleteInRdbPredicatesAnalysis(cmd, rdbPredicate);
944 }
945 
DeleteInRdbPredicatesAnalysis(MediaLibraryCommand & cmd,NativeRdb::RdbPredicates & rdbPredicate)946 int32_t MediaLibraryDataManager::DeleteInRdbPredicatesAnalysis(MediaLibraryCommand &cmd,
947     NativeRdb::RdbPredicates &rdbPredicate)
948 {
949     if (MediaLibraryRestore::GetInstance().IsBackuping() && !MediaLibraryRestore::GetInstance().IsWaiting()) {
950         MEDIA_INFO_LOG("[DeleteInRdbPredicatesAnalysis] rdb is backuping");
951         return E_FAIL;
952     }
953     switch (cmd.GetOprnObject()) {
954         case OperationObject::VISION_START ... OperationObject::VISION_END:
955             return MediaLibraryVisionOperations::DeleteOperation(cmd);
956 
957         case OperationObject::GEO_DICTIONARY:
958         case OperationObject::GEO_KNOWLEDGE:
959         case OperationObject::GEO_PHOTO:
960             return MediaLibraryLocationOperations::DeleteOperation(cmd);
961 
962         case OperationObject::STORY_ALBUM:
963         case OperationObject::STORY_COVER:
964         case OperationObject::STORY_PLAY:
965         case OperationObject::USER_PHOTOGRAPHY:
966             return MediaLibraryStoryOperations::DeleteOperation(cmd);
967 
968         case OperationObject::SEARCH_TOTAL:
969             return MediaLibrarySearchOperations::DeleteOperation(cmd);
970         default:
971             break;
972     }
973 
974     return E_FAIL;
975 }
976 
Update(MediaLibraryCommand & cmd,const DataShareValuesBucket & dataShareValue,const DataSharePredicates & predicates)977 int32_t MediaLibraryDataManager::Update(MediaLibraryCommand &cmd, const DataShareValuesBucket &dataShareValue,
978     const DataSharePredicates &predicates)
979 {
980     MEDIA_DEBUG_LOG("MediaLibraryDataManager::Update");
981     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
982     if (refCnt_.load() <= 0) {
983         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
984         return E_FAIL;
985     }
986 
987     ValuesBucket value = RdbUtils::ToValuesBucket(dataShareValue);
988     if (value.IsEmpty()) {
989         MEDIA_ERR_LOG("MediaLibraryDataManager Update:Input parameter is invalid ");
990         return E_INVALID_VALUES;
991     }
992 
993 #ifdef MEDIALIBRARY_COMPATIBILITY
994     ChangeUriFromValuesBucket(value);
995 #endif
996 
997     cmd.SetValueBucket(value);
998     cmd.SetDataSharePred(predicates);
999     // MEDIALIBRARY_TABLE just for RdbPredicates
1000     NativeRdb::RdbPredicates rdbPredicate = RdbUtils::ToPredicates(predicates,
1001         cmd.GetTableName());
1002     cmd.GetAbsRdbPredicates()->SetWhereClause(rdbPredicate.GetWhereClause());
1003     cmd.GetAbsRdbPredicates()->SetWhereArgs(rdbPredicate.GetWhereArgs());
1004     return UpdateInternal(cmd, value, predicates);
1005 }
1006 
SplitUriString(const std::string & str,char delimiter)1007 static std::vector<std::string> SplitUriString(const std::string& str, char delimiter)
1008 {
1009     std::vector<std::string> elements;
1010     std::stringstream ss(str);
1011     std::string item;
1012     while (std::getline(ss, item, delimiter)) {
1013         if (!item.empty()) {
1014             elements.emplace_back(item);
1015         }
1016     }
1017     return elements;
1018 }
1019 
ExtractFileIdFromUri(const std::string & uri)1020 static std::string ExtractFileIdFromUri(const std::string& uri)
1021 {
1022     auto uriParts = SplitUriString(uri, '/');
1023     if (uriParts.size() >= MediaLibraryDataManager::URI_MIN_NUM) {
1024         return uriParts[uriParts.size() - MediaLibraryDataManager::URI_MIN_NUM];
1025     }
1026     return "";
1027 }
1028 
BuildWhereClause(const std::vector<std::string> & dismissAssetArray,int32_t albumId)1029 static std::string BuildWhereClause(const std::vector<std::string>& dismissAssetArray, int32_t albumId)
1030 {
1031     std::string whereClause = MediaColumn::MEDIA_ID + " IN (";
1032 
1033     for (size_t i = 0; i < dismissAssetArray.size(); ++i) {
1034         std::string fileId = ExtractFileIdFromUri(dismissAssetArray[i]);
1035         if (fileId.empty()) {
1036             continue;
1037         }
1038 
1039         if (i > 0) {
1040             whereClause += ",";
1041         }
1042 
1043         whereClause += "'" + fileId + "'";
1044     }
1045 
1046     whereClause += ") AND EXISTS (SELECT 1 FROM " + ANALYSIS_ALBUM_TABLE +
1047         " WHERE " + ANALYSIS_ALBUM_TABLE + "." + PhotoAlbumColumns::ALBUM_ID +
1048         " = " + std::to_string(albumId) + " AND " +
1049         ANALYSIS_ALBUM_TABLE + ".tag_id = " + VISION_IMAGE_FACE_TABLE + ".tag_id)";
1050 
1051     return whereClause;
1052 }
1053 
HandleAnalysisFaceUpdate(MediaLibraryCommand & cmd,NativeRdb::ValuesBucket & value,const DataShare::DataSharePredicates & predicates)1054 static int HandleAnalysisFaceUpdate(MediaLibraryCommand& cmd, NativeRdb::ValuesBucket &value,
1055     const DataShare::DataSharePredicates &predicates)
1056 {
1057     string keyOperation = cmd.GetQuerySetParam(MEDIA_OPERN_KEYWORD);
1058     if (keyOperation.empty() || keyOperation != UPDATE_DISMISS_ASSET) {
1059         cmd.SetValueBucket(value);
1060         return MediaLibraryObjectUtils::ModifyInfoByIdInDb(cmd);
1061     }
1062 
1063     const string &clause = predicates.GetWhereClause();
1064     std::vector<std::string> clauses = SplitUriString(clause, ',');
1065     if (clauses.empty()) {
1066         MEDIA_ERR_LOG("Clause is empty, cannot extract album ID.");
1067         return E_INVALID_FILEID;
1068     }
1069 
1070     std::string albumStr = clauses[0];
1071     int32_t albumId {0};
1072     std::stringstream ss(albumStr);
1073     if (!(ss >> albumId)) {
1074         MEDIA_ERR_LOG("Unable to convert albumId string to integer.");
1075         return E_INVALID_FILEID;
1076     }
1077 
1078     std::vector<std::string> uris;
1079     for (size_t i = 1; i < clauses.size(); ++i) {
1080         uris.push_back(clauses[i]);
1081     }
1082 
1083     if (uris.empty()) {
1084         MEDIA_ERR_LOG("No URIs found after album ID.");
1085         return E_INVALID_FILEID;
1086     }
1087 
1088     std::string predicate = BuildWhereClause(uris, albumId);
1089     cmd.SetValueBucket(value);
1090     cmd.GetAbsRdbPredicates()->SetWhereClause(predicate);
1091     return MediaLibraryObjectUtils::ModifyInfoByIdInDb(cmd);
1092 }
1093 
HandleFilesystemOperations(MediaLibraryCommand & cmd)1094 static int32_t HandleFilesystemOperations(MediaLibraryCommand &cmd)
1095 {
1096     switch (cmd.GetOprnObject()) {
1097         case OperationObject::FILESYSTEM_ASSET: {
1098             auto ret = MediaLibraryFileOperations::ModifyFileOperation(cmd);
1099             if (ret == E_SAME_PATH) {
1100                 return E_OK;
1101             } else {
1102                 return ret;
1103             }
1104         }
1105         case OperationObject::FILESYSTEM_DIR:
1106             // supply a ModifyDirOperation here to replace
1107             // modify in the HandleDirOperations in Insert function, if need
1108             return E_OK;
1109 
1110         case OperationObject::FILESYSTEM_ALBUM: {
1111             return MediaLibraryAlbumOperations::ModifyAlbumOperation(cmd);
1112         }
1113         default:
1114             return E_OK;
1115     }
1116 }
1117 
UpdateInternal(MediaLibraryCommand & cmd,NativeRdb::ValuesBucket & value,const DataShare::DataSharePredicates & predicates)1118 int32_t MediaLibraryDataManager::UpdateInternal(MediaLibraryCommand &cmd, NativeRdb::ValuesBucket &value,
1119     const DataShare::DataSharePredicates &predicates)
1120 {
1121     int32_t result = HandleFilesystemOperations(cmd);
1122     if (result != E_OK) {
1123         return result;
1124     }
1125     switch (cmd.GetOprnObject()) {
1126         case OperationObject::PAH_PHOTO:
1127         case OperationObject::PAH_VIDEO:
1128         case OperationObject::FILESYSTEM_PHOTO:
1129         case OperationObject::FILESYSTEM_AUDIO:
1130         case OperationObject::PTP_OPERATION:
1131             return MediaLibraryAssetOperations::UpdateOperation(cmd);
1132         case OperationObject::ANALYSIS_PHOTO_ALBUM: {
1133             if ((cmd.GetOprnType() >= OperationType::PORTRAIT_DISPLAY_LEVEL &&
1134                  cmd.GetOprnType() <= OperationType::GROUP_COVER_URI)) {
1135                 return MediaLibraryAlbumOperations::HandleAnalysisPhotoAlbum(cmd.GetOprnType(), value, predicates);
1136             }
1137             break;
1138         }
1139         case OperationObject::PHOTO_ALBUM:
1140             return MediaLibraryAlbumOperations::HandlePhotoAlbum(cmd.GetOprnType(), value, predicates);
1141         case OperationObject::GEO_DICTIONARY:
1142         case OperationObject::GEO_KNOWLEDGE:
1143             return MediaLibraryLocationOperations::UpdateOperation(cmd);
1144         case OperationObject::STORY_ALBUM:
1145         case OperationObject::STORY_COVER:
1146         case OperationObject::STORY_PLAY:
1147         case OperationObject::USER_PHOTOGRAPHY:
1148             return MediaLibraryStoryOperations::UpdateOperation(cmd);
1149         case OperationObject::PAH_MULTISTAGES_CAPTURE: {
1150             std::vector<std::string> columns;
1151             MultiStagesPhotoCaptureManager::GetInstance().HandleMultiStagesOperation(cmd, columns);
1152             return E_OK;
1153         }
1154         case OperationObject::PAH_BATCH_THUMBNAIL_OPERATE:
1155             return ProcessThumbnailBatchCmd(cmd, value, predicates);
1156         case OperationObject::PAH_CLOUD_ENHANCEMENT_OPERATE:
1157             return EnhancementManager::GetInstance().HandleEnhancementUpdateOperation(cmd);
1158         case OperationObject::VISION_IMAGE_FACE:
1159             return HandleAnalysisFaceUpdate(cmd, value, predicates);
1160         default:
1161             break;
1162     }
1163     // ModifyInfoByIdInDb can finish the default update of smartalbum and smartmap,
1164     // so no need to distinct them in switch-case deliberately
1165     cmd.SetValueBucket(value);
1166     return MediaLibraryObjectUtils::ModifyInfoByIdInDb(cmd);
1167 }
1168 
InterruptBgworker()1169 void MediaLibraryDataManager::InterruptBgworker()
1170 {
1171     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
1172     if (refCnt_.load() <= 0) {
1173         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
1174         return;
1175     }
1176 
1177     if (thumbnailService_ == nullptr) {
1178         return;
1179     }
1180     thumbnailService_->InterruptBgworker();
1181     shared_ptr<TrashAsyncTaskWorker> asyncWorker = TrashAsyncTaskWorker::GetInstance();
1182     if (asyncWorker == nullptr) {
1183         MEDIA_ERR_LOG("asyncWorker null");
1184         return;
1185     }
1186     asyncWorker->Interrupt();
1187 }
1188 
GenerateThumbnailBackground()1189 int32_t MediaLibraryDataManager::GenerateThumbnailBackground()
1190 {
1191     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
1192     if (refCnt_.load() <= 0) {
1193         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
1194         return E_FAIL;
1195     }
1196 
1197     if (thumbnailService_ == nullptr) {
1198         return E_THUMBNAIL_SERVICE_NULLPTR;
1199     }
1200     return thumbnailService_->GenerateThumbnailBackground();
1201 }
1202 
UpgradeThumbnailBackground(bool isWifiConnected)1203 int32_t MediaLibraryDataManager::UpgradeThumbnailBackground(bool isWifiConnected)
1204 {
1205     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
1206     if (refCnt_.load() <= 0) {
1207         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
1208         return E_FAIL;
1209     }
1210 
1211     if (thumbnailService_ == nullptr) {
1212         return E_THUMBNAIL_SERVICE_NULLPTR;
1213     }
1214     return thumbnailService_->UpgradeThumbnailBackground(isWifiConnected);
1215 }
1216 
RestoreThumbnailDualFrame()1217 int32_t MediaLibraryDataManager::RestoreThumbnailDualFrame()
1218 {
1219     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
1220     if (refCnt_.load() <= 0) {
1221         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
1222         return E_FAIL;
1223     }
1224 
1225     if (thumbnailService_ == nullptr) {
1226         return E_THUMBNAIL_SERVICE_NULLPTR;
1227     }
1228     return thumbnailService_->RestoreThumbnailDualFrame();
1229 }
1230 
CacheAging()1231 static void CacheAging()
1232 {
1233     if (!MediaFileUtils::IsDirectory(MEDIA_CACHE_DIR)) {
1234         return;
1235     }
1236     time_t now = time(nullptr);
1237     constexpr int thresholdSeconds = 24 * 60 * 60; // 24 hours
1238     vector<string> files;
1239     GetDirFiles(MEDIA_CACHE_DIR, files);
1240     for (auto &file : files) {
1241         struct stat statInfo {};
1242         if (stat(file.c_str(), &statInfo) != 0) {
1243             MEDIA_WARN_LOG("skip %{private}s, stat errno: %{public}d", file.c_str(), errno);
1244             continue;
1245         }
1246         time_t timeModified = statInfo.st_mtime;
1247         double duration = difftime(now, timeModified); // diff in seconds
1248         if (duration < thresholdSeconds) {
1249             continue;
1250         }
1251         if (!MediaFileUtils::DeleteFile(file)) {
1252             MEDIA_ERR_LOG("delete failed %{public}s, errno: %{public}d", file.c_str(), errno);
1253         }
1254     }
1255 }
1256 
ClearInvalidDeletedAlbum()1257 static int32_t ClearInvalidDeletedAlbum()
1258 {
1259     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
1260     if (rdbStore == nullptr) {
1261         MEDIA_ERR_LOG("rdbStore is nullptr");
1262         return E_FAIL;
1263     }
1264 
1265     const std::string QUERY_NO_CLOUD_DELETED_ALBUM_INFO =
1266         "SELECT album_id, album_name FROM PhotoAlbum WHERE " + PhotoAlbumColumns::ALBUM_DIRTY +
1267         " = " + std::to_string(static_cast<int32_t>(DirtyTypes::TYPE_DELETED)) +
1268         " AND " + PhotoColumn::PHOTO_CLOUD_ID + " is NULL";
1269     shared_ptr<NativeRdb::ResultSet> resultSet = rdbStore->QuerySql(QUERY_NO_CLOUD_DELETED_ALBUM_INFO);
1270     if (resultSet == nullptr) {
1271         MEDIA_ERR_LOG("Query not match data fails");
1272         return E_HAS_DB_ERROR;
1273     }
1274 
1275     vector<string> albumIds;
1276     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
1277         int columnIndex = 0;
1278         int32_t albumId = -1;
1279         if (resultSet->GetColumnIndex(PhotoAlbumColumns::ALBUM_ID, columnIndex) == NativeRdb::E_OK) {
1280             resultSet->GetInt(columnIndex, albumId);
1281             albumIds.emplace_back(to_string(albumId));
1282         }
1283         std::string albumName = "";
1284         if (resultSet->GetColumnIndex(PhotoAlbumColumns::ALBUM_NAME, columnIndex) == NativeRdb::E_OK) {
1285             resultSet->GetString(columnIndex, albumName);
1286         }
1287         MEDIA_INFO_LOG("Handle name %{public}s id %{public}d", DfxUtils::GetSafeAlbumName(albumName).c_str(), albumId);
1288     }
1289     if (albumIds.size() == 0) {
1290         return E_OK;
1291     }
1292 
1293     NativeRdb::RdbPredicates predicates(PhotoAlbumColumns::TABLE);
1294     predicates.In(PhotoAlbumColumns::ALBUM_ID, albumIds);
1295     int deleteRow = -1;
1296     auto ret = rdbStore->Delete(deleteRow, predicates);
1297     MEDIA_INFO_LOG("Delete invalid album, deleteRow is %{public}d", deleteRow);
1298     if (ret != NativeRdb::E_OK) {
1299         MEDIA_ERR_LOG("Delete invalid album failed, ret = %{public}d, deleteRow is %{public}d", ret, deleteRow);
1300         return E_HAS_DB_ERROR;
1301     }
1302     return E_OK;
1303 }
1304 
DoAging()1305 int32_t MediaLibraryDataManager::DoAging()
1306 {
1307     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
1308     MEDIA_DEBUG_LOG("MediaLibraryDataManager::DoAging IN");
1309     if (refCnt_.load() <= 0) {
1310         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
1311         return E_FAIL;
1312     }
1313 
1314     CacheAging(); // aging file in .cache
1315 
1316     ClearInvalidDeletedAlbum(); // Clear invalid album data with null cloudid and dirty '4'
1317 
1318     shared_ptr<TrashAsyncTaskWorker> asyncWorker = TrashAsyncTaskWorker::GetInstance();
1319     if (asyncWorker == nullptr) {
1320         MEDIA_ERR_LOG("asyncWorker null");
1321         return E_FAIL;
1322     }
1323     asyncWorker->Init();
1324     return E_OK;
1325 }
1326 
GenerateUuid()1327 static string GenerateUuid()
1328 {
1329     uuid_t uuid;
1330     uuid_generate(uuid);
1331     char str[UUID_STR_LENGTH] = {};
1332     uuid_unparse(uuid, str);
1333     return str;
1334 }
1335 
generateRegexpMatchForNumber(const int32_t num)1336 static string generateRegexpMatchForNumber(const int32_t num)
1337 {
1338     string regexpMatchNumber = "[0-9]";
1339     string strRegexpMatch = "";
1340     for (int i = 0; i < num; i++) {
1341         strRegexpMatch += regexpMatchNumber;
1342     }
1343     return strRegexpMatch;
1344 }
1345 
generateUpdateSql(const bool isCover,const string title,const int32_t ownerAlbumId)1346 static string generateUpdateSql(const bool isCover, const string title, const int32_t ownerAlbumId)
1347 {
1348     uint32_t index = title.find_first_of("BURST");
1349     string globMember = title.substr(0, index) + "BURST" + generateRegexpMatchForNumber(3);
1350     string globCover = globMember + "_COVER";
1351     string updateSql;
1352     if (isCover) {
1353         string burstkey = GenerateUuid();
1354         updateSql = "UPDATE " + PhotoColumn::PHOTOS_TABLE + " SET " + PhotoColumn::PHOTO_SUBTYPE + " = " +
1355             to_string(static_cast<int32_t>(PhotoSubType::BURST)) + ", " + PhotoColumn::PHOTO_BURST_KEY + " = '" +
1356             burstkey + "', " + PhotoColumn::PHOTO_BURST_COVER_LEVEL + " = CASE WHEN " + MediaColumn::MEDIA_TITLE +
1357             " NOT LIKE '%COVER%' THEN " + to_string(static_cast<int32_t>(BurstCoverLevelType::MEMBER)) + " ELSE " +
1358             to_string(static_cast<int32_t>(BurstCoverLevelType::COVER)) + " END WHERE " + MediaColumn::MEDIA_TYPE +
1359             " = " + to_string(static_cast<int32_t>(MEDIA_TYPE_IMAGE)) + " AND " + PhotoColumn::PHOTO_SUBTYPE + " != " +
1360             to_string(static_cast<int32_t>(PhotoSubType::MOVING_PHOTO)) + " AND " + PhotoColumn::PHOTO_OWNER_ALBUM_ID +
1361             " = " + to_string(ownerAlbumId) + " AND (LOWER(" + MediaColumn::MEDIA_TITLE + ") GLOB LOWER('" +
1362             globMember + "') OR LOWER(" + MediaColumn::MEDIA_TITLE + ") GLOB LOWER('" + globCover + "'));";
1363     } else {
1364         string subWhere = "FROM " + PhotoColumn::PHOTOS_TABLE + " AS p2 WHERE LOWER(p2." + MediaColumn::MEDIA_TITLE +
1365             ") GLOB LOWER('" + globCover + "') AND p2." + PhotoColumn::PHOTO_OWNER_ALBUM_ID + " = " +
1366             to_string(ownerAlbumId);
1367 
1368         updateSql = "UPDATE " + PhotoColumn::PHOTOS_TABLE + " AS p1 SET " + PhotoColumn::PHOTO_BURST_KEY +
1369             " = (SELECT CASE WHEN p2." + PhotoColumn::PHOTO_BURST_KEY + " IS NOT NULL THEN p2." +
1370             PhotoColumn::PHOTO_BURST_KEY + " ELSE NULL END " + subWhere + " LIMIT 1 ), " +
1371             PhotoColumn::PHOTO_BURST_COVER_LEVEL + " = (SELECT CASE WHEN COUNT(1) > 0 THEN " +
1372             to_string(static_cast<int32_t>(BurstCoverLevelType::MEMBER)) + " ELSE " +
1373             to_string(static_cast<int32_t>(BurstCoverLevelType::COVER)) + " END " + subWhere + "), " +
1374             PhotoColumn::PHOTO_SUBTYPE + " = (SELECT CASE WHEN COUNT(1) > 0 THEN " +
1375             to_string(static_cast<int32_t>(PhotoSubType::BURST)) + " ELSE p1." + PhotoColumn::PHOTO_SUBTYPE + " END " +
1376             subWhere + ") WHERE p1." + MediaColumn::MEDIA_TITLE + " = '" + title + "' AND p1." +
1377             PhotoColumn::PHOTO_OWNER_ALBUM_ID + " = " + to_string(ownerAlbumId);
1378     }
1379     return updateSql;
1380 }
1381 
UpdateBurstPhoto(const bool isCover,const shared_ptr<MediaLibraryRdbStore> rdbStore,shared_ptr<NativeRdb::ResultSet> resultSet)1382 static int32_t UpdateBurstPhoto(const bool isCover, const shared_ptr<MediaLibraryRdbStore> rdbStore,
1383     shared_ptr<NativeRdb::ResultSet> resultSet)
1384 {
1385     int32_t count;
1386     int32_t retCount = resultSet->GetRowCount(count);
1387     if (count == 0) {
1388         if (isCover) {
1389             MEDIA_INFO_LOG("No burst cover need to update");
1390         } else {
1391             MEDIA_INFO_LOG("No burst member need to update");
1392         }
1393         return E_SUCCESS;
1394     }
1395     if (retCount != E_SUCCESS || count < 0) {
1396         return E_ERR;
1397     }
1398 
1399     int32_t ret = E_ERR;
1400     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
1401         int columnIndex = 0;
1402         string title;
1403         if (resultSet->GetColumnIndex(MediaColumn::MEDIA_TITLE, columnIndex) == NativeRdb::E_OK) {
1404             resultSet->GetString(columnIndex, title);
1405         }
1406         int32_t ownerAlbumId = 0;
1407         if (resultSet->GetColumnIndex(PhotoColumn::PHOTO_OWNER_ALBUM_ID, columnIndex) == NativeRdb::E_OK) {
1408             resultSet->GetInt(columnIndex, ownerAlbumId);
1409         }
1410 
1411         string updateSql = generateUpdateSql(isCover, title, ownerAlbumId);
1412         ret = rdbStore->ExecuteSql(updateSql);
1413         if (ret != NativeRdb::E_OK) {
1414             MEDIA_ERR_LOG("rdbStore->ExecuteSql failed, ret = %{public}d", ret);
1415             return E_HAS_DB_ERROR;
1416         }
1417     }
1418     return ret;
1419 }
1420 
QueryBurst(const shared_ptr<MediaLibraryRdbStore> rdbStore,const string globNameRule1,const string globNameRule2)1421 static shared_ptr<NativeRdb::ResultSet> QueryBurst(const shared_ptr<MediaLibraryRdbStore> rdbStore,
1422     const string globNameRule1, const string globNameRule2)
1423 {
1424     string querySql = "SELECT " + MediaColumn::MEDIA_TITLE + ", " + PhotoColumn::PHOTO_OWNER_ALBUM_ID +
1425         " FROM " + PhotoColumn::PHOTOS_TABLE + " WHERE " + MediaColumn::MEDIA_TYPE + " = " +
1426         to_string(static_cast<int32_t>(MEDIA_TYPE_IMAGE)) + " AND " + PhotoColumn::PHOTO_SUBTYPE + " != " +
1427         to_string(static_cast<int32_t>(PhotoSubType::MOVING_PHOTO)) + " AND " + PhotoColumn::PHOTO_BURST_KEY +
1428         " IS NULL AND (LOWER(" + MediaColumn::MEDIA_TITLE + ") GLOB LOWER('" + globNameRule1 + "') OR LOWER(" +
1429         MediaColumn::MEDIA_TITLE + ") GLOB LOWER('" + globNameRule2 + "'))";
1430 
1431     auto resultSet = rdbStore->QueryByStep(querySql);
1432     if (resultSet == nullptr) {
1433         MEDIA_ERR_LOG("failed to acquire result from visitor query.");
1434     }
1435     return resultSet;
1436 }
1437 
UpdateBurstFromGallery()1438 int32_t MediaLibraryDataManager::UpdateBurstFromGallery()
1439 {
1440     MEDIA_INFO_LOG("Begin UpdateBurstFromGallery");
1441     MediaLibraryTracer tracer;
1442     tracer.Start("MediaLibraryDataManager::UpdateBurstFromGallery");
1443     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
1444     if (refCnt_.load() <= 0) {
1445         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
1446         return E_FAIL;
1447     }
1448     if (rdbStore_ == nullptr) {
1449         MEDIA_DEBUG_LOG("rdbStore_ is nullptr");
1450         return E_FAIL;
1451     }
1452 
1453     string globNameRule = "IMG_" + generateRegexpMatchForNumber(8) + "_" + generateRegexpMatchForNumber(6) + "_";
1454 
1455     // regexp match IMG_xxxxxxxx_xxxxxx_BURSTxxx, 'x' represents a number
1456     string globMemberStr1 = globNameRule + "BURST" + generateRegexpMatchForNumber(3);
1457     string globMemberStr2 = globNameRule + "[0-9]_BURST" + generateRegexpMatchForNumber(3);
1458     // regexp match IMG_xxxxxxxx_xxxxxx_BURSTxxx_COVER, 'x' represents a number
1459     string globCoverStr1 = globMemberStr1 + "_COVER";
1460     string globCoverStr2 = globMemberStr2 + "_COVER";
1461 
1462     auto resultSet = QueryBurst(rdbStore_, globCoverStr1, globCoverStr2);
1463     int32_t ret = UpdateBurstPhoto(true, rdbStore_, resultSet);
1464     if (ret != E_SUCCESS) {
1465         MEDIA_ERR_LOG("failed to UpdateBurstPhotoByCovers.");
1466         return E_FAIL;
1467     }
1468 
1469     resultSet = QueryBurst(rdbStore_, globMemberStr1, globMemberStr2);
1470     ret = UpdateBurstPhoto(false, rdbStore_, resultSet);
1471     if (ret != E_SUCCESS) {
1472         MEDIA_ERR_LOG("failed to UpdateBurstPhotoByMembers.");
1473         return E_FAIL;
1474     }
1475     MEDIA_INFO_LOG("End UpdateBurstFromGallery");
1476     return ret;
1477 }
1478 
1479 #ifdef DISTRIBUTED
LcdDistributeAging()1480 int32_t MediaLibraryDataManager::LcdDistributeAging()
1481 {
1482     MEDIA_DEBUG_LOG("MediaLibraryDataManager::LcdDistributeAging IN");
1483     auto deviceInstance = MediaLibraryDevice::GetInstance();
1484     if ((thumbnailService_ == nullptr) || (deviceInstance == nullptr)) {
1485         return E_THUMBNAIL_SERVICE_NULLPTR;
1486     }
1487     int32_t result = E_SUCCESS;
1488     vector<string> deviceUdids;
1489     deviceInstance->QueryAllDeviceUdid(deviceUdids);
1490     for (string &udid : deviceUdids) {
1491         result = thumbnailService_->LcdDistributeAging(udid);
1492         if (result != E_SUCCESS) {
1493             MEDIA_ERR_LOG("LcdDistributeAging fail result is %{public}d", result);
1494             break;
1495         }
1496     }
1497     return result;
1498 }
1499 
DistributeDeviceAging()1500 int32_t MediaLibraryDataManager::DistributeDeviceAging()
1501 {
1502     MEDIA_DEBUG_LOG("MediaLibraryDataManager::DistributeDeviceAging IN");
1503     auto deviceInstance = MediaLibraryDevice::GetInstance();
1504     if ((thumbnailService_ == nullptr) || (deviceInstance == nullptr)) {
1505         return E_FAIL;
1506     }
1507     int32_t result = E_FAIL;
1508     vector<MediaLibraryDeviceInfo> deviceDataBaseList;
1509     deviceInstance->QueryAgingDeviceInfos(deviceDataBaseList);
1510     MEDIA_DEBUG_LOG("MediaLibraryDevice InitDeviceRdbStore deviceDataBaseList size =  %{public}d",
1511         (int) deviceDataBaseList.size());
1512     for (MediaLibraryDeviceInfo deviceInfo : deviceDataBaseList) {
1513         result = thumbnailService_->InvalidateDistributeThumbnail(deviceInfo.deviceUdid);
1514         if (result != E_SUCCESS) {
1515             MEDIA_ERR_LOG("invalidate fail %{public}d", result);
1516             continue;
1517         }
1518     }
1519     return result;
1520 }
1521 #endif
1522 
GetThumbnail(const string & uri)1523 int MediaLibraryDataManager::GetThumbnail(const string &uri)
1524 {
1525     if (thumbnailService_ == nullptr) {
1526         return E_THUMBNAIL_SERVICE_NULLPTR;
1527     }
1528     if (!uri.empty() && MediaLibraryObjectUtils::CheckUriPending(uri)) {
1529         MEDIA_ERR_LOG("failed to get thumbnail, the file:%{private}s is pending", uri.c_str());
1530         return E_FAIL;
1531     }
1532     return thumbnailService_->GetThumbnailFd(uri);
1533 }
1534 
CreateThumbnailAsync(const string & uri,const string & path)1535 void MediaLibraryDataManager::CreateThumbnailAsync(const string &uri, const string &path)
1536 {
1537     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
1538     if (refCnt_.load() <= 0) {
1539         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
1540         return;
1541     }
1542 
1543     if (thumbnailService_ == nullptr) {
1544         return;
1545     }
1546     if (!uri.empty()) {
1547         if (MediaLibraryObjectUtils::CheckUriPending(uri)) {
1548             MEDIA_ERR_LOG("failed to get thumbnail, the file:%{private}s is pending", uri.c_str());
1549             return;
1550         }
1551         int32_t err = thumbnailService_->CreateThumbnailFileScaned(uri, path);
1552         if (err != E_SUCCESS) {
1553             MEDIA_ERR_LOG("ThumbnailService CreateThumbnailFileScaned failed : %{public}d", err);
1554         }
1555     }
1556 }
1557 
Query(MediaLibraryCommand & cmd,const vector<string> & columns,const DataSharePredicates & predicates,int & errCode)1558 shared_ptr<ResultSetBridge> MediaLibraryDataManager::Query(MediaLibraryCommand &cmd,
1559     const vector<string> &columns, const DataSharePredicates &predicates, int &errCode)
1560 {
1561     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
1562     if (refCnt_.load() <= 0) {
1563         errCode = E_FAIL;
1564         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
1565         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, errCode},
1566             {KEY_OPT_TYPE, OptType::QUERY}};
1567         PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
1568         return nullptr;
1569     }
1570 
1571     MediaLibraryTracer tracer;
1572     tracer.Start("MediaLibraryDataManager::Query");
1573     if (rdbStore_ == nullptr) {
1574         errCode = E_FAIL;
1575         MEDIA_ERR_LOG("Rdb Store is not initialized");
1576         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, errCode},
1577             {KEY_OPT_TYPE, OptType::QUERY}};
1578         PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
1579         return nullptr;
1580     }
1581 
1582     auto absResultSet = QueryRdb(cmd, columns, predicates, errCode);
1583     if (absResultSet == nullptr) {
1584         errCode = (errCode != E_OK) ? errCode : E_FAIL;
1585         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, errCode},
1586             {KEY_OPT_TYPE, OptType::QUERY}};
1587         PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
1588         return nullptr;
1589     }
1590     return RdbUtils::ToResultSetBridge(absResultSet);
1591 }
1592 
1593 #ifdef DISTRIBUTED
SyncPullThumbnailKeys(const Uri & uri)1594 int32_t MediaLibraryDataManager::SyncPullThumbnailKeys(const Uri &uri)
1595 {
1596     if (MediaLibraryDevice::GetInstance() == nullptr || !MediaLibraryDevice::GetInstance()->IsHasActiveDevice()) {
1597         return E_ERR;
1598     }
1599     if (kvStorePtr_ == nullptr) {
1600         return E_ERR;
1601     }
1602 
1603     MediaLibraryCommand cmd(uri, OperationType::QUERY);
1604     cmd.GetAbsRdbPredicates()->BeginWrap()->EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, to_string(MEDIA_TYPE_IMAGE))
1605         ->Or()->EqualTo(MEDIA_DATA_DB_MEDIA_TYPE, to_string(MEDIA_TYPE_VIDEO))->EndWrap()
1606         ->And()->EqualTo(MEDIA_DATA_DB_DATE_TRASHED, to_string(0))
1607         ->And()->NotEqualTo(MEDIA_DATA_DB_MEDIA_TYPE, to_string(MEDIA_TYPE_ALBUM))
1608         ->OrderByDesc(MEDIA_DATA_DB_DATE_ADDED);
1609     vector<string> columns = { MEDIA_DATA_DB_THUMBNAIL, MEDIA_DATA_DB_LCD };
1610     auto resultset = MediaLibraryFileOperations::QueryFileOperation(cmd, columns);
1611     if (resultset == nullptr) {
1612         return E_HAS_DB_ERROR;
1613     }
1614 
1615     vector<string> thumbnailKeys;
1616     int count = 0;
1617     while (resultset->GoToNextRow() == NativeRdb::E_OK && count < MAX_QUERY_THUMBNAIL_KEY_COUNT) {
1618         string thumbnailKey =
1619             get<string>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_THUMBNAIL, resultset, TYPE_STRING));
1620         thumbnailKeys.push_back(thumbnailKey);
1621         string lcdKey = get<string>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_LCD, resultset, TYPE_STRING));
1622         thumbnailKeys.push_back(lcdKey);
1623         count++;
1624     }
1625 
1626     if (thumbnailKeys.empty()) {
1627         return E_NO_SUCH_FILE;
1628     }
1629     MediaLibrarySyncOperation::SyncPullKvstore(kvStorePtr_, thumbnailKeys,
1630         MediaFileUtils::GetNetworkIdFromUri(uri.ToString()));
1631     return E_SUCCESS;
1632 }
1633 #endif
1634 
1635 static const map<OperationObject, string> QUERY_CONDITION_MAP {
1636     { OperationObject::SMART_ALBUM, SMARTALBUM_DB_ID },
1637     { OperationObject::SMART_ALBUM_MAP, SMARTALBUMMAP_DB_ALBUM_ID },
1638     { OperationObject::FILESYSTEM_DIR, MEDIA_DATA_DB_ID },
1639     { OperationObject::ALL_DEVICE, "" },
1640     { OperationObject::ACTIVE_DEVICE, "" },
1641     { OperationObject::ASSETMAP, "" },
1642     { OperationObject::SMART_ALBUM_ASSETS, "" },
1643     { OperationObject::BUNDLE_PERMISSION, "" },
1644 };
1645 
CheckIsPortraitAlbum(MediaLibraryCommand & cmd)1646 bool CheckIsPortraitAlbum(MediaLibraryCommand &cmd)
1647 {
1648     auto predicates = cmd.GetAbsRdbPredicates();
1649     auto whereClause = predicates->GetWhereClause();
1650     if (whereClause.find(USER_DISPLAY_LEVEL) != string::npos || whereClause.find(IS_ME) != string::npos ||
1651         whereClause.find(ALBUM_NAME_NOT_NULL) != string::npos) {
1652         return true;
1653     }
1654     return false;
1655 }
1656 
QuerySet(MediaLibraryCommand & cmd,const vector<string> & columns,const DataSharePredicates & predicates,int & errCode)1657 shared_ptr<NativeRdb::ResultSet> MediaLibraryDataManager::QuerySet(MediaLibraryCommand &cmd,
1658     const vector<string> &columns, const DataSharePredicates &predicates, int &errCode)
1659 {
1660     MediaLibraryTracer tracer;
1661     tracer.Start("QueryRdb");
1662     tracer.Start("CheckWhereClause");
1663     MEDIA_DEBUG_LOG("CheckWhereClause start %{public}s", cmd.GetUri().ToString().c_str());
1664     auto whereClause = predicates.GetWhereClause();
1665     if (!MediaLibraryCommonUtils::CheckWhereClause(whereClause)) {
1666         errCode = E_INVALID_VALUES;
1667         MEDIA_ERR_LOG("illegal query whereClause input %{private}s", whereClause.c_str());
1668         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, errCode},
1669             {KEY_OPT_TYPE, OptType::QUERY}};
1670         PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
1671         return nullptr;
1672     }
1673     MEDIA_DEBUG_LOG("CheckWhereClause end");
1674     tracer.Finish();
1675 
1676     cmd.SetDataSharePred(predicates);
1677     // MEDIALIBRARY_TABLE just for RdbPredicates
1678     NativeRdb::RdbPredicates rdbPredicate = RdbUtils::ToPredicates(predicates, MEDIALIBRARY_TABLE);
1679     cmd.GetAbsRdbPredicates()->SetWhereClause(rdbPredicate.GetWhereClause());
1680     cmd.GetAbsRdbPredicates()->SetWhereArgs(rdbPredicate.GetWhereArgs());
1681     cmd.GetAbsRdbPredicates()->SetOrder(rdbPredicate.GetOrder());
1682     MediaLibraryRdbUtils::AddVirtualColumnsOfDateType(const_cast<vector<string> &>(columns));
1683 
1684     OperationObject oprnObject = cmd.GetOprnObject();
1685     auto it = QUERY_CONDITION_MAP.find(oprnObject);
1686     if (it != QUERY_CONDITION_MAP.end()) {
1687         return MediaLibraryObjectUtils::QueryWithCondition(cmd, columns, it->second);
1688     }
1689 
1690     return QueryInternal(cmd, columns, predicates);
1691 }
1692 
QueryAnalysisAlbum(MediaLibraryCommand & cmd,const vector<string> & columns,const DataSharePredicates & predicates)1693 shared_ptr<NativeRdb::ResultSet> QueryAnalysisAlbum(MediaLibraryCommand &cmd,
1694     const vector<string> &columns, const DataSharePredicates &predicates)
1695 {
1696     RdbPredicates rdbPredicates = RdbUtils::ToPredicates(predicates, cmd.GetTableName());
1697     int32_t albumSubtype = MediaLibraryRdbUtils::GetAlbumSubtypeArgument(rdbPredicates);
1698     MEDIA_DEBUG_LOG("Query analysis album of subtype: %{public}d", albumSubtype);
1699     if (albumSubtype == PhotoAlbumSubType::GROUP_PHOTO) {
1700         return MediaLibraryAnalysisAlbumOperations::QueryGroupPhotoAlbum(cmd, columns);
1701     }
1702     if (CheckIsPortraitAlbum(cmd)) {
1703         return MediaLibraryAlbumOperations::QueryPortraitAlbum(cmd, columns);
1704     }
1705     return MediaLibraryRdbStore::QueryWithFilter(rdbPredicates, columns);
1706 }
1707 
QueryInternal(MediaLibraryCommand & cmd,const vector<string> & columns,const DataSharePredicates & predicates)1708 shared_ptr<NativeRdb::ResultSet> MediaLibraryDataManager::QueryInternal(MediaLibraryCommand &cmd,
1709     const vector<string> &columns, const DataSharePredicates &predicates)
1710 {
1711     MediaLibraryTracer tracer;
1712     switch (cmd.GetOprnObject()) {
1713         case OperationObject::FILESYSTEM_ALBUM:
1714         case OperationObject::MEDIA_VOLUME:
1715             return MediaLibraryAlbumOperations::QueryAlbumOperation(cmd, columns);
1716         case OperationObject::INDEX_CONSTRUCTION_STATUS:
1717             return MediaLibrarySearchOperations::QueryIndexConstructProgress();
1718         case OperationObject::PHOTO_ALBUM:
1719             return MediaLibraryAlbumOperations::QueryPhotoAlbum(cmd, columns);
1720         case OperationObject::ANALYSIS_PHOTO_ALBUM:
1721             return QueryAnalysisAlbum(cmd, columns, predicates);
1722         case OperationObject::PHOTO_MAP:
1723         case OperationObject::ANALYSIS_PHOTO_MAP: {
1724             return PhotoMapOperations::QueryPhotoAssets(
1725                 RdbUtils::ToPredicates(predicates, PhotoColumn::PHOTOS_TABLE), columns);
1726         }
1727         case OperationObject::FILESYSTEM_PHOTO:
1728         case OperationObject::FILESYSTEM_AUDIO:
1729         case OperationObject::PAH_MOVING_PHOTO:
1730             return MediaLibraryAssetOperations::QueryOperation(cmd, columns);
1731         case OperationObject::VISION_START ... OperationObject::VISION_END:
1732             return MediaLibraryRdbStore::QueryWithFilter(RdbUtils::ToPredicates(predicates, cmd.GetTableName()),
1733                 columns);
1734         case OperationObject::GEO_DICTIONARY:
1735         case OperationObject::GEO_KNOWLEDGE:
1736         case OperationObject::GEO_PHOTO:
1737         case OperationObject::SEARCH_TOTAL:
1738         case OperationObject::STORY_ALBUM:
1739         case OperationObject::STORY_COVER:
1740         case OperationObject::STORY_PLAY:
1741         case OperationObject::USER_PHOTOGRAPHY:
1742         case OperationObject::APP_URI_PERMISSION_INNER:
1743             return MediaLibraryRdbStore::QueryWithFilter(RdbUtils::ToPredicates(predicates, cmd.GetTableName()),
1744                 columns);
1745         case OperationObject::PAH_MULTISTAGES_CAPTURE:
1746             return MultiStagesPhotoCaptureManager::GetInstance().HandleMultiStagesOperation(cmd, columns);
1747         case OperationObject::PAH_CLOUD_ENHANCEMENT_OPERATE:
1748             return EnhancementManager::GetInstance().HandleEnhancementQueryOperation(cmd, columns);
1749         case OperationObject::TAB_OLD_PHOTO:
1750             return MediaLibraryTabOldPhotosOperations().Query(
1751                 RdbUtils::ToPredicates(predicates, TabOldPhotosColumn::OLD_PHOTOS_TABLE), columns);
1752         default:
1753             tracer.Start("QueryFile");
1754             return MediaLibraryFileOperations::QueryFileOperation(cmd, columns);
1755     }
1756 }
1757 
QueryRdb(MediaLibraryCommand & cmd,const vector<string> & columns,const DataSharePredicates & predicates,int & errCode)1758 shared_ptr<NativeRdb::ResultSet> MediaLibraryDataManager::QueryRdb(MediaLibraryCommand &cmd,
1759     const vector<string> &columns, const DataSharePredicates &predicates, int &errCode)
1760 {
1761     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
1762     if (refCnt_.load() <= 0) {
1763         errCode = E_FAIL;
1764         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, errCode},
1765             {KEY_OPT_TYPE, OptType::QUERY}};
1766         PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
1767         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
1768         return nullptr;
1769     }
1770 
1771     return QuerySet(cmd, columns, predicates, errCode);
1772 }
1773 
1774 #ifdef DISTRIBUTED
QuerySync(const string & networkId,const string & tableName)1775 bool MediaLibraryDataManager::QuerySync(const string &networkId, const string &tableName)
1776 {
1777     if (networkId.empty() || tableName.empty()) {
1778         return false;
1779     }
1780 
1781     OHOS::DistributedHardware::DmDeviceInfo deviceInfo;
1782     auto &deviceManager = OHOS::DistributedHardware::DeviceManager::GetInstance();
1783     auto ret = deviceManager.GetLocalDeviceInfo(bundleName_, deviceInfo);
1784     if (ret != ERR_OK) {
1785         MEDIA_ERR_LOG("MediaLibraryDataManager QuerySync Failed to get local device info.");
1786         return false;
1787     }
1788 
1789     if (networkId == string(deviceInfo.networkId)) {
1790         return true;
1791     }
1792 
1793     int32_t syncStatus = DEVICE_SYNCSTATUSING;
1794     auto result = MediaLibraryDevice::GetInstance()->GetDeviceSyncStatus(networkId, tableName, syncStatus);
1795     if (result && syncStatus == DEVICE_SYNCSTATUS_COMPLETE) {
1796         return true;
1797     }
1798 
1799     vector<string> devices = { networkId };
1800     MediaLibrarySyncOpts syncOpts;
1801     syncOpts.rdbStore = rdbStore_;
1802     syncOpts.table = tableName;
1803     syncOpts.bundleName = bundleName_;
1804     return MediaLibrarySyncOperation::SyncPullTable(syncOpts, devices);
1805 }
1806 #endif
1807 
OpenFile(MediaLibraryCommand & cmd,const string & mode)1808 int32_t MediaLibraryDataManager::OpenFile(MediaLibraryCommand &cmd, const string &mode)
1809 {
1810     MediaLibraryTracer tracer;
1811     tracer.Start("MediaLibraryDataManager::OpenFile");
1812     auto oprnObject = cmd.GetOprnObject();
1813     if (oprnObject == OperationObject::FILESYSTEM_PHOTO || oprnObject == OperationObject::FILESYSTEM_AUDIO ||
1814         oprnObject == OperationObject::HIGHLIGHT_COVER  || oprnObject == OperationObject::HIGHLIGHT_URI ||
1815         oprnObject == OperationObject::PTP_OPERATION) {
1816         return MediaLibraryAssetOperations::OpenOperation(cmd, mode);
1817     }
1818 
1819 #ifdef MEDIALIBRARY_COMPATIBILITY
1820     if (oprnObject != OperationObject::THUMBNAIL && oprnObject != OperationObject::THUMBNAIL_ASTC &&
1821         oprnObject != OperationObject::REQUEST_PICTURE && oprnObject != OperationObject::PHOTO_REQUEST_PICTURE_BUFFER) {
1822         string opObject = MediaFileUri::GetPathFirstDentry(const_cast<Uri &>(cmd.GetUri()));
1823         if (opObject == IMAGE_ASSET_TYPE || opObject == VIDEO_ASSET_TYPE || opObject == URI_TYPE_PHOTO) {
1824             cmd.SetOprnObject(OperationObject::FILESYSTEM_PHOTO);
1825             return MediaLibraryAssetOperations::OpenOperation(cmd, mode);
1826         }
1827         if (opObject == AUDIO_ASSET_TYPE || opObject == URI_TYPE_AUDIO_V10) {
1828             cmd.SetOprnObject(OperationObject::FILESYSTEM_AUDIO);
1829             return MediaLibraryAssetOperations::OpenOperation(cmd, mode);
1830         }
1831     }
1832 #endif
1833 
1834     return MediaLibraryObjectUtils::OpenFile(cmd, mode);
1835 }
1836 
NotifyChange(const Uri & uri)1837 void MediaLibraryDataManager::NotifyChange(const Uri &uri)
1838 {
1839     shared_lock<shared_mutex> sharedLock(mgrSharedMutex_);
1840     if (refCnt_.load() <= 0) {
1841         MEDIA_DEBUG_LOG("MediaLibraryDataManager is not initialized");
1842         return;
1843     }
1844 
1845     if (extension_ == nullptr) {
1846         MEDIA_ERR_LOG("MediaLibraryDataManager::NotifyChange failed");
1847         return;
1848     }
1849 
1850     extension_->NotifyChange(uri);
1851 }
1852 
InitialiseThumbnailService(const shared_ptr<OHOS::AbilityRuntime::Context> & extensionContext)1853 int32_t MediaLibraryDataManager::InitialiseThumbnailService(
1854     const shared_ptr<OHOS::AbilityRuntime::Context> &extensionContext)
1855 {
1856     if (thumbnailService_ != nullptr) {
1857         return E_OK;
1858     }
1859     thumbnailService_ = ThumbnailService::GetInstance();
1860     if (thumbnailService_ == nullptr) {
1861         return E_THUMBNAIL_SERVICE_NULLPTR;
1862     }
1863 #ifdef DISTRIBUTED
1864     thumbnailService_->Init(rdbStore_, kvStorePtr_, extensionContext);
1865 #else
1866     thumbnailService_->Init(rdbStore_,  extensionContext);
1867 #endif
1868     return E_OK;
1869 }
1870 
InitACLPermission()1871 void MediaLibraryDataManager::InitACLPermission()
1872 {
1873     if (access(THUMB_DIR.c_str(), F_OK) == 0) {
1874         return;
1875     }
1876 
1877     if (!MediaFileUtils::CreateDirectory(THUMB_DIR)) {
1878         MEDIA_ERR_LOG("Failed create thumbs Photo dir");
1879         return;
1880     }
1881 
1882     if (Acl::AclSetDefault() != E_OK) {
1883         MEDIA_ERR_LOG("Failed to set the acl read permission for the thumbs Photo dir");
1884     }
1885 }
1886 
InitDatabaseACLPermission()1887 void MediaLibraryDataManager::InitDatabaseACLPermission()
1888 {
1889     if (access(RDB_DIR.c_str(), F_OK) != E_OK) {
1890         if (!MediaFileUtils::CreateDirectory(RDB_DIR)) {
1891             MEDIA_ERR_LOG("Failed create media rdb dir");
1892             return;
1893         }
1894     }
1895 
1896     if (access(KVDB_DIR.c_str(), F_OK) != E_OK) {
1897         if (!MediaFileUtils::CreateDirectory(KVDB_DIR)) {
1898             MEDIA_ERR_LOG("Failed create media kvdb dir");
1899             return;
1900         }
1901     }
1902 
1903     if (Acl::AclSetDatabase() != E_OK) {
1904         MEDIA_ERR_LOG("Failed to set the acl db permission for the media db dir");
1905     }
1906 }
1907 
OnScanFinished(const int32_t status,const string & uri,const string & path)1908 int32_t ScanFileCallback::OnScanFinished(const int32_t status, const string &uri, const string &path)
1909 {
1910     auto instance = MediaLibraryDataManager::GetInstance();
1911     if (instance != nullptr) {
1912         instance->CreateThumbnailAsync(uri, path);
1913     }
1914     return E_OK;
1915 }
1916 
SetCmdBundleAndDevice(MediaLibraryCommand & outCmd)1917 int32_t MediaLibraryDataManager::SetCmdBundleAndDevice(MediaLibraryCommand &outCmd)
1918 {
1919     string clientBundle = MediaLibraryBundleManager::GetInstance()->GetClientBundleName();
1920     if (clientBundle.empty()) {
1921         MEDIA_ERR_LOG("GetClientBundleName failed");
1922         return E_GET_CLIENTBUNDLE_FAIL;
1923     }
1924     outCmd.SetBundleName(clientBundle);
1925 #ifdef DISTRIBUTED
1926     OHOS::DistributedHardware::DmDeviceInfo deviceInfo;
1927     auto &deviceManager = OHOS::DistributedHardware::DeviceManager::GetInstance();
1928     int32_t ret = deviceManager.GetLocalDeviceInfo(bundleName_, deviceInfo);
1929     if (ret < 0) {
1930         MEDIA_ERR_LOG("GetLocalDeviceInfo ret = %{public}d", ret);
1931     } else {
1932         outCmd.SetDeviceName(deviceInfo.deviceName);
1933     }
1934     return ret;
1935 #endif
1936     return 0;
1937 }
1938 
DoTrashAging(shared_ptr<int> countPtr)1939 int32_t MediaLibraryDataManager::DoTrashAging(shared_ptr<int> countPtr)
1940 {
1941     shared_ptr<int> smartAlbumTrashPtr = make_shared<int>();
1942     MediaLibrarySmartAlbumMapOperations::HandleAgingOperation(smartAlbumTrashPtr);
1943 
1944     shared_ptr<int> albumTrashtPtr = make_shared<int>();
1945     MediaLibraryAlbumOperations::HandlePhotoAlbum(OperationType::AGING, {}, {}, albumTrashtPtr);
1946 
1947     shared_ptr<int> audioTrashtPtr = make_shared<int>();
1948     MediaLibraryAudioOperations::TrashAging(audioTrashtPtr);
1949 
1950     if (countPtr != nullptr) {
1951       *countPtr = *smartAlbumTrashPtr + *albumTrashtPtr + *audioTrashtPtr;
1952     }
1953     return E_SUCCESS;
1954 }
1955 
RevertPendingByFileId(const std::string & fileId)1956 int32_t MediaLibraryDataManager::RevertPendingByFileId(const std::string &fileId)
1957 {
1958     MediaLibraryCommand cmd(OperationObject::FILESYSTEM_ASSET, OperationType::UPDATE);
1959     ValuesBucket values;
1960     values.PutLong(Media::MEDIA_DATA_DB_TIME_PENDING, 0);
1961     cmd.SetValueBucket(values);
1962     int32_t retVal = MediaLibraryObjectUtils::ModifyInfoByIdInDb(cmd, fileId);
1963     if (retVal <= 0) {
1964         MEDIA_ERR_LOG("failed to revert pending error, fileId:%{private}s", fileId.c_str());
1965         return retVal;
1966     }
1967     auto fileAsset = MediaLibraryObjectUtils::GetFileAssetFromId(fileId);
1968     string srcPath = fileAsset->GetPath();
1969     MediaLibraryObjectUtils::ScanFileAsync(srcPath, fileId, MediaLibraryApi::API_10);
1970     return E_SUCCESS;
1971 }
1972 
RevertPendingByPackage(const std::string & bundleName)1973 int32_t MediaLibraryDataManager::RevertPendingByPackage(const std::string &bundleName)
1974 {
1975     MediaLibraryCommand queryCmd(OperationObject::FILESYSTEM_ASSET, OperationType::QUERY);
1976     queryCmd.GetAbsRdbPredicates()
1977         ->EqualTo(MEDIA_DATA_DB_OWNER_PACKAGE, bundleName)
1978         ->And()
1979         ->NotEqualTo(MEDIA_DATA_DB_TIME_PENDING, to_string(0));
1980     vector<string> columns = { MEDIA_DATA_DB_ID };
1981     auto result = MediaLibraryObjectUtils::QueryWithCondition(queryCmd, columns);
1982     if (result == nullptr) {
1983         return E_HAS_DB_ERROR;
1984     }
1985 
1986     int32_t ret = E_SUCCESS;
1987     while (result->GoToNextRow() == NativeRdb::E_OK) {
1988         int32_t id = GetInt32Val(MEDIA_DATA_DB_ID, result);
1989         int32_t retVal = RevertPendingByFileId(to_string(id));
1990         if (retVal != E_SUCCESS) {
1991             ret = retVal;
1992             MEDIA_ERR_LOG("Revert file %{public}d failed, ret=%{public}d", id, retVal);
1993             continue;
1994         }
1995     }
1996     return ret;
1997 }
1998 
SetStartupParameter()1999 void MediaLibraryDataManager::SetStartupParameter()
2000 {
2001     static constexpr uint32_t BASE_USER_RANGE = 200000; // for get uid
2002     uid_t uid = getuid() / BASE_USER_RANGE;
2003     const string key = "multimedia.medialibrary.startup." + to_string(uid);
2004     string value = "true";
2005     int32_t ret = SetParameter(key.c_str(), value.c_str());
2006     if (ret != 0) {
2007         MEDIA_ERR_LOG("Failed to set startup, result: %{public}d", ret);
2008     } else {
2009         MEDIA_INFO_LOG("Set startup success: %{public}s", to_string(uid).c_str());
2010     }
2011     // init backup param
2012     std::string backupParam = "persist.multimedia.medialibrary.rdb_switch_status";
2013     ret = system::SetParameter(backupParam, "0");
2014     if (ret != 0) {
2015         MEDIA_ERR_LOG("Failed to set parameter backup, ret:%{public}d", ret);
2016     }
2017     std::string nextFlag = "persist.update.hmos_to_next_flag";
2018     auto isUpgrade = system::GetParameter(nextFlag, "");
2019     MEDIA_INFO_LOG("isUpgrade:%{public}s", isUpgrade.c_str());
2020     if (isUpgrade != "1") {
2021         return;
2022     }
2023     std::string CLONE_FLAG = "multimedia.medialibrary.cloneFlag";
2024     auto currentTime = to_string(MediaFileUtils::UTCTimeSeconds());
2025     MEDIA_INFO_LOG("SetParameterForClone currentTime:%{public}s", currentTime.c_str());
2026     bool retFlag = system::SetParameter(CLONE_FLAG, currentTime);
2027     if (!retFlag) {
2028         MEDIA_ERR_LOG("Failed to set parameter cloneFlag, retFlag:%{public}d", retFlag);
2029     }
2030 }
2031 
ProcessThumbnailBatchCmd(const MediaLibraryCommand & cmd,const NativeRdb::ValuesBucket & value,const DataShare::DataSharePredicates & predicates)2032 int32_t MediaLibraryDataManager::ProcessThumbnailBatchCmd(const MediaLibraryCommand &cmd,
2033     const NativeRdb::ValuesBucket &value, const DataShare::DataSharePredicates &predicates)
2034 {
2035     if (thumbnailService_ == nullptr) {
2036         return E_THUMBNAIL_SERVICE_NULLPTR;
2037     }
2038 
2039     int32_t requestId = 0;
2040     ValueObject valueObject;
2041     if (value.GetObject(THUMBNAIL_BATCH_GENERATE_REQUEST_ID, valueObject)) {
2042         valueObject.GetInt(requestId);
2043     }
2044 
2045     if (cmd.GetOprnType() == OperationType::START_GENERATE_THUMBNAILS) {
2046         NativeRdb::RdbPredicates rdbPredicate = RdbUtils::ToPredicates(predicates, PhotoColumn::PHOTOS_TABLE);
2047         return thumbnailService_->CreateAstcBatchOnDemand(rdbPredicate, requestId);
2048     } else if (cmd.GetOprnType() == OperationType::STOP_GENERATE_THUMBNAILS) {
2049         thumbnailService_->CancelAstcBatchTask(requestId);
2050         return E_OK;
2051     } else if (cmd.GetOprnType() == OperationType::GENERATE_THUMBNAILS_RESTORE) {
2052         return thumbnailService_->RestoreThumbnailDualFrame();
2053     } else {
2054         MEDIA_ERR_LOG("invalid mediaLibrary command");
2055         return E_INVALID_ARGUMENTS;
2056     }
2057 }
2058 
CheckCloudThumbnailDownloadFinish()2059 int32_t MediaLibraryDataManager::CheckCloudThumbnailDownloadFinish()
2060 {
2061     if (thumbnailService_ == nullptr) {
2062         MEDIA_ERR_LOG("thumbanilService is nullptr");
2063         return E_THUMBNAIL_SERVICE_NULLPTR;
2064     }
2065 
2066     return thumbnailService_->CheckCloudThumbnailDownloadFinish();
2067 }
2068 
UploadDBFileInner()2069 void MediaLibraryDataManager::UploadDBFileInner()
2070 {
2071     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
2072     if (rdbStore == nullptr) {
2073         MEDIA_ERR_LOG("rdbStore is nullptr!");
2074         return;
2075     }
2076 
2077     std::string destPath = "/data/storage/el2/log/logpack/media_library.db";
2078     std::string tmpPath = MEDIA_DB_DIR + "/rdb/media_library_tmp.db";
2079     int32_t errCode = rdbStore->Backup(tmpPath);
2080     if (errCode != 0) {
2081         MEDIA_ERR_LOG("rdb backup fail: %{public}d", errCode);
2082         return;
2083     }
2084     MediaFileUtils::CopyFileUtil(tmpPath, destPath);
2085 }
2086 
SubscriberPowerConsumptionDetection()2087 void MediaLibraryDataManager::SubscriberPowerConsumptionDetection()
2088 {
2089 #ifdef DEVICE_STANDBY_ENABLE
2090     auto subscriber = new (std::nothrow) MediaLibraryStandbyServiceSubscriber();
2091     subscriber->SetSubscriberName(SUBSCRIBER_NAME);
2092     subscriber->SetModuleName(MODULE_NAME);
2093     DevStandbyMgr::StandbyServiceClient::GetInstance().SubscribeStandbyCallback(subscriber);
2094 #endif
2095 }
2096 
SearchDateTakenWhenZero(const shared_ptr<MediaLibraryRdbStore> rdbStore,bool & needUpdate,unordered_map<string,string> & updateData)2097 static int32_t SearchDateTakenWhenZero(const shared_ptr<MediaLibraryRdbStore> rdbStore, bool &needUpdate,
2098     unordered_map<string, string> &updateData)
2099 {
2100     if (rdbStore == nullptr) {
2101         MEDIA_ERR_LOG("rdbStore is nullptr");
2102         return E_FAIL;
2103     }
2104     RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
2105     predicates.EqualTo(MediaColumn::MEDIA_DATE_TAKEN, "0");
2106     vector<string> columns = {MediaColumn::MEDIA_ID, MediaColumn::MEDIA_DATE_MODIFIED};
2107     auto resultSet = rdbStore->Query(predicates, columns);
2108     if (resultSet == nullptr) {
2109         MEDIA_ERR_LOG("failed to acquire result from visitor query.");
2110         return E_HAS_DB_ERROR;
2111     }
2112     int32_t count;
2113     int32_t retCount = resultSet->GetRowCount(count);
2114     if (retCount != E_SUCCESS || count < 0) {
2115         return E_HAS_DB_ERROR;
2116     }
2117     if (count == 0) {
2118         MEDIA_INFO_LOG("No dateTaken need to update");
2119         needUpdate = false;
2120         return E_OK;
2121     }
2122     MEDIA_INFO_LOG("Have dateTaken need to update, count = %{public}d", count);
2123     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
2124         int32_t fileId =
2125             get<int32_t>(ResultSetUtils::GetValFromColumn(MediaColumn::MEDIA_ID, resultSet, TYPE_INT32));
2126         int64_t newDateTaken =
2127             get<int64_t>(ResultSetUtils::GetValFromColumn(MediaColumn::MEDIA_DATE_MODIFIED, resultSet, TYPE_INT64));
2128         updateData.emplace(to_string(fileId), to_string(newDateTaken));
2129     }
2130     return E_OK;
2131 }
2132 
UpdateDateTakenWhenZero()2133 int32_t MediaLibraryDataManager::UpdateDateTakenWhenZero()
2134 {
2135     MEDIA_DEBUG_LOG("UpdateDateTakenWhenZero start");
2136     if (rdbStore_ == nullptr) {
2137         MEDIA_ERR_LOG("rdbStore_ is nullptr");
2138         return E_FAIL;
2139     }
2140     bool needUpdate = true;
2141     unordered_map<string, string> updateData;
2142     int32_t ret = SearchDateTakenWhenZero(rdbStore_, needUpdate, updateData);
2143     if (ret) {
2144         MEDIA_ERR_LOG("SerchDateTaken failed, ret = %{public}d", ret);
2145         return ret;
2146     }
2147     if (!needUpdate) {
2148         return E_OK;
2149     }
2150     string updateSql = "UPDATE " + PhotoColumn::PHOTOS_TABLE + " SET " + MediaColumn::MEDIA_DATE_TAKEN +
2151         " = " + PhotoColumn::MEDIA_DATE_MODIFIED + "," + PhotoColumn::PHOTO_DETAIL_TIME +
2152         " = strftime('%Y:%m:%d %H:%M:%S', date_modified/1000, 'unixepoch', 'localtime')" +
2153         " WHERE " + MediaColumn::MEDIA_DATE_TAKEN + " = 0";
2154     ret = rdbStore_->ExecuteSql(updateSql);
2155     if (ret != NativeRdb::E_OK) {
2156         MEDIA_ERR_LOG("rdbStore->ExecuteSql failed, ret = %{public}d", ret);
2157         return E_HAS_DB_ERROR;
2158     }
2159     for (const auto& data : updateData) {
2160         ThumbnailService::GetInstance()->UpdateAstcWithNewDateTaken(data.first, data.second, "0");
2161     }
2162     MEDIA_DEBUG_LOG("UpdateDateTakenWhenZero start");
2163     return ret;
2164 }
2165 
DoUpdateBurstCoverLevelOperation(const shared_ptr<MediaLibraryRdbStore> rdbStore,const std::vector<std::string> & fileIdVec)2166 static int32_t DoUpdateBurstCoverLevelOperation(const shared_ptr<MediaLibraryRdbStore> rdbStore,
2167     const std::vector<std::string> &fileIdVec)
2168 {
2169     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_FAIL, "rdbStore is nullptr");
2170     AbsRdbPredicates updatePredicates = AbsRdbPredicates(PhotoColumn::PHOTOS_TABLE);
2171     updatePredicates.In(MediaColumn::MEDIA_ID, fileIdVec);
2172     updatePredicates.BeginWrap();
2173     updatePredicates.EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL, WRONG_VALUE);
2174     updatePredicates.Or();
2175     updatePredicates.IsNull(PhotoColumn::PHOTO_BURST_COVER_LEVEL);
2176     updatePredicates.EndWrap();
2177     ValuesBucket values;
2178     values.PutInt(PhotoColumn::PHOTO_BURST_COVER_LEVEL, static_cast<int32_t>(BurstCoverLevelType::COVER));
2179 
2180     int32_t changedRows = -1;
2181     int32_t ret = rdbStore->Update(changedRows, values, updatePredicates);
2182     CHECK_AND_RETURN_RET_LOG((ret == E_OK && changedRows > 0), E_FAIL,
2183         "Failed to UpdateBurstCoverLevelFromGallery, ret: %{public}d, updateRows: %{public}d", ret, changedRows);
2184     MEDIA_INFO_LOG("UpdateBurstCoverLevelFromGallery success, changedRows: %{public}d, fileIdVec.size(): %{public}d.",
2185         changedRows, static_cast<int32_t>(fileIdVec.size()));
2186     return ret;
2187 }
2188 
UpdateBurstCoverLevelFromGallery()2189 int32_t MediaLibraryDataManager::UpdateBurstCoverLevelFromGallery()
2190 {
2191     MEDIA_INFO_LOG("UpdateBurstCoverLevelFromGallery start");
2192     CHECK_AND_RETURN_RET_LOG(refCnt_.load() > 0, E_FAIL, "MediaLibraryDataManager is not initialized");
2193     CHECK_AND_RETURN_RET_LOG(rdbStore_ != nullptr, E_FAIL, "rdbStore_ is nullptr");
2194 
2195     const std::vector<std::string> columns = { MediaColumn::MEDIA_ID };
2196     AbsRdbPredicates predicates = AbsRdbPredicates(PhotoColumn::PHOTOS_TABLE);
2197     predicates.BeginWrap();
2198     predicates.EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL, WRONG_VALUE);
2199     predicates.Or();
2200     predicates.IsNull(PhotoColumn::PHOTO_BURST_COVER_LEVEL);
2201     predicates.EndWrap();
2202     predicates.Limit(BATCH_QUERY_NUMBER);
2203 
2204     bool nextUpdate = true;
2205     while (nextUpdate && MedialibrarySubscriber::IsCurrentStatusOn()) {
2206         auto resultSet = rdbStore_->Query(predicates, columns);
2207         CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_FAIL, "Failed to query resultSet");
2208         int32_t rowCount = 0;
2209         int32_t ret = resultSet->GetRowCount(rowCount);
2210         CHECK_AND_RETURN_RET_LOG((ret == E_OK && rowCount >= 0), E_FAIL, "Failed to GetRowCount");
2211         if (rowCount == 0) {
2212             MEDIA_INFO_LOG("No need to UpdateBurstCoverLevelFromGallery.");
2213             return E_OK;
2214         }
2215         if (rowCount < BATCH_QUERY_NUMBER) {
2216             nextUpdate = false;
2217         }
2218 
2219         std::vector<std::string> fileIdVec;
2220         while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
2221             std::string fileId = GetStringVal(MediaColumn::MEDIA_ID, resultSet);
2222             fileIdVec.push_back(fileId);
2223         }
2224         resultSet->Close();
2225 
2226         CHECK_AND_RETURN_RET_LOG(DoUpdateBurstCoverLevelOperation(rdbStore_, fileIdVec) == E_OK,
2227             E_FAIL, "Failed to DoUpdateBurstCoverLevelOperation");
2228     }
2229     return E_OK;
2230 }
2231 }  // namespace Media
2232 }  // namespace OHOS
2233