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