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