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