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