1 /*
2 * Copyright (C) 2021-2022 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 #define MLOG_TAG "DataManager"
16
17 #include "medialibrary_data_manager.h"
18
19 #include <unordered_set>
20 #include <shared_mutex>
21
22 #include "abs_rdb_predicates.h"
23 #include "datashare_abs_result_set.h"
24 #include "device_manager.h"
25 #include "device_manager_callback.h"
26 #include "hitrace_meter.h"
27 #include "ipc_skeleton.h"
28 #include "media_datashare_ext_ability.h"
29 #include "media_file_utils.h"
30 #include "media_log.h"
31 #include "media_scanner_manager.h"
32 #include "medialibrary_album_operations.h"
33 #include "medialibrary_uripermission_operations.h"
34 #include "medialibrary_common_utils.h"
35 #include "medialibrary_device.h"
36 #include "medialibrary_device_info.h"
37 #include "medialibrary_dir_operations.h"
38 #include "medialibrary_errno.h"
39 #include "medialibrary_file_operations.h"
40 #include "medialibrary_object_utils.h"
41 #include "medialibrary_smartalbum_map_operations.h"
42 #include "medialibrary_smartalbum_operations.h"
43 #include "medialibrary_sync_table.h"
44 #include "medialibrary_unistore_manager.h"
45 #include "medialibrary_tracer.h"
46 #include "rdb_store.h"
47 #include "rdb_utils.h"
48 #include "system_ability_definition.h"
49 #include "timer.h"
50 #include "permission_utils.h"
51
52 using namespace std;
53 using namespace OHOS::AppExecFwk;
54 using namespace OHOS::AbilityRuntime;
55 using namespace OHOS::NativeRdb;
56 using namespace OHOS::DistributedKv;
57 using namespace OHOS::DataShare;
58 using namespace OHOS::RdbDataShareAdapter;
59
60 namespace {
61 const OHOS::DistributedKv::AppId KVSTORE_APPID = {"com.ohos.medialibrary.medialibrarydata"};
62 const OHOS::DistributedKv::StoreId KVSTORE_STOREID = {"medialibrary_thumbnail"};
63 };
64
65 namespace OHOS {
66 namespace Media {
67
68 std::shared_ptr<MediaLibraryDataManager> MediaLibraryDataManager::instance_ = nullptr;
69 std::mutex MediaLibraryDataManager::mutex_;
70
MediaLibraryDataManager(void)71 MediaLibraryDataManager::MediaLibraryDataManager(void)
72 {
73 }
74
~MediaLibraryDataManager(void)75 MediaLibraryDataManager::~MediaLibraryDataManager(void)
76 {
77 if (kvStorePtr_ != nullptr) {
78 dataManager_.CloseKvStore(KVSTORE_APPID, kvStorePtr_);
79 kvStorePtr_ = nullptr;
80 }
81 }
82
GetInstance()83 std::shared_ptr<MediaLibraryDataManager> MediaLibraryDataManager::GetInstance()
84 {
85 if (instance_ == nullptr) {
86 std::lock_guard<std::mutex> lock(mutex_);
87 if (instance_ == nullptr) {
88 instance_ = std::make_shared<MediaLibraryDataManager>();
89 }
90 }
91 return instance_;
92 }
93
MediaDataShareCreator(const std::unique_ptr<Runtime> & runtime)94 static DataShare::DataShareExtAbility *MediaDataShareCreator(const std::unique_ptr<Runtime> &runtime)
95 {
96 MEDIA_DEBUG_LOG("MediaLibraryCreator::%{public}s", __func__);
97 return MediaDataShareExtAbility::Create(runtime);
98 }
99
RegisterDataShareCreator()100 __attribute__((constructor)) void RegisterDataShareCreator()
101 {
102 MEDIA_DEBUG_LOG("MediaLibraryDataMgr::%{public}s", __func__);
103 DataShare::DataShareExtAbility::SetCreator(MediaDataShareCreator);
104 }
105
MakeRootDirs()106 static void MakeRootDirs()
107 {
108 for (auto &dir : PRESET_ROOT_DIRS) {
109 Uri createAlbumUri(MEDIALIBRARY_DATA_URI + "/" + MEDIA_ALBUMOPRN + "/" + MEDIA_ALBUMOPRN_CREATEALBUM);
110 ValuesBucket valuesBucket;
111 valuesBucket.PutString(MEDIA_DATA_DB_FILE_PATH, ROOT_MEDIA_DIR + dir);
112 MediaLibraryCommand cmd(createAlbumUri, valuesBucket);
113 auto ret = MediaLibraryAlbumOperations::CreateAlbumOperation(cmd);
114 if (ret <= 0) {
115 MEDIA_ERR_LOG("Failed to preset root dir: %{public}s", dir.c_str());
116 }
117 MediaFileUtils::CreateDirectory(ROOT_MEDIA_DIR + dir + ".recycle");
118 }
119 }
120
InitMediaLibraryMgr(const std::shared_ptr<OHOS::AbilityRuntime::Context> & context,const std::shared_ptr<OHOS::AbilityRuntime::Context> & extensionContext)121 void MediaLibraryDataManager::InitMediaLibraryMgr(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context,
122 const std::shared_ptr<OHOS::AbilityRuntime::Context> &extensionContext)
123 {
124 std::lock_guard<std::shared_mutex> lock(mgrSharedMutex_);
125
126 refCnt_++;
127 if (refCnt_.load() > 1) {
128 MEDIA_DEBUG_LOG("already initialized");
129 return;
130 }
131
132 context_ = context;
133 InitMediaLibraryRdbStore();
134 InitDeviceData();
135 MakeDirQuerySetMap(dirQuerySetMap_);
136 MakeRootDirs();
137 InitialiseKvStore();
138 InitialiseThumbnailService(extensionContext);
139 }
140
InitDeviceData()141 void MediaLibraryDataManager::InitDeviceData()
142 {
143 if (rdbStore_ == nullptr) {
144 MEDIA_ERR_LOG("MediaLibraryDataManager InitDeviceData rdbStore is null");
145 return;
146 }
147
148 MediaLibraryTracer tracer;
149 tracer.Start("InitDeviceRdbStoreTrace");
150 if (!MediaLibraryDevice::GetInstance()->InitDeviceRdbStore(rdbStore_)) {
151 MEDIA_ERR_LOG("MediaLibraryDataManager InitDeviceData failed!");
152 }
153 }
154
ClearMediaLibraryMgr()155 void MediaLibraryDataManager::ClearMediaLibraryMgr()
156 {
157 std::lock_guard<std::shared_mutex> lock(mgrSharedMutex_);
158
159 refCnt_--;
160 if (refCnt_.load() > 0) {
161 MEDIA_DEBUG_LOG("still other extension exist");
162 return;
163 }
164
165 rdbStore_ = nullptr;
166
167 if (kvStorePtr_ != nullptr) {
168 dataManager_.CloseKvStore(KVSTORE_APPID, kvStorePtr_);
169 kvStorePtr_ = nullptr;
170 }
171 if (MediaLibraryDevice::GetInstance()) {
172 MediaLibraryDevice::GetInstance()->Stop();
173 };
174 if (thumbnailService_ != nullptr) {
175 thumbnailService_->ReleaseService();
176 thumbnailService_ = nullptr;
177 }
178 MediaLibraryUnistoreManager::GetInstance().Stop();
179 extension_ = nullptr;
180 }
181
InitMediaLibraryRdbStore()182 int32_t MediaLibraryDataManager::InitMediaLibraryRdbStore()
183 {
184 if (rdbStore_) {
185 return E_SUCCESS;
186 }
187
188 MediaLibraryUnistoreManager::GetInstance().Init(context_);
189 rdbStore_ = MediaLibraryUnistoreManager::GetInstance().GetRdbStoreRaw()->GetRaw();
190
191 return E_SUCCESS;
192 }
193
InitialiseKvStore()194 void MediaLibraryDataManager::InitialiseKvStore()
195 {
196 if (kvStorePtr_ != nullptr) {
197 return;
198 }
199
200 Options options = {
201 .createIfMissing = true,
202 .encrypt = false,
203 .backup = false,
204 .autoSync = false,
205 .securityLevel = DistributedKv::SecurityLevel::S3,
206 .area = DistributedKv::Area::EL2,
207 .kvStoreType = KvStoreType::SINGLE_VERSION,
208 .baseDir = context_->GetDatabaseDir(),
209 };
210
211 Status status = dataManager_.GetSingleKvStore(options, KVSTORE_APPID, KVSTORE_STOREID, kvStorePtr_);
212 if (status != Status::SUCCESS || kvStorePtr_ == nullptr) {
213 MEDIA_INFO_LOG("MediaLibraryDataManager::InitialiseKvStore failed %{private}d", status);
214 }
215 }
216
GetOwner()217 std::shared_ptr<MediaDataShareExtAbility> MediaLibraryDataManager::GetOwner()
218 {
219 return extension_;
220 }
221
SetOwner(const std::shared_ptr<MediaDataShareExtAbility> & datashareExternsion)222 void MediaLibraryDataManager::SetOwner(const std::shared_ptr<MediaDataShareExtAbility> &datashareExternsion)
223 {
224 extension_ = datashareExternsion;
225 }
226
GetType(const Uri & uri)227 std::string MediaLibraryDataManager::GetType(const Uri &uri)
228 {
229 MEDIA_INFO_LOG("GetType uri: %{public}s", uri.ToString().c_str());
230 return "";
231 }
232
MakeDirQuerySetMap(unordered_map<string,DirAsset> & outDirQuerySetMap)233 void MediaLibraryDataManager::MakeDirQuerySetMap(unordered_map<string, DirAsset> &outDirQuerySetMap)
234 {
235 int32_t count = -1;
236 int32_t dirTypeVal = -1;
237 int32_t columnIndexDir, columnIndexMedia, columnIndexEx, columnIndexDirType;
238 string dirVal, mediaVal, exVal;
239 vector<string> columns;
240 shared_ptr<AbsSharedResultSet> queryResultSet;
241 AbsRdbPredicates dirAbsPred(MEDIATYPE_DIRECTORY_TABLE);
242 queryResultSet = rdbStore_->Query(dirAbsPred, columns);
243 auto ret = queryResultSet->GetRowCount(count);
244 if (ret != NativeRdb::E_OK) {
245 MEDIA_ERR_LOG("rdb failed");
246 return;
247 }
248 MEDIA_INFO_LOG("MakeDirQuerySetMap count = %{public}d", count);
249 if (count == 0) {
250 MEDIA_ERR_LOG("can not find any dirAsset");
251 return;
252 }
253 while (queryResultSet->GoToNextRow() == NativeRdb::E_OK) {
254 DirAsset dirAsset;
255 queryResultSet->GetColumnIndex(CATEGORY_MEDIATYPE_DIRECTORY_DB_DIRECTORY_TYPE, columnIndexDirType);
256 queryResultSet->GetInt(columnIndexDirType, dirTypeVal);
257 queryResultSet->GetColumnIndex(CATEGORY_MEDIATYPE_DIRECTORY_DB_DIRECTORY, columnIndexDir);
258 queryResultSet->GetString(columnIndexDir, dirVal);
259 queryResultSet->GetColumnIndex(CATEGORY_MEDIATYPE_DIRECTORY_DB_MEDIA_TYPE, columnIndexMedia);
260 queryResultSet->GetString(columnIndexMedia, mediaVal);
261 queryResultSet->GetColumnIndex(CATEGORY_MEDIATYPE_DIRECTORY_DB_EXTENSION, columnIndexEx);
262 queryResultSet->GetString(columnIndexEx, exVal);
263 dirAsset.SetDirType(dirTypeVal);
264 dirAsset.SetDirectory(dirVal);
265 dirAsset.SetMediaTypes(mediaVal);
266 dirAsset.SetExtensions(exVal);
267 MEDIA_INFO_LOG("dirTypeVal: %{public}d dirVal: %{private}s mediaVal: %{public}s exVal: %{public}s",
268 dirTypeVal, dirVal.c_str(), mediaVal.c_str(), exVal.c_str());
269 outDirQuerySetMap.insert(make_pair(dirVal, dirAsset));
270 }
271 MEDIA_DEBUG_LOG("MakeDirQuerySetMap OUT");
272 }
273
GetDirQuerySetMap() const274 std::unordered_map<std::string, DirAsset> MediaLibraryDataManager::GetDirQuerySetMap() const
275 {
276 return dirQuerySetMap_;
277 }
278
Insert(const Uri & uri,const DataShareValuesBucket & dataShareValue)279 int32_t MediaLibraryDataManager::Insert(const Uri &uri, const DataShareValuesBucket &dataShareValue)
280 {
281 MEDIA_DEBUG_LOG("MediaLibraryDataManager::Insert");
282 std::shared_lock<std::shared_mutex> sharedLock(mgrSharedMutex_);
283
284 ValuesBucket value = RdbUtils::ToValuesBucket(dataShareValue);
285 if (value.IsEmpty()) {
286 MEDIA_ERR_LOG("MediaLibraryDataManager Insert: Input parameter is invalid");
287 return E_INVALID_VALUES;
288 }
289
290 MediaLibraryCommand cmd(uri, value);
291 // boardcast operation
292 if (cmd.GetOprnType() == OperationType::SCAN) {
293 string scanPath = ROOT_MEDIA_DIR;
294 return MediaScannerManager::GetInstance()->ScanDir(scanPath, nullptr);
295 } else if ((cmd.GetOprnType() == OperationType::CREATE) && !CheckFileNameValid(dataShareValue)) {
296 return E_FILE_NAME_INVALID;
297 }
298
299 int32_t result = E_FAIL;
300 vector<string> devices;
301 // after replace all xxxOperations following, remove "operationType"
302 string operationType = MediaLibraryDataManagerUtils::GetOperationType(uri.ToString());
303 switch (cmd.GetOprnObject()) {
304 case OperationObject::FILESYSTEM_ASSET: {
305 result = MediaLibraryFileOperations::HandleFileOperation(cmd);
306 break;
307 }
308 case OperationObject::FILESYSTEM_ALBUM: {
309 result = MediaLibraryAlbumOperations::CreateAlbumOperation(cmd);
310 break;
311 }
312 case OperationObject::FILESYSTEM_DIR: {
313 MediaLibraryDirOperations dirOprn;
314 result = dirOprn.HandleDirOperations(operationType, value, rdbStore_, dirQuerySetMap_);
315 MediaLibrarySyncTable::SyncPushTable(rdbStore_, bundleName_, MEDIALIBRARY_TABLE, devices);
316 break;
317 }
318 case OperationObject::SMART_ALBUM: {
319 MediaLibrarySmartAlbumOperations smartalbumOprn;
320 result = smartalbumOprn.HandleSmartAlbumOperations(operationType, value, rdbStore_);
321 MediaLibrarySyncTable::SyncPushTable(rdbStore_, bundleName_, MEDIALIBRARY_TABLE, devices);
322 break;
323 }
324 case OperationObject::SMART_ALBUM_MAP: {
325 MediaLibrarySmartAlbumMapOperations smartalbumMapOprn;
326 result = smartalbumMapOprn.HandleSmartAlbumMapOperations(operationType, value, rdbStore_, dirQuerySetMap_);
327 MediaLibrarySyncTable::SyncPushTable(rdbStore_, bundleName_, MEDIALIBRARY_TABLE, devices);
328 break;
329 }
330 case OperationObject::THUMBNAIL: {
331 result = HandleThumbnailOperations(cmd);
332 break;
333 }
334 case OperationObject::BUNDLE_PERMISSION: {
335 result = UriPermissionOperations::HandleUriPermOperations(cmd);
336 break;
337 }
338 default: {
339 result = MediaLibraryObjectUtils::InsertInDb(cmd);
340 MediaLibrarySyncTable::SyncPushTable(rdbStore_, bundleName_, MEDIALIBRARY_TABLE, devices);
341 break;
342 }
343 }
344 return result;
345 }
346
HandleThumbnailOperations(MediaLibraryCommand & cmd)347 int32_t MediaLibraryDataManager::HandleThumbnailOperations(MediaLibraryCommand &cmd)
348 {
349 int32_t result = E_FAIL;
350 switch (cmd.GetOprnType()) {
351 case OperationType::GENERATE:
352 result = thumbnailService_->GenerateThumbnails();
353 break;
354 case OperationType::AGING:
355 result = thumbnailService_->LcdAging();
356 break;
357 case OperationType::DISTRIBUTE_AGING:
358 result = DistributeDeviceAging();
359 break;
360 case OperationType::DISTRIBUTE_CREATE:
361 result = CreateThumbnail(cmd.GetValueBucket());
362 break;
363 default:
364 MEDIA_ERR_LOG("bad operation type %{public}u", cmd.GetOprnType());
365 }
366 return result;
367 }
368
BatchInsert(const Uri & uri,const vector<DataShareValuesBucket> & values)369 int32_t MediaLibraryDataManager::BatchInsert(const Uri &uri, const vector<DataShareValuesBucket> &values)
370 {
371 MEDIA_DEBUG_LOG("MediaLibraryDataManager::BatchInsert");
372 std::shared_lock<std::shared_mutex> sharedLock(mgrSharedMutex_);
373
374 string uriString = uri.ToString();
375 if (uriString != MEDIALIBRARY_DATA_URI) {
376 MEDIA_ERR_LOG("MediaLibraryDataManager BatchInsert: Input parameter is invalid");
377 return E_INVALID_URI;
378 }
379 int32_t rowCount = 0;
380 for (auto it = values.begin(); it != values.end(); it++) {
381 if (Insert(uri, *it) >= 0) {
382 rowCount++;
383 }
384 }
385
386 return rowCount;
387 }
388
Delete(const Uri & uri,const DataSharePredicates & predicates)389 int32_t MediaLibraryDataManager::Delete(const Uri &uri, const DataSharePredicates &predicates)
390 {
391 MEDIA_DEBUG_LOG("MediaLibraryDataManager::Delete");
392 std::shared_lock<std::shared_mutex> sharedLock(mgrSharedMutex_);
393
394 if (uri.ToString().find(MEDIALIBRARY_DATA_URI) == string::npos) {
395 MEDIA_ERR_LOG("MediaLibraryDataManager Delete: Not Data ability Uri");
396 return E_INVALID_URI;
397 }
398
399 MediaLibraryCommand cmd(uri, OperationType::DELETE);
400 cmd.GetAbsRdbPredicates()->SetWhereClause(predicates.GetWhereClause());
401 cmd.GetAbsRdbPredicates()->SetWhereArgs(predicates.GetWhereArgs());
402
403 vector<string> devices;
404 switch (cmd.GetOprnObject()) {
405 case OperationObject::FILESYSTEM_ASSET: {
406 auto ret = MediaLibraryFileOperations::DeleteFileOperation(cmd, dirQuerySetMap_);
407 MediaLibrarySyncTable::SyncPushTable(rdbStore_, bundleName_, MEDIALIBRARY_TABLE, devices);
408 return ret;
409 }
410 case OperationObject::FILESYSTEM_DIR:
411 // supply a DeleteDirOperation here to replace
412 // delete in the HandleDirOperations in Insert function, if need
413 break;
414 case OperationObject::FILESYSTEM_ALBUM: {
415 auto ret = MediaLibraryAlbumOperations::DeleteAlbumOperation(cmd);
416 MediaLibrarySyncTable::SyncPushTable(rdbStore_, bundleName_, MEDIALIBRARY_TABLE, devices);
417 return ret;
418 }
419 default:
420 break;
421 }
422
423 // DeleteInfoByIdInDb can finish the default delete of smartalbum and smartmap,
424 // so no need to distinct them in switch-case deliberately
425 return MediaLibraryObjectUtils::DeleteInfoByIdInDb(cmd);
426 }
427
Update(const Uri & uri,const DataShareValuesBucket & dataShareValue,const DataSharePredicates & predicates)428 int32_t MediaLibraryDataManager::Update(const Uri &uri, const DataShareValuesBucket &dataShareValue,
429 const DataSharePredicates &predicates)
430 {
431 MEDIA_DEBUG_LOG("MediaLibraryDataManager::Update");
432 std::shared_lock<std::shared_mutex> sharedLock(mgrSharedMutex_);
433
434 ValuesBucket value = RdbUtils::ToValuesBucket(dataShareValue);
435 if (value.IsEmpty()) {
436 MEDIA_ERR_LOG("MediaLibraryDataManager Update:Input parameter is invalid ");
437 return E_INVALID_VALUES;
438 }
439
440 MediaLibraryCommand cmd(uri, value);
441 cmd.GetAbsRdbPredicates()->SetWhereClause(predicates.GetWhereClause());
442 cmd.GetAbsRdbPredicates()->SetWhereArgs(predicates.GetWhereArgs());
443
444 switch (cmd.GetOprnObject()) {
445 case OperationObject::FILESYSTEM_ASSET: {
446 auto ret = MediaLibraryFileOperations::ModifyFileOperation(cmd);
447 if (ret == E_SAME_PATH) {
448 break;
449 } else {
450 return ret;
451 }
452 }
453 case OperationObject::FILESYSTEM_DIR:
454 // supply a ModifyDirOperation here to replace
455 // modify in the HandleDirOperations in Insert function, if need
456 break;
457 case OperationObject::FILESYSTEM_ALBUM: {
458 return MediaLibraryAlbumOperations::ModifyAlbumOperation(cmd);
459 }
460 default:
461 break;
462 }
463 // ModifyInfoByIdInDb can finish the default update of smartalbum and smartmap,
464 // so no need to distinct them in switch-case deliberately
465 cmd.SetValueBucket(value);
466 return MediaLibraryObjectUtils::ModifyInfoByIdInDb(cmd);
467 }
468
InterruptBgworker()469 void MediaLibraryDataManager::InterruptBgworker()
470 {
471 std::shared_lock<std::shared_mutex> sharedLock(mgrSharedMutex_);
472 if (thumbnailService_ == nullptr) {
473 MEDIA_ERR_LOG("thumbnailService_ is null");
474 return;
475 }
476 thumbnailService_->InterruptBgworker();
477 }
478
GenerateThumbnails()479 int32_t MediaLibraryDataManager::GenerateThumbnails()
480 {
481 std::shared_lock<std::shared_mutex> sharedLock(mgrSharedMutex_);
482 if (thumbnailService_ == nullptr) {
483 MEDIA_ERR_LOG("thumbnailService_ is null");
484 return E_FAIL;
485 }
486 return thumbnailService_->GenerateThumbnails();
487 }
488
DoAging()489 int32_t MediaLibraryDataManager::DoAging()
490 {
491 MEDIA_DEBUG_LOG("MediaLibraryDataManager::DoAging IN");
492 std::shared_lock<std::shared_mutex> sharedLock(mgrSharedMutex_);
493 if (thumbnailService_ == nullptr) {
494 MEDIA_ERR_LOG("thumbnailService_ is null");
495 return E_FAIL;
496 }
497 int32_t errorCode = thumbnailService_->LcdAging();
498 if (errorCode != 0) {
499 MEDIA_ERR_LOG("LcdAging exist error %{public}d", errorCode);
500 }
501
502 errorCode = DistributeDeviceAging();
503 if (errorCode != 0) {
504 MEDIA_ERR_LOG("DistributeDeviceAging exist error %{public}d", errorCode);
505 }
506
507 errorCode = LcdDistributeAging();
508 if (errorCode != 0) {
509 MEDIA_ERR_LOG("LcdDistributeAging exist error %{public}d", errorCode);
510 }
511
512 return errorCode;
513 }
514
LcdDistributeAging()515 int32_t MediaLibraryDataManager::LcdDistributeAging()
516 {
517 MEDIA_DEBUG_LOG("MediaLibraryDataManager::LcdDistributeAging IN");
518 auto deviceInstance = MediaLibraryDevice::GetInstance();
519 if ((thumbnailService_ == nullptr) || (deviceInstance == nullptr)) {
520 MEDIA_ERR_LOG("thumbnailService_ is null");
521 return E_FAIL;
522 }
523 int32_t result = E_SUCCESS;
524 vector<string> deviceUdids;
525 deviceInstance->QueryAllDeviceUdid(deviceUdids);
526 for (string &udid : deviceUdids) {
527 result = thumbnailService_->LcdDistributeAging(udid);
528 if (result != E_SUCCESS) {
529 MEDIA_ERR_LOG("LcdDistributeAging fail result is %{public}d", result);
530 break;
531 }
532 }
533 return result;
534 }
535
DistributeDeviceAging()536 int32_t MediaLibraryDataManager::DistributeDeviceAging()
537 {
538 MEDIA_DEBUG_LOG("MediaLibraryDataManager::DistributeDeviceAging IN");
539 auto deviceInstance = MediaLibraryDevice::GetInstance();
540 if ((thumbnailService_ == nullptr) || (deviceInstance == nullptr)) {
541 MEDIA_ERR_LOG("thumbnailService_ is null");
542 return E_FAIL;
543 }
544 int32_t result = E_FAIL;
545 vector<MediaLibraryDeviceInfo> deviceDataBaseList;
546 deviceInstance->QueryAgingDeviceInfos(deviceDataBaseList);
547 MEDIA_DEBUG_LOG("MediaLibraryDevice InitDeviceRdbStore deviceDataBaseList size = %{public}d",
548 (int) deviceDataBaseList.size());
549 for (MediaLibraryDeviceInfo deviceInfo : deviceDataBaseList) {
550 result = thumbnailService_->InvalidateDistributeThumbnail(deviceInfo.deviceUdid);
551 if (result != E_SUCCESS) {
552 MEDIA_ERR_LOG("invalidate fail %{public}d", result);
553 continue;
554 }
555 }
556 return result;
557 }
558
GenThumbnail(const string & uri)559 shared_ptr<ResultSetBridge> MediaLibraryDataManager::GenThumbnail(const string &uri)
560 {
561 if (thumbnailService_ == nullptr) {
562 MEDIA_ERR_LOG("thumbnailService_ is null");
563 return nullptr;
564 }
565 return thumbnailService_->GetThumbnail(uri);
566 }
567
CreateThumbnailAsync(const string & uri)568 void MediaLibraryDataManager::CreateThumbnailAsync(const string &uri)
569 {
570 std::shared_lock<std::shared_mutex> sharedLock(mgrSharedMutex_);
571 if (thumbnailService_ == nullptr) {
572 MEDIA_ERR_LOG("thumbnailService_ is null");
573 return;
574 }
575 if (!uri.empty()) {
576 int32_t err = thumbnailService_->CreateThumbnailAsync(uri);
577 if (err != E_SUCCESS) {
578 MEDIA_ERR_LOG("ThumbnailService CreateThumbnailAsync failed : %{public}d", err);
579 }
580 }
581 }
582
CreateThumbnail(const ValuesBucket & values)583 int32_t MediaLibraryDataManager::CreateThumbnail(const ValuesBucket &values)
584 {
585 if (thumbnailService_ == nullptr) {
586 MEDIA_ERR_LOG("thumbnailService_ is null");
587 return E_ERR;
588 }
589 string actualUri;
590 ValueObject valueObject;
591
592 if (values.GetObject(MEDIA_DATA_DB_URI, valueObject)) {
593 valueObject.GetString(actualUri);
594 }
595
596 if (!actualUri.empty()) {
597 int32_t errorCode = thumbnailService_->CreateThumbnail(actualUri);
598 if (errorCode != E_OK) {
599 MEDIA_ERR_LOG("CreateThumbnail failed : %{public}d", errorCode);
600 return errorCode;
601 }
602 }
603 MEDIA_DEBUG_LOG("MediaLibraryDataManager CreateThumbnail: OUT");
604 return E_OK;
605 }
606
NeedQuerySync(const string & networkId,OperationObject oprnObject)607 void MediaLibraryDataManager::NeedQuerySync(const string &networkId, OperationObject oprnObject)
608 {
609 if (networkId.empty()) {
610 return;
611 }
612 // tabletype mapping into tablename
613 std::string tableName = MEDIALIBRARY_TABLE;
614 if (oprnObject == OperationObject::SMART_ALBUM) {
615 tableName = SMARTALBUM_TABLE;
616 } else if (oprnObject == OperationObject::SMART_ALBUM_MAP) {
617 tableName = SMARTALBUM_MAP_TABLE;
618 }
619
620 if ((oprnObject != OperationObject::ASSETMAP) && (oprnObject != OperationObject::SMART_ABLUM_ASSETS)) {
621 MediaLibraryTracer tracer;
622 tracer.Start("QuerySync");
623 auto ret = QuerySync(networkId, tableName);
624 MEDIA_INFO_LOG("MediaLibraryDataManager QuerySync result = %{private}d", ret);
625 }
626 }
627
Query(const Uri & uri,const vector<string> & columns,const DataSharePredicates & predicates)628 shared_ptr<ResultSetBridge> MediaLibraryDataManager::Query(const Uri &uri,
629 const vector<string> &columns, const DataSharePredicates &predicates)
630 {
631 MEDIA_DEBUG_LOG("MediaLibraryDataManager::Query");
632 MediaLibraryTracer tracer;
633 tracer.Start("MediaLibraryDataManager::Query");
634 if (rdbStore_ == nullptr) {
635 MEDIA_ERR_LOG("Rdb Store is not initialized");
636 return nullptr;
637 }
638
639 auto whereClause = predicates.GetWhereClause();
640 if (!MediaLibraryCommonUtils::CheckWhereClause(whereClause)) {
641 MEDIA_ERR_LOG("illegal query whereClause input %{public}s", whereClause.c_str());
642 return nullptr;
643 }
644
645 MediaLibraryCommand cmd(uri, OperationType::QUERY);
646 cmd.GetAbsRdbPredicates()->SetWhereClause(whereClause);
647 cmd.GetAbsRdbPredicates()->SetWhereArgs(predicates.GetWhereArgs());
648 cmd.GetAbsRdbPredicates()->SetOrder(predicates.GetOrder());
649
650 string networkId = cmd.GetOprnDevice();
651 OperationObject oprnObject = cmd.GetOprnObject();
652 NeedQuerySync(networkId, oprnObject);
653
654 shared_ptr<ResultSetBridge> queryResultSet;
655 if (cmd.GetOprnObject() == OperationObject::THUMBNAIL) {
656 string uriString = uri.ToString();
657 if (!ThumbnailService::ParseThumbnailInfo(uriString)) {
658 return nullptr;
659 }
660 tracer.Start("GenThumbnail");
661 queryResultSet = GenThumbnail(uriString);
662 } else {
663 auto absResultSet = QueryRdb(uri, columns, predicates);
664 queryResultSet = RdbUtils::ToResultSetBridge(absResultSet);
665 }
666
667 return queryResultSet;
668 }
669
QueryRdb(const Uri & uri,const vector<string> & columns,const DataSharePredicates & predicates)670 shared_ptr<AbsSharedResultSet> MediaLibraryDataManager::QueryRdb(const Uri &uri, const vector<string> &columns,
671 const DataSharePredicates &predicates)
672 {
673 std::shared_lock<std::shared_mutex> sharedLock(mgrSharedMutex_);
674 MediaLibraryTracer tracer;
675 tracer.Start("MediaLibraryDataManager::QueryRdb");
676 static const map<OperationObject, string> queryConditionMap {
677 { OperationObject::SMART_ALBUM, SMARTALBUM_DB_ID },
678 { OperationObject::SMART_ALBUM_MAP, SMARTALBUMMAP_DB_ALBUM_ID },
679 { OperationObject::FILESYSTEM_DIR, MEDIA_DATA_DB_ID },
680 { OperationObject::ALL_DEVICE, "" },
681 { OperationObject::ACTIVE_DEVICE, "" },
682 { OperationObject::ASSETMAP, "" },
683 { OperationObject::SMART_ABLUM_ASSETS, "" },
684 { OperationObject::BUNDLE_PERMISSION, "" },
685 };
686
687 MediaLibraryCommand cmd(uri, OperationType::QUERY);
688 // MEDIALIBRARY_TABLE just for RdbPredicates
689 NativeRdb::RdbPredicates rdbPredicate = RdbDataShareAdapter::RdbUtils::ToPredicates(predicates,
690 MEDIALIBRARY_TABLE);
691 cmd.GetAbsRdbPredicates()->SetWhereClause(rdbPredicate.GetWhereClause());
692 cmd.GetAbsRdbPredicates()->SetWhereArgs(rdbPredicate.GetWhereArgs());
693 cmd.GetAbsRdbPredicates()->SetOrder(rdbPredicate.GetOrder());
694
695 shared_ptr<AbsSharedResultSet> queryResultSet;
696 OperationObject oprnObject = cmd.GetOprnObject();
697 auto it = queryConditionMap.find(oprnObject);
698 if (it != queryConditionMap.end()) {
699 queryResultSet = MediaLibraryObjectUtils::QueryWithCondition(cmd, columns, it->second);
700 } else if (oprnObject == OperationObject::FILESYSTEM_ALBUM || oprnObject == OperationObject::MEDIA_VOLUME) {
701 queryResultSet = MediaLibraryAlbumOperations::QueryAlbumOperation(cmd, columns);
702 } else {
703 tracer.Start("QueryFile");
704 queryResultSet = MediaLibraryFileOperations::QueryFileOperation(cmd, columns);
705 }
706 CHECK_AND_RETURN_RET_LOG(queryResultSet != nullptr, nullptr, "Query functionality failed");
707 return queryResultSet;
708 }
709
QuerySync(const std::string & networkId,const std::string & tableName)710 bool MediaLibraryDataManager::QuerySync(const std::string &networkId, const std::string &tableName)
711 {
712 if (networkId.empty() || tableName.empty()) {
713 return false;
714 }
715
716 OHOS::DistributedHardware::DmDeviceInfo deviceInfo;
717 auto &deviceManager = OHOS::DistributedHardware::DeviceManager::GetInstance();
718 auto ret = deviceManager.GetLocalDeviceInfo(bundleName_, deviceInfo);
719 if (ret != ERR_OK) {
720 MEDIA_ERR_LOG("MediaLibraryDataManager QuerySync Failed to get local device info.");
721 return false;
722 }
723
724 if (networkId == std::string(deviceInfo.networkId)) {
725 return true;
726 }
727
728 int32_t syncStatus = DEVICE_SYNCSTATUSING;
729 auto result = MediaLibraryDevice::GetInstance()->GetDevicieSyncStatus(networkId, syncStatus);
730 if (result && syncStatus == DEVICE_SYNCSTATUS_COMPLETE) {
731 return true;
732 }
733
734 std::vector<std::string> devices = { networkId };
735 return MediaLibrarySyncTable::SyncPullTable(rdbStore_, bundleName_, tableName, devices);
736 }
737
OpenFile(const Uri & uri,const std::string & mode)738 int32_t MediaLibraryDataManager::OpenFile(const Uri &uri, const std::string &mode)
739 {
740 MediaLibraryCommand cmd(uri, OperationType::OPEN);
741 return MediaLibraryObjectUtils::OpenFile(cmd, mode);
742 }
743
CheckFileNameValid(const DataShareValuesBucket & value)744 bool MediaLibraryDataManager::CheckFileNameValid(const DataShareValuesBucket &value)
745 {
746 bool isValid = false;
747 std::string displayName = value.Get(MEDIA_DATA_DB_NAME, isValid);
748 if (!isValid) {
749 return false;
750 }
751
752 if (displayName.empty()) {
753 return false;
754 }
755
756 return true;
757 }
758
NotifyChange(const Uri & uri)759 void MediaLibraryDataManager::NotifyChange(const Uri &uri)
760 {
761 std::shared_lock<std::shared_mutex> sharedLock(mgrSharedMutex_);
762 if (extension_ != nullptr) {
763 extension_->NotifyChange(uri);
764 }
765 }
766
InitialiseThumbnailService(const std::shared_ptr<OHOS::AbilityRuntime::Context> & extensionContext)767 void MediaLibraryDataManager::InitialiseThumbnailService(
768 const std::shared_ptr<OHOS::AbilityRuntime::Context> &extensionContext)
769 {
770 if (thumbnailService_ != nullptr) {
771 return;
772 }
773 thumbnailService_ = ThumbnailService::GetInstance();
774 if (thumbnailService_ == nullptr) {
775 MEDIA_INFO_LOG("MediaLibraryDataManager::InitialiseThumbnailService failed");
776 }
777 thumbnailService_->Init(rdbStore_, kvStorePtr_, extensionContext);
778 }
779
OnScanFinished(const int32_t status,const std::string & uri,const std::string & path)780 int32_t ScanFileCallback::OnScanFinished(const int32_t status, const std::string &uri, const std::string &path)
781 {
782 auto instance = MediaLibraryDataManager::GetInstance();
783 if (instance != nullptr) {
784 instance->CreateThumbnailAsync(uri);
785 }
786 return E_OK;
787 };
788 } // namespace Media
789 } // namespace OHOS
790