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