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