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