1 /*
2 * Copyright (C) 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 #define MLOG_TAG "DfxManager"
16
17 #include "dfx_manager.h"
18
19 #include "dfx_cloud_manager.h"
20 #include "dfx_utils.h"
21 #include "media_file_utils.h"
22 #include "media_log.h"
23 #include "userfile_manager_types.h"
24 #include "medialibrary_bundle_manager.h"
25 #ifdef META_RECOVERY_SUPPORT
26 #include "medialibrary_meta_recovery.h"
27 #endif
28 #include "dfx_database_utils.h"
29 #include "vision_aesthetics_score_column.h"
30 #include "parameters.h"
31 #include "preferences.h"
32 #include "preferences_helper.h"
33 #include "hi_audit.h"
34 #include "medialibrary_errno.h"
35
36 using namespace std;
37
38 namespace OHOS {
39 namespace Media {
40
41 shared_ptr<DfxManager> DfxManager::dfxManagerInstance_{nullptr};
42 mutex DfxManager::instanceLock_;
43
GetInstance()44 shared_ptr<DfxManager> DfxManager::GetInstance()
45 {
46 lock_guard<mutex> lockGuard(instanceLock_);
47 if (dfxManagerInstance_ == nullptr) {
48 dfxManagerInstance_ = make_shared<DfxManager>();
49 if (dfxManagerInstance_ != nullptr) {
50 dfxManagerInstance_->Init();
51 }
52 }
53 return dfxManagerInstance_;
54 }
55
DfxManager()56 DfxManager::DfxManager() : isInitSuccess_(false)
57 {
58 }
59
~DfxManager()60 DfxManager::~DfxManager()
61 {
62 }
63
Init()64 void DfxManager::Init()
65 {
66 MEDIA_INFO_LOG("Init DfxManager");
67 dfxCollector_ = make_shared<DfxCollector>();
68 dfxAnalyzer_ = make_shared<DfxAnalyzer>();
69 dfxReporter_ = make_shared<DfxReporter>();
70 dfxWorker_ = DfxWorker::GetInstance();
71 dfxWorker_->Init();
72 isInitSuccess_ = true;
73 }
74
HandleTimeOutOperation(std::string &bundleName, int32_t type, int32_t object, int32_t time)75 void DfxManager::HandleTimeOutOperation(std::string &bundleName, int32_t type, int32_t object, int32_t time)
76 {
77 if (!isInitSuccess_) {
78 MEDIA_WARN_LOG("DfxManager not init");
79 return;
80 }
81 dfxReporter_->ReportTimeOutOperation(bundleName, type, object, time);
82 }
83
HandleHighMemoryThumbnail(std::string &path, int32_t mediaType, int32_t width, int32_t height)84 int32_t DfxManager::HandleHighMemoryThumbnail(std::string &path, int32_t mediaType, int32_t width,
85 int32_t height)
86 {
87 if (!isInitSuccess_) {
88 MEDIA_WARN_LOG("DfxManager not init");
89 return NOT_INIT;
90 }
91 string suffix = MediaFileUtils::GetExtensionFromPath(path);
92 if (mediaType == MEDIA_TYPE_IMAGE) {
93 return dfxReporter_->ReportHighMemoryImageThumbnail(path, suffix, width, height);
94 } else {
95 return dfxReporter_->ReportHighMemoryVideoThumbnail(path, suffix, width, height);
96 }
97 }
98
HandleThumbnailError(const std::string &path, int32_t method, int32_t errorCode)99 void DfxManager::HandleThumbnailError(const std::string &path, int32_t method, int32_t errorCode)
100 {
101 string safePath = DfxUtils::GetSafePath(path);
102 MEDIA_ERR_LOG("Failed to %{public}d, path: %{public}s, err: %{public}d", method, safePath.c_str(), errorCode);
103 if (!isInitSuccess_) {
104 MEDIA_WARN_LOG("DfxManager not init");
105 return;
106 }
107 dfxCollector_->CollectThumbnailError(safePath, method, errorCode);
108 }
109
HandleThumbnailGeneration(const ThumbnailData::GenerateStats &stats)110 void DfxManager::HandleThumbnailGeneration(const ThumbnailData::GenerateStats &stats)
111 {
112 if (!isInitSuccess_) {
113 MEDIA_WARN_LOG("DfxManager not init");
114 return;
115 }
116 dfxReporter_->ReportThumbnailGeneration(stats);
117 }
118
HandleCommonBehavior(string bundleName, int32_t type)119 void DfxManager::HandleCommonBehavior(string bundleName, int32_t type)
120 {
121 if (!isInitSuccess_) {
122 MEDIA_WARN_LOG("DfxManager not init");
123 return;
124 }
125 dfxCollector_->AddCommonBahavior(bundleName, type);
126 }
127
LogDelete(DfxData *data)128 static void LogDelete(DfxData *data)
129 {
130 if (data == nullptr) {
131 return;
132 }
133 auto *taskData = static_cast<DeleteBehaviorTask *>(data);
134 string id = taskData->id_;
135 int32_t type = taskData->type_;
136 int32_t size = taskData->size_;
137 std::shared_ptr<DfxReporter> dfxReporter = taskData->dfxReporter_;
138 MEDIA_INFO_LOG("id: %{public}s, type: %{public}d, size: %{public}d", id.c_str(), type, size);
139
140 OHOS::Media::AuditLog auditLog;
141 auditLog.isUserBehavior = true;
142 auditLog.cause = "USER BEHAVIOR";
143 auditLog.operationType = "DELETE";
144 auditLog.operationScenario = "io";
145 auditLog.operationCount = 1,
146 auditLog.operationStatus = "running";
147 auditLog.extend = "OK",
148 auditLog.id = id;
149 auditLog.type = type;
150 auditLog.size = size;
151 OHOS::Media::HiAudit::GetInstance().Write(auditLog);
152
153 std::vector<std::string> uris = taskData->uris_;
154 if (!uris.empty()) {
155 for (auto& uri: uris) {
156 string::size_type pos = uri.find_last_of('/');
157 if (pos == string::npos) {
158 continue;
159 }
160 string halfUri = uri.substr(0, pos);
161 string::size_type pathPos = halfUri.find_last_of('/');
162 if (pathPos == string::npos) {
163 continue;
164 }
165 dfxReporter->ReportDeleteBehavior(id, type, halfUri.substr(pathPos + 1));
166 }
167 }
168 }
169
HandleNoPermmison(int32_t type, int32_t object, int32_t error)170 void DfxManager::HandleNoPermmison(int32_t type, int32_t object, int32_t error)
171 {
172 MEDIA_INFO_LOG("permission deny: {%{public}d, %{public}d, %{public}d}", type, object, error);
173 }
174
HandleDeleteBehavior(int32_t type, int32_t size, std::vector<std::string> &uris, string bundleName)175 void DfxManager::HandleDeleteBehavior(int32_t type, int32_t size, std::vector<std::string> &uris, string bundleName)
176 {
177 if (bundleName == "") {
178 bundleName = MediaLibraryBundleManager::GetInstance()->GetClientBundleName();
179 }
180 dfxCollector_->CollectDeleteBehavior(bundleName, type, size);
181 if (dfxWorker_ == nullptr) {
182 MEDIA_ERR_LOG("Can not get dfxWork_");
183 return;
184 }
185 string id = bundleName == "" ? to_string(IPCSkeleton::GetCallingUid()) : bundleName;
186 auto *taskData = new (nothrow) DeleteBehaviorTask(id, type, size, uris, dfxReporter_);
187 if (taskData == nullptr) {
188 MEDIA_ERR_LOG("Failed to new taskData");
189 return;
190 }
191 auto deleteBehaviorTask = make_shared<DfxTask>(LogDelete, taskData);
192 if (deleteBehaviorTask == nullptr) {
193 MEDIA_ERR_LOG("Failed to create async task for deleteBehaviorTask.");
194 return;
195 }
196 dfxWorker_->AddTask(deleteBehaviorTask);
197 }
198
HandlePhotoInfo(std::shared_ptr<DfxReporter> &dfxReporter)199 static void HandlePhotoInfo(std::shared_ptr<DfxReporter> &dfxReporter)
200 {
201 int32_t localImageCount = DfxDatabaseUtils::QueryFromPhotos(MediaType::MEDIA_TYPE_IMAGE, true);
202 int32_t localVideoCount = DfxDatabaseUtils::QueryFromPhotos(MediaType::MEDIA_TYPE_VIDEO, true);
203 int32_t cloudImageCount = DfxDatabaseUtils::QueryFromPhotos(MediaType::MEDIA_TYPE_IMAGE, false);
204 int32_t cloudVideoCount = DfxDatabaseUtils::QueryFromPhotos(MediaType::MEDIA_TYPE_VIDEO, false);
205 MEDIA_INFO_LOG("localImageCount: %{public}d, localVideoCount: %{public}d, cloudImageCount: %{public}d, \
206 cloudVideoCount: %{public}d", localImageCount, localVideoCount, cloudImageCount, cloudVideoCount);
207 dfxReporter->ReportPhotoInfo(localImageCount, localVideoCount, cloudImageCount, cloudVideoCount);
208 }
209
HandleAlbumInfoBySubtype(std::shared_ptr<DfxReporter> &dfxReporter, int32_t albumSubType)210 static void HandleAlbumInfoBySubtype(std::shared_ptr<DfxReporter> &dfxReporter, int32_t albumSubType)
211 {
212 AlbumInfo albumInfo = DfxDatabaseUtils::QueryAlbumInfoBySubtype(albumSubType);
213 string albumName = ALBUM_MAP.at(albumSubType);
214 MEDIA_INFO_LOG("album %{public}s: {count:%{public}d, imageCount:%{public}d, videoCount:%{public}d, \
215 isLocal:%{public}d}", albumName.c_str(), albumInfo.count, albumInfo.imageCount, albumInfo.videoCount,
216 albumInfo.isLocal);
217 dfxReporter->ReportAlbumInfo(albumName.c_str(), albumInfo.imageCount, albumInfo.videoCount, albumInfo.isLocal);
218 }
219
HandleAlbumInfo(std::shared_ptr<DfxReporter> &dfxReporter)220 static void HandleAlbumInfo(std::shared_ptr<DfxReporter> &dfxReporter)
221 {
222 HandleAlbumInfoBySubtype(dfxReporter, static_cast<int32_t>(PhotoAlbumSubType::IMAGE));
223 HandleAlbumInfoBySubtype(dfxReporter, static_cast<int32_t>(PhotoAlbumSubType::VIDEO));
224 HandleAlbumInfoBySubtype(dfxReporter, static_cast<int32_t>(PhotoAlbumSubType::FAVORITE));
225 HandleAlbumInfoBySubtype(dfxReporter, static_cast<int32_t>(PhotoAlbumSubType::HIDDEN));
226 HandleAlbumInfoBySubtype(dfxReporter, static_cast<int32_t>(PhotoAlbumSubType::TRASH));
227 }
228
HandleDirtyCloudPhoto(std::shared_ptr<DfxReporter> &dfxReporter)229 static void HandleDirtyCloudPhoto(std::shared_ptr<DfxReporter> &dfxReporter)
230 {
231 vector<PhotoInfo> photoInfoList = DfxDatabaseUtils::QueryDirtyCloudPhoto();
232 if (photoInfoList.empty()) {
233 return;
234 }
235 for (auto& photoInfo: photoInfoList) {
236 dfxReporter->ReportDirtyCloudPhoto(photoInfo.data, photoInfo.dirty, photoInfo.cloudVersion);
237 }
238 }
239
HandleLocalVersion(std::shared_ptr<DfxReporter> &dfxReporter)240 static void HandleLocalVersion(std::shared_ptr<DfxReporter> &dfxReporter)
241 {
242 int32_t dbVersion = DfxDatabaseUtils::QueryDbVersion();
243 dfxReporter->ReportCommonVersion(dbVersion);
244 int32_t aestheticsVersion = DfxDatabaseUtils::QueryAnalysisVersion("tab_analysis_aesthetics_score",
245 AESTHETICS_VERSION);
246 dfxReporter->ReportAnalysisVersion("tab_analysis_aesthetics_score", aestheticsVersion);
247 }
248
HandleStatistic(DfxData *data)249 static void HandleStatistic(DfxData *data)
250 {
251 if (data == nullptr) {
252 return;
253 }
254 auto *taskData = static_cast<StatisticData *>(data);
255 std::shared_ptr<DfxReporter> dfxReporter = taskData->dfxReporter_;
256 HandlePhotoInfo(dfxReporter);
257 HandleAlbumInfo(dfxReporter);
258 HandleDirtyCloudPhoto(dfxReporter);
259 HandleLocalVersion(dfxReporter);
260 #ifdef META_RECOVERY_SUPPORT
261 MediaLibraryMetaRecovery::GetInstance().RecoveryStatistic();
262 #endif
263 }
264
HandleHalfDayMissions()265 void DfxManager::HandleHalfDayMissions()
266 {
267 if (!isInitSuccess_) {
268 MEDIA_WARN_LOG("DfxManager not init");
269 return;
270 }
271 int32_t errCode;
272 shared_ptr<NativePreferences::Preferences> prefs =
273 NativePreferences::PreferencesHelper::GetPreferences(DFX_COMMON_XML, errCode);
274 if (!prefs) {
275 MEDIA_ERR_LOG("get preferences error: %{public}d", errCode);
276 return;
277 }
278 int64_t lastReportTime = prefs->GetLong(LAST_HALF_DAY_REPORT_TIME, 0);
279 if (MediaFileUtils::UTCTimeSeconds() - lastReportTime > HALF_DAY && dfxWorker_ != nullptr) {
280 MEDIA_INFO_LOG("start handle statistic behavior");
281 auto *taskData = new (nothrow) StatisticData(dfxReporter_);
282 if (taskData == nullptr) {
283 MEDIA_ERR_LOG("Failed to alloc async data for Handle Half Day Missions!");
284 return;
285 }
286 auto statisticTask = make_shared<DfxTask>(HandleStatistic, taskData);
287 if (statisticTask == nullptr) {
288 MEDIA_ERR_LOG("Failed to create statistic task.");
289 return;
290 }
291 dfxWorker_->AddTask(statisticTask);
292 int64_t time = MediaFileUtils::UTCTimeSeconds();
293 prefs->PutLong(LAST_HALF_DAY_REPORT_TIME, time);
294 prefs->FlushSync();
295 }
296 }
297
IsDirectoryExist(const string& dirName)298 void DfxManager::IsDirectoryExist(const string& dirName)
299 {
300 struct stat statInfo {};
301 if (stat(dirName.c_str(), &statInfo) == E_SUCCESS) {
302 if (statInfo.st_mode & S_IFDIR) {
303 return;
304 }
305 MEDIA_ERR_LOG("Not Is DIR, errno is %{public}d", errno);
306 return;
307 }
308 MEDIA_ERR_LOG("Directory Not Exist, errno is %{public}d", errno);
309 return;
310 }
311
CheckStatus()312 void DfxManager::CheckStatus()
313 {
314 const std::string CLOUD_FILE_PATH = "/storage/cloud/files";
315 IsDirectoryExist(CLOUD_FILE_PATH);
316 }
317
HandleFiveMinuteTask()318 void DfxManager::HandleFiveMinuteTask()
319 {
320 if (!isInitSuccess_) {
321 MEDIA_WARN_LOG("DfxManager not init");
322 return;
323 }
324 std::unordered_map<string, CommonBehavior> commonBehavior = dfxCollector_->GetCommonBehavior();
325 dfxAnalyzer_->FlushCommonBehavior(commonBehavior);
326 HandleDeleteBehaviors();
327 std::unordered_map<std::string, ThumbnailErrorInfo> result = dfxCollector_->GetThumbnailError();
328 dfxAnalyzer_->FlushThumbnail(result);
329 AdaptationToMovingPhotoInfo adaptationInfo = dfxCollector_->GetAdaptationToMovingPhotoInfo();
330 dfxAnalyzer_->FlushAdaptationToMovingPhoto(adaptationInfo);
331 CheckStatus();
332 }
333
HandleDeleteBehaviors()334 void DfxManager::HandleDeleteBehaviors()
335 {
336 std::unordered_map<string, int32_t> deleteAssetToTrash =
337 dfxCollector_->GetDeleteBehavior(DfxType::TRASH_PHOTO);
338 dfxAnalyzer_->FlushDeleteBehavior(deleteAssetToTrash, DfxType::TRASH_PHOTO);
339 std::unordered_map<string, int32_t> deleteAssetFromDisk =
340 dfxCollector_->GetDeleteBehavior(DfxType::ALBUM_DELETE_ASSETS);
341 dfxAnalyzer_->FlushDeleteBehavior(deleteAssetToTrash, DfxType::ALBUM_DELETE_ASSETS);
342 std::unordered_map<string, int32_t> removeAssets =
343 dfxCollector_->GetDeleteBehavior(DfxType::ALBUM_REMOVE_PHOTOS);
344 dfxAnalyzer_->FlushDeleteBehavior(removeAssets, DfxType::ALBUM_REMOVE_PHOTOS);
345 }
346
HandleMiddleReport()347 int64_t DfxManager::HandleMiddleReport()
348 {
349 if (!isInitSuccess_) {
350 MEDIA_WARN_LOG("DfxManager not init");
351 return MediaFileUtils::UTCTimeSeconds();
352 }
353 dfxReporter_->ReportCommonBehavior();
354 dfxReporter_->ReportDeleteStatistic();
355 return MediaFileUtils::UTCTimeSeconds();
356 }
357
HandleOneDayReport()358 int64_t DfxManager::HandleOneDayReport()
359 {
360 if (!isInitSuccess_) {
361 MEDIA_WARN_LOG("DfxManager not init");
362 return MediaFileUtils::UTCTimeSeconds();
363 }
364 dfxReporter_->ReportThumbnailError();
365 dfxReporter_->ReportAdaptationToMovingPhoto();
366 dfxReporter_->ReportPhotoRecordInfo();
367 return MediaFileUtils::UTCTimeSeconds();
368 }
369
HandleAdaptationToMovingPhoto(const string &appName, bool adapted)370 void DfxManager::HandleAdaptationToMovingPhoto(const string &appName, bool adapted)
371 {
372 if (!isInitSuccess_) {
373 MEDIA_WARN_LOG("DfxManager not init");
374 return;
375 }
376 dfxCollector_->CollectAdaptationToMovingPhotoInfo(appName, adapted);
377 }
378
IsReported()379 bool IsReported()
380 {
381 int32_t errCode;
382 shared_ptr<NativePreferences::Preferences> prefs =
383 NativePreferences::PreferencesHelper::GetPreferences(DFX_COMMON_XML, errCode);
384 if (!prefs) {
385 MEDIA_ERR_LOG("get dfx common preferences error: %{public}d", errCode);
386 return false;
387 }
388 return prefs->GetBool(IS_REPORTED, false);
389 }
390
SetReported(bool isReported)391 void SetReported(bool isReported)
392 {
393 int32_t errCode;
394 shared_ptr<NativePreferences::Preferences> prefs =
395 NativePreferences::PreferencesHelper::GetPreferences(DFX_COMMON_XML, errCode);
396 if (!prefs) {
397 MEDIA_ERR_LOG("get dfx common preferences error: %{public}d", errCode);
398 return;
399 }
400 prefs->PutBool(IS_REPORTED, isReported);
401 }
402
~CloudSyncDfxManager()403 CloudSyncDfxManager::~CloudSyncDfxManager()
404 {
405 ShutDownTimer();
406 }
407
GetInstance()408 CloudSyncDfxManager& CloudSyncDfxManager::GetInstance()
409 {
410 static CloudSyncDfxManager cloudSyncDfxManager;
411 return cloudSyncDfxManager;
412 }
413
GetCloudSyncStatus()414 CloudSyncStatus GetCloudSyncStatus()
415 {
416 return static_cast<CloudSyncStatus>(system::GetParameter(CLOUDSYNC_STATUS_KEY, "0").at(0) - '0');
417 }
418
CloudSyncDfxManager()419 CloudSyncDfxManager::CloudSyncDfxManager()
420 {
421 InitSyncState();
422 uint16_t newState = static_cast<uint16_t>(syncState_);
423 stateProcessFuncs_[newState].Process(*this);
424 }
425
InitSyncState()426 void CloudSyncDfxManager::InitSyncState()
427 {
428 CloudSyncStatus cloudSyncStatus = GetCloudSyncStatus();
429 switch (cloudSyncStatus) {
430 case CloudSyncStatus::BEGIN:
431 case CloudSyncStatus::SYNC_SWITCHED_OFF:
432 syncState_ = SyncState::INIT_STATE;
433 return;
434 case CloudSyncStatus::FIRST_FIVE_HUNDRED:
435 case CloudSyncStatus::TOTAL_DOWNLOAD:
436 syncState_ = SyncState::START_STATE;
437 return;
438 case CloudSyncStatus::TOTAL_DOWNLOAD_FINISH:
439 syncState_ = SyncState::END_STATE;
440 return;
441 default:
442 return;
443 }
444 }
445
StateSwitch(CloudSyncDfxManager& manager)446 bool InitState::StateSwitch(CloudSyncDfxManager& manager)
447 {
448 CloudSyncStatus cloudSyncStatus = GetCloudSyncStatus();
449 switch (cloudSyncStatus) {
450 case CloudSyncStatus::FIRST_FIVE_HUNDRED:
451 case CloudSyncStatus::TOTAL_DOWNLOAD:
452 manager.syncState_ = SyncState::START_STATE;
453 return true;
454 case CloudSyncStatus::TOTAL_DOWNLOAD_FINISH:
455 manager.syncState_ = SyncState::END_STATE;
456 MEDIA_INFO_LOG("CloudSyncDfxManager new status:%{public}hu", manager.syncState_);
457 return true;
458 default:
459 return false;
460 }
461 }
462
Process(CloudSyncDfxManager& manager)463 void InitState::Process(CloudSyncDfxManager& manager)
464 {
465 MEDIA_INFO_LOG("CloudSyncDfxManager new status:%{public}hu", manager.syncState_);
466 manager.ResetStartTime();
467 manager.ShutDownTimer();
468 SetReported(false);
469 }
470
RunDfx()471 void CloudSyncDfxManager::RunDfx()
472 {
473 uint16_t oldState = static_cast<uint16_t>(syncState_);
474 if (stateProcessFuncs_[oldState].StateSwitch(*this)) {
475 uint16_t newState = static_cast<uint16_t>(syncState_);
476 stateProcessFuncs_[newState].Process(*this);
477 }
478 }
479
StateSwitch(CloudSyncDfxManager& manager)480 bool StartState::StateSwitch(CloudSyncDfxManager& manager)
481 {
482 CloudSyncStatus cloudSyncStatus = GetCloudSyncStatus();
483 switch (cloudSyncStatus) {
484 case CloudSyncStatus::BEGIN:
485 case CloudSyncStatus::SYNC_SWITCHED_OFF:
486 manager.syncState_ = SyncState::INIT_STATE;
487 return true;
488 case CloudSyncStatus::TOTAL_DOWNLOAD_FINISH:
489 manager.syncState_ = SyncState::END_STATE;
490 MEDIA_INFO_LOG("CloudSyncDfxManager new status:%{public}hu", manager.syncState_);
491 return true;
492 default:
493 return false;
494 }
495 }
496
Process(CloudSyncDfxManager& manager)497 void StartState::Process(CloudSyncDfxManager& manager)
498 {
499 MEDIA_INFO_LOG("CloudSyncDfxManager new status:%{public}hu", manager.syncState_);
500 manager.SetStartTime();
501 manager.StartTimer();
502 SetReported(false);
503 }
504
StateSwitch(CloudSyncDfxManager& manager)505 bool EndState::StateSwitch(CloudSyncDfxManager& manager)
506 {
507 CloudSyncStatus cloudSyncStatus = GetCloudSyncStatus();
508 switch (cloudSyncStatus) {
509 case CloudSyncStatus::BEGIN:
510 case CloudSyncStatus::SYNC_SWITCHED_OFF:
511 manager.syncState_ = SyncState::INIT_STATE;
512 return true;
513 case CloudSyncStatus::TOTAL_DOWNLOAD_FINISH:
514 return true;
515 default:
516 return false;
517 }
518 }
519
Process(CloudSyncDfxManager& manager)520 void EndState::Process(CloudSyncDfxManager& manager)
521 {
522 std::unique_lock<std::mutex> lock(manager.endStateMutex_);
523 if (IsReported()) {
524 manager.ShutDownTimer();
525 return;
526 }
527 manager.SetStartTime();
528 manager.StartTimer();
529 int32_t downloadedThumb = 0;
530 int32_t generatedThumb = 0;
531 if (!DfxDatabaseUtils::QueryDownloadedAndGeneratedThumb(downloadedThumb, generatedThumb)) {
532 if (downloadedThumb != generatedThumb) {
533 return;
534 }
535 int32_t totalDownload = 0;
536 DfxDatabaseUtils::QueryTotalCloudThumb(totalDownload);
537 if (totalDownload != downloadedThumb) {
538 return;
539 }
540 SetReported(true);
541 manager.ShutDownTimer();
542 DfxReporter::ReportCloudSyncThumbGenerationStatus(downloadedThumb, generatedThumb, totalDownload);
543 }
544 }
545
StartTimer()546 void CloudSyncDfxManager::StartTimer()
547 {
548 std::unique_lock<std::mutex> lock(timerMutex_);
549 if (timerId_ != 0) {
550 return;
551 }
552 if (timer_.Setup() != ERR_OK) {
553 MEDIA_INFO_LOG("CloudSync Dfx Set Timer Failed");
554 return;
555 }
556 Utils::Timer::TimerCallback timerCallback = [this]() {
557 if (IsReported()) {
558 return;
559 }
560 int32_t generatedThumb = 0;
561 int32_t downloadedThumb = 0;
562 if (!DfxDatabaseUtils::QueryDownloadedAndGeneratedThumb(downloadedThumb, generatedThumb)) {
563 int32_t totalDownload = 0;
564 DfxDatabaseUtils::QueryTotalCloudThumb(totalDownload);
565 if (downloadedThumb == generatedThumb && totalDownload == generatedThumb) {
566 MEDIA_INFO_LOG("CloudSyncDfxManager Dfx report Thumb generation status, "
567 "download: %{public}d, generate: %{public}d", downloadedThumb, generatedThumb);
568 SetReported(true);
569 }
570 DfxReporter::ReportCloudSyncThumbGenerationStatus(downloadedThumb, generatedThumb, totalDownload);
571 }
572 };
573 timerId_ = timer_.Register(timerCallback, SIX_HOUR * TO_MILLION, false);
574 MEDIA_INFO_LOG("CloudSyncDfxManager StartTimer id:%{public}d", timerId_);
575 }
576
ShutDownTimer()577 void CloudSyncDfxManager::ShutDownTimer()
578 {
579 std::unique_lock<std::mutex> lock(timerMutex_);
580 if (timerId_ == 0) {
581 return;
582 }
583 MEDIA_INFO_LOG("CloudSyncDfxManager ShutDownTimer id:%{public}d", timerId_);
584 timer_.Unregister(timerId_);
585 timerId_ = 0;
586 timer_.Shutdown();
587 }
588
ResetStartTime()589 void CloudSyncDfxManager::ResetStartTime()
590 {
591 int32_t errCode;
592 shared_ptr<NativePreferences::Preferences> prefs =
593 NativePreferences::PreferencesHelper::GetPreferences(DFX_COMMON_XML, errCode);
594 if (!prefs) {
595 MEDIA_ERR_LOG("get dfx common preferences error: %{public}d", errCode);
596 return;
597 }
598 prefs->PutLong(CLOUD_SYNC_START_TIME, 0);
599 prefs->FlushSync();
600 }
601
SetStartTime()602 void CloudSyncDfxManager::SetStartTime()
603 {
604 int32_t errCode;
605 shared_ptr<NativePreferences::Preferences> prefs =
606 NativePreferences::PreferencesHelper::GetPreferences(DFX_COMMON_XML, errCode);
607 if (!prefs) {
608 MEDIA_ERR_LOG("get dfx common preferences error: %{public}d", errCode);
609 return;
610 }
611 int64_t time = prefs->GetLong(CLOUD_SYNC_START_TIME, 0);
612 // if startTime exists, no need to reset startTime
613 if (time != 0) {
614 return;
615 }
616 time = MediaFileUtils::UTCTimeSeconds();
617 prefs->PutLong(CLOUD_SYNC_START_TIME, time);
618 prefs->FlushSync();
619 }
620
621 } // namespace Media
622 } // namespace OHOS