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