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